/** * The platform should invoke this function in platform context to start * the Java VM and run installed Java Content Handler. * * @param handlerID launched Content Handler ID * @param url Invocation parameter: URL * @param action optional Invocation parameter: Action * * @note allowed argument description can be obtained by '-help' value as arg1. */ void javanotify_start_handler(char* handlerID, char* url, char* action) { int argc = 0; char *argv[MIDP_RUNMIDLET_MAXIMUM_ARGS]; javacall_result res; REPORT_INFO3(LC_CORE,"javanotify_start_handler() >> %s %s %s\n", handlerID, url, action); if (initialize_memory_slavemode() != JAVACALL_OK) { return; } argv[argc++] = "runMidlet"; argv[argc++] = "-1"; argv[argc++] = "com.sun.midp.content.Invoker"; if (NULL != handlerID) { argv[argc++] = handlerID; if (NULL != url) { argv[argc++] = url; if (NULL != action) argv[argc++] = action; } } javacall_lifecycle_state_changed(JAVACALL_LIFECYCLE_MIDLET_STARTED, JAVACALL_OK); res = runMidlet(argc, argv); }
/** * Opens a file and fills the content of the file in the result_buf. <BR> * This function made memory allocation inside. * * @param filename Path to the file. * @param result_buf Pointer to the buffer that will be filled by content of the file. * @return buffer file size in bytes */ long readJadFile(const pcsl_string * filename, char** result_buf) { int fd = 0; char* err = NULL; long bufsize = -1; int numread = 0; char* res = *result_buf; if (pcsl_string_length(filename) <= 0) { REPORT_INFO(LC_AMS, "readJadFile():No file name."); return BAD_PARAMS; } fd = storage_open(&err, filename, OPEN_READ); if(err != NULL) { REPORT_INFO1(LC_AMS, "readJadFile():Can't open jad file '%s'",err); storageFreeError(err); return NO_JAD_FILE; } bufsize = storageSizeOf(&err, fd); if((bufsize <= 0) || (err != NULL)) { REPORT_INFO1(LC_AMS, "readJadFile():Problem getting file size: %s", err ); storageFreeError(err); return IO_ERROR; } res = (char*)midpMalloc(bufsize+1); if (res == NULL || (err != NULL)) { REPORT_INFO1(LC_AMS, "readJadFile():Can't allocate memory. %s", err); storageFreeError(err); return OUT_OF_MEMORY; } memset(res,0,(bufsize+1)); REPORT_INFO2(LC_AMS, "fd = %d, bufsize = %ld\n", fd, bufsize); numread = storageRead(&err, fd, res, bufsize); if((numread <= 0) || (numread != bufsize) || (err)) { REPORT_INFO3(LC_AMS, "size = %ld, numread = %d, err = %s.", bufsize, numread, err); storageClose(&err, fd); return IO_ERROR; } REPORT_INFO2(LC_AMS, "size = %ld, numread = %d", bufsize, numread); storageClose(&err, fd); if(err != NULL) { REPORT_INFO1(LC_AMS, "Can't close jad file %s\n", err); } *result_buf = res; return bufsize; } /* end of readJadFile */
/** * The notification function to be called by platform for pen * press/release/drag occurences. * The platform will invoke the call back in platform context for * each pen press, pen release and pen dragg occurence * @param x the x positoin when the pen was pressed/released/dragged * @param y the y positoin when the pen was pressed/released/dragged * @param type <tt>JAVACALL_PENPRESSED</tt> when pen was pressed * <tt>JAVACALL_PENRELEASED</tt> when pen was released * <tt>JAVACALL_PENDRAGGED</tt> when pen was dragged */ void javanotify_pen_event(int x, int y, javacall_penevent_type type) { midp_jc_event_union e; REPORT_INFO3(LC_CORE,"javanotify_pen_event() >> x=%d, y=%d type=%d\n",x,y,type); e.eventType = MIDP_JC_EVENT_PEN; e.data.penEvent.type = type; e.data.penEvent.x = x; e.data.penEvent.y = y; midp_jc_event_send(&e); }
/** * Create a new entry and enqueue in data-structure * * @param timeToWakeup the abs time for the timer (used to order the timer queue) * @param userData user specified data * @param userCallback user specified callback * * @return poitner to new element if successful, * NULL if there was an error allocating this timer. */ TimerHandle* new_timer( jlong timeToWakeup, void* userData, fTimerCallback userCallback) { TimerHandle* newTimer = (TimerHandle*)midpMalloc(sizeof(TimerHandle)); if (newTimer != NULL) { REPORT_INFO3(LC_PUSH, "[new_timer] timeToWakeup=%#lx userData=%p userCallback=%p", (long)timeToWakeup, userData, (void *)userCallback); newTimer->next = NULL; newTimer->timeToWakeup = timeToWakeup; newTimer->userData = userData; newTimer->userCallback = userCallback; add_timer(newTimer); } return newTimer; }
/** * The platform should invoke this function in platform context to start * the Java VM and run installed Java Content Handler. * * @param handlerID launched Content Handler ID * @param url Invocation parameter: URL * @param action optional Invocation parameter: Action * * @note allowed argument description can be obtained by '-help' value as arg1. */ void javanotify_start_handler(char* handlerID, char* url, char* action) { midp_jc_event_union e; midp_jc_event_start_arbitrary_arg *data = &e.data.startMidletArbitraryArgEvent; REPORT_INFO3(LC_CORE,"javanotify_start_handler() >> %s %s %s\n", handlerID, url, action); e.eventType = MIDP_JC_EVENT_START_ARBITRARY_ARG; data->argc = 0; data->argv[data->argc++] = "runMidlet"; data->argv[data->argc++] = "-1"; data->argv[data->argc++] = "com.sun.midp.content.Invoker"; if (NULL != handlerID) { data->argv[data->argc++] = handlerID; if (NULL != url) { data->argv[data->argc++] = url; if (NULL != action) data->argv[data->argc++] = action; } } midp_jc_event_send(&e); }
static MidpProperties midpParseMf(jchar* jchar_buffer) { MidpProperties mfsmp = {0, ALL_OK, NULL}; pcsl_string mfkey; pcsl_string mfkey_trimmed; pcsl_string mfvalue; pcsl_string mfvalue_trimmed; pcsl_string mfline; MIDPError err; pcsl_string_status rc; int countLines = 0; int index = 0; int count = 0; if (!jchar_buffer) { mfsmp.status = BAD_PARAMS; return mfsmp; } countLines = count_mf_lines(jchar_buffer); if (countLines <= 0) { REPORT_INFO(LC_AMS, "midpParseMf(): Empty manifest."); mfsmp.status = OUT_OF_MEMORY; return mfsmp; } mfsmp.pStringArr = alloc_pcsl_string_list(countLines * 2); if (mfsmp.pStringArr == NULL) { mfsmp.status = OUT_OF_MEMORY; return mfsmp; } mfsmp.numberOfProperties = countLines; for (count = 0; count < countLines * 2 ; /* count increased at the end of for */ ) { /* memory for the line is allocated here */ /* line continuation striped out */ err = readMfLine(&jchar_buffer, &mfline); if (OUT_OF_MEMORY == err) { midp_free_properties(&mfsmp); mfsmp.status = OUT_OF_MEMORY; return mfsmp; } else if (END_OF_MF == err) { /* we are done */ mfsmp.status = ALL_OK; break; } index = pcsl_string_index_of(&mfline, ':'); if (index <= 0) { mfsmp.status = BAD_MF_KEY; pcsl_string_free(&mfline); continue; } /* memory for mfkey is allocated here */ if (PCSL_STRING_OK != pcsl_string_substring(&mfline, 0, index, &mfkey)) { midp_free_properties(&mfsmp); mfsmp.status = OUT_OF_MEMORY; pcsl_string_free(&mfline); return mfsmp; } rc = pcsl_string_trim(&mfkey, &mfkey_trimmed); pcsl_string_free(&mfkey); if (PCSL_STRING_OK != rc) { mfsmp.status = OUT_OF_MEMORY; midp_free_properties(&mfsmp); pcsl_string_free(&mfline); return mfsmp; } if (pcsl_string_length(&mfkey_trimmed) < 1) { mfsmp.status = BAD_PARAMS; pcsl_string_free(&mfline); pcsl_string_free(&mfkey_trimmed); continue; } err = checkMfKeyChars(&mfkey_trimmed); if (OUT_OF_MEMORY == err) { mfsmp.status = OUT_OF_MEMORY; midp_free_properties(&mfsmp); pcsl_string_free(&mfline); pcsl_string_free(&mfkey_trimmed); return mfsmp; } else if (BAD_MF_KEY == err) { mfsmp.status = BAD_MF_KEY; pcsl_string_free(&mfline); pcsl_string_free(&mfkey_trimmed); continue; } rc = pcsl_string_substring(&mfline, index + 1, pcsl_string_length(&mfline), &mfvalue); /* free the mfline once we have got the key and value */ pcsl_string_free(&mfline); if (PCSL_STRING_OK != rc) { mfsmp.status = OUT_OF_MEMORY; midp_free_properties(&mfsmp); pcsl_string_free(&mfkey_trimmed); return mfsmp; } /* memory for value is allocated here */ rc = pcsl_string_trim(&mfvalue, &mfvalue_trimmed); pcsl_string_free(&mfvalue); if (PCSL_STRING_OK != rc) { mfsmp.status = OUT_OF_MEMORY; midp_free_properties(&mfsmp); pcsl_string_free(&mfkey_trimmed); return mfsmp; } if (pcsl_string_is_null(&mfvalue_trimmed)) { mfsmp.status = NULL_LEN; pcsl_string_free(&mfkey_trimmed); continue; } err = checkMfValueChars(&mfvalue_trimmed); if (OUT_OF_MEMORY == err) { mfsmp.status = OUT_OF_MEMORY; midp_free_properties(&mfsmp); pcsl_string_free(&mfkey_trimmed); pcsl_string_free(&mfvalue_trimmed); return mfsmp; } else if (BAD_MF_VALUE == err) { mfsmp.status = BAD_MF_VALUE; pcsl_string_free(&mfkey_trimmed); pcsl_string_free(&mfvalue_trimmed); continue; } printPcslStringWithMessage("midpParseMf()", &mfkey_trimmed); printPcslStringWithMessage(" = ", &mfvalue_trimmed); /* Store key:value pair. */ mfsmp.pStringArr[count] = mfkey_trimmed; mfsmp.pStringArr[count+1] = mfvalue_trimmed; count += 2; } /* end of for */ mfsmp = verifyMfMustProperties(mfsmp); REPORT_INFO3(LC_AMS, "End of midpParseMf: Status=%d, count=%d, countLines=%d", mfsmp.status, count, countLines); return mfsmp; } /* end of midpParseMf */
static MidpProperties midpParseJad(jchar* jchar_buffer) { MidpProperties jadsmp = {0, ALL_OK, NULL}; pcsl_string jadkey; pcsl_string jadkey_trimmed; pcsl_string jadvalue; pcsl_string jadvalue_trimmed; pcsl_string jadline; MIDPError err; pcsl_string_status rc; int countLines = 0; jint index = 0; int count = 0; if (!jchar_buffer) { jadsmp.status = BAD_PARAMS; return jadsmp; } countLines = count_jad_lines(jchar_buffer); if (countLines <= 0) { REPORT_INFO(LC_AMS, "midpParseJad(): Empty jad file."); jadsmp.status = OUT_OF_MEMORY; return jadsmp; } jadsmp.pStringArr = alloc_pcsl_string_list(countLines * 2); if (jadsmp.pStringArr == NULL) { jadsmp.status = OUT_OF_MEMORY; return jadsmp; } jadsmp.numberOfProperties = countLines; for (count = 0; count < countLines * 2 ; /* count increased at the end of for */ ) { /* memory for the line is allocated here */ err = readJadLine(&jchar_buffer, &jadline); if (OUT_OF_MEMORY == err) { midp_free_properties(&jadsmp); jadsmp.status = OUT_OF_MEMORY; return jadsmp; } else if (END_OF_JAD == err) { /* we are done */ jadsmp.status = ALL_OK; break; } index = pcsl_string_index_of(&jadline, ':'); if (index <= 0) { jadsmp.status = BAD_JAD_KEY; pcsl_string_free(&jadline); continue; } /* memory for key is allocated here */ if (PCSL_STRING_OK != pcsl_string_substring(&jadline, 0, index, &jadkey)) { midp_free_properties(&jadsmp); jadsmp.status = OUT_OF_MEMORY; pcsl_string_free(&jadline); return jadsmp; } rc = pcsl_string_trim(&jadkey, &jadkey_trimmed); pcsl_string_free(&jadkey); if (PCSL_STRING_OK != rc) { jadsmp.status = OUT_OF_MEMORY; midp_free_properties(&jadsmp); pcsl_string_free(&jadline); return jadsmp; } if (pcsl_string_length(&jadkey_trimmed) < 1) { jadsmp.status = BAD_PARAMS; pcsl_string_free(&jadline); pcsl_string_free(&jadkey_trimmed); continue; } err = checkJadKeyChars(&jadkey_trimmed); if (OUT_OF_MEMORY == err) { jadsmp.status = OUT_OF_MEMORY; midp_free_properties(&jadsmp); pcsl_string_free(&jadline); pcsl_string_free(&jadkey_trimmed); return jadsmp; } else if (BAD_JAD_KEY == err) { jadsmp.status = BAD_JAD_KEY; pcsl_string_free(&jadline); pcsl_string_free(&jadkey_trimmed); continue; } rc = pcsl_string_substring(&jadline, index + 1, pcsl_string_length(&jadline), &jadvalue); /* free the jadline once we have got the key and value */ pcsl_string_free(&jadline); if (PCSL_STRING_OK != rc) { jadsmp.status = OUT_OF_MEMORY; midp_free_properties(&jadsmp); pcsl_string_free(&jadkey_trimmed); return jadsmp; } /* memory for value is allocated here */ rc = pcsl_string_trim(&jadvalue, &jadvalue_trimmed); pcsl_string_free(&jadvalue); if (PCSL_STRING_OK != rc) { jadsmp.status = OUT_OF_MEMORY; midp_free_properties(&jadsmp); pcsl_string_free(&jadkey_trimmed); return jadsmp; } if (pcsl_string_is_null(&jadvalue_trimmed)) { jadsmp.status = NULL_LEN; pcsl_string_free(&jadkey_trimmed); continue; } err = checkJadValueChars(&jadvalue_trimmed); if (OUT_OF_MEMORY == err) { jadsmp.status = OUT_OF_MEMORY; midp_free_properties(&jadsmp); pcsl_string_free(&jadkey_trimmed); pcsl_string_free(&jadvalue_trimmed); return jadsmp; } else if (BAD_JAD_VALUE == err) { jadsmp.status = BAD_JAD_VALUE; pcsl_string_free(&jadkey_trimmed); pcsl_string_free(&jadvalue_trimmed); continue; } printPcslStringWithMessage("midpParseJad()", &jadkey_trimmed); printPcslStringWithMessage("midpParseJad()", &jadvalue_trimmed); /* Store key:value pair. */ jadsmp.pStringArr[count] = jadkey_trimmed; jadsmp.pStringArr[count+1] = jadvalue_trimmed; count += 2; } /* end of for */ jadsmp = verifyJadMustProperties(jadsmp); REPORT_INFO3(LC_AMS, "End jad parsing. Status=%d, count=%d, countLines=%d.", jadsmp.status, count, countLines); return jadsmp; } /* end of midpParseJad */
/* * 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); }
/** * 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); }
/** * 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); }