Home | History | Annotate | Download | only in jni
      1 /*
      2  * Copyright (C) 2010 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 <semaphore.h>
     18 
     19 #include "com_android_nfc.h"
     20 
     21 static sem_t *nfc_jni_llcp_sem;
     22 static NFCSTATUS nfc_jni_cb_status = NFCSTATUS_FAILED;
     23 
     24 
     25 namespace android {
     26 
     27 extern phLibNfc_Handle hIncommingLlcpSocket;
     28 extern sem_t *nfc_jni_llcp_listen_sem;
     29 extern void nfc_jni_llcp_transport_socket_err_callback(void*      pContext,
     30                                                               uint8_t    nErrCode);
     31 /*
     32  * Callbacks
     33  */
     34 static void nfc_jni_llcp_accept_socket_callback(void*        pContext,
     35                                                        NFCSTATUS    status)
     36 {
     37    PHNFC_UNUSED_VARIABLE(pContext);
     38 
     39    LOG_CALLBACK("nfc_jni_llcp_accept_socket_callback", status);
     40 
     41    nfc_jni_cb_status = status;
     42 
     43    sem_post(nfc_jni_llcp_sem);
     44 }
     45 
     46 
     47 /*
     48  * Methods
     49  */
     50 static jobject com_NativeLlcpServiceSocket_doAccept(JNIEnv *e, jobject o, jint miu, jint rw, jint linearBufferLength)
     51 {
     52    NFCSTATUS ret;
     53    struct timespec ts;
     54    phLibNfc_Llcp_sSocketOptions_t sOptions;
     55    phNfc_sData_t sWorkingBuffer;
     56    jfieldID f;
     57    jclass clsNativeLlcpSocket;
     58    jobject clientSocket = 0;
     59 
     60 
     61    /* Wait for tag Notification */
     62    if(sem_wait(nfc_jni_llcp_listen_sem) == -1)
     63    {
     64       return NULL;
     65    }
     66 
     67    /* Set socket options with the socket options of the service */
     68    sOptions.miu = miu;
     69    sOptions.rw = rw;
     70 
     71    /* Allocate Working buffer length */
     72    sWorkingBuffer.buffer = (uint8_t*)malloc((miu*rw)+miu+linearBufferLength);
     73    sWorkingBuffer.length = (miu*rw)+ miu + linearBufferLength;
     74 
     75    /* Accept the incomming socket */
     76    TRACE("phLibNfc_Llcp_Accept()");
     77    REENTRANCE_LOCK();
     78    ret = phLibNfc_Llcp_Accept( hIncommingLlcpSocket,
     79                                &sOptions,
     80                                &sWorkingBuffer,
     81                                nfc_jni_llcp_transport_socket_err_callback,
     82                                nfc_jni_llcp_accept_socket_callback,
     83                                (void*)hIncommingLlcpSocket);
     84    REENTRANCE_UNLOCK();
     85    if(ret != NFCSTATUS_PENDING)
     86    {
     87       LOGE("phLibNfc_Llcp_Accept() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
     88       return NULL;
     89    }
     90    TRACE("phLibNfc_Llcp_Accept() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
     91 
     92    /* Wait for tag Notification */
     93    if(sem_wait(nfc_jni_llcp_sem) == -1)
     94    {
     95          return NULL;
     96    }
     97 
     98    if(nfc_jni_cb_status == NFCSTATUS_SUCCESS)
     99    {
    100       /* Create new LlcpSocket object */
    101       if(nfc_jni_cache_object(e,"com/android/nfc/NativeLlcpSocket",&(clientSocket)) == -1)
    102       {
    103          LOGD("LLCP Socket creation error");
    104          return NULL;
    105       }
    106 
    107       /* Get NativeConnectionOriented class object */
    108       clsNativeLlcpSocket = e->GetObjectClass(clientSocket);
    109       if(e->ExceptionCheck())
    110       {
    111          LOGD("LLCP Socket get class object error");
    112          return NULL;
    113       }
    114 
    115       /* Set socket handle */
    116       f = e->GetFieldID(clsNativeLlcpSocket, "mHandle", "I");
    117       e->SetIntField(clientSocket, f,(jint)hIncommingLlcpSocket);
    118 
    119       /* Set socket MIU */
    120       f = e->GetFieldID(clsNativeLlcpSocket, "mLocalMiu", "I");
    121       e->SetIntField(clientSocket, f,(jint)miu);
    122 
    123       /* Set socket RW */
    124       f = e->GetFieldID(clsNativeLlcpSocket, "mLocalRw", "I");
    125       e->SetIntField(clientSocket, f,(jint)rw);
    126 
    127       TRACE("socket handle 0x%02x: MIU = %d, RW = %d\n",hIncommingLlcpSocket, miu, rw);
    128 
    129       return clientSocket;
    130 
    131    }
    132    else
    133    {
    134       return NULL;
    135    }
    136 }
    137 
    138 static jboolean com_NativeLlcpServiceSocket_doClose(JNIEnv *e, jobject o)
    139 {
    140    NFCSTATUS ret;
    141    phLibNfc_Handle hLlcpSocket;
    142    TRACE("Close Service socket");
    143 
    144    /* Retrieve socket handle */
    145    hLlcpSocket = nfc_jni_get_nfc_socket_handle(e,o);
    146 
    147    REENTRANCE_LOCK();
    148    ret = phLibNfc_Llcp_Close(hLlcpSocket);
    149    REENTRANCE_UNLOCK();
    150    if(ret == NFCSTATUS_SUCCESS)
    151    {
    152       TRACE("Close Service socket OK");
    153       return TRUE;
    154    }
    155    else
    156    {
    157       LOGD("Close Service socket KO");
    158       return FALSE;
    159    }
    160 }
    161 
    162 
    163 /*
    164  * JNI registration.
    165  */
    166 static JNINativeMethod gMethods[] =
    167 {
    168    {"doAccept", "(III)Lcom/android/nfc/NativeLlcpSocket;",
    169       (void *)com_NativeLlcpServiceSocket_doAccept},
    170 
    171    {"doClose", "()Z",
    172       (void *)com_NativeLlcpServiceSocket_doClose},
    173 };
    174 
    175 
    176 int register_com_android_nfc_NativeLlcpServiceSocket(JNIEnv *e)
    177 {
    178     nfc_jni_llcp_sem = (sem_t *)malloc(sizeof(sem_t));
    179    if(sem_init(nfc_jni_llcp_sem, 0, 0) == -1)
    180       return -1;
    181 
    182    return jniRegisterNativeMethods(e,
    183       "com/android/nfc/NativeLlcpServiceSocket",
    184       gMethods, NELEM(gMethods));
    185 }
    186 
    187 } // namespace android
    188