| /* |
| * Copyright 2016, The Android Open Source Project |
| * |
| * 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. |
| */ |
| |
| #define LOG_TAG "wifinan" |
| |
| #include "jni.h" |
| #include "JniConstants.h" |
| #include <ScopedUtfChars.h> |
| #include <ScopedBytes.h> |
| #include <utils/misc.h> |
| #include <utils/Log.h> |
| #include <utils/String16.h> |
| #include <ctype.h> |
| #include <stdlib.h> |
| #include <sys/socket.h> |
| #include <linux/if.h> |
| #include "wifi.h" |
| #include "wifi_hal.h" |
| #include "jni_helper.h" |
| |
| namespace android { |
| |
| static jclass mCls; /* saved WifiNanNative object */ |
| static JavaVM *mVM = NULL; /* saved JVM pointer */ |
| |
| wifi_handle getWifiHandle(JNIHelper &helper, jclass cls); |
| wifi_interface_handle getIfaceHandle(JNIHelper &helper, jclass cls, jint index); |
| |
| extern wifi_hal_fn hal_fn; |
| |
| // Start NAN functions |
| |
| static void OnNanNotifyResponse(transaction_id id, NanResponseMsg* msg) { |
| ALOGD( |
| "OnNanNotifyResponse: transaction_id=%d, status=%d, value=%d, response_type=%d", |
| id, msg->status, msg->value, msg->response_type); |
| |
| JNIHelper helper(mVM); |
| switch (msg->response_type) { |
| case NAN_RESPONSE_PUBLISH: |
| helper.reportEvent(mCls, "onNanNotifyResponsePublishSubscribe", |
| "(SIIII)V", (short) id, (int) msg->response_type, |
| (int) msg->status, (int) msg->value, |
| msg->body.publish_response.publish_id); |
| break; |
| case NAN_RESPONSE_SUBSCRIBE: |
| helper.reportEvent(mCls, "onNanNotifyResponsePublishSubscribe", |
| "(SIIII)V", (short) id, (int) msg->response_type, |
| (int) msg->status, (int) msg->value, |
| msg->body.subscribe_response.subscribe_id); |
| break; |
| case NAN_GET_CAPABILITIES: { |
| JNIObject<jobject> data = helper.createObject( |
| "com/android/server/wifi/nan/WifiNanNative$Capabilities"); |
| if (data == NULL) { |
| ALOGE( |
| "Error in allocating WifiNanNative.Capabilities OnNanNotifyResponse"); |
| return; |
| } |
| |
| helper.setIntField( |
| data, "maxConcurrentNanClusters", |
| (int) msg->body.nan_capabilities.max_concurrent_nan_clusters); |
| helper.setIntField(data, "maxPublishes", |
| (int) msg->body.nan_capabilities.max_publishes); |
| helper.setIntField(data, "maxSubscribes", |
| (int) msg->body.nan_capabilities.max_subscribes); |
| helper.setIntField(data, "maxServiceNameLen", |
| (int) msg->body.nan_capabilities.max_service_name_len); |
| helper.setIntField(data, "maxMatchFilterLen", |
| (int) msg->body.nan_capabilities.max_match_filter_len); |
| helper.setIntField( |
| data, "maxTotalMatchFilterLen", |
| (int) msg->body.nan_capabilities.max_total_match_filter_len); |
| helper.setIntField( |
| data, "maxServiceSpecificInfoLen", |
| (int) msg->body.nan_capabilities.max_service_specific_info_len); |
| helper.setIntField(data, "maxVsaDataLen", |
| (int) msg->body.nan_capabilities.max_vsa_data_len); |
| helper.setIntField(data, "maxMeshDataLen", |
| (int) msg->body.nan_capabilities.max_mesh_data_len); |
| helper.setIntField(data, "maxNdiInterfaces", |
| (int) msg->body.nan_capabilities.max_ndi_interfaces); |
| helper.setIntField(data, "maxNdpSessions", |
| (int) msg->body.nan_capabilities.max_ndp_sessions); |
| helper.setIntField(data, "maxAppInfoLen", |
| (int) msg->body.nan_capabilities.max_app_info_len); |
| helper.setIntField(data, "maxQueuedTransmitMessages", |
| (int) msg->body.nan_capabilities.max_queued_transmit_followup_msgs); |
| |
| helper.reportEvent( |
| mCls, "onNanNotifyResponseCapabilities", |
| "(SIILcom/android/server/wifi/nan/WifiNanNative$Capabilities;)V", |
| (short) id, (int) msg->status, (int) msg->value, data.get()); |
| break; |
| } |
| default: |
| helper.reportEvent(mCls, "onNanNotifyResponse", "(SIII)V", (short) id, |
| (int) msg->response_type, (int) msg->status, |
| (int) msg->value); |
| break; |
| } |
| } |
| |
| static void OnNanEventPublishTerminated(NanPublishTerminatedInd* event) { |
| ALOGD("OnNanEventPublishTerminated"); |
| |
| JNIHelper helper(mVM); |
| helper.reportEvent(mCls, "onPublishTerminated", "(II)V", |
| event->publish_id, event->reason); |
| } |
| |
| static void OnNanEventMatch(NanMatchInd* event) { |
| ALOGD("OnNanEventMatch"); |
| |
| JNIHelper helper(mVM); |
| |
| JNIObject<jbyteArray> macBytes = helper.newByteArray(6); |
| helper.setByteArrayRegion(macBytes, 0, 6, (jbyte *) event->addr); |
| |
| JNIObject<jbyteArray> ssiBytes = helper.newByteArray(event->service_specific_info_len); |
| helper.setByteArrayRegion(ssiBytes, 0, event->service_specific_info_len, |
| (jbyte *) event->service_specific_info); |
| |
| JNIObject<jbyteArray> mfBytes = helper.newByteArray(event->sdf_match_filter_len); |
| helper.setByteArrayRegion(mfBytes, 0, event->sdf_match_filter_len, |
| (jbyte *) event->sdf_match_filter); |
| |
| helper.reportEvent(mCls, "onMatchEvent", "(II[B[BI[BI)V", |
| (int) event->publish_subscribe_id, |
| (int) event->requestor_instance_id, |
| macBytes.get(), |
| ssiBytes.get(), event->service_specific_info_len, |
| mfBytes.get(), event->sdf_match_filter_len); |
| } |
| |
| static void OnNanEventMatchExpired(NanMatchExpiredInd* event) { |
| ALOGD("OnNanEventMatchExpired"); |
| } |
| |
| static void OnNanEventSubscribeTerminated(NanSubscribeTerminatedInd* event) { |
| ALOGD("OnNanEventSubscribeTerminated"); |
| |
| JNIHelper helper(mVM); |
| helper.reportEvent(mCls, "onSubscribeTerminated", "(II)V", |
| event->subscribe_id, event->reason); |
| } |
| |
| static void OnNanEventFollowup(NanFollowupInd* event) { |
| ALOGD("OnNanEventFollowup"); |
| |
| JNIHelper helper(mVM); |
| |
| JNIObject<jbyteArray> macBytes = helper.newByteArray(6); |
| helper.setByteArrayRegion(macBytes, 0, 6, (jbyte *) event->addr); |
| |
| JNIObject<jbyteArray> msgBytes = helper.newByteArray(event->service_specific_info_len); |
| helper.setByteArrayRegion(msgBytes, 0, event->service_specific_info_len, (jbyte *) event->service_specific_info); |
| |
| helper.reportEvent(mCls, "onFollowupEvent", "(II[B[BI)V", |
| (int) event->publish_subscribe_id, |
| (int) event->requestor_instance_id, |
| macBytes.get(), |
| msgBytes.get(), |
| (int) event->service_specific_info_len); |
| } |
| |
| static void OnNanEventDiscEngEvent(NanDiscEngEventInd* event) { |
| ALOGD("OnNanEventDiscEngEvent called: event_type=%d", event->event_type); |
| |
| JNIHelper helper(mVM); |
| |
| JNIObject<jbyteArray> macBytes = helper.newByteArray(6); |
| if (event->event_type == NAN_EVENT_ID_DISC_MAC_ADDR) { |
| helper.setByteArrayRegion(macBytes, 0, 6, (jbyte *) event->data.mac_addr.addr); |
| } else { |
| helper.setByteArrayRegion(macBytes, 0, 6, (jbyte *) event->data.cluster.addr); |
| } |
| |
| helper.reportEvent(mCls, "onDiscoveryEngineEvent", "(I[B)V", |
| (int) event->event_type, macBytes.get()); |
| } |
| |
| static void OnNanEventDisabled(NanDisabledInd* event) { |
| ALOGD("OnNanEventDisabled called: reason=%d", event->reason); |
| |
| JNIHelper helper(mVM); |
| |
| helper.reportEvent(mCls, "onDisabledEvent", "(I)V", (int) event->reason); |
| } |
| |
| static void OnNanEventTca(NanTCAInd* event) { |
| ALOGD("OnNanEventTca"); |
| } |
| |
| static void OnNanEventBeaconSdfPayload(NanBeaconSdfPayloadInd* event) { |
| ALOGD("OnNanEventSdfPayload"); |
| } |
| |
| static void OnNanEventDataRequest(NanDataPathRequestInd* event) { |
| ALOGD("OnNanEventDataRequest"); |
| } |
| |
| static void OnNanEventDataConfirm(NanDataPathConfirmInd* event) { |
| ALOGD("OnNanEventDataConfirm"); |
| } |
| |
| static void OnNanEventDataEnd(NanDataPathEndInd* event) { |
| ALOGD("OnNanEventDataEnd"); |
| } |
| |
| static void OnNanEventTransmitFollowup(NanTransmitFollowupInd* event) { |
| ALOGD("OnNanEventTransmitFollowup: transaction_id=%d, reason=%d", event->id, |
| event->reason); |
| |
| JNIHelper helper(mVM); |
| |
| helper.reportEvent(mCls, "onTransmitFollowupEvent", "(SI)V", |
| (short) event->id, (int) event->reason); |
| } |
| |
| static jint android_net_wifi_nan_register_handler(JNIEnv *env, jclass cls, |
| jclass wifi_native_cls, |
| jint iface) { |
| JNIHelper helper(env); |
| wifi_interface_handle handle = getIfaceHandle(helper, wifi_native_cls, iface); |
| |
| ALOGD("android_net_wifi_nan_register_handler handle=%p", handle); |
| |
| NanCallbackHandler handlers; |
| memset(&handlers, 0, sizeof(NanCallbackHandler)); |
| handlers.NotifyResponse = OnNanNotifyResponse; |
| handlers.EventPublishTerminated = OnNanEventPublishTerminated; |
| handlers.EventMatch = OnNanEventMatch; |
| handlers.EventMatchExpired = OnNanEventMatchExpired; |
| handlers.EventSubscribeTerminated = OnNanEventSubscribeTerminated; |
| handlers.EventFollowup = OnNanEventFollowup; |
| handlers.EventDiscEngEvent = OnNanEventDiscEngEvent; |
| handlers.EventDisabled = OnNanEventDisabled; |
| handlers.EventTca = OnNanEventTca; |
| handlers.EventBeaconSdfPayload = OnNanEventBeaconSdfPayload; |
| handlers.EventDataRequest = OnNanEventDataRequest; |
| handlers.EventDataConfirm = OnNanEventDataConfirm; |
| handlers.EventDataEnd = OnNanEventDataEnd; |
| handlers.EventTransmitFollowup = OnNanEventTransmitFollowup; |
| |
| if (mVM == NULL) { |
| env->GetJavaVM(&mVM); |
| mCls = (jclass) env->NewGlobalRef(cls); |
| } |
| |
| return hal_fn.wifi_nan_register_handler(handle, handlers); |
| } |
| |
| static jint android_net_wifi_nan_enable_request(JNIEnv *env, jclass cls, |
| jshort transaction_id, |
| jclass wifi_native_cls, |
| jint iface, |
| jobject config_request) { |
| JNIHelper helper(env); |
| wifi_interface_handle handle = getIfaceHandle(helper, wifi_native_cls, iface); |
| |
| ALOGD("android_net_wifi_nan_enable_request handle=%p, id=%d", |
| handle, transaction_id); |
| |
| NanEnableRequest msg; |
| memset(&msg, 0, sizeof(NanEnableRequest)); |
| |
| /* configurable settings */ |
| msg.config_support_5g = 1; |
| msg.support_5g_val = helper.getBoolField(config_request, "mSupport5gBand"); |
| msg.master_pref = helper.getIntField(config_request, "mMasterPreference"); |
| msg.cluster_low = helper.getIntField(config_request, "mClusterLow"); |
| msg.cluster_high = helper.getIntField(config_request, "mClusterHigh"); |
| |
| return hal_fn.wifi_nan_enable_request(transaction_id, handle, &msg); |
| } |
| |
| static jint android_net_wifi_nan_config_request(JNIEnv *env, jclass cls, |
| jshort transaction_id, |
| jclass wifi_native_cls, |
| jint iface, |
| jobject config_request) { |
| JNIHelper helper(env); |
| wifi_interface_handle handle = getIfaceHandle(helper, wifi_native_cls, iface); |
| |
| ALOGD("android_net_wifi_nan_config_request handle=%p, id=%d", |
| handle, transaction_id); |
| |
| NanConfigRequest msg; |
| memset(&msg, 0, sizeof(NanConfigRequest)); |
| |
| /* configurable settings */ |
| msg.config_master_pref = 1; |
| msg.master_pref = helper.getIntField(config_request, "mMasterPreference"); |
| |
| return hal_fn.wifi_nan_config_request(transaction_id, handle, &msg); |
| } |
| |
| static jint android_net_wifi_nan_get_capabilities(JNIEnv *env, jclass cls, |
| jshort transaction_id, |
| jclass wifi_native_cls, |
| jint iface) { |
| JNIHelper helper(env); |
| wifi_interface_handle handle = getIfaceHandle(helper, wifi_native_cls, iface); |
| |
| ALOGD("android_net_wifi_nan_get_capabilities handle=%p, id=%d", handle, |
| transaction_id); |
| |
| return hal_fn.wifi_nan_get_capabilities(transaction_id, handle); |
| } |
| |
| static jint android_net_wifi_nan_disable_request(JNIEnv *env, jclass cls, |
| jshort transaction_id, |
| jclass wifi_native_cls, |
| jint iface) { |
| JNIHelper helper(env); |
| wifi_interface_handle handle = getIfaceHandle(helper, wifi_native_cls, iface); |
| |
| ALOGD("android_net_wifi_nan_disable_request handle=%p, id=%d", |
| handle, transaction_id); |
| |
| return hal_fn.wifi_nan_disable_request(transaction_id, handle); |
| } |
| |
| static jint android_net_wifi_nan_publish(JNIEnv *env, jclass cls, |
| jshort transaction_id, |
| jint publish_id, |
| jclass wifi_native_cls, |
| jint iface, |
| jobject publish_config) { |
| JNIHelper helper(env); |
| wifi_interface_handle handle = getIfaceHandle(helper, wifi_native_cls, iface); |
| |
| ALOGD("android_net_wifi_nan_publish handle=%p, id=%d", handle, transaction_id); |
| |
| NanPublishRequest msg; |
| memset(&msg, 0, sizeof(NanPublishRequest)); |
| |
| /* hard-coded settings - TBD: move to configurable */ |
| msg.period = 500; |
| msg.publish_match_indicator = NAN_MATCH_ALG_MATCH_ONCE; |
| msg.rssi_threshold_flag = 0; |
| msg.connmap = 0; |
| |
| /* configurable settings */ |
| msg.publish_id = publish_id; |
| |
| JNIObject<jstring> objStr1 = helper.getStringField(publish_config, "mServiceName"); |
| if (objStr1 == NULL) { |
| ALOGE("Error accessing mServiceName field"); |
| return 0; |
| } |
| ScopedUtfChars chars1(env, objStr1); |
| const char *serviceName = chars1.c_str(); |
| if (serviceName == NULL) { |
| ALOGE("Error getting mServiceName"); |
| return 0; |
| } |
| msg.service_name_len = strlen(serviceName); |
| strcpy((char*)msg.service_name, serviceName); |
| |
| msg.service_specific_info_len = helper.getIntField(publish_config, "mServiceSpecificInfoLength"); |
| if (msg.service_specific_info_len != 0) { |
| helper.getByteArrayField(publish_config, "mServiceSpecificInfo", |
| msg.service_specific_info, msg.service_specific_info_len); |
| } |
| |
| |
| msg.tx_match_filter_len = helper.getIntField(publish_config, "mTxFilterLength"); |
| if (msg.tx_match_filter_len != 0) { |
| helper.getByteArrayField(publish_config, "mTxFilter", |
| msg.tx_match_filter, msg.tx_match_filter_len); |
| } |
| |
| msg.rx_match_filter_len = helper.getIntField(publish_config, "mRxFilterLength"); |
| if (msg.rx_match_filter_len != 0) { |
| helper.getByteArrayField(publish_config, "mRxFilter", |
| msg.rx_match_filter, msg.rx_match_filter_len); |
| } |
| |
| msg.publish_type = (NanPublishType)helper.getIntField(publish_config, "mPublishType"); |
| msg.publish_count = helper.getIntField(publish_config, "mPublishCount"); |
| msg.ttl = helper.getIntField(publish_config, "mTtlSec"); |
| |
| msg.tx_type = NAN_TX_TYPE_BROADCAST; |
| if (msg.publish_type != NAN_PUBLISH_TYPE_UNSOLICITED) |
| msg.tx_type = NAN_TX_TYPE_UNICAST; |
| |
| msg.recv_indication_cfg = 0; |
| if (!helper.getBoolField(publish_config, "mEnableTerminateNotification")) { |
| msg.recv_indication_cfg |= 0x1; |
| } |
| |
| return hal_fn.wifi_nan_publish_request(transaction_id, handle, &msg); |
| } |
| |
| static jint android_net_wifi_nan_subscribe(JNIEnv *env, jclass cls, |
| jshort transaction_id, |
| jint subscribe_id, |
| jclass wifi_native_cls, |
| jint iface, |
| jobject subscribe_config) { |
| JNIHelper helper(env); |
| wifi_interface_handle handle = getIfaceHandle(helper, wifi_native_cls, iface); |
| |
| ALOGD("android_net_wifi_nan_subscribe handle=%p, id=%d", handle, transaction_id); |
| |
| NanSubscribeRequest msg; |
| memset(&msg, 0, sizeof(NanSubscribeRequest)); |
| |
| /* hard-coded settings - TBD: move to configurable */ |
| msg.period = 500; |
| msg.serviceResponseFilter = NAN_SRF_ATTR_PARTIAL_MAC_ADDR; |
| msg.serviceResponseInclude = NAN_SRF_INCLUDE_RESPOND; |
| msg.useServiceResponseFilter = NAN_DO_NOT_USE_SRF; |
| msg.ssiRequiredForMatchIndication = NAN_SSI_NOT_REQUIRED_IN_MATCH_IND; |
| msg.rssi_threshold_flag = 0; |
| msg.connmap = 0; |
| msg.num_intf_addr_present = 0; |
| |
| /* configurable settings */ |
| msg.subscribe_id = subscribe_id; |
| |
| JNIObject<jstring> objStr1 = helper.getStringField(subscribe_config, "mServiceName"); |
| if (objStr1 == NULL) { |
| ALOGE("Error accessing mServiceName field"); |
| return 0; |
| } |
| ScopedUtfChars chars1(env, objStr1); |
| const char *serviceName = chars1.c_str(); |
| if (serviceName == NULL) { |
| ALOGE("Error getting mServiceName"); |
| return 0; |
| } |
| msg.service_name_len = strlen(serviceName); |
| strcpy((char*)msg.service_name, serviceName); |
| |
| msg.service_specific_info_len = helper.getIntField(subscribe_config, "mServiceSpecificInfoLength"); |
| if (msg.service_specific_info_len != 0) { |
| helper.getByteArrayField(subscribe_config, "mServiceSpecificInfo", |
| msg.service_specific_info, msg.service_specific_info_len); |
| } |
| |
| msg.tx_match_filter_len = helper.getIntField(subscribe_config, "mTxFilterLength"); |
| if (msg.tx_match_filter_len != 0) { |
| helper.getByteArrayField(subscribe_config, "mTxFilter", |
| msg.tx_match_filter, msg.tx_match_filter_len); |
| } |
| |
| msg.rx_match_filter_len = helper.getIntField(subscribe_config, "mRxFilterLength"); |
| if (msg.rx_match_filter_len != 0) { |
| helper.getByteArrayField(subscribe_config, "mRxFilter", |
| msg.rx_match_filter, msg.rx_match_filter_len); |
| } |
| |
| msg.subscribe_type = (NanSubscribeType)helper.getIntField(subscribe_config, "mSubscribeType"); |
| msg.subscribe_count = helper.getIntField(subscribe_config, "mSubscribeCount"); |
| msg.ttl = helper.getIntField(subscribe_config, "mTtlSec"); |
| msg.subscribe_match_indicator = (NanMatchAlg) helper.getIntField( |
| subscribe_config, "mMatchStyle"); |
| |
| msg.recv_indication_cfg = 0; |
| if (!helper.getBoolField(subscribe_config, "mEnableTerminateNotification")) { |
| msg.recv_indication_cfg |= 0x1; |
| } |
| |
| return hal_fn.wifi_nan_subscribe_request(transaction_id, handle, &msg); |
| } |
| |
| static jint android_net_wifi_nan_send_message(JNIEnv *env, jclass cls, |
| jshort transaction_id, |
| jclass wifi_native_cls, |
| jint iface, |
| jint pub_sub_id, |
| jint req_instance_id, |
| jbyteArray dest, |
| jbyteArray message, |
| jint message_length) { |
| JNIHelper helper(env); |
| wifi_interface_handle handle = getIfaceHandle(helper, wifi_native_cls, iface); |
| |
| ALOGD("android_net_wifi_nan_send_message handle=%p, id=%d", handle, transaction_id); |
| |
| NanTransmitFollowupRequest msg; |
| memset(&msg, 0, sizeof(NanTransmitFollowupRequest)); |
| |
| /* hard-coded settings - TBD: move to configurable */ |
| msg.publish_subscribe_id = pub_sub_id; |
| msg.requestor_instance_id = req_instance_id; |
| msg.priority = NAN_TX_PRIORITY_NORMAL; |
| msg.dw_or_faw = NAN_TRANSMIT_IN_DW; |
| |
| /* configurable settings */ |
| msg.service_specific_info_len = message_length; |
| |
| ScopedBytesRO messageBytes(env, message); |
| memcpy(msg.service_specific_info, (byte*) messageBytes.get(), message_length); |
| |
| ScopedBytesRO destBytes(env, dest); |
| memcpy(msg.addr, (byte*) destBytes.get(), 6); |
| |
| return hal_fn.wifi_nan_transmit_followup_request(transaction_id, handle, &msg); |
| } |
| |
| static jint android_net_wifi_nan_stop_publish(JNIEnv *env, jclass cls, |
| jshort transaction_id, |
| jclass wifi_native_cls, |
| jint iface, |
| jint pub_sub_id) { |
| JNIHelper helper(env); |
| wifi_interface_handle handle = getIfaceHandle(helper, wifi_native_cls, iface); |
| |
| ALOGD("android_net_wifi_nan_stop_publish handle=%p, id=%d", handle, transaction_id); |
| |
| NanPublishCancelRequest msg; |
| memset(&msg, 0, sizeof(NanPublishCancelRequest)); |
| |
| msg.publish_id = pub_sub_id; |
| |
| return hal_fn.wifi_nan_publish_cancel_request(transaction_id, handle, &msg); |
| } |
| |
| static jint android_net_wifi_nan_stop_subscribe(JNIEnv *env, jclass cls, |
| jshort transaction_id, |
| jclass wifi_native_cls, |
| jint iface, |
| jint pub_sub_id) { |
| JNIHelper helper(env); |
| wifi_interface_handle handle = getIfaceHandle(helper, wifi_native_cls, iface); |
| |
| ALOGD("android_net_wifi_nan_stop_subscribe handle=%p, id=%d", handle, transaction_id); |
| |
| NanSubscribeCancelRequest msg; |
| memset(&msg, 0, sizeof(NanSubscribeCancelRequest)); |
| |
| msg.subscribe_id = pub_sub_id; |
| |
| return hal_fn.wifi_nan_subscribe_cancel_request(transaction_id, handle, &msg); |
| } |
| |
| // ---------------------------------------------------------------------------- |
| |
| /* |
| * JNI registration. |
| */ |
| |
| static JNINativeMethod gWifiNanMethods[] = { |
| /* name, signature, funcPtr */ |
| {"initNanHandlersNative", "(Ljava/lang/Class;I)I", (void*)android_net_wifi_nan_register_handler }, |
| {"getCapabilitiesNative", "(SLjava/lang/Class;I)I", (void*)android_net_wifi_nan_get_capabilities }, |
| {"enableAndConfigureNative", "(SLjava/lang/Class;ILandroid/net/wifi/nan/ConfigRequest;)I", (void*)android_net_wifi_nan_enable_request }, |
| {"updateConfigurationNative", "(SLjava/lang/Class;ILandroid/net/wifi/nan/ConfigRequest;)I", (void*)android_net_wifi_nan_config_request }, |
| {"disableNative", "(SLjava/lang/Class;I)I", (void*)android_net_wifi_nan_disable_request }, |
| {"publishNative", "(SILjava/lang/Class;ILandroid/net/wifi/nan/PublishConfig;)I", (void*)android_net_wifi_nan_publish }, |
| {"subscribeNative", "(SILjava/lang/Class;ILandroid/net/wifi/nan/SubscribeConfig;)I", (void*)android_net_wifi_nan_subscribe }, |
| {"sendMessageNative", "(SLjava/lang/Class;III[B[BI)I", (void*)android_net_wifi_nan_send_message }, |
| {"stopPublishNative", "(SLjava/lang/Class;II)I", (void*)android_net_wifi_nan_stop_publish }, |
| {"stopSubscribeNative", "(SLjava/lang/Class;II)I", (void*)android_net_wifi_nan_stop_subscribe }, |
| }; |
| |
| /* User to register native functions */ |
| extern "C" |
| jint Java_com_android_server_wifi_nan_WifiNanNative_registerNanNatives(JNIEnv* env, jclass clazz) { |
| return jniRegisterNativeMethods(env, |
| "com/android/server/wifi/nan/WifiNanNative", gWifiNanMethods, NELEM(gWifiNanMethods)); |
| } |
| |
| }; // namespace android |