Ejemplo n.º 1
0
int midp_vsnprintf(char *buffer, int bufferSize, 
        const char* format, va_list argptr) {

	int rv, num;
    char vsprintf_buffer[VSPRINTF_BUFFER_SIZE];

    /* Fill num as minimum of bufferSize and VSPRINTF_BUFFER_SIZE */
	if (bufferSize > VSPRINTF_BUFFER_SIZE) {
        num = VSPRINTF_BUFFER_SIZE;
		REPORT_WARN1(LC_CORE,
            "Internal buffer is smaller than %d, data truncated", bufferSize);
	} else 
        num = bufferSize;
 
   /* IMPL_NOTE: using vsprintf function is not safely because it can
    * overflow output buffer. The javacall implementation will support
	* size limit format output and this function will be used here.
    * Current implementation detects buffer overflow by checking the last
	* byte and reports about it. In this case the VSPRINTF_BUFFER_SIZE
    * value need be increased.
    */
    rv = vsprintf(vsprintf_buffer, format, argptr);
    if (rv > VSPRINTF_BUFFER_SIZE - 1) {
		REPORT_CRIT2(LC_CORE, "Internal buffer %p overflow detected at %p !!!",
            vsprintf_buffer, vsprintf_buffer + VSPRINTF_BUFFER_SIZE);
    }
    if (num  > rv + 1) {
		num = rv + 1;
	} else 
        vsprintf_buffer[num - 1] = 0;

    memcpy(buffer, vsprintf_buffer, num);

    return rv;
}
Ejemplo n.º 2
0
/**
 * Same as for midp_snprintf. Not all compilers provide vsnprintf
 * function, so we have to use workaround. In debug mode it does
 * buffer overflow checking, and in release mode it works as vsprintf.
 */
int midp_vsnprintf(char *buffer, int bufferSize,
                   const char* format, va_list argptr) {

    int rv;

    buffer[bufferSize-1] = '\0';
    rv = vsprintf(buffer, format, argptr);

    if (buffer[bufferSize-1] != '\0') {
        buffer[bufferSize-1] = '\0';
        REPORT_CRIT2(LC_CORE, "Buffer %p overflow detected at %p !!!",
                     buffer, buffer + bufferSize);
    }

    return rv;
}
Ejemplo n.º 3
0
/*
 * 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);
}
Ejemplo n.º 4
0
/*
 * 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);
}
Ejemplo n.º 5
0
/**
 * 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();
}
Ejemplo n.º 6
0
/**
 * 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);
}
Ejemplo n.º 7
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);
}
Ejemplo n.º 8
0
/**
 * 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);
}