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 
17 #include <android-base/stringprintf.h>
18 #include <base/logging.h>
19 #include <nativehelper/JNIHelp.h>
20 
21 #include "JavaClassConstants.h"
22 #include "NfcAdaptation.h"
23 #include "NfcJniUtil.h"
24 #include "PeerToPeer.h"
25 #include "nfa_api.h"
26 #include "nfa_p2p_api.h"
27 
28 using android::base::StringPrintf;
29 
30 extern bool nfc_debug_enabled;
31 
32 namespace android {
33 
34 /*******************************************************************************
35 **
36 ** Function:        nativeLlcpServiceSocket_doAccept
37 **
38 ** Description:     Accept a connection request from a peer.
39 **                  e: JVM environment.
40 **                  o: Java object.
41 **                  miu: Maximum information unit.
42 **                  rw: Receive window.
43 **                  linearBufferLength: Not used.
44 **
45 ** Returns:         LlcpSocket Java object.
46 **
47 *******************************************************************************/
nativeLlcpServiceSocket_doAccept(JNIEnv * e,jobject o,jint miu,jint rw,jint)48 static jobject nativeLlcpServiceSocket_doAccept(JNIEnv* e, jobject o, jint miu,
49                                                 jint rw,
50                                                 jint /*linearBufferLength*/) {
51   jobject clientSocket = NULL;
52   jclass clsNativeLlcpSocket = NULL;
53   jfieldID f = 0;
54   PeerToPeer::tJNI_HANDLE serverHandle;  // handle of the local server
55   bool stat = false;
56   PeerToPeer::tJNI_HANDLE connHandle =
57       PeerToPeer::getInstance().getNewJniHandle();
58 
59   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: enter", __func__);
60 
61   serverHandle = (PeerToPeer::tJNI_HANDLE)nfc_jni_get_nfc_socket_handle(e, o);
62 
63   stat = PeerToPeer::getInstance().accept(serverHandle, connHandle, miu, rw);
64 
65   if (!stat) {
66     LOG(ERROR) << StringPrintf("%s: fail accept", __func__);
67     goto TheEnd;
68   }
69 
70   /* Create new LlcpSocket object */
71   if (nfc_jni_cache_object_local(e, gNativeLlcpSocketClassName,
72                                  &(clientSocket)) == -1) {
73     LOG(ERROR) << StringPrintf("%s: fail create NativeLlcpSocket", __func__);
74     goto TheEnd;
75   }
76 
77   /* Get NativeConnectionOriented class object */
78   clsNativeLlcpSocket = e->GetObjectClass(clientSocket);
79   if (e->ExceptionCheck()) {
80     e->ExceptionClear();
81     LOG(ERROR) << StringPrintf("%s: get class object error", __func__);
82     goto TheEnd;
83   }
84 
85   /* Set socket handle */
86   f = e->GetFieldID(clsNativeLlcpSocket, "mHandle", "I");
87   e->SetIntField(clientSocket, f, (jint)connHandle);
88 
89   /* Set socket MIU */
90   f = e->GetFieldID(clsNativeLlcpSocket, "mLocalMiu", "I");
91   e->SetIntField(clientSocket, f, (jint)miu);
92 
93   /* Set socket RW */
94   f = e->GetFieldID(clsNativeLlcpSocket, "mLocalRw", "I");
95   e->SetIntField(clientSocket, f, (jint)rw);
96 
97 TheEnd:
98   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: exit", __func__);
99   return clientSocket;
100 }
101 
102 /*******************************************************************************
103 **
104 ** Function:        nativeLlcpServiceSocket_doClose
105 **
106 ** Description:     Close a server socket.
107 **                  e: JVM environment.
108 **                  o: Java object.
109 **
110 ** Returns:         True if ok.
111 **
112 *******************************************************************************/
nativeLlcpServiceSocket_doClose(JNIEnv * e,jobject o)113 static jboolean nativeLlcpServiceSocket_doClose(JNIEnv* e, jobject o) {
114   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: enter", __func__);
115   PeerToPeer::tJNI_HANDLE jniServerHandle = 0;
116   bool stat = false;
117 
118   jniServerHandle = nfc_jni_get_nfc_socket_handle(e, o);
119 
120   stat = PeerToPeer::getInstance().deregisterServer(jniServerHandle);
121 
122   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: exit", __func__);
123   return JNI_TRUE;
124 }
125 
126 /*****************************************************************************
127 **
128 ** Description:     JNI functions
129 **
130 *****************************************************************************/
131 static JNINativeMethod gMethods[] = {
132     {"doAccept", "(III)Lcom/android/nfc/dhimpl/NativeLlcpSocket;",
133      (void*)nativeLlcpServiceSocket_doAccept},
134     {"doClose", "()Z", (void*)nativeLlcpServiceSocket_doClose},
135 };
136 
137 /*******************************************************************************
138 **
139 ** Function:        register_com_android_nfc_NativeLlcpServiceSocket
140 **
141 ** Description:     Regisgter JNI functions with Java Virtual Machine.
142 **                  e: Environment of JVM.
143 **
144 ** Returns:         Status of registration.
145 **
146 *******************************************************************************/
register_com_android_nfc_NativeLlcpServiceSocket(JNIEnv * e)147 int register_com_android_nfc_NativeLlcpServiceSocket(JNIEnv* e) {
148   return jniRegisterNativeMethods(e, gNativeLlcpServiceSocketClassName,
149                                   gMethods, NELEM(gMethods));
150 }
151 
152 }  // namespace android
153