/** * Report a message to the Logging service. On the linux emulator * this will end up going to stdout. On the Zaurus device it will * be written to a file. * * The <code>message</code> parameter is treated as a format * string to the standard C library call printf would be, with * conversion specifications (%s, %d, %c, etc) causing the * conversion and output of each successive argument after * <code>message</code> As with printf, having a conversion * character in <code>message</code> without an associated argument * following it is an error. * * To ensure that no character in <code>message</code> is * interpreted as requiring conversion, a safe way to call * this method is: * <code> reportToLog(severity, chanID, "%s", message); </code> * @param severity severity level of report * @param channelID area report relates to, from midp_constants_data.h * @param message detail message to go with the report * should not be NULL */ void reportToLog(int severity, int channelID, char* message, ...) { va_list ap; if (!fChannelSetupDone) { /* * Get the system property to check if the specific * channels were set for logging. */ const char* pChannelsArg = getSystemProperty(LOG_CHANNELS_ARG); if (pChannelsArg) { createLogChannelsList(pChannelsArg); } fChannelSetupDone = 1; } if (message != NULL && channelInList(channelID)) { midp_snprintf(gLoggingBuffer, LOGGING_BUFFER_SIZE, "REPORT: <level:%d> <channel:%d> ", severity, channelID); pcsl_print(gLoggingBuffer); va_start(ap, message); midp_vsnprintf(gLoggingBuffer, LOGGING_BUFFER_SIZE, message, ap); pcsl_print(gLoggingBuffer); va_end(ap); pcsl_print("\n"); } }
/* * Checks refId for validity, gets its handle value, and stores it * into obj. An error message incorporating msg is emitted if refId is * invalid or if the handle returns is null. */ static void getReference(int refId, char *msg, jobject obj) { if (refId == INVALID_REFERENCE_ID) { midp_snprintf(gKNIBuffer, KNI_BUFFER_SIZE, "invalid reference ID in %s", msg); REPORT_CRIT(LC_CORE, gKNIBuffer); KNI_ReleaseHandle(obj); } else { SNI_GetReference(refId, obj); if (KNI_IsNullHandle(obj)) { midp_snprintf(gKNIBuffer, KNI_BUFFER_SIZE, "null reference from SNI_GetReference in %s", msg); REPORT_CRIT(LC_CORE, gKNIBuffer); } } }
/** * Configure a serial port optional parameters. * * @param port device port returned from open * @param baud baud rate to set the port at * @param flags options for the serial port: * bit 0: 0 - 1 stop bit, 1 - 2 stop bits * bit 2-1: 00 - no parity, 01 - odd parity, 10 - even parity * bit 4: 0 - no auto RTS, 1 - set auto RTS * bit 5: 0 - no auto CTS, 1 - set auto CTS * bit 7-6: 01 - 7 bits per symbol, 11 - 8 bits per symbol */ KNIEXPORT KNI_RETURNTYPE_VOID Java_com_sun_midp_io_j2me_comm_Protocol_native_1configurePort() { unsigned int flags = (int)KNI_GetParameterAsInt(3); int baud = (int)KNI_GetParameterAsInt(2); int port = (int)KNI_GetParameterAsInt(1); int status = configurePort(port, baud, flags); if (status != PCSL_NET_SUCCESS) { midp_snprintf(gKNIBuffer, KNI_BUFFER_SIZE, "Error configure port %d \n", port); REPORT_INFO1(LC_PROTOCOL, "%s\n", gKNIBuffer); KNI_ThrowNew(midpIOException, gKNIBuffer); } KNI_ReturnVoid(); }
/** * Releases any native resources used by the socket connection. * <p> * Java declaration: * <pre> * finalize(V)V * </pre> */ KNIEXPORT KNI_RETURNTYPE_VOID Java_com_sun_midp_io_j2me_socket_Protocol_finalize(void) { void *pcslHandle; int status = PCSL_NET_INVALID; void* context = NULL; KNI_StartHandles(1); KNI_DeclareHandle(thisObject); KNI_GetThisPointer(thisObject); pcslHandle = (void *)(getMidpSocketProtocolPtr(thisObject)->handle); REPORT_INFO1(LC_PROTOCOL, "socket::finalize handle=%d\n", pcslHandle); if (INVALID_HANDLE != pcslHandle) { status = pcsl_socket_close_start(pcslHandle, &context); getMidpSocketProtocolPtr(thisObject)->handle = (jint)INVALID_HANDLE; if (midpDecResourceCount(RSC_TYPE_TCP_CLI, 1) == 0) { REPORT_INFO(LC_PROTOCOL, "Resource limit update error"); } if (status == PCSL_NET_IOERROR) { midp_snprintf(gKNIBuffer, KNI_BUFFER_SIZE, "IOError in socket::finalize error=%d\n", (int)pcsl_network_error(pcslHandle)); REPORT_ERROR1(LC_PROTOCOL, "%s", gKNIBuffer); } else if (status == PCSL_NET_WOULDBLOCK) { /* blocking during finalize is not supported */ REPORT_CRIT1(LC_PROTOCOL, "socket::finalize = 0x%x blocked\n", pcslHandle); } } FINISH_NETWORK_INDICATOR; KNI_EndHandles(); KNI_ReturnVoid(); }
/** * Gets the number of bytes that can be read without blocking. * <p> * Java declaration: * <pre> * available0(V)I * </pre> * * @return number of bytes that can be read without blocking */ KNIEXPORT KNI_RETURNTYPE_INT Java_com_sun_midp_io_j2me_socket_Protocol_available0(void) { void *pcslHandle; int bytesAvailable = 0; KNI_StartHandles(1); KNI_DeclareHandle(thisObject); KNI_GetThisPointer(thisObject); pcslHandle = (void *)(getMidpSocketProtocolPtr(thisObject)->handle); KNI_EndHandles(); REPORT_INFO1(LC_PROTOCOL, "socket::available0 fd=%d\n", (int)pcslHandle); if (INVALID_HANDLE == pcslHandle) { KNI_ThrowNew(midpIOException, "invalid handle during socket::available"); } else { int status; status = pcsl_socket_available(pcslHandle, &bytesAvailable); /* status is only PCSL_NET_SUCCESS or PCSL_NET_IOERROR */ if (status == PCSL_NET_IOERROR) { bytesAvailable = 0; midp_snprintf(gKNIBuffer, KNI_BUFFER_SIZE, "IOError %d during socket::available0", pcsl_network_error(pcslHandle)); KNI_ThrowNew(midpIOException, gKNIBuffer); } } REPORT_INFO1(LC_PROTOCOL, "socket::available0 bytesAvailable=%d\n", bytesAvailable); KNI_ReturnInt((jint)bytesAvailable); }
/** * 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(); }
/** * 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); }
/* * 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(); }
/** * Native finalizer. * Releases all native resources used by this connection. */ KNIEXPORT KNI_RETURNTYPE_VOID Java_com_sun_midp_io_j2me_btl2cap_L2CAPNotifierImpl_finalize(void) { javacall_handle handle, peer; int status = JAVACALL_FAIL; REPORT_INFO(LC_PROTOCOL, "btl2cap_notif::finalize"); KNI_StartHandles(1); KNI_DeclareHandle(thisHandle); KNI_GetThisPointer(thisHandle); handle = (javacall_handle)KNI_GetIntField(thisHandle, notifHandleID); if (handle != BT_INVALID_HANDLE) { status = javacall_bt_l2cap_close(handle); KNI_SetIntField(thisHandle, notifHandleID, (jint)BT_INVALID_HANDLE); // Need revisit: add resource counting /* if (midpDecResourceCount(RSC_TYPE_BT_SER, 1) == 0) { REPORT_INFO(LC_PROTOCOL, "Resource limit update error"); } */ if (status == JAVACALL_FAIL) { char* pError; javacall_bt_l2cap_get_error(handle, &pError); midp_snprintf(gKNIBuffer, KNI_BUFFER_SIZE, "IO error in bt_l2cap_notif::finalize (%s)\n", pError); REPORT_ERROR(LC_PROTOCOL, gKNIBuffer); } else if (status == JAVACALL_WOULD_BLOCK) { /* blocking during finalize is not supported */ REPORT_CRIT1(LC_PROTOCOL, "btl2cap_notif::finalize notifier blocked, handle = %d\n", handle); } } peer = (javacall_handle)KNI_GetIntField(thisHandle, peerHandleID); if (peer != BT_INVALID_HANDLE) { status = javacall_bt_l2cap_close(peer); KNI_SetIntField(thisHandle, peerHandleID, (jint)BT_INVALID_HANDLE); // Need revisit: add resource counting /* if (midpDecResourceCount(RSC_TYPE_BT_CLI, 1) == 0) { REPORT_INFO(LC_PROTOCOL, "Resource limit update error"); } */ if (status == JAVACALL_FAIL) { char* pError; javacall_bt_l2cap_get_error(peer, &pError); midp_snprintf(gKNIBuffer, KNI_BUFFER_SIZE, "IO error in bt_l2cap_notif::finalize (%s)\n", pError); REPORT_ERROR(LC_PROTOCOL, gKNIBuffer); } else if (status == JAVACALL_WOULD_BLOCK) { /* blocking during finalize is not supported */ REPORT_CRIT1(LC_PROTOCOL, "btl2cap_notif::finalize blocked, handle = %d\n", peer); } } REPORT_INFO(LC_PROTOCOL, "btl2cap_notif::finalize done!"); 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); }
/** * 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(); }
/* * 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); }
/** * Receives a datagram. * <p> * Java declaration: * <pre> * receive0([BII)J * </pre> * * @param buf the data buffer * @param off the offset into the data buffer * @param len the length of the data in the buffer * @return The upper 32 bits contain the raw IPv4 address of the * host the datagram was received from. The next 16 bits * contain the port. The last 16 bits contain the number * of bytes received. */ KNIEXPORT KNI_RETURNTYPE_LONG Java_com_sun_midp_io_j2me_datagram_Protocol_receive0(void) { int offset; int length; void *socketHandle; jlong lres = 0; MidpReentryData* info; KNI_StartHandles(2); KNI_DeclareHandle(bufferObject); KNI_DeclareHandle(thisObject); KNI_GetThisPointer(thisObject); KNI_GetParameterAsObject(1, bufferObject); offset = (int)KNI_GetParameterAsInt(2); length = (int)KNI_GetParameterAsInt(3); socketHandle = (void *)getMidpDatagramProtocolPtr(thisObject)->nativeHandle; info = (MidpReentryData*)SNI_GetReentryData(NULL); REPORT_INFO3(LC_PROTOCOL, "datagram::receive0 off=%d len=%d handle=0x%x", offset, length, (int)socketHandle); if (socketHandle != INVALID_HANDLE) { int ipAddress; int port; int bytesReceived; /* * Check the push cache for a waiting datagram. * * If pusheddatagram() returns -1 [IMPL NOTE: the code checks for less * than zero; which is correct?], we need to read a datagram * ourselves. Otherwise, pusheddatagram() has returned a waiting * datagram and has set ipAddress and port to valid values. */ SNI_BEGIN_RAW_POINTERS; bytesReceived = pusheddatagram((int)socketHandle, &ipAddress, &port, (char*)&(JavaByteArray(bufferObject)[offset]), length); SNI_END_RAW_POINTERS; if (bytesReceived < 0) { int status; unsigned char ipBytes[MAX_ADDR_LENGTH]; void *context; if (info == NULL) { /* initial invocation */ INC_NETWORK_INDICATOR; SNI_BEGIN_RAW_POINTERS; status = pcsl_datagram_read_start( socketHandle, ipBytes, &port, (char*)&(JavaByteArray(bufferObject)[offset]), length, &bytesReceived, &context); SNI_END_RAW_POINTERS; } else { /* reinvocation */ if ((void *)info->descriptor != socketHandle) { REPORT_CRIT2(LC_PROTOCOL, "datagram::send0 handle mismatch 0x%x != 0x%x\n", socketHandle, info->descriptor); } context = info->pResult; SNI_BEGIN_RAW_POINTERS; status = pcsl_datagram_read_finish( socketHandle, ipBytes, &port, (char*)&(JavaByteArray(bufferObject)[offset]), length, &bytesReceived, context); SNI_END_RAW_POINTERS; } if (status == PCSL_NET_SUCCESS) { memcpy(&ipAddress, ipBytes, MAX_ADDR_LENGTH); lres = pack_recv_retval(ipAddress, port, bytesReceived); DEC_NETWORK_INDICATOR; } else if (status == PCSL_NET_WOULDBLOCK) { midp_thread_wait(NETWORK_READ_SIGNAL, (int)socketHandle, context); } else if (status == PCSL_NET_INTERRUPTED) { KNI_ThrowNew(midpInterruptedIOException, NULL); DEC_NETWORK_INDICATOR; } else { /* status == PCSL_NET_IOERROR */ midp_snprintf(gKNIBuffer, KNI_BUFFER_SIZE, "error code %d", pcsl_network_error(socketHandle)); KNI_ThrowNew(midpIOException, gKNIBuffer); DEC_NETWORK_INDICATOR; } } else { /* push gave us a datagram */ lres = pack_recv_retval(ipAddress, port, bytesReceived); } } else { if (info == NULL) { /* initial invocation */ KNI_ThrowNew(midpIOException, "socket closed"); } else { /* reinvocation */ KNI_ThrowNew(midpInterruptedIOException, NULL); DEC_NETWORK_INDICATOR; } } KNI_EndHandles(); KNI_ReturnLong(lres); }
/** * 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); }
/** * 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(); }
/** * 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); }
/** * 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(); }
/** * 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(); }
/* * 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); }
/** * Sends a datagram. * <p> * Java declaration: * <pre> * send0(II[BII)I * </pre> * * @param ipNumber raw IPv4 address of the remote host * @param port UDP port of the remote host * @param buf the data buffer to send * @param off the offset into the data buffer * @param len the length of the data in the buffer * @return number of bytes sent */ KNIEXPORT KNI_RETURNTYPE_INT Java_com_sun_midp_io_j2me_datagram_Protocol_send0(void) { int ipAddress; int port; int offset; int length; int bytesSent = 0; void *socketHandle; MidpReentryData* info; unsigned char ipBytes[MAX_ADDR_LENGTH]; KNI_StartHandles(2); KNI_DeclareHandle(bufferObject); KNI_DeclareHandle(thisObject); KNI_GetThisPointer(thisObject); ipAddress = (int)KNI_GetParameterAsInt(1); port = (int)KNI_GetParameterAsInt(2); KNI_GetParameterAsObject(3, bufferObject); offset = (int)KNI_GetParameterAsInt(4); length = (int)KNI_GetParameterAsInt(5); socketHandle = (void *)getMidpDatagramProtocolPtr(thisObject)->nativeHandle; REPORT_INFO5(LC_PROTOCOL, "datagram::send0 off=%d len=%d port=%d ip=0x%x handle=0x%x", offset, length, port, ipAddress, (int)socketHandle); /* Convert ipAddress(integer) to ipBytes */ memcpy(ipBytes, &ipAddress, sizeof(ipBytes)); info = (MidpReentryData*)SNI_GetReentryData(NULL); if (socketHandle != INVALID_HANDLE) { int status; void *context; if (info == NULL) { /* initial invocation */ INC_NETWORK_INDICATOR; SNI_BEGIN_RAW_POINTERS; status = pcsl_datagram_write_start( socketHandle, ipBytes, port, (char*)&(JavaByteArray(bufferObject)[offset]), length, &bytesSent, &context); SNI_END_RAW_POINTERS; } else { /* reinvocation */ if ((void *)info->descriptor != socketHandle) { REPORT_CRIT2(LC_PROTOCOL, "datagram::send0 handle mismatch 0x%x != 0x%x\n", socketHandle, info->descriptor); } context = info->pResult; SNI_BEGIN_RAW_POINTERS; status = pcsl_datagram_write_finish( socketHandle, ipBytes, port, (char*)&(JavaByteArray(bufferObject)[offset]), length, &bytesSent, context); SNI_END_RAW_POINTERS; } if (status == PCSL_NET_SUCCESS) { DEC_NETWORK_INDICATOR; } else if (status == PCSL_NET_WOULDBLOCK) { midp_thread_wait(NETWORK_WRITE_SIGNAL, (int)socketHandle, context); } else if (status == PCSL_NET_INTERRUPTED) { KNI_ThrowNew(midpInterruptedIOException, NULL); DEC_NETWORK_INDICATOR; } else { /* status == PCSL_NET_IOERROR */ midp_snprintf(gKNIBuffer, KNI_BUFFER_SIZE, "error code %d", pcsl_network_error(socketHandle)); KNI_ThrowNew(midpIOException, gKNIBuffer); DEC_NETWORK_INDICATOR; } } else { if (info == NULL) { /* initial invocation */ KNI_ThrowNew(midpIOException, "socket closed"); } else { /* reinvocation */ KNI_ThrowNew(midpInterruptedIOException, NULL); DEC_NETWORK_INDICATOR; } } KNI_EndHandles(); KNI_ReturnInt((jint)bytesSent); }