/** * Common implementation between pcsl_datagram_read_start() * and pcsl_datagram_read_finish(). * * @param protocol A protocol type (e.g.: <code>WMA_SMS_PROTOCOL</code>). * @param pAddress The network address from the datagram. * @param port The network port from the datagram. * @param buffer The buffer for the bytes to be read. * @param length The number of bytes to be read. * @param pBytesRead The number of bytes read. * * @return <code>WMA_NET_SUCCESS</code> if the read was successful; * <code>WMA_NET_WOULDBLOCK</code> if ??; * <code>WMA_NET_INTERRUPTED</code> if ??; * <code>WMA_NET_IOERROR</code>, otherwise. */ WMA_STATUS jsr120_datagram_read(WMA_PROTOCOLS protocol, unsigned char *pAddress, jint *port, char *buffer, jint length, jint *pBytesRead) { void *context; jint fd = -1; jint status; /* Pick up the socket descriptor for the given protocol. */ if (protocol == WMA_SMS_PROTOCOL) { fd = wmaGetRawSocketFD(smsHandle); } else if (protocol == WMA_CBS_PROTOCOL) { fd = wmaGetRawSocketFD(cbsHandle); } #if ENABLE_JSR_205 else if (protocol == WMA_MMS_PROTOCOL) { fd = wmaGetRawSocketFD(mmsHandle); } #endif if (fd < 0) { /* Unknown protocol type. */ return WMA_NET_IOERROR; } /* Read the datagram packet. */ status = pcsl_datagram_read_start((void*)fd, pAddress, port, buffer, length, pBytesRead, &context); switch (status) { case PCSL_NET_SUCCESS: return WMA_NET_SUCCESS; case PCSL_NET_WOULDBLOCK: return WMA_NET_WOULDBLOCK; case PCSL_NET_INTERRUPTED: return WMA_NET_INTERRUPTED; default: return WMA_NET_IOERROR; } }
/** * 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); }