/** * Query native security manager for permission. * This call may block if user needs to be asked. * * Java prototype: * <pre> * native boolean checkPermission0(String suiteId, String permission); * </pre> * @param suiteId the MIDlet suite the permission should be checked against * @param permission the permission id * @return true if permission is granted. Otherwise, false. */ KNIEXPORT KNI_RETURNTYPE_BOOLEAN Java_com_sun_midp_security_SecurityHandler_checkPermission0() { jboolean granted = KNI_FALSE; MidpReentryData* info = (MidpReentryData*)SNI_GetReentryData(NULL); if (!isListenerRegistered) { midpport_security_set_permission_listener(midpPermissionListener); isListenerRegistered = 1; } if (info == NULL) { /* initial invocation: send request */ jint requestHandle; jint suiteId = KNI_GetParameterAsInt(1); jint permId = KNI_GetParameterAsInt(2); jint result = midpport_security_check_permission(suiteId, permId, &requestHandle); if (result == 1) { granted = KNI_TRUE; } else if (result == -1) { /* Block the caller until the security listener is called */ midp_thread_wait(SECURITY_CHECK_SIGNAL, requestHandle, NULL); } } else { /* reinvocation: check result */ granted = (jboolean)(info->status); } KNI_ReturnBoolean(granted); }
/** * Gets a raw IPv4 address for the given hostname. * <p> * Java declaration: * <pre> * static getIpNumber([B)I * </pre> * * @param szHost the hostname to lookup as a 'C' string * @return raw IPv4 address or <tt>-1</tt> if there was an error */ KNIEXPORT KNI_RETURNTYPE_INT Java_com_sun_midp_io_j2me_datagram_Protocol_getIpNumber(void) { int len; int status; int ipn = -1; unsigned char ipBytes[MAX_ADDR_LENGTH]; void* context = NULL; void* handle; MidpReentryData* info; KNI_StartHandles(1); KNI_DeclareHandle(hostObject); KNI_GetParameterAsObject(1, hostObject); info = (MidpReentryData*)SNI_GetReentryData(NULL); if (info == NULL) { /* First invocation */ SNI_BEGIN_RAW_POINTERS; status = pcsl_network_gethostbyname_start( (char*)JavaByteArray(hostObject), ipBytes, MAX_ADDR_LENGTH, &len, &handle, &context); SNI_END_RAW_POINTERS; } else { /* Reinvocation after unblocking the thread */ handle = (void*)info->descriptor; /* IMPL NOTE: Please see 6440539 for details. */ /* All but windows implementations of pcsl_network_gethostbyname_finish */ /* ignore context parameter. Windows one expects status code there. */ context = (void*)info->status; status = pcsl_network_gethostbyname_finish(ipBytes, MAX_ADDR_LENGTH, &len, handle, context); } KNI_EndHandles(); if (status == PCSL_NET_SUCCESS) { /* * Convert the unsigned char ip bytes array into an integer * that represents a raw IP address. */ //ipn = pcsl_network_getRawIpNumber(ipBytes); memcpy(&ipn, ipBytes, MAX_ADDR_LENGTH); } else if (status == PCSL_NET_WOULDBLOCK) { midp_thread_wait(HOST_NAME_LOOKUP_SIGNAL, (int)handle, context); } else { /* status is either PCSL_NET_IOERROR or PCSL_NET_INVALID */ ipn = -1; REPORT_INFO1(LC_PROTOCOL, "datagram::getIpNumber returns PCSL error code %d", status); /* * IOException is thrown at the Java layer when return value * is -1 */ //KNI_ThrowNew(midpIOException, "Host name could not be resolved"); } KNI_ReturnInt((jint)ipn); }
void initDevice() { if (!(state & DEVICE_INITED)) { START_REQUEST APPEND_DEV_REQ(INIT_DEVICE); END_REQUEST if (NULL == SNI_GetReentryData(NULL)) { /* This condition preserves from calling midp_thread_wait twice without unblocking current thread. */ midp_thread_wait(JSR82_SIGNAL, BTE_SIGNAL_HANDLE, NULL); } }
/** * Receives an SMS message. * * @param port The port number to be matched against incoming SMS messages. * @param handle The handle to the open SMS message connection. * @param messageObject The Java message object to be populated. * * @return The length of the SMS message (in bytes). */ KNIEXPORT KNI_RETURNTYPE_INT KNIDECL(com_sun_midp_io_j2me_sms_Protocol_receive0) { #if ENABLE_REENTRY MidpReentryData *info = (MidpReentryData*)SNI_GetReentryData(NULL); #endif int port, handle; int messageLength = -1; SmsMessage *psmsData = NULL; /* The midlet suite name for this connection. */ AppIdType msid = UNUSED_APP_ID; jboolean isOpen; KNI_StartHandles(6); KNI_DeclareHandle(this); KNI_DeclareHandle(thisClass); KNI_GetThisPointer(this); KNI_GetObjectClass(this, thisClass); isOpen = KNI_GetBooleanField(this, KNI_GetFieldID(thisClass, "open", "Z")); if (isOpen) { /* No close in progress */ KNI_DeclareHandle(messageClazz); KNI_DeclareHandle(messageObject); KNI_DeclareHandle(addressArray); KNI_DeclareHandle(byteArray); port = KNI_GetParameterAsInt(1); msid = KNI_GetParameterAsInt(2); handle = KNI_GetParameterAsInt(3); KNI_GetParameterAsObject(4, messageObject); do { #if ENABLE_REENTRY if (!info) { #endif psmsData = jsr120_sms_pool_peek_next_msg((jchar)port); if (psmsData == NULL) { #if ENABLE_REENTRY /* block and wait for a message. */ midp_thread_wait(WMA_SMS_READ_SIGNAL, handle, NULL); #else do { CVMD_gcSafeExec(_ee, { jsr120_wait_for_signal(handle, WMA_SMS_READ_SIGNAL); }); psmsData = jsr120_sms_pool_peek_next_msg((jchar)port); isOpen = KNI_GetBooleanField(this, KNI_GetFieldID(thisClass, "open", "Z")); } while (psmsData == NULL && isOpen); #endif } #if ENABLE_REENTRY } else {
/** * private static native int getLinkCount0(); */ KNIEXPORT KNI_RETURNTYPE_INT Java_com_sun_midp_links_LinkPortal_getLinkCount0(void) { int retval = 0; int targetIsolate = JVM_CurrentIsolateID(); if (portals == NULL || portals[targetIsolate].count == -1) { midp_thread_wait(LINK_PORTAL_SIGNAL, targetIsolate, NULL); } else { retval = portals[targetIsolate].count; } KNI_ReturnInt(retval); }
/** * Performs platform lock of the device. * <p>Java declaration: * <pre> * private native boolean lock0(); * </pre> * @return KNI_TRUE in case of success, else KNI_FALSE */ KNIEXPORT KNI_RETURNTYPE_INT KNIDECL(com_sun_cardreader_PlatformCardDevice_lock0) { javacall_result lock_retcode = JAVACALL_OK; jboolean retcode = KNI_FALSE; if ((lock_retcode=javacall_carddevice_lock()) == JAVACALL_OK) { javacall_carddevice_clear_error(); retcode = KNI_TRUE; } else { if (lock_retcode == JAVACALL_WOULD_BLOCK) { midp_thread_wait(CARD_READER_DATA_SIGNAL, SIGNAL_LOCK, NULL); } } KNI_ReturnInt(retcode); }
void closePort(int hPort) { javacall_result ret; void* context = NULL; MidpReentryData* info = (MidpReentryData*)SNI_GetReentryData(NULL); if (info == NULL) { //first invocation ret = javacall_serial_close_start((javacall_handle)hPort); } else { /* Reinvocation */ hPort = info->descriptor; context = info->pResult; ret = javacall_serial_close_finish((javacall_handle)hPort); } if (JAVACALL_WOULD_BLOCK == ret) { midp_thread_wait(COMM_CLOSE_SIGNAL, hPort, context); } }
/** * Gets a raw IPv4 address for the given hostname. * <p> * Java declaration: * <pre> * getIpNumber([B)I * </pre> * * @param szHost the hostname to lookup as a 'C' string * @param ipBytes Output parameter that represents an unsigned char * array for an IP address * @return len Length of ipBytes * */ KNIEXPORT KNI_RETURNTYPE_INT Java_com_sun_midp_io_j2me_socket_Protocol_getIpNumber0(void) { int len = -1; int status = PCSL_NET_INVALID; unsigned char ipBytes[MAX_ADDR_LENGTH]; void* context = NULL; void* pcslHandle; MidpReentryData* info; KNI_StartHandles(2); KNI_DeclareHandle(hostObject); KNI_DeclareHandle(ipAddressObject); KNI_GetParameterAsObject(1, hostObject); KNI_GetParameterAsObject(2, ipAddressObject); info = (MidpReentryData*)SNI_GetReentryData(NULL); if (info == NULL) { /* First invocation */ SNI_BEGIN_RAW_POINTERS; status = pcsl_network_gethostbyname_start( (char*)JavaByteArray(hostObject), ipBytes, MAX_ADDR_LENGTH, &len, &pcslHandle, &context); SNI_END_RAW_POINTERS; } else { /* Reinvocation after unblocking the thread */ pcslHandle = (void*)info->descriptor; /* IMPL NOTE: Please see 6440539 for details. */ /* All but windows implementations of pcsl_network_gethostbyname_finish */ /* ignore context parameter. Windows one expects status code there. */ context = (void*)info->status; status = pcsl_network_gethostbyname_finish(ipBytes, MAX_ADDR_LENGTH, &len, pcslHandle, context); } if (status == PCSL_NET_SUCCESS) { KNI_SetRawArrayRegion(ipAddressObject, 0, len, (jbyte *)ipBytes); } else if (status == PCSL_NET_WOULDBLOCK) { midp_thread_wait(HOST_NAME_LOOKUP_SIGNAL, (int)pcslHandle, context); } else { /* must be PCSL_NET_IOERROR or PCSL_NET_INVALID */ len = -1; } KNI_EndHandles(); KNI_ReturnInt((jint)len); }
/** * Performs reset of the device. * <p>Java declaration: * <pre> * private native int reset0(byte[] atr); * </pre> * @param atr ATR bytes * @return Length of ATR in case of success, else -1 */ KNIEXPORT KNI_RETURNTYPE_INT KNIDECL(com_sun_cardreader_PlatformCardDevice_reset0) { jint retcode; javacall_int32 atr_length; char *atr_buffer; MidpReentryData* info; void *context = NULL; javacall_result status_code; KNI_StartHandles(1); KNI_DeclareHandle(atr_handle); info = (MidpReentryData*)SNI_GetReentryData(NULL); KNI_GetParameterAsObject(1, atr_handle); if (KNI_IsNullHandle(atr_handle)) { atr_buffer = NULL; atr_length = 0; } else { atr_length = KNI_GetArrayLength(atr_handle); atr_buffer = SNI_GetRawArrayPointer(atr_handle); } if (info == NULL) { status_code = javacall_carddevice_reset_start(atr_buffer, &atr_length, &context); } else { context = info->pResult; status_code = javacall_carddevice_reset_finish(atr_buffer, &atr_length, context); } if (status_code == JAVACALL_WOULD_BLOCK) { midp_thread_wait(CARD_READER_DATA_SIGNAL, SIGNAL_RESET, context); goto end; } if (status_code != JAVACALL_OK) { retcode = -1; } else { retcode = atr_length; } end: KNI_EndHandles(); KNI_ReturnInt(retcode); }
/** * Blocks Java thread that monitors specified event queue. * * @param queueId queue ID */ static void blockMonitorThread(jint queueId) { EventQueue* pEventQueue; jint isolateId; GET_EVENT_QUEUE_BY_ID(pEventQueue, queueId); if (IS_ISOLATE_QUEUE(queueId)) { /* * To speed up unblocking the event monitor thread, this thread * is saved as the "special" thread of an Isolate to avoid having * to search the entire list of threads. */ isolateId = QUEUE_ID_TO_ISOLATE_ID(queueId); SNI_SetSpecialThread(isolateId); SNI_BlockThread(); } else { /* Block thread in the normal way */ midp_thread_wait(EVENT_QUEUE_SIGNAL, queueId, 0); } pEventQueue->isMonitorBlocked = KNI_TRUE; }
/** * Checks if this slot is SAT slot. * <p>Java declaration: * <pre> * private native int isSatSlot0(int slotNumber); * </pre> * @param slotNumber Slot number * @return <code> 1</code> if the slot is dedicated for SAT, * <code> 0</code> if not, * <code>-1</code> if any error occured */ KNIEXPORT KNI_RETURNTYPE_INT KNIDECL(com_sun_cardreader_PlatformCardDevice_isSatSlot0) { jint retcode; javacall_bool result; MidpReentryData* info; javacall_result status_code; void *context = NULL; int slotIndex = KNI_GetParameterAsInt(1); info = (MidpReentryData*)SNI_GetReentryData(NULL); if (info == NULL) { status_code = javacall_carddevice_is_sat_start(slotIndex, &result, &context); } else { context = info->pResult; status_code = javacall_carddevice_is_sat_finish(slotIndex, &result, context); } if (status_code == JAVACALL_WOULD_BLOCK) { midp_thread_wait(CARD_READER_DATA_SIGNAL, SIGNAL_XFER, context); goto end; } if (status_code != JAVACALL_OK) { retcode = -1; } else { if (result == JAVACALL_FALSE) { retcode = 0; } else { retcode = 1; } } end: KNI_ReturnInt(retcode); }
/** * private native void send0(LinkMessage msg) * throws ClosedLinkException, * InterruptedIOException, * IOException; */ KNIEXPORT KNI_RETURNTYPE_VOID Java_com_sun_midp_links_Link_send0(void) { rendezvous *rp; KNI_StartHandles(3); KNI_DeclareHandle(thisObj); KNI_DeclareHandle(messageObj); KNI_DeclareHandle(otherMessageObj); KNI_GetThisPointer(thisObj); KNI_GetParameterAsObject(1, messageObj); rp = getNativePointer(thisObj); if (rp == NULL) { if (SNI_GetReentryData(NULL) == NULL) { KNI_ThrowNew(midpClosedLinkException, NULL); } else { KNI_ThrowNew(midpInterruptedIOException, NULL); } } else if (JVM_CurrentIsolateID() != rp->sender) { KNI_ThrowNew(midpIllegalArgumentException, NULL); } else { switch (rp->state) { case IDLE: rp->msg = SNI_AddStrongReference(messageObj); rp->state = SENDING; midp_thread_wait(LINK_READY_SIGNAL, (int)rp, NULL); break; case RECEIVING: rp->msg = SNI_AddStrongReference(messageObj); rp->state = RENDEZVOUS; midp_thread_signal(LINK_READY_SIGNAL, (int)rp, 0); midp_thread_wait(LINK_READY_SIGNAL, (int)rp, NULL); break; case SENDING: case RENDEZVOUS: midp_thread_wait(LINK_READY_SIGNAL, (int)rp, NULL); break; case DONE: getReference(rp->msg, "send0/DONE", otherMessageObj); if (KNI_IsSameObject(messageObj, otherMessageObj)) { /* it's our message, finish processing */ SNI_DeleteReference(rp->msg); rp->msg = INVALID_REFERENCE_ID; rp->state = IDLE; midp_thread_signal(LINK_READY_SIGNAL, (int)rp, 0); if (rp->retcode != OK) { KNI_ThrowNew(midpIOException, NULL); } } else { /* somebody else's message, just go back to sleep */ midp_thread_wait(LINK_READY_SIGNAL, (int)rp, NULL); } break; case CLOSED: setNativePointer(thisObj, NULL); if (rp->msg != INVALID_REFERENCE_ID) { /* a message was stranded in the link; clean it out */ SNI_DeleteReference(rp->msg); rp->msg = INVALID_REFERENCE_ID; } rp_decref(rp); if (SNI_GetReentryData(NULL) == NULL) { KNI_ThrowNew(midpClosedLinkException, NULL); } else { KNI_ThrowNew(midpInterruptedIOException, NULL); } break; } } KNI_EndHandles(); KNI_ReturnVoid(); }
/** * private native void receive0(LinkMessage msg, Link link) * throws ClosedLinkException, * InterruptedIOException, * IOException; */ KNIEXPORT KNI_RETURNTYPE_VOID Java_com_sun_midp_links_Link_receive0(void) { rendezvous *rp; KNI_StartHandles(4); KNI_DeclareHandle(thisObj); KNI_DeclareHandle(recvMessageObj); KNI_DeclareHandle(sendMessageObj); KNI_DeclareHandle(linkObj); KNI_GetThisPointer(thisObj); KNI_GetParameterAsObject(1, recvMessageObj); KNI_GetParameterAsObject(2, linkObj); rp = getNativePointer(thisObj); if (rp == NULL) { if (SNI_GetReentryData(NULL) == NULL) { KNI_ThrowNew(midpClosedLinkException, NULL); } else { KNI_ThrowNew(midpInterruptedIOException, NULL); } } else if (JVM_CurrentIsolateID() != rp->receiver) { KNI_ThrowNew(midpIllegalArgumentException, NULL); } else { jboolean ok; switch (rp->state) { case IDLE: rp->state = RECEIVING; midp_thread_wait(LINK_READY_SIGNAL, (int)rp, NULL); break; case SENDING: getReference(rp->msg, "receive0/SENDING", sendMessageObj); ok = copy(sendMessageObj, recvMessageObj, linkObj); if (ok) { rp->retcode = OK; } else { rp->retcode = ERROR; KNI_ThrowNew(midpIOException, NULL); } rp->state = DONE; midp_thread_signal(LINK_READY_SIGNAL, (int)rp, 0); break; case RENDEZVOUS: getReference(rp->msg, "receive0/RENDEZVOUS", sendMessageObj); ok = copy(sendMessageObj, recvMessageObj, linkObj); if (ok) { rp->retcode = OK; } else { rp->retcode = ERROR; KNI_ThrowNew(midpIOException, NULL); } rp->state = DONE; midp_thread_signal(LINK_READY_SIGNAL, (int)rp, 0); break; case RECEIVING: case DONE: midp_thread_wait(LINK_READY_SIGNAL, (int)rp, NULL); break; case CLOSED: setNativePointer(thisObj, NULL); rp_decref(rp); if (SNI_GetReentryData(NULL) == NULL) { KNI_ThrowNew(midpClosedLinkException, NULL); } else { KNI_ThrowNew(midpInterruptedIOException, NULL); } break; } } KNI_EndHandles(); KNI_ReturnVoid(); }
/** * Performs data transfer to the device. * <p>Java declaration: * <pre> * private native int cmdXfer0(byte[] request, byte[] response); * </pre> * @param request Buffer with request data * @param response Buffer for response data * @return Length of response in case of success, else -1 */ KNIEXPORT KNI_RETURNTYPE_INT KNIDECL(com_sun_cardreader_PlatformCardDevice_cmdXfer0) { jint retcode; javacall_int32 tx_length, rx_length; char *tx_buffer, *rx_buffer; MidpReentryData* info; void *context = NULL; javacall_result status_code; KNI_StartHandles(2); KNI_DeclareHandle(request_handle); KNI_DeclareHandle(response_handle); info = (MidpReentryData*)SNI_GetReentryData(NULL); KNI_GetParameterAsObject(1, request_handle); if (KNI_IsNullHandle(request_handle)) { tx_buffer = NULL; tx_length = 0; retcode = -1; goto end; } else { tx_length = KNI_GetArrayLength(request_handle); tx_buffer = SNI_GetRawArrayPointer(request_handle); } KNI_GetParameterAsObject(2, response_handle); if (KNI_IsNullHandle(response_handle)) { rx_buffer = NULL; rx_length = 0; retcode = -1; goto end; } else { rx_length = KNI_GetArrayLength(response_handle); rx_buffer = SNI_GetRawArrayPointer(response_handle); } if (tx_length > 5) { jsize apdu_len = 5 + (tx_buffer[4]&0xFF) + 1; if (tx_length > apdu_len) { tx_length = apdu_len; } } if (info == NULL) { status_code = javacall_carddevice_xfer_data_start(tx_buffer, tx_length, rx_buffer, &rx_length, &context); } else { context = info->pResult; status_code = javacall_carddevice_xfer_data_finish(tx_buffer, tx_length, rx_buffer, &rx_length, context); } if (status_code == JAVACALL_WOULD_BLOCK) { midp_thread_wait(CARD_READER_DATA_SIGNAL, SIGNAL_XFER, context); goto end; } if (status_code != JAVACALL_OK) { retcode = -1; } else { retcode = rx_length; } end: KNI_EndHandles(); KNI_ReturnInt(retcode); }
/** * Closes the socket connection. * <p> * Java declaration: * <pre> * close0(V)V * </pre> */ KNIEXPORT KNI_RETURNTYPE_VOID Java_com_sun_midp_io_j2me_socket_Protocol_close0(void) { void *pcslHandle; int status = PCSL_NET_INVALID; void* context = NULL; MidpReentryData* info; KNI_StartHandles(1); KNI_DeclareHandle(thisObject); KNI_GetThisPointer(thisObject); info = (MidpReentryData*)SNI_GetReentryData(NULL); if (info == NULL) { /* initial invocation */ pcslHandle = (void *)(getMidpSocketProtocolPtr(thisObject)->handle); if (INVALID_HANDLE == pcslHandle) { KNI_ThrowNew(midpIOException, "invalid handle during socket::close"); } else { status = pcsl_socket_close_start(pcslHandle, &context); getMidpSocketProtocolPtr(thisObject)->handle = (jint)INVALID_HANDLE; midp_thread_signal(NETWORK_READ_SIGNAL, (int)pcslHandle, 0); midp_thread_signal(NETWORK_WRITE_SIGNAL, (int)pcslHandle, 0); } } else { /* reinvocation */ pcslHandle = (void *)(info->descriptor); context = info->pResult; status = pcsl_socket_close_finish(pcslHandle, context); } REPORT_INFO1(LC_PROTOCOL, "socket::close handle=%d\n", pcslHandle); if (INVALID_HANDLE != pcslHandle) { if (status == PCSL_NET_SUCCESS) { if (midpDecResourceCount(RSC_TYPE_TCP_CLI, 1) == 0) { REPORT_INFO(LC_PROTOCOL, "Resource limit update error"); } } else if (status == PCSL_NET_WOULDBLOCK) { REPORT_INFO1(LC_PROTOCOL, "socket::close = 0x%x blocked\n", pcslHandle); /* IMPL NOTE: unclear whether this is the right signal */ midp_thread_wait(NETWORK_READ_SIGNAL, (int)pcslHandle, context); } else { /* must be PCSL_NET_IOERROR */ midp_snprintf(gKNIBuffer, KNI_BUFFER_SIZE, "IOError in socket::close = %d\n", (int)pcsl_network_error(pcslHandle)); REPORT_INFO1(LC_PROTOCOL, "%s", gKNIBuffer); KNI_ThrowNew(midpIOException, gKNIBuffer); } } KNI_EndHandles(); KNI_ReturnVoid(); }
/** * Accepts incoming client connection request. * * Note: the method gets native connection handle directly from * <code>handle<code> field of <code>L2CAPNotifierImpl</code> object. * * Note: new native connection handle to work with accepted incoming * client connection is setted directly to <code>handle</code> field of * appropriate <code>L2CAPConnectionImpl</code> object. * * @return Negotiated ReceiveMTU and TransmitMTU. * 16 high bits is ReceiveMTU, 16 low bits is TransmitMTU. * @throws IOException if an I/O error occurs */ KNIEXPORT KNI_RETURNTYPE_INT Java_com_sun_midp_io_j2me_btl2cap_L2CAPNotifierImpl_accept0(void) { javacall_handle handle = BT_INVALID_HANDLE; javacall_handle peer_handle = BT_INVALID_HANDLE; MidpReentryData* info; int status = JAVACALL_FAIL; int processStatus = KNI_FALSE; int imtu, omtu, mtus; void *context = NULL; javacall_bt_address peer_addr; unsigned char *address = NULL; KNI_StartHandles(2); KNI_DeclareHandle(thisHandle); KNI_DeclareHandle(arrayHandle); KNI_GetThisPointer(thisHandle); handle = (javacall_handle)KNI_GetIntField(thisHandle, notifHandleID); KNI_GetObjectField(thisHandle, peerAddrID, arrayHandle); if (handle == BT_INVALID_HANDLE) { REPORT_ERROR(LC_PROTOCOL, "L2CAP server socket was closed before btl2cap_notif::accept"); KNI_ThrowNew(midpInterruptedIOException, EXCEPTION_MSG( "L2CAP notifier was closed")); } else { bt_pushid_t pushid = KNI_GetIntField(thisHandle, pushHandleID); if (pushid != BT_INVALID_PUSH_HANDLE) { if (bt_push_checkout_client(pushid, &peer_handle, peer_addr, &imtu, &omtu) == JAVACALL_OK) { pushcheckoutaccept((int)handle); processStatus = KNI_TRUE; status = JAVACALL_OK; } } if (peer_handle == BT_INVALID_HANDLE) { info = (MidpReentryData*)SNI_GetReentryData(NULL); if (info == NULL) { /* First invocation */ REPORT_INFO1(LC_PROTOCOL, "btl2cap_notif::accept handle=%d\n", handle); // Need revisit: add resource counting /* * An incoming socket connection counts against the client socket * resource limit. */ /* if (midpCheckResourceLimit(RSC_TYPE_BT_CLI, 1) == 0) { const char* pMsg = "Resource limit exceeded for BT client sockets"; REPORT_INFO(LC_PROTOCOL, pMsg); KNI_ThrowNew(midpIOException, EXCEPTION_MSG(pMsg)); */ // } else { status = javacall_bt_l2cap_accept( handle, &peer_handle, &peer_addr, &imtu, &omtu); processStatus = KNI_TRUE; // } } else { /* Reinvocation after unblocking the thread */ if ((javacall_handle)info->descriptor != handle) { midp_snprintf(gKNIBuffer, KNI_BUFFER_SIZE, "btl2cap_notif::accept handles mismatched %d != %d\n", handle, info->descriptor); REPORT_CRIT(LC_PROTOCOL, gKNIBuffer); KNI_ThrowNew(midpIllegalStateException, EXCEPTION_MSG( "Internal error in btl2cap_notif::accept")); } else { // Need revisit: add resource counting /* if (midpCheckResourceLimit(RSC_TYPE_BT_CLI, 1) == 0) { const char* pMsg = "Resource limit exceeded for BT client sockets" REPORT_INFO(LC_PROTOCOL, pMsg); KNI_ThrowNew(midpIOException, EXCEPTION_MSG(pMsg)); } else { */ status = javacall_bt_l2cap_accept( handle, &peer_handle, &peer_addr, &imtu, &omtu); processStatus = KNI_TRUE; // } } } } if (processStatus) { REPORT_INFO1(LC_PROTOCOL, "btl2cap_notif::accept server handle=%d\n", handle); if (status == JAVACALL_OK) { int i; // Need revisit: add resource counting /* if (midpIncResourceCount(RSC_TYPE_BT_CLI, 1) == 0) { REPORT_INFO(LC_PROTOCOL, "btl2cap_notif: Resource limit update error"); } */ // store client native connection handle for temporary storing KNI_SetIntField(thisHandle, peerHandleID, (jint)peer_handle); // copy address to Java object field SNI_BEGIN_RAW_POINTERS; address = JavaByteArray(arrayHandle); for (i = 0; i < BT_ADDRESS_SIZE; i++) { address[i] = peer_addr[i]; } SNI_END_RAW_POINTERS; REPORT_INFO(LC_PROTOCOL, "btl2cap_notif::accept incoming connection accepted!"); } else if (status == JAVACALL_WOULD_BLOCK) { midp_thread_wait(NETWORK_READ_SIGNAL, (int)handle, context); } else if (status == JAVACALL_FAIL) { char* pError; javacall_bt_l2cap_get_error(handle, &pError); midp_snprintf(gKNIBuffer, KNI_BUFFER_SIZE, "IO error in btl2cap_notif::accept (%s)\n", pError); REPORT_INFO(LC_PROTOCOL, gKNIBuffer); KNI_ThrowNew(midpIOException, EXCEPTION_MSG(gKNIBuffer)); } else { char* pMsg = "Unknown error during btl2cap_notif::accept"; REPORT_INFO(LC_PROTOCOL, pMsg); KNI_ThrowNew(midpIOException, EXCEPTION_MSG(pMsg)); } } } mtus = (imtu << 16) & 0xFFFF0000; mtus |= omtu & 0xFFFF; KNI_EndHandles(); KNI_ReturnInt(mtus); }
/** * Open a serial port by system dependent device name. * * @param name device name of the port * @param baud baud rate to set the port at * @param flags options for the serial port * * @return handle to a native serial port * * @exception IOException if an I/O error occurs. */ KNIEXPORT KNI_RETURNTYPE_INT Java_com_sun_midp_io_j2me_comm_Protocol_native_1openByName() { int flags = (int)KNI_GetParameterAsInt(3); int baud = (int)KNI_GetParameterAsInt(2); int nameLen; char szName[MAX_NAME_LEN]; jchar* temp; int hPort = (int)INVALID_HANDLE; int i; int status = PCSL_NET_IOERROR; void* context = NULL; MidpReentryData* info; KNI_StartHandles(1); KNI_DeclareHandle(nameObject); KNI_GetParameterAsObject(1, nameObject); info = (MidpReentryData*)SNI_GetReentryData(NULL); if (info == NULL) { nameLen = KNI_GetStringLength(nameObject); if (nameLen > MAX_NAME_LEN) { midp_snprintf(gKNIBuffer, KNI_BUFFER_SIZE, "Serial device name has wrong length: %d\n", nameLen); REPORT_INFO1(LC_PROTOCOL, "%s\n", gKNIBuffer); KNI_ThrowNew(midpIllegalArgumentException, gKNIBuffer); } else { temp = (jchar*)szName; KNI_GetStringRegion(nameObject, 0, nameLen, temp); /* device names are in ASCII */ for (i = 0; i < nameLen; i++) { szName[i] = (char)temp[i]; } szName[nameLen] = 0; status = openPortByNameStart(szName, baud, flags, &hPort, &context); } } else { /* reinvocation */ hPort = info->descriptor; context = info->pResult; status = openPortByNameFinish(szName, baud, flags, &hPort, context); } switch (status) { case PCSL_NET_SUCCESS: /* do nothing and return normally */ break; case PCSL_NET_INTERRUPTED: midp_snprintf(gKNIBuffer, KNI_BUFFER_SIZE, "Opening port %s has been interrupted\n", szName); REPORT_INFO1(LC_PROTOCOL, "%s\n", gKNIBuffer); KNI_ThrowNew(midpInterruptedIOException, gKNIBuffer); break; case PCSL_NET_WOULDBLOCK: midp_thread_wait(COMM_OPEN_SIGNAL, hPort, context); break; default: midp_snprintf(gKNIBuffer, KNI_BUFFER_SIZE, "Opening port %s was failed\n", szName); REPORT_INFO1(LC_PROTOCOL, "%s\n", gKNIBuffer); KNI_ThrowNew(midpIOException, gKNIBuffer); } KNI_EndHandles(); KNI_ReturnInt((jint)hPort); }
/* JAVADOC COMMENT ELIDED */ static void lock_thread(jint waitingFor, jint provider) { (void)waitingFor; midp_thread_wait(JSR179_LOCATION_SIGNAL, provider, NULL); }
/** * Performs data transfer to the device. This method must be called within * <tt>synchronize</tt> block with the Slot object. * <p>Java declaration: * <pre> * public native static int exchangeAPDU0(Handle h, Slot slot, byte[] request, byte[] response) throws IOException; * </pre> * @param h Connection handle. Can be null for internal purposes * @param slot Slot object. Unused when <tt>h</tt> is not null. * Must be provided if <tt>h</tt> is null. * @param request Buffer with request data * @param response Buffer for response data * @return Length of response data * @exception NullPointerException if any parameter is null * @exception IllegalArgumentException if request does not contain proper APDU * @exception InterruptedIOException if the connection handle is suddenly closed * in the middle of exchange or the card was removed and inserted again * @exception IOException if any I/O troubles occured */ KNIEXPORT KNI_RETURNTYPE_INT Java_com_sun_midp_io_j2me_apdu_APDUManager_exchangeAPDU0() { jint retcode = -1; MidpReentryData* info; void *context = NULL; JSR177_STATUSCODE status_code; JSR177_CARD_MOVEMENT movements; jsize tx_length, rx_length, rx_length_max; jbyte *tx_buffer, *rx_buffer; jbyte *cur; jbyte case_2[5]; int Lc, Le; int cla, channel; ConnectionHandle *h; CardSlot *card_slot; char *err_msg; jbyte getResponseAPDU[5]; KNI_StartHandles(4); KNI_DeclareHandle(connection_handle); KNI_DeclareHandle(slot_handle); KNI_DeclareHandle(request_handle); KNI_DeclareHandle(response_handle); info = (MidpReentryData*)SNI_GetReentryData(NULL); // If the Handle object is provided we get a Slot object from it KNI_GetParameterAsObject(1, connection_handle); if (!KNI_IsNullHandle(connection_handle)) { h = unhand(ConnectionHandle,(connection_handle)); card_slot = h->cardSlot; if (card_slot == NULL) { KNI_ThrowNew(midpNullPointerException, "Slot object is null"); goto end; } } else { h = NULL; KNI_GetParameterAsObject(2, slot_handle); if (KNI_IsNullHandle(slot_handle)) { KNI_ThrowNew(midpNullPointerException, "Handle and slot are null"); goto end; } card_slot = unhand(CardSlot,(slot_handle)); } KNI_GetParameterAsObject(3, request_handle); if (KNI_IsNullHandle(request_handle)) { KNI_ThrowNew(midpNullPointerException, "Request APDU is null"); goto end; } tx_length = KNI_GetArrayLength(request_handle); tx_buffer = SNI_GetRawArrayPointer(request_handle); KNI_GetParameterAsObject(4, response_handle); if (KNI_IsNullHandle(response_handle)) { KNI_ThrowNew(midpNullPointerException, "Response buffer is null"); goto end; } rx_length_max = KNI_GetArrayLength(response_handle); rx_buffer = SNI_GetRawArrayPointer(response_handle); if (h != NULL && (!h->opened || h->cardSessionId != card_slot->cardSessionId)) { char *msg = "Connection closed"; if (!card_slot->locked) { KNI_ThrowNew(midpIOException, msg); goto end; } else { KNI_ThrowNew(midpInterruptedIOException, msg); goto unlock_end; } } if (!card_slot->powered) { char *msg = "Card not powered up"; if (!card_slot->locked) { KNI_ThrowNew(midpIOException, msg); goto end; } else { KNI_ThrowNew(midpInterruptedIOException, msg); goto unlock_end; } } if (tx_length < 4) { // invalid APDU: too short invalid_apdu: KNI_ThrowNew(midpIllegalArgumentException, "Invalid APDU"); goto end; } // trying to guess the case if (tx_length == 4) { // case 1 Lc = Le = 0; } else { Lc = (tx_buffer[4]&0xFF); if (tx_length == 5) { // case 2 Le = Lc; Lc = 0; if (Le == 0) { Le = 256; } } else if (tx_length == 5 + Lc) { // case 3 Le = 0; } else { // case 4 if (5 + Lc >= tx_length) { // invalid APDU: bad Lc field goto invalid_apdu; } Le = tx_buffer[5 + Lc] & 0xFF; if (Le == 0) { Le = 256; } } } // if APDU of case 4 has Lc=0 then we transform it to case 2 if (tx_length > 5 && Lc == 0) { memcpy(case_2, tx_buffer, 4); case_2[4] = tx_buffer[5]; tx_buffer = case_2; tx_length = 5; } // trimming APDU if (tx_length > 5 + Lc + 1) { tx_length = 5 + Lc + 1; } cla = tx_buffer[0] & 0xf8; // mask channel and secure bit channel = cla != 0 && (cla < 0x80 || cla > 0xA0) ? 0 : tx_buffer[0] & 3; // locked slot means that we are in the middle of an exchange, // otherwise we should start a data transfer if (!card_slot->locked) { card_slot->received = 0; cur = rx_buffer; } else { cur = rx_buffer + card_slot->received; } do { // infinite loop int sw1, sw2; rx_length = rx_length_max - (jint)(cur - rx_buffer); if (rx_length < Le + 2) { err_msg = "Too long response"; goto err_mess; } if (info == NULL || info->status == SIGNAL_LOCK) { if (!card_slot->locked) { status_code = jsr177_lock(); if (status_code == JSR177_STATUSCODE_WOULD_BLOCK) { midp_thread_wait(CARD_READER_DATA_SIGNAL, SIGNAL_LOCK, NULL); goto end; } if (status_code != JSR177_STATUSCODE_OK) { goto err; } card_slot->locked = KNI_TRUE; // Since this line slot is locked status_code = jsr177_select_slot(card_slot->slot); if (status_code != JSR177_STATUSCODE_OK) { goto err; } } status_code = jsr177_xfer_data_start(tx_buffer, tx_length, cur, &rx_length, &context); } else { context = info->pResult; status_code = jsr177_xfer_data_finish(tx_buffer, tx_length, cur, &rx_length, context); } if (jsr177_card_movement_events(&movements) == JSR177_STATUSCODE_OK) { if ((movements & JSR177_CARD_MOVEMENT_MASK) != 0) { err_msg = "Card changed"; jsr177_set_error(err_msg); if (jsr177_get_error((jbyte*)gKNIBuffer, KNI_BUFFER_SIZE)) { err_msg = gKNIBuffer; } card_slot->powered = KNI_FALSE; goto interrupted; } } if (status_code == JSR177_STATUSCODE_WOULD_BLOCK) { midp_thread_wait(CARD_READER_DATA_SIGNAL, SIGNAL_XFER, context); card_slot->received = (jint)(cur - rx_buffer); goto end; } if (status_code != JSR177_STATUSCODE_OK) { err: if (jsr177_get_error((jbyte*)gKNIBuffer, KNI_BUFFER_SIZE)) { err_msg = gKNIBuffer; } else { err_msg = "exchangeAPDU0()"; } err_mess: KNI_ThrowNew(midpIOException, err_msg); if (card_slot->locked) { status_code = jsr177_unlock(); // ignore status_code card_slot->locked = KNI_FALSE; midp_thread_signal(CARD_READER_DATA_SIGNAL, SIGNAL_LOCK, SIGNAL_LOCK); } goto end; } if (rx_length < 2) { err_msg = "Response error"; goto err_mess; } if (h != NULL && (!h->opened || h->cardSessionId != card_slot->cardSessionId)) { err_msg = "Handle invalid or closed"; interrupted: KNI_ThrowNew(midpInterruptedIOException, err_msg); goto unlock_end; } sw1 = cur[rx_length - 2] & 0xFF; sw2 = cur[rx_length - 1] & 0xFF; if (sw1 == 0x6C && sw2 != 0x00 && Le != 0) { tx_buffer[tx_length - 1] = sw2; Le = sw2; info = NULL; continue; } cur += rx_length; if (Le == 0 || (sw1 != 0x61 && (channel != 0 || !card_slot->SIMPresent || (sw1 != 0x62 && sw1 != 0x63 && sw1 != 0x9E && sw1 != 0x9F)))) { break; } cur -= 2; // delete last SW1/SW2 from buffer Le = sw1 == 0x62 || sw1 == 0x63 ? 0 : sw2; memset(getResponseAPDU, 0, sizeof getResponseAPDU); tx_buffer = getResponseAPDU; tx_buffer[0] = channel; tx_buffer[1] = 0xC0; tx_buffer[4] = Le; if (Le == 0) { Le = 256; } tx_length = 5; info = NULL; } while(1); retcode = (jint)(cur - rx_buffer); unlock_end: card_slot->locked = KNI_FALSE; midp_thread_signal(CARD_READER_DATA_SIGNAL, SIGNAL_LOCK, SIGNAL_LOCK); status_code = jsr177_unlock(); if (status_code != JSR177_STATUSCODE_OK) { goto err; } end: KNI_EndHandles(); KNI_ReturnInt(retcode); }
/** * Sends an SMS message. * * @param handle The handle to the open SMS connection. * @param messageType The type of message: binary or text. * @param address The SMS-formatted address. * @param destPort The port number of the recipient. * @param sourcePort The port number of the sender. * @param messageBuffer The buffer containing the SMS message. * * @return Always returns <code>0</code>. */ KNIEXPORT KNI_RETURNTYPE_INT KNIDECL(com_sun_midp_io_j2me_sms_Protocol_send0) { WMA_STATUS status = WMA_ERR; jint messageLength = 0; jint messageType; jint sourcePort; jint destPort; jint handle; jint msAddress_len; jchar* msAddress_data; int i; unsigned char *pAddress = NULL; unsigned char *pMessageBuffer = NULL; jboolean stillWaiting = KNI_FALSE; jboolean trySend = KNI_FALSE; void *pdContext = NULL; #if ENABLE_REENTRY MidpReentryData *info; jsr120_sms_message_state_data *messageStateData = NULL; #endif jboolean isOpen; KNI_StartHandles(4); KNI_DeclareHandle(this); KNI_DeclareHandle(thisClass); KNI_GetThisPointer(this); KNI_GetObjectClass(this, thisClass); isOpen = KNI_GetBooleanField(this, KNI_GetFieldID(thisClass, "open", "Z")); if (isOpen) { /* No close in progress */ KNI_DeclareHandle(messageBuffer); KNI_DeclareHandle(address); handle = KNI_GetParameterAsInt(1); messageType = KNI_GetParameterAsInt(2); KNI_GetParameterAsObject(3, address); destPort = KNI_GetParameterAsInt(4); sourcePort = KNI_GetParameterAsInt(5); KNI_GetParameterAsObject(6, messageBuffer); do { #if ENABLE_REENTRY info = (MidpReentryData*)SNI_GetReentryData(NULL); if (info == NULL) { /* First invocation. */ #endif if (KNI_IsNullHandle(address)) { KNI_ThrowNew(midpIllegalArgumentException, NULL); break; } else { msAddress_len = KNI_GetStringLength(address); msAddress_data = (jchar *)pcsl_mem_malloc(msAddress_len * sizeof (jchar)); if (msAddress_data == NULL) { KNI_ThrowNew(midpOutOfMemoryError, NULL); break; } else { KNI_GetStringRegion(address, 0, msAddress_len, msAddress_data); pAddress = (unsigned char*)pcsl_mem_malloc(msAddress_len + 1); if (pAddress != NULL) { for (i = 0; i < msAddress_len; i++) { pAddress[i] = (unsigned char)msAddress_data[i]; } pAddress[msAddress_len] = 0; } //pAddress = (unsigned char *)midpJcharsToChars(msAddress); pcsl_mem_free(msAddress_data); if (!KNI_IsNullHandle(messageBuffer)) { messageLength = KNI_GetArrayLength(messageBuffer); } if (messageLength >= 0) { if (messageLength > 0) { pMessageBuffer = (unsigned char *)pcsl_mem_malloc(messageLength); memset(pMessageBuffer, 0, messageLength); KNI_GetRawArrayRegion(messageBuffer, 0, messageLength, (jbyte *)pMessageBuffer); } trySend = KNI_TRUE; } } } #if ENABLE_REENTRY } else { /* Reinvocation after unblocking the thread. */ if (info->pResult == NULL) { /* waiting for mms_send_completed event */ if (info->status == WMA_ERR) { KNI_ThrowNew(midpInterruptedIOException, "Sending SMS"); } break; } messageStateData = info->pResult; pMessageBuffer = messageStateData->pMessageBuffer; pAddress = messageStateData->pAddress; pdContext = messageStateData->pdContext; trySend = KNI_TRUE; } #endif if (trySend == KNI_TRUE) { /* send message. */ status = jsr120_send_sms((jchar)messageType, pAddress, pMessageBuffer, (jchar)messageLength, (jchar)sourcePort, (jchar)destPort, handle, &pdContext); if (status == WMA_ERR) { KNI_ThrowNew(midpIOException, "Sending SMS"); break; } #if ENABLE_REENTRY else if (status == WMA_NET_WOULDBLOCK) { if (messageStateData == NULL) { messageStateData = (jsr120_sms_message_state_data *)pcsl_mem_malloc( sizeof(*messageStateData)); messageStateData->pMessageBuffer = pMessageBuffer; messageStateData->pAddress = pAddress; } messageStateData->pdContext = pdContext; /* Block calling Java Thread. */ midp_thread_wait(WMA_SMS_WRITE_SIGNAL, handle, messageStateData); stillWaiting = KNI_TRUE; break; } else { /* waiting for sms_send_completed event */ midp_thread_wait(WMA_SMS_WRITE_SIGNAL, handle, NULL); } #endif } } while (0); if (!stillWaiting) { pcsl_mem_free(pMessageBuffer); pcsl_mem_free(pAddress); } } KNI_EndHandles(); KNI_ReturnInt(0); /* currently ignored. */ }
/** * Opens a TCP connection to a server. * <p> * Java declaration: * <pre> * open([BI)V * </pre> * * @param ipBytes Byte array that represents a raw IP address * @param port TCP port at host * * @return a native handle to the network connection. */ KNIEXPORT KNI_RETURNTYPE_VOID Java_com_sun_midp_io_j2me_socket_Protocol_open0(void) { int port; void *pcslHandle = INVALID_HANDLE; int status; void* context = NULL; MidpReentryData* info; port = (int)KNI_GetParameterAsInt(2); KNI_StartHandles(2); KNI_DeclareHandle(thisObject); KNI_DeclareHandle(bufferObject); KNI_GetThisPointer(thisObject); KNI_GetParameterAsObject(1, bufferObject); info = (MidpReentryData*)SNI_GetReentryData(NULL); if (info == NULL) { /* First invocation */ getMidpSocketProtocolPtr(thisObject)->handle = (jint)INVALID_HANDLE; /** * Verify that the resource is available well within limit as per * the policy in ResourceLimiter */ if (midpCheckResourceLimit(RSC_TYPE_TCP_CLI, 1) == 0) { REPORT_INFO(LC_PROTOCOL, "Resource limit exceeded for TCP client sockets"); KNI_ThrowNew(midpIOException, "Resource limit exceeded for TCP client sockets"); } else { SNI_BEGIN_RAW_POINTERS; status = pcsl_socket_open_start( (unsigned char*)JavaByteArray(bufferObject), port, &pcslHandle, &context); SNI_END_RAW_POINTERS; if (status == PCSL_NET_SUCCESS) { getMidpSocketProtocolPtr(thisObject)->handle = (jint)pcslHandle; if (midpIncResourceCount(RSC_TYPE_TCP_CLI, 1) == 0) { REPORT_INFO(LC_PROTOCOL, "Resource limit update error"); } } else if (status == PCSL_NET_IOERROR) { midp_snprintf(gKNIBuffer, KNI_BUFFER_SIZE, "IOError in socket::open = %d\n", (int)pcsl_network_error(pcslHandle)); REPORT_INFO1(LC_PROTOCOL, "%s\n", gKNIBuffer); KNI_ThrowNew(midpIOException, gKNIBuffer); } else if (status == PCSL_NET_CONNECTION_NOTFOUND) { midp_snprintf(gKNIBuffer, KNI_BUFFER_SIZE, "ConnectionNotFound error in socket::open :" " error = %d\n", (int)pcsl_network_error(pcslHandle)); REPORT_INFO1(LC_PROTOCOL, "%s\n", gKNIBuffer); KNI_ThrowNew(midpConnectionNotFoundException, gKNIBuffer); } else if (status == PCSL_NET_WOULDBLOCK) { INC_NETWORK_INDICATOR; getMidpSocketProtocolPtr(thisObject)->handle = (jint)pcslHandle; if (midpIncResourceCount(RSC_TYPE_TCP_CLI, 1) == 0) { REPORT_INFO(LC_PROTOCOL, "Resource limit update error"); } REPORT_INFO1(LC_PROTOCOL, " handle = %d\n", pcslHandle); midp_thread_wait(NETWORK_WRITE_SIGNAL, (int)pcslHandle, context); } else { REPORT_INFO(LC_PROTOCOL, "Unknown error during socket::open"); KNI_ThrowNew(midpIOException, NULL); } } } else { /* Reinvocation after unblocking the thread */ pcslHandle = (void *) info->descriptor; context = (void *)info->status; if (getMidpSocketProtocolPtr(thisObject)->handle != (jint)pcslHandle) { REPORT_CRIT2(LC_PROTOCOL, "socket::open Handles mismatched 0x%x != 0x%x\n", pcslHandle, getMidpSocketProtocolPtr(thisObject)->handle); } status = pcsl_socket_open_finish(pcslHandle, context); if (status == PCSL_NET_SUCCESS) { DEC_NETWORK_INDICATOR; } else if (status == PCSL_NET_WOULDBLOCK) { midp_thread_wait(NETWORK_WRITE_SIGNAL, (int)pcslHandle, context); } else { DEC_NETWORK_INDICATOR; getMidpSocketProtocolPtr(thisObject)->handle = (jint)INVALID_HANDLE; if (midpDecResourceCount(RSC_TYPE_TCP_CLI, 1) == 0) { REPORT_INFO(LC_PROTOCOL, "Resource limit update error"); } midp_snprintf(gKNIBuffer, KNI_BUFFER_SIZE, "error %d in socket::open", (int)pcsl_network_error(pcslHandle)); REPORT_INFO1(LC_PROTOCOL, "%s\n", gKNIBuffer); KNI_ThrowNew(midpConnectionNotFoundException, gKNIBuffer); } } KNI_EndHandles(); KNI_ReturnVoid(); }
/** * Opens a datagram connection on the given port. * <p> * Java declaration: * <pre> * open0(I[B)V * </pre> * * @param port port to listen on, or 0 to have one selected * @param suiteId the ID of the current MIDlet suite */ KNIEXPORT KNI_RETURNTYPE_VOID Java_com_sun_midp_io_j2me_datagram_Protocol_open0(void) { int port; SuiteIdType suiteId; jboolean tryOpen = KNI_TRUE; KNI_StartHandles(1); KNI_DeclareHandle(thisObject); KNI_GetThisPointer(thisObject); port = (int)KNI_GetParameterAsInt(1); suiteId = KNI_GetParameterAsInt(2); if (getMidpDatagramProtocolPtr(thisObject)->nativeHandle != (jint)INVALID_HANDLE) { KNI_ThrowNew(midpIOException, "already open"); tryOpen = KNI_FALSE; } if (tryOpen) { int pushReturn; pushReturn = pushcheckout("datagram", port, (char*)midp_suiteid2chars(suiteId)); /* * pushcheckout() returns -1 if the handle wasn't found, -2 if it's * already in use by another suite, otherwise a valid checked-out * handle. */ if (pushReturn == -1) { /* leave tryOpen == KNI_TRUE and try again below */ } else if (pushReturn == -2) { KNI_ThrowNew(midpIOException, "already in use"); tryOpen = KNI_FALSE; } else { /* IMPL NOTE: need to do resource accounting for this case */ getMidpDatagramProtocolPtr(thisObject)->nativeHandle = (jint)pushReturn; tryOpen = KNI_FALSE; } } if (tryOpen) { if (midpCheckResourceLimit(RSC_TYPE_UDP, 1) == 0) { KNI_ThrowNew(midpIOException, "resource limit exceeded"); } else { MidpReentryData* info; int status; void *socketHandle; void *context; info = (MidpReentryData*)SNI_GetReentryData(NULL); if (info == NULL) { /* initial invocation */ INC_NETWORK_INDICATOR; status = pcsl_datagram_open_start(port, &socketHandle, &context); } else { /* reinvocation */ socketHandle = (void *)info->descriptor; context = info->pResult; status = pcsl_datagram_open_finish(socketHandle, context); } if (status == PCSL_NET_SUCCESS) { if (midpIncResourceCount(RSC_TYPE_UDP, 1) == 0) { REPORT_INFO(LC_PROTOCOL, "Datagrams: resource limit update error"); } getMidpDatagramProtocolPtr(thisObject)->nativeHandle = (jint)socketHandle; DEC_NETWORK_INDICATOR; } else if (status == PCSL_NET_WOULDBLOCK) { midp_thread_wait(NETWORK_WRITE_SIGNAL, (int)socketHandle, context); } else { /* status == PCSL_NET_IOERROR */ midp_snprintf(gKNIBuffer, KNI_BUFFER_SIZE, "error code %d", pcsl_network_error(socketHandle)); REPORT_INFO1(LC_PROTOCOL, "datagram::open0 %s", gKNIBuffer); KNI_ThrowNew(midpIOException, gKNIBuffer); DEC_NETWORK_INDICATOR; } } } KNI_EndHandles(); KNI_ReturnVoid(); }
/** * Performs reset of the card in the slot. This method must be called within * <tt>synchronize</tt> block with the Slot object. * <p>Java declaration: * <pre> * public native static byte[] reset0(Slot cardSlot) throws IOException; * </pre> * @param cardSlot Slot object * @return byte array with ATR * @exception NullPointerException if parameter is null * @exception IOException if any i/o troubles occured */ KNIEXPORT KNI_RETURNTYPE_OBJECT Java_com_sun_midp_io_j2me_apdu_APDUManager_reset0() { MidpReentryData* info; void *context = NULL; JSR177_STATUSCODE status_code; CardSlot *card_slot; jsize atr_length; char *err_msg; // IMPL_NOTE: I assumed that maximum length of ATR is 256 bytes jbyte atr_buffer[256]; KNI_StartHandles(2); KNI_DeclareHandle(slot_handle); KNI_DeclareHandle(atr_handle); info = (MidpReentryData*)SNI_GetReentryData(NULL); KNI_GetParameterAsObject(1, slot_handle); if (!KNI_IsNullHandle(slot_handle)) { card_slot = unhand(CardSlot,(slot_handle)); } else { KNI_ThrowNew(midpNullPointerException, "Slot object is null"); goto end; } atr_length = sizeof atr_buffer; if (info == NULL || info->status == SIGNAL_LOCK) { if (!card_slot->locked) { status_code = jsr177_lock(); if (status_code == JSR177_STATUSCODE_WOULD_BLOCK) { midp_thread_wait(CARD_READER_DATA_SIGNAL, SIGNAL_LOCK, NULL); goto end; } if (status_code != JSR177_STATUSCODE_OK) { goto err; } card_slot->locked = KNI_TRUE; // Since this line slot is locked status_code = jsr177_select_slot(card_slot->slot); if (status_code != JSR177_STATUSCODE_OK) { goto err; } } status_code = jsr177_reset_start(atr_buffer, &atr_length, &context); } else { context = info->pResult; status_code = jsr177_reset_finish(atr_buffer, &atr_length, context); } if (status_code == JSR177_STATUSCODE_WOULD_BLOCK) { midp_thread_wait(CARD_READER_DATA_SIGNAL, SIGNAL_RESET, context); goto end; } if (status_code != JSR177_STATUSCODE_OK) { err: if (jsr177_get_error((jbyte*)gKNIBuffer, KNI_BUFFER_SIZE)) { err_msg = gKNIBuffer; } else { err_msg = "reset0()"; } KNI_ThrowNew(midpIOException, err_msg); if (card_slot->locked) { status_code = jsr177_unlock(); // ignore status_code card_slot->locked = KNI_FALSE; midp_thread_signal(CARD_READER_DATA_SIGNAL, SIGNAL_LOCK, SIGNAL_LOCK); } goto end; } status_code = jsr177_is_sat(card_slot->slot, &card_slot->SIMPresent); if (status_code != JSR177_STATUSCODE_OK) { goto err; } card_slot->cardSessionId++; card_slot->powered = KNI_TRUE; card_slot->locked = KNI_FALSE; midp_thread_signal(CARD_READER_DATA_SIGNAL, SIGNAL_LOCK, SIGNAL_LOCK); status_code = jsr177_unlock(); if (status_code != JSR177_STATUSCODE_OK) { goto err; } SNI_NewArray(SNI_BYTE_ARRAY, atr_length, atr_handle); memcpy(JavaByteArray(atr_handle), atr_buffer, atr_length); end: KNI_EndHandlesAndReturnObject(atr_handle); }
/** * Accepts incoming client connection request. * * Note: the method gets native connection handle directly from * <code>handle<code> field of <code>BTSPPNotifierImpl</code> object. * * Note: new native connection handle to work with accepted incoming * client connection is setted directly to <code>handle</code> field of * appropriate <code>RFCOMMConnectionImpl</code> object. * * @throws IOException if an I/O error occurs */ KNIEXPORT KNI_RETURNTYPE_VOID Java_com_sun_midp_io_j2me_btspp_BTSPPNotifierImpl_accept0(void) { bt_handle_t handle = BT_INVALID_HANDLE; bt_handle_t peer_handle = BT_INVALID_HANDLE; MidpReentryData* info; int status = BT_RESULT_FAILURE; int processStatus = KNI_FALSE; void *context = NULL; bt_bdaddr_t peer_addr; unsigned char *address = NULL; KNI_StartHandles(2); KNI_DeclareHandle(thisHandle); KNI_DeclareHandle(arrayHandle); KNI_GetThisPointer(thisHandle); handle = (bt_handle_t)KNI_GetIntField(thisHandle, notifHandleID); KNI_GetObjectField(thisHandle, peerAddrID, arrayHandle); if (handle == BT_INVALID_HANDLE) { REPORT_ERROR(LC_PROTOCOL, "RFCOMM notifier was closed before btspp_notif::accept"); KNI_ThrowNew(midpInterruptedIOException, EXCEPTION_MSG( "RFCOMM notifier was closed")); } else { bt_pushid_t pushid = KNI_GetIntField(thisHandle, pushHandleID); if (pushid != BT_INVALID_PUSH_HANDLE) { if (bt_push_checkout_client(pushid, &peer_handle, peer_addr, NULL, NULL) == BT_RESULT_SUCCESS) { pushcheckoutaccept((int)handle); processStatus = KNI_TRUE; status = BT_RESULT_SUCCESS; } } if (peer_handle == BT_INVALID_HANDLE) { info = (MidpReentryData*)SNI_GetReentryData(NULL); if (info == NULL) { /* First invocation */ REPORT_INFO1(LC_PROTOCOL, "btspp_notif::accept handle=%d\n", handle); // IMPL_NOTE: add resource counting /* * An incoming socket connection counts against the client socket * resource limit. */ /* if (midpCheckResourceLimit(RSC_TYPE_BT_CLI, 1) == 0) { const char* pMsg = "Resource limit exceeded for BT client sockets"; REPORT_INFO(LC_PROTOCOL, pMsg); KNI_ThrowNew(midpIOException, EXCEPTION_MSG(pMsg)); */ // } else { status = bt_rfcomm_accept_start( handle, &peer_handle, peer_addr, &context); processStatus = KNI_TRUE; // } } else { /* Reinvocation after unblocking the thread */ if ((bt_handle_t)info->descriptor != handle) { midp_snprintf(gKNIBuffer, KNI_BUFFER_SIZE, "btspp_notif::accept handles mismatched %d != %d\n", handle, info->descriptor); REPORT_CRIT(LC_PROTOCOL, gKNIBuffer); KNI_ThrowNew(midpIllegalStateException, EXCEPTION_MSG( "Internal error in btspp_notif::accept")); } else { // IMPL_NOTE: add resource counting /* if (midpCheckResourceLimit(RSC_TYPE_BT_CLI, 1) == 0) { const char* pMsg = "Resource limit exceeded for BT client sockets" REPORT_INFO(LC_PROTOCOL, pMsg); KNI_ThrowNew(midpIOException, EXCEPTION_MSG(pMsg)); } else { */ status = bt_rfcomm_accept_finish( handle, &peer_handle, peer_addr, context); processStatus = KNI_TRUE; // } } } } if (processStatus) { REPORT_INFO1(LC_PROTOCOL, "btspp_notif::accept server handle=%d\n", handle); if (status == BT_RESULT_SUCCESS) { int i; // IMPL_NOTE: add resource counting /* if (midpIncResourceCount(RSC_TYPE_BT_CLI, 1) == 0) { REPORT_INFO(LC_PROTOCOL, "btspp_notif: Resource limit update error"); } */ // store client native connection handle for temporary storing KNI_SetIntField(thisHandle, peerHandleID, (jint)peer_handle); // copy address to Java object field SNI_BEGIN_RAW_POINTERS; address = (unsigned char*)JavaByteArray(arrayHandle); for (i = 0; i < BT_ADDRESS_SIZE; i++) { address[i] = peer_addr[i]; } SNI_END_RAW_POINTERS; RegisterRFCOMMConnection0(peer_addr, peer_handle); REPORT_INFO(LC_PROTOCOL, "btspp_notif::accept incoming connection accepted!"); } else if (status == BT_RESULT_WOULDBLOCK) { midp_thread_wait(NETWORK_READ_SIGNAL, (int)handle, context); } else if (status == BT_RESULT_FAILURE) { char* pError; bt_rfcomm_get_error(handle, &pError); midp_snprintf(gKNIBuffer, KNI_BUFFER_SIZE, "IO error in btspp_notif::accept (%s)\n", pError); REPORT_INFO(LC_PROTOCOL, gKNIBuffer); KNI_ThrowNew(midpIOException, EXCEPTION_MSG(gKNIBuffer)); } else { char* pMsg = "Unknown error during btspp_notif::accept"; REPORT_INFO(LC_PROTOCOL, pMsg); KNI_ThrowNew(midpIOException, EXCEPTION_MSG(pMsg)); } } } KNI_EndHandles(); KNI_ReturnVoid(); }
/* * Accepts incoming client connection request. * * Note: the method gets native connection handle directly from * <code>handle<code> field of <code>BTSPPNotifierImpl</code> object. * * Note: new native connection handle to work with accepted incoming * client connection is setted directly to <code>handle</code> field of * appropriate <code>RFCOMMConnectionImpl</code> object. * * @throws IOException if an I/O error occurs */ KNIEXPORT KNI_RETURNTYPE_VOID Java_com_sun_jsr082_bluetooth_btspp_BTSPPNotifierImpl_accept0(void) { javacall_handle handle = JAVACALL_BT_INVALID_HANDLE; javacall_handle peer_handle = JAVACALL_BT_INVALID_HANDLE; MidpReentryData* info; int status = JAVACALL_FAIL; int processStatus = KNI_FALSE; void *context = NULL; javacall_bt_address peer_addr; jfieldID notifHandleID = NULL; jfieldID peerHandleID = NULL; jfieldID peerAddrID = NULL; jfieldID pushHandleID = NULL; KNI_StartHandles(3); KNI_DeclareHandle(thisHandle); KNI_DeclareHandle(arrayHandle); KNI_DeclareHandle(classHandle); KNI_GetClassPointer(classHandle); GET_FIELDID(classHandle, "handle", "I", notifHandleID) GET_FIELDID(classHandle, "peerHandle", "I", peerHandleID) GET_FIELDID(classHandle, "peerAddress", "[B", peerAddrID) GET_FIELDID(classHandle, "pushHandle", "I", pushHandleID) KNI_GetThisPointer(thisHandle); handle = (javacall_handle)KNI_GetIntField(thisHandle, notifHandleID); KNI_GetObjectField(thisHandle, peerAddrID, arrayHandle); if (handle == JAVACALL_BT_INVALID_HANDLE) { REPORT_ERROR(LC_PROTOCOL, "RFCOMM notifier was closed before btspp_notif::accept"); KNI_ThrowNew(midpInterruptedIOException, EXCEPTION_MSG( "RFCOMM notifier was closed")); } else { #ifndef NO_PUSH bt_pushid_t pushid = KNI_GetIntField(thisHandle, pushHandleID); if (pushid != BT_INVALID_PUSH_HANDLE) { if (bt_push_checkout_client(pushid, &peer_handle, peer_addr, NULL, NULL) == JAVACALL_OK) { pushcheckoutaccept((int)handle); processStatus = KNI_TRUE; status = JAVACALL_OK; } } #endif if (peer_handle == JAVACALL_BT_INVALID_HANDLE) { info = (MidpReentryData*)SNI_GetReentryData(NULL); if (info == NULL) { /* First invocation */ REPORT_INFO1(LC_PROTOCOL, "btspp_notif::accept handle=%d\n", handle); // Need revisit: add resource counting /* * An incoming socket connection counts against the client socket * resource limit. */ /* if (midpCheckResourceLimit(RSC_TYPE_BT_CLI, 1) == 0) { const char* pMsg = "Resource limit exceeded for BT client sockets"; REPORT_INFO(LC_PROTOCOL, pMsg); KNI_ThrowNew(midpIOException, EXCEPTION_MSG(pMsg)); */ // } else { status = javacall_bt_rfcomm_accept( handle, &peer_handle, &peer_addr); processStatus = KNI_TRUE; // } } else { /* Reinvocation after unblocking the thread */ if ((javacall_handle)info->descriptor != handle) { midp_snprintf(gKNIBuffer, KNI_BUFFER_SIZE, "btspp_notif::accept handles mismatched %d != %d\n", handle, info->descriptor); REPORT_CRIT(LC_PROTOCOL, gKNIBuffer); KNI_ThrowNew(midpIllegalStateException, EXCEPTION_MSG( "Internal error in btspp_notif::accept")); } else { // Need revisit: add resource counting /* if (midpCheckResourceLimit(RSC_TYPE_BT_CLI, 1) == 0) { const char* pMsg = "Resource limit exceeded for BT client sockets" REPORT_INFO(LC_PROTOCOL, pMsg); KNI_ThrowNew(midpIOException, EXCEPTION_MSG(pMsg)); } else { */ context = info->pResult; status = javacall_bt_rfcomm_accept( handle, &peer_handle, &peer_addr); processStatus = KNI_TRUE; // } } } } if (processStatus) { REPORT_INFO1(LC_PROTOCOL, "btspp_notif::accept server handle=%d\n", handle); if (status == JAVACALL_OK) { // Need revisit: add resource counting /* if (midpIncResourceCount(RSC_TYPE_BT_CLI, 1) == 0) { REPORT_INFO(LC_PROTOCOL, "btspp_notif: Resource limit update error"); } */ // store client native connection handle for temporary storing KNI_SetIntField(thisHandle, peerHandleID, (jint)peer_handle); // copy address to Java object field KNI_SetRawArrayRegion(arrayHandle, 0, JAVACALL_BT_ADDRESS_SIZE, (jbyte*) peer_addr); REPORT_INFO(LC_PROTOCOL, "btspp_notif::accept incoming connection accepted!"); } else if (status == JAVACALL_WOULD_BLOCK) { midp_thread_wait(NETWORK_READ_SIGNAL, (int)handle, context); } else if (status == JAVACALL_FAIL) { char* pError; javacall_bt_rfcomm_get_error(handle, &pError); midp_snprintf(gKNIBuffer, KNI_BUFFER_SIZE, "IO error in btspp_notif::accept (%s)\n", pError); REPORT_INFO(LC_PROTOCOL, gKNIBuffer); KNI_ThrowNew(midpIOException, EXCEPTION_MSG(gKNIBuffer)); } else { char* pMsg = "Unknown error during btspp_notif::accept"; REPORT_INFO(LC_PROTOCOL, pMsg); KNI_ThrowNew(midpIOException, EXCEPTION_MSG(pMsg)); } } } KNI_EndHandles(); KNI_ReturnVoid(); }
/** * Writes to the open socket connection. * <p> * Java declaration: * <pre> * write0([BII)I * </pre> * * @param b the buffer of the data to write * @param off the start offset in array <tt>b</tt> * at which the data is written. * @param len the number of bytes to write. * * @return the total number of bytes written */ KNIEXPORT KNI_RETURNTYPE_INT Java_com_sun_midp_io_j2me_socket_Protocol_write0(void) { int length; int offset; void *pcslHandle; int bytesWritten = 0; int status = PCSL_NET_INVALID; void *context = NULL; MidpReentryData* info; length = (int)KNI_GetParameterAsInt(3); offset = (int)KNI_GetParameterAsInt(2); KNI_StartHandles(2); KNI_DeclareHandle(bufferObject); KNI_DeclareHandle(thisObject); KNI_GetThisPointer(thisObject); KNI_GetParameterAsObject(1, bufferObject); pcslHandle = (void *)(getMidpSocketProtocolPtr(thisObject)->handle); REPORT_INFO3(LC_PROTOCOL, "socket::write0 o=%d l=%d fd=%d\n", offset, length, pcslHandle); info = (MidpReentryData*)SNI_GetReentryData(NULL); START_NETWORK_INDICATOR; if (info == NULL) { /* First invocation */ if (INVALID_HANDLE == pcslHandle) { KNI_ThrowNew(midpIOException, "invalid handle during socket::write"); } else { INC_NETWORK_INDICATOR; SNI_BEGIN_RAW_POINTERS; status = pcsl_socket_write_start(pcslHandle, (char*)&(JavaByteArray(bufferObject)[offset]), length, &bytesWritten, &context); SNI_END_RAW_POINTERS; } } else { /* Reinvocation after unblocking the thread */ if (INVALID_HANDLE == pcslHandle) { /* closed by another thread */ KNI_ThrowNew(midpInterruptedIOException, "Interrupted IO error during socket::read"); DEC_NETWORK_INDICATOR; } else { if ((void *)info->descriptor != pcslHandle) { REPORT_CRIT2(LC_PROTOCOL, "socket::write Handles mismatched 0x%x != 0x%x\n", pcslHandle, info->descriptor); } context = info->pResult; SNI_BEGIN_RAW_POINTERS; status = pcsl_socket_write_finish(pcslHandle, (char*)&(JavaByteArray(bufferObject)[offset]), length, &bytesWritten, context); SNI_END_RAW_POINTERS; } } if (INVALID_HANDLE != pcslHandle) { if (status == PCSL_NET_SUCCESS) { DEC_NETWORK_INDICATOR; } else { REPORT_INFO1(LC_PROTOCOL, "socket::write error=%d\n", (int)pcsl_network_error(pcslHandle)); if (status == PCSL_NET_WOULDBLOCK) { midp_thread_wait(NETWORK_WRITE_SIGNAL, (int)pcslHandle, context); } else if (status == PCSL_NET_INTERRUPTED) { midp_snprintf(gKNIBuffer, KNI_BUFFER_SIZE, "Interrupted IO error %d during socket::write ", pcsl_network_error(pcslHandle)); KNI_ThrowNew(midpInterruptedIOException, gKNIBuffer); DEC_NETWORK_INDICATOR; } else { midp_snprintf(gKNIBuffer, KNI_BUFFER_SIZE, "IOError %d during socket:: write \n", pcsl_network_error(pcslHandle)); KNI_ThrowNew(midpIOException, gKNIBuffer); DEC_NETWORK_INDICATOR; } } } REPORT_INFO1(LC_PROTOCOL, "socket::write0 bytesWritten=%d\n", bytesWritten); KNI_EndHandles(); KNI_ReturnInt((jint)bytesWritten); }
/** * Write to a serial port without blocking. * * @param hPort handle to a native serial port * @param b I/O buffer * @param off starting offset for data * @param len length of data * * @return number of bytes that were written * * @exception IOException if an I/O error occurs. */ KNIEXPORT KNI_RETURNTYPE_INT Java_com_sun_midp_io_j2me_comm_Protocol_native_1writeBytes() { int length = (int)KNI_GetParameterAsInt(4); int offset = (int)KNI_GetParameterAsInt(3); int hPort = (int)KNI_GetParameterAsInt(1); int bytesWritten = 0; int status = PCSL_NET_IOERROR; void* context = NULL; MidpReentryData* info; KNI_StartHandles(1); KNI_DeclareHandle(bufferObject); KNI_GetParameterAsObject(2, bufferObject); info = (MidpReentryData*)SNI_GetReentryData(NULL); if (info == NULL) { if (hPort < 0) { midp_snprintf(gKNIBuffer, KNI_BUFFER_SIZE, "Write to port: handle %d is invalid\n", hPort); REPORT_INFO1(LC_PROTOCOL, "%s\n", gKNIBuffer); KNI_ThrowNew(midpIllegalArgumentException, gKNIBuffer); } else { SNI_BEGIN_RAW_POINTERS; status = writeToPortStart(hPort, (char*)&(JavaByteArray(bufferObject)[offset]), length, &bytesWritten, &context); SNI_END_RAW_POINTERS; } } else { /* reinvocation */ hPort = info->descriptor; context = info->pResult; SNI_BEGIN_RAW_POINTERS; status = writeToPortFinish(hPort, (char*)&(JavaByteArray(bufferObject)[offset]), length, &bytesWritten, context); SNI_END_RAW_POINTERS; } switch (status) { case PCSL_NET_SUCCESS: /*do nothing and return normally */ break; case PCSL_NET_INTERRUPTED: midp_snprintf(gKNIBuffer, KNI_BUFFER_SIZE, "Writing to port %d has been interrupted\n", hPort); REPORT_INFO1(LC_PROTOCOL, "%s\n", gKNIBuffer); KNI_ThrowNew(midpInterruptedIOException, gKNIBuffer); break; case PCSL_NET_WOULDBLOCK: midp_thread_wait(COMM_WRITE_SIGNAL, hPort, context); break; default: midp_snprintf(gKNIBuffer, KNI_BUFFER_SIZE, "Writing to port %d was failed\n", hPort); REPORT_INFO1(LC_PROTOCOL, "%s\n", gKNIBuffer); KNI_ThrowNew(midpIOException, gKNIBuffer); } KNI_EndHandles(); KNI_ReturnInt((jint)bytesWritten); }
/* * Reads data from a packet received via Bluetooth stack. * * Note: the method gets native connection handle directly from * <code>handle<code> field of <code>L2CAPConnectionImpl</code> object. * * @param buf the buffer to read to * @param offset he start offset in array <code>buf</code> * at which the data to be written * @param size the maximum number of bytes to read, * the rest of the packet is discarded. * @return total number of bytes read into the buffer or * <code>0</code> if a zero length packet is received * @throws IOException if an I/O error occurs */ KNIEXPORT KNI_RETURNTYPE_INT Java_com_sun_jsr082_bluetooth_btl2cap_L2CAPConnectionImpl_receive0(void) { int length, offset; javacall_handle handle; int bytesRead = -1; int status = JAVACALL_FAIL; void* context = NULL; MidpReentryData* info; jfieldID connHandleID = NULL; offset = (int)KNI_GetParameterAsInt(2); length = (int)KNI_GetParameterAsInt(3); KNI_StartHandles(3); KNI_DeclareHandle(arrayHandle); KNI_DeclareHandle(thisHandle); KNI_DeclareHandle(classHandle); KNI_GetThisPointer(thisHandle); KNI_GetClassPointer(classHandle); GET_FIELDID(classHandle, "handle", "I", connHandleID) handle = (javacall_handle)KNI_GetIntField(thisHandle, connHandleID); KNI_GetParameterAsObject(1, arrayHandle); REPORT_INFO3(LC_PROTOCOL, "btl2cap::receive off=%d len=%d handle=%d\n", offset, length, handle); info = (MidpReentryData*)SNI_GetReentryData(NULL); // Need revisit: add bluetooth activity indicator // START_BT_INDICATOR; if (info == NULL) { /* First invocation */ if (JAVACALL_BT_INVALID_HANDLE == handle) { KNI_ThrowNew(midpIOException, EXCEPTION_MSG( "Invalid handle during btl2cap::receive")); } else { // Need revisit: add bluetooth activity indicator // INC_BT_INDICATOR; SNI_BEGIN_RAW_POINTERS; status = javacall_bt_l2cap_receive(handle, (unsigned char*)&(JavaByteArray(arrayHandle)[offset]), length, &bytesRead); SNI_END_RAW_POINTERS; } } else { /* Reinvocation after unblocking the thread */ if (JAVACALL_BT_INVALID_HANDLE == handle) { /* closed by another thread */ KNI_ThrowNew(midpInterruptedIOException, EXCEPTION_MSG( "Interrupted IO error during btl2cap::receive")); // Need revisit: add bluetooth activity indicator // DEC_BT_INDICATOR; } else { if ((javacall_handle)info->descriptor != handle) { REPORT_CRIT2(LC_PROTOCOL, "btl2cap::receive handles mismatched %d != %d\n", handle, (javacall_handle)info->descriptor); } context = info->pResult; SNI_BEGIN_RAW_POINTERS; status = javacall_bt_l2cap_receive(handle, (unsigned char*)&(JavaByteArray(arrayHandle)[offset]), length, &bytesRead); SNI_END_RAW_POINTERS; } } REPORT_INFO1(LC_PROTOCOL, "btl2cap::receive bytes=%d\n", bytesRead); if (JAVACALL_BT_INVALID_HANDLE != handle) { if (status == JAVACALL_OK) { // Need revisit: add bluetooth activity indicator // DEC_BT_INDICATOR; } else { char* pError; javacall_bt_l2cap_get_error(handle, &pError); REPORT_INFO1(LC_PROTOCOL, "btl2cap::receive (%s)\n", pError); if (status == JAVACALL_WOULD_BLOCK) { midp_thread_wait(NETWORK_READ_SIGNAL, (int)handle, context); } else if (status == JAVACALL_INTERRUPTED) { char* pError; javacall_bt_l2cap_get_error(handle, &pError); midp_snprintf(gKNIBuffer, KNI_BUFFER_SIZE, "Interrupted IO error during btl2cap::receive (%s)", pError); KNI_ThrowNew(midpInterruptedIOException, EXCEPTION_MSG(gKNIBuffer)); // Need revisit: add bluetooth activity indicator // DEC_BT_INDICATOR; } else { char* pError; javacall_bt_l2cap_get_error(handle, &pError); midp_snprintf(gKNIBuffer, KNI_BUFFER_SIZE, "Unknown error during btl2cap::receive (%s)", pError); KNI_ThrowNew(midpIOException, EXCEPTION_MSG(gKNIBuffer)); // Need revisit: add bluetooth activity indicator // DEC_BT_INDICATOR; } } } // Need revisit: add bluetooth activity indicator // STOP_BT_INDICATOR; KNI_EndHandles(); KNI_ReturnInt((jint)bytesRead); }
/* * Performs client connection establishment. * * Note: the method gets native connection handle directly from * <code>handle<code> field of <code>L2CAPConnectionImpl</code> object. * * @param addr bluetooth address of device to connect to * @param psm Protocol Service Multiplexor (PSM) value * @return Negotiated ReceiveMTU and TransmitMTU. * 16 high bits is ReceiveMTU, 16 low bits is TransmitMTU. * * @throws IOException if any I/O error occurs */ KNIEXPORT KNI_RETURNTYPE_INT Java_com_sun_jsr082_bluetooth_btl2cap_L2CAPConnectionImpl_connect0(void) { unsigned char *address = NULL; int psm = (int)KNI_GetParameterAsInt(2); javacall_handle handle = JAVACALL_BT_INVALID_HANDLE; int status, i, imtu, omtu, mtus; void* context = NULL; MidpReentryData* info; javacall_bt_address addr; jfieldID connHandleID = NULL; KNI_StartHandles(3); KNI_DeclareHandle(thisHandle); KNI_DeclareHandle(arrayHandle); KNI_DeclareHandle(classHandle); KNI_GetThisPointer(thisHandle); KNI_GetClassPointer(classHandle); GET_FIELDID(classHandle, "handle", "I", connHandleID) KNI_GetParameterAsObject(1, arrayHandle); handle = (javacall_handle)KNI_GetIntField(thisHandle, connHandleID); REPORT_INFO1(LC_PROTOCOL, "btl2cap::connect handle=%d", handle); /* copy address from Java input array */ SNI_BEGIN_RAW_POINTERS; address = JavaByteArray(arrayHandle); for (i = 0; i < JAVACALL_BT_ADDRESS_SIZE; i++) { addr[i] = address[i]; } SNI_END_RAW_POINTERS; info = (MidpReentryData*)SNI_GetReentryData(NULL); if (info == NULL) { /* First invocation */ // Need revisit: add resource counting /* * Verify that the resource is available well within limit as per * the policy in ResourceLimiter */ /* if (midpCheckResourceLimit(RSC_TYPE_BT_CLI, 1) == 0) { const char* pMsg = "Resource limit exceeded for BT client sockets"; REPORT_INFO(LC_PROTOCOL, pMsg); KNI_ThrowNew(midpIOException, EXCEPTION_MSG(pMsg)); } else { */ status = javacall_bt_l2cap_connect(handle, address, psm, &imtu, &omtu); if (status == JAVACALL_OK) { // Need revisit: add resource counting /* if (midpIncResourceCount(RSC_TYPE_BT_CLI, 1) == 0) { REPORT_INFO(LC_PROTOCOL, "Resource limit update error"); } */ } else if (status == JAVACALL_FAIL) { char* pError; javacall_bt_l2cap_get_error(handle, &pError); midp_snprintf(gKNIBuffer, KNI_BUFFER_SIZE, "IO error in btl2cap::connect (%s)\n", pError); REPORT_INFO(LC_PROTOCOL, gKNIBuffer); KNI_ThrowNew(midpIOException, EXCEPTION_MSG(gKNIBuffer)); } else if (status == JAVACALL_WOULD_BLOCK) { // Need revisit: add bluetooth activity indicator // INC_BT_INDICATOR; // Need revisit: add resource counting /* if (midpIncResourceCount(RSC_TYPE_BT_CLI, 1) == 0) { REPORT_INFO(LC_PROTOCOL, "Resource limit update error"); } */ REPORT_INFO1(LC_PROTOCOL, "btl2cap::connect is waiting for complete notify" ", handle = %d\n", handle); midp_thread_wait(NETWORK_WRITE_SIGNAL, (int)handle, context); } else { char* pMsg = "Unknown error during btl2cap::connect"; REPORT_INFO(LC_PROTOCOL, pMsg); KNI_ThrowNew(midpIOException, EXCEPTION_MSG(pMsg)); } // } } else { /* Reinvocation after unblocking the thread */ context = info->pResult; if ((javacall_handle)info->descriptor != handle) { REPORT_CRIT2(LC_PROTOCOL, "btl2cap::connect handles mismatched %d != %d\n", handle, (javacall_handle)info->descriptor); } status = javacall_bt_l2cap_connect(handle, address, psm, &imtu, &omtu); if (status == JAVACALL_OK) { // Need revisit: add bluetooth activity indicator // DEC_BT_INDICATOR; } else if (status == JAVACALL_WOULD_BLOCK) { midp_thread_wait(NETWORK_WRITE_SIGNAL, (int)handle, context); } else { char* pError; KNI_SetIntField(thisHandle, connHandleID, (jint)JAVACALL_BT_INVALID_HANDLE); // Need revisit: add bluetooth activity indicator // DEC_BT_INDICATOR; // Need revisit: add resource counting /* if (midpDecResourceCount(RSC_TYPE_BT_CLI, 1) == 0) { REPORT_INFO(LC_PROTOCOL, "Resource limit update error"); } */ javacall_bt_l2cap_get_error(handle, &pError); midp_snprintf(gKNIBuffer, KNI_BUFFER_SIZE, "Error in btl2cap::connect (%s)", pError); REPORT_INFO(LC_PROTOCOL, gKNIBuffer); KNI_ThrowNew(midpConnectionNotFoundException, EXCEPTION_MSG(gKNIBuffer)); } } mtus = (imtu << 16) & 0xFFFF0000; mtus |= omtu & 0xFFFF; KNI_EndHandles(); KNI_ReturnInt(mtus); }
/** * Closes the datagram connection. * <p> * Java declaration: * <pre> * close0(V)V * </pre> */ KNIEXPORT KNI_RETURNTYPE_VOID Java_com_sun_midp_io_j2me_datagram_Protocol_close0(void) { void *socketHandle; MidpReentryData *info; KNI_StartHandles(1); KNI_DeclareHandle(thisObject); KNI_GetThisPointer(thisObject); socketHandle = (void *)getMidpDatagramProtocolPtr(thisObject)->nativeHandle; info = (MidpReentryData*)SNI_GetReentryData(NULL); REPORT_INFO1(LC_PROTOCOL, "datagram::close handle=0x%x", (int)socketHandle); if (socketHandle != INVALID_HANDLE) { int status; status = pushcheckin((int)socketHandle); if (status == -1) { void *context = NULL; if (info == NULL) { /* first invocation */ INC_NETWORK_INDICATOR; status = pcsl_datagram_close_start(socketHandle, &context); getMidpDatagramProtocolPtr(thisObject)->nativeHandle = (jint)INVALID_HANDLE; midp_thread_signal(NETWORK_READ_SIGNAL, (int)socketHandle, 0); midp_thread_signal(NETWORK_WRITE_SIGNAL, (int)socketHandle, 0); } else { /* reinvocation */ socketHandle = (void *)(info->descriptor); context = info->pResult; status = pcsl_datagram_close_finish(socketHandle, context); } if (status == PCSL_NET_WOULDBLOCK) { /* IMPL NOTE: unclear whether this is the right signal */ midp_thread_wait(NETWORK_READ_SIGNAL, (int)socketHandle, context); } else { /* PCSL_NET_SUCCESS or PCSL_NET_IOERROR */ DEC_NETWORK_INDICATOR; if (midpDecResourceCount(RSC_TYPE_UDP, 1) == 0) { REPORT_INFO(LC_PROTOCOL, "datagram::close0 resource limit update error"); } if (status != PCSL_NET_SUCCESS) { midp_snprintf(gKNIBuffer, KNI_BUFFER_SIZE, "error code %d", pcsl_network_error(socketHandle)); REPORT_INFO1(LC_PROTOCOL, "datagram::close %s", gKNIBuffer); KNI_ThrowNew(midpIOException, gKNIBuffer); } } } else { /* it was checked into push; don't really close the socket but notify a possible listeners to be unblocked */ getMidpDatagramProtocolPtr(thisObject)->nativeHandle = (jint)INVALID_HANDLE; midp_thread_signal(NETWORK_READ_SIGNAL, (int)socketHandle, 0); midp_thread_signal(NETWORK_WRITE_SIGNAL, (int)socketHandle, 0); } } else { if (info == NULL) { /* first invocation */ /* already closed, do nothing */ } else { /* reinvocation */ DEC_NETWORK_INDICATOR; } } KNI_EndHandles(); KNI_ReturnVoid(); }