1 /* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 #include <android-base/stringprintf.h> 17 #include <base/logging.h> 18 #include <nativehelper/ScopedPrimitiveArray.h> 19 #include <nativehelper/ScopedUtfChars.h> 20 21 #include "JavaClassConstants.h" 22 #include "PeerToPeer.h" 23 24 using android::base::StringPrintf; 25 26 extern bool nfc_debug_enabled; 27 28 namespace android { 29 30 /******************************************************************************* 31 ** 32 ** Function: nativeLlcpSocket_doConnect 33 ** 34 ** Description: Establish a connection to the peer. 35 ** e: JVM environment. 36 ** o: Java object. 37 ** nSap: Service access point. 38 ** 39 ** Returns: True if ok. 40 ** 41 *******************************************************************************/ 42 static jboolean nativeLlcpSocket_doConnect(JNIEnv* e, jobject o, jint nSap) { 43 DLOG_IF(INFO, nfc_debug_enabled) 44 << StringPrintf("%s: enter; sap=%d", __func__, nSap); 45 46 PeerToPeer::tJNI_HANDLE jniHandle = 47 (PeerToPeer::tJNI_HANDLE)nfc_jni_get_nfc_socket_handle(e, o); 48 bool stat = PeerToPeer::getInstance().connectConnOriented(jniHandle, nSap); 49 50 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: exit", __func__); 51 return stat ? JNI_TRUE : JNI_FALSE; 52 } 53 54 /******************************************************************************* 55 ** 56 ** Function: nativeLlcpSocket_doConnectBy 57 ** 58 ** Description: Establish a connection to the peer. 59 ** e: JVM environment. 60 ** o: Java object. 61 ** sn: Service name. 62 ** 63 ** Returns: True if ok. 64 ** 65 *******************************************************************************/ 66 static jboolean nativeLlcpSocket_doConnectBy(JNIEnv* e, jobject o, jstring sn) { 67 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: enter", __func__); 68 69 PeerToPeer::tJNI_HANDLE jniHandle = 70 (PeerToPeer::tJNI_HANDLE)nfc_jni_get_nfc_socket_handle(e, o); 71 72 ScopedUtfChars serviceName(e, sn); 73 if (serviceName.c_str() == NULL) { 74 return JNI_FALSE; 75 } 76 bool stat = PeerToPeer::getInstance().connectConnOriented( 77 jniHandle, serviceName.c_str()); 78 79 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: exit", __func__); 80 return stat ? JNI_TRUE : JNI_FALSE; 81 } 82 83 /******************************************************************************* 84 ** 85 ** Function: nativeLlcpSocket_doClose 86 ** 87 ** Description: Close socket. 88 ** e: JVM environment. 89 ** o: Java object. 90 ** 91 ** Returns: True if ok. 92 ** 93 *******************************************************************************/ 94 static jboolean nativeLlcpSocket_doClose(JNIEnv* e, jobject o) { 95 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: enter", __func__); 96 97 PeerToPeer::tJNI_HANDLE jniHandle = 98 (PeerToPeer::tJNI_HANDLE)nfc_jni_get_nfc_socket_handle(e, o); 99 bool stat = PeerToPeer::getInstance().disconnectConnOriented(jniHandle); 100 101 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: exit", __func__); 102 return stat ? JNI_TRUE : JNI_FALSE; 103 } 104 105 /******************************************************************************* 106 ** 107 ** Function: nativeLlcpSocket_doSend 108 ** 109 ** Description: Send data to peer. 110 ** e: JVM environment. 111 ** o: Java object. 112 ** data: Buffer of data. 113 ** 114 ** Returns: True if sent ok. 115 ** 116 *******************************************************************************/ 117 static jboolean nativeLlcpSocket_doSend(JNIEnv* e, jobject o, jbyteArray data) { 118 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: enter", __func__); 119 120 ScopedByteArrayRO bytes(e, data); 121 122 PeerToPeer::tJNI_HANDLE jniHandle = 123 (PeerToPeer::tJNI_HANDLE)nfc_jni_get_nfc_socket_handle(e, o); 124 uint8_t* raw_ptr = const_cast<uint8_t*>(reinterpret_cast<const uint8_t*>( 125 &bytes[0])); // TODO: API bug: send should take const*! 126 bool stat = PeerToPeer::getInstance().send(jniHandle, raw_ptr, bytes.size()); 127 128 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: exit", __func__); 129 return stat ? JNI_TRUE : JNI_FALSE; 130 } 131 132 /******************************************************************************* 133 ** 134 ** Function: nativeLlcpSocket_doReceive 135 ** 136 ** Description: Receive data from peer. 137 ** e: JVM environment. 138 ** o: Java object. 139 ** origBuffer: Buffer to put received data. 140 ** 141 ** Returns: Number of bytes received. 142 ** 143 *******************************************************************************/ 144 static jint nativeLlcpSocket_doReceive(JNIEnv* e, jobject o, 145 jbyteArray origBuffer) { 146 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: enter", __func__); 147 148 ScopedByteArrayRW bytes(e, origBuffer); 149 150 PeerToPeer::tJNI_HANDLE jniHandle = 151 (PeerToPeer::tJNI_HANDLE)nfc_jni_get_nfc_socket_handle(e, o); 152 uint16_t actualLen = 0; 153 bool stat = PeerToPeer::getInstance().receive( 154 jniHandle, reinterpret_cast<uint8_t*>(&bytes[0]), bytes.size(), 155 actualLen); 156 157 jint retval = 0; 158 if (stat && (actualLen > 0)) { 159 retval = actualLen; 160 } else 161 retval = -1; 162 163 DLOG_IF(INFO, nfc_debug_enabled) 164 << StringPrintf("%s: exit; actual len=%d", __func__, retval); 165 return retval; 166 } 167 168 /******************************************************************************* 169 ** 170 ** Function: nativeLlcpSocket_doGetRemoteSocketMIU 171 ** 172 ** Description: Get peer's maximum information unit. 173 ** e: JVM environment. 174 ** o: Java object. 175 ** 176 ** Returns: Peer's maximum information unit. 177 ** 178 *******************************************************************************/ 179 static jint nativeLlcpSocket_doGetRemoteSocketMIU(JNIEnv* e, jobject o) { 180 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: enter", __func__); 181 182 PeerToPeer::tJNI_HANDLE jniHandle = 183 (PeerToPeer::tJNI_HANDLE)nfc_jni_get_nfc_socket_handle(e, o); 184 jint miu = PeerToPeer::getInstance().getRemoteMaxInfoUnit(jniHandle); 185 186 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: exit", __func__); 187 return miu; 188 } 189 190 /******************************************************************************* 191 ** 192 ** Function: nativeLlcpSocket_doGetRemoteSocketRW 193 ** 194 ** Description: Get peer's receive window size. 195 ** e: JVM environment. 196 ** o: Java object. 197 ** 198 ** Returns: Peer's receive window size. 199 ** 200 *******************************************************************************/ 201 static jint nativeLlcpSocket_doGetRemoteSocketRW(JNIEnv* e, jobject o) { 202 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: enter", __func__); 203 204 PeerToPeer::tJNI_HANDLE jniHandle = 205 (PeerToPeer::tJNI_HANDLE)nfc_jni_get_nfc_socket_handle(e, o); 206 jint rw = PeerToPeer::getInstance().getRemoteRecvWindow(jniHandle); 207 208 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: exit", __func__); 209 return rw; 210 } 211 212 /***************************************************************************** 213 ** 214 ** Description: JNI functions 215 ** 216 *****************************************************************************/ 217 static JNINativeMethod gMethods[] = { 218 {"doConnect", "(I)Z", (void*)nativeLlcpSocket_doConnect}, 219 {"doConnectBy", "(Ljava/lang/String;)Z", 220 (void*)nativeLlcpSocket_doConnectBy}, 221 {"doClose", "()Z", (void*)nativeLlcpSocket_doClose}, 222 {"doSend", "([B)Z", (void*)nativeLlcpSocket_doSend}, 223 {"doReceive", "([B)I", (void*)nativeLlcpSocket_doReceive}, 224 {"doGetRemoteSocketMiu", "()I", 225 (void*)nativeLlcpSocket_doGetRemoteSocketMIU}, 226 {"doGetRemoteSocketRw", "()I", (void*)nativeLlcpSocket_doGetRemoteSocketRW}, 227 }; 228 229 /******************************************************************************* 230 ** 231 ** Function: register_com_android_nfc_NativeLlcpSocket 232 ** 233 ** Description: Regisgter JNI functions with Java Virtual Machine. 234 ** e: Environment of JVM. 235 ** 236 ** Returns: Status of registration. 237 ** 238 *******************************************************************************/ 239 int register_com_android_nfc_NativeLlcpSocket(JNIEnv* e) { 240 return jniRegisterNativeMethods(e, gNativeLlcpSocketClassName, gMethods, 241 NELEM(gMethods)); 242 } 243 244 } // namespace android 245