Example #1
0
/**
 * 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;
    }

}
Example #2
0
/**
 * 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);
}