| /* |
| * Copyright (c) 2016 Cisco and/or its affiliates. |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at: |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| #ifndef __included_vppjni_h__ |
| #define __included_vppjni_h__ |
| |
| #include <vnet/vnet.h> |
| #include <vnet/ip/ip.h> |
| #include <vnet/api_errno.h> |
| #include <vlibapi/api.h> |
| #include <vlibmemory/api.h> |
| #include <jni.h> |
| |
| typedef struct { |
| /* Unique identifier used for matching replays with requests */ |
| volatile u32 context_id; |
| |
| /* Spinlock */ |
| volatile u32 lock; |
| u32 tag; |
| |
| /* Used for first control ping */ |
| // TODO better names? |
| volatile u32 result_ready; |
| volatile i32 retval; |
| |
| /* JNI Native Method Interface pointer for message handlers */ |
| JNIEnv *jenv; |
| |
| /* thread cleanup */ |
| pthread_key_t cleanup_rx_thread_key; |
| |
| /* JNI Invoke Interface pointer for attachment of rx thread to java thread */ |
| JavaVM *jvm; |
| |
| /* Callback object and class references enabling asynchronous Java calls */ |
| jobject callback; |
| jclass callbackClass; |
| |
| /* Connected indication */ |
| volatile u8 is_connected; |
| |
| /* Convenience */ |
| unix_shared_memory_queue_t * vl_input_queue; |
| u32 my_client_index; |
| |
| } vppjni_main_t; |
| |
| vppjni_main_t vppjni_main __attribute__((aligned (64))); |
| |
| static inline u32 vppjni_get_context_id (vppjni_main_t * jm) |
| { |
| return __sync_add_and_fetch (&jm->context_id, 1); |
| } |
| |
| static inline void vppjni_lock (vppjni_main_t * jm, u32 tag) |
| { |
| while (__sync_lock_test_and_set (&jm->lock, 1)) |
| ; |
| jm->tag = tag; |
| } |
| |
| static inline void vppjni_unlock (vppjni_main_t * jm) |
| { |
| jm->tag = 0; |
| CLIB_MEMORY_BARRIER(); |
| jm->lock = 0; |
| } |
| |
| static inline int vppjni_sanity_check (vppjni_main_t * jm) |
| { |
| if (!jm->is_connected) |
| return VNET_API_ERROR_NOT_CONNECTED; |
| return 0; |
| } |
| |
| // TODO remove macros (code is now fully autogenerated) |
| |
| /* M: construct, but don't yet send a message */ |
| #define M(T,t) \ |
| do { \ |
| jm->result_ready = 0; \ |
| mp = vl_msg_api_alloc(sizeof(*mp)); \ |
| memset (mp, 0, sizeof (*mp)); \ |
| mp->_vl_msg_id = ntohs (VL_API_##T); \ |
| mp->client_index = jm->my_client_index; \ |
| } while(0); |
| |
| #define M2(T,t,n) \ |
| do { \ |
| jm->result_ready = 0; \ |
| mp = vl_msg_api_alloc(sizeof(*mp)+(n)); \ |
| memset (mp, 0, sizeof (*mp)); \ |
| mp->_vl_msg_id = ntohs (VL_API_##T); \ |
| mp->client_index = jm->my_client_index; \ |
| } while(0); |
| |
| /* S: send a message */ |
| #define S (vl_msg_api_send_shmem (jm->vl_input_queue, (u8 *)&mp)) |
| |
| #endif /* __included_vppjni_h__ */ |