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 *******************************************************************************/
nativeLlcpSocket_doConnect(JNIEnv * e,jobject o,jint nSap)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 *******************************************************************************/
nativeLlcpSocket_doConnectBy(JNIEnv * e,jobject o,jstring sn)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 *******************************************************************************/
nativeLlcpSocket_doClose(JNIEnv * e,jobject o)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 *******************************************************************************/
nativeLlcpSocket_doSend(JNIEnv * e,jobject o,jbyteArray data)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 *******************************************************************************/
nativeLlcpSocket_doReceive(JNIEnv * e,jobject o,jbyteArray origBuffer)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 *******************************************************************************/
nativeLlcpSocket_doGetRemoteSocketMIU(JNIEnv * e,jobject o)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 *******************************************************************************/
nativeLlcpSocket_doGetRemoteSocketRW(JNIEnv * e,jobject o)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 *******************************************************************************/
register_com_android_nfc_NativeLlcpSocket(JNIEnv * e)239 int register_com_android_nfc_NativeLlcpSocket(JNIEnv* e) {
240 return jniRegisterNativeMethods(e, gNativeLlcpSocketClassName, gMethods,
241 NELEM(gMethods));
242 }
243
244 } // namespace android
245