Example #1
0
/**
 * Initiates data sending via connection.
 *
 * If JAVACALL_WOULD_BLOCK is returned,
 * this function should be called again after the notification through 
 * javanotify_bt_protocol_event() with JAVACALL_EVENT_BT_SEND_COMPLETE type. 
 *
 * @param handle connection handle
 * @param pData pointer to data buffer
 * @param len length of the data
 * @param pBytesSent number of bytes that were really sent
 * @retval JAVACALL_OK on success,
 * @retval JAVACALL_WOULD_BLOCK if the caller needs a notification to complete the operation
 * @retval JAVACALL_FAIL on error
 */
javacall_result javacall_bt_rfcomm_send(
        javacall_handle handle,
        const char* pData, 
        int len, 
        /*OUT*/ int* pBytesSent)
{
    return javacall_bt_l2cap_send(handle, pData, len, pBytesSent);
}    
/*
 * Sends the specified data via Bluetooth stack.
 *
 * Note: the method gets native connection handle directly from
 * <code>handle<code> field of <code>L2CAPConnectionImpl</code> object.
 *
 * @param buf the data to send
 * @param off the offset into the data buffer
 * @param len the length of the data in the buffer
 * @return total number of send bytes,
 *         or <code>0</code> if empty pcaket has been send
 * @throws IOException if an I/O error occurs
 */
KNIEXPORT KNI_RETURNTYPE_INT
Java_com_sun_jsr082_bluetooth_btl2cap_L2CAPConnectionImpl_send0(void) {
    int length, offset;
    javacall_handle handle;
    int bytesWritten = 0;
    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::send 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::send"));
        } else {
            // Need revisit: add bluetooth activity indicator
//            INC_BT_INDICATOR;
            SNI_BEGIN_RAW_POINTERS;
            status = javacall_bt_l2cap_send(handle,
                           (char*)&(JavaByteArray(arrayHandle)[offset]),
                           length, &bytesWritten);
            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::send"));
            // Need revisit: add bluetooth activity indicator
//            DEC_BT_INDICATOR;
        } else {
            if ((javacall_handle)info->descriptor != handle) {
                REPORT_CRIT2(LC_PROTOCOL,
                    "btl2cap::send handles mismatched %d != %d\n",
                    handle, (javacall_handle)info->descriptor);
            }
            context = info->pResult;
            SNI_BEGIN_RAW_POINTERS;
            status = javacall_bt_l2cap_send(handle,
                       (char*)&(JavaByteArray(arrayHandle)[offset]),
                       length, &bytesWritten);
            SNI_END_RAW_POINTERS;
        }
    }

   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::send (%s)\n", pError);

            if (status == JAVACALL_WOULD_BLOCK) {
                midp_thread_wait(NETWORK_WRITE_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 during btl2cap::send (%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,
                    "IO error during btl2cap::send (%s)", pError);
                KNI_ThrowNew(midpIOException, EXCEPTION_MSG(gKNIBuffer));

                // Need revisit: add bluetooth activity indicator
//                DEC_BT_INDICATOR;
            }
        }
    }

    REPORT_INFO1(LC_PROTOCOL, "btl2cap::send bytes=%d\n", bytesWritten);

    KNI_EndHandles();
    KNI_ReturnInt((jint)bytesWritten);
}