/**
 * Send an MMS message.
 *
 * @param sendingToSelf <code>1</code> if sending the message to this device;
 *     <code>0</code>, otherwise.
 * @param toAddr The recipient's MMS address.
 * @param fromAddr The sender's MMS address.
 * @param appID The application ID string associated with this message.
 * @param replyToAppID The reply-to application ID string associated with this
 *     message.
 * @param msgLen The total length, in bytes, of the MMS message.
 * @param msg A pointer to the MMS message, which contains both the message
 *     header and message body structures.
 * @param bytesWritten Returns the number of bytes written after successful
 *     write operation. This is only set if this function returns
 *     WMA_NET_SUCCESS.
 * @param pContext pointer to location to save operation context for asynchronous
 *     operations
 *
 * @return WMA_NET_SUCCESS for successful write operation;\n
 *	 WMA_NET_WOULDBLOCK if the operation would block,\n
 *	 WMA_NET_INTERRUPTED for an Interrupted IO Exception\n
 *	 WMA_NET_IOERROR for all other errors.
 */
WMA_STATUS jsr205_mms_write(jint sendingToSelf, char *toAddr, char* fromAddr, 
                               char* appID, char* replyToAppID, jint msgLen, char* msg, 
                               jint *bytesWritten, void **pContext) {

    /** The writing index. */
    int index = 0;

    /** The return status. */
    WMA_STATUS status;

    jsr120_udp_emulator_context *context;

    char *buffer;

#if ENABLE_WMA_LOOPBACK
    MmsMessage* mms;

    (void)sendingToSelf;
    (void)toAddr;
#else
    if (sendingToSelf == WMA_NET_IOERROR) {
        return WMA_NET_IOERROR;
    }
#endif

    if (appID == NULL) appID = "";
    if (replyToAppID == NULL) replyToAppID = "";

    if (*pContext == NULL) {
        context = (jsr120_udp_emulator_context *)pcsl_mem_malloc(sizeof(*context));
        if (context == NULL)
            return WMA_NET_IOERROR;

        memset(context, 0, sizeof(*context));

        /*
         * Create storage for the following:
         * - Application ID and its terminator (1 byte)
         * - The 1-byte terminator for the replyToAppID, or the 1-byte
         *   special flag when replyToAppID is NULL.
         * - The message length data
         * - The message data.
         */
        context->totalLength = strlen(fromAddr) + 1 +
            strlen(appID) + 1 +
            strlen(replyToAppID) + 1 +
            sizeof(int) + msgLen;
        buffer = (char*)pcsl_mem_malloc(context->totalLength);
        if (buffer == NULL) {
            pcsl_mem_free(context);
            return WMA_NET_IOERROR;
        }

        *pContext = context;

        memset(buffer, 0, context->totalLength);
        context->msg_buffer = buffer;

        /* Populate the buffer to be written. */
        wma_put_string(buffer, &index, (char*)fromAddr);
        wma_put_string(buffer, &index, (char*)appID);
        wma_put_string(buffer, &index, (char*)replyToAppID);
        wma_put_int(buffer, &index, msgLen);
        wma_put_bytes(buffer, &index, (char *)msg, msgLen);
    }
    else {
        context = (jsr120_udp_emulator_context*)*pContext;

        buffer = context->msg_buffer;
    }

#if ENABLE_WMA_LOOPBACK
    mms = createMmsMessage(fromAddr, appID, replyToAppID, msgLen, msg);

    /* Add the message to the pool. */
    jsr205_mms_pool_add_msg(mms);
    /* Notify all listeners of the new message. */
    jsr205_mms_message_arrival_notifier(mms);

    /* Fake the written count as well as the "sending" status. */
    *bytesWritten = context->totalLength;
    status = WMA_NET_SUCCESS;

#else
    {
        int outputPort = mmsOutPortNumber;

        /* The buffer to be written would have the reply-to address. */
        (void)replyToAppID;

        /* If talking to ourselves, redirect output to the in-port. */
        if (sendingToSelf != 0) {
            outputPort = mmsInPortNumber;
        }
        status = jsr205_datagram_write(WMA_MMS_PROTOCOL, outputPort, mmsHandle,
                                    toAddr, fromAddr, context->totalLength,
                                    buffer, bytesWritten, context);
    }
#endif

    if (status != WMA_NET_WOULDBLOCK) {
        /*
         * Message was sent or operation aborted, so free the buffer and
         * context.
         */
        pcsl_mem_free(buffer);
        pcsl_mem_free(context);
        *pContext = NULL;
    }

    return status;
}
Exemple #2
0
jboolean checkReadSignal(int socket) {

    WMA_STATUS status;
    unsigned char ipBytes[MAX_ADDR_LENGTH];
    jint ipPort;
    jint datagramLength;
    jint length;
    char* msg = NULL;
    char* recipientPhone = NULL;
    char *filter = NULL;
    jint i;
    WMA_PROTOCOLS sockProtocol;
    char* p;
    jint index;

    /* Message structures for the protocols SMS and CBS. */
    SmsMessage* sms = NULL;
    CbsMessage* cbs = NULL;

#if ENABLE_JSR_205
    /* Message structures for MMS. */
    MmsMessage* mms = NULL;
#endif

    if (wmaGetProtocolByFD(socket, &sockProtocol) != WMA_OK)
        return KNI_FALSE;

    /* Read the datagram. */
    p = (char *)pcsl_mem_malloc(MAX_DATAGRAM_LENGTH);
    if (p != NULL) {
        memset(p, 0, MAX_DATAGRAM_LENGTH);

        status = jsr120_datagram_read(sockProtocol, ipBytes, &ipPort, p, MAX_DATAGRAM_LENGTH,
                                      &datagramLength);

        if (status == WMA_NET_SUCCESS) {
            index = 0;

            switch (sockProtocol) {

            case WMA_SMS_PROTOCOL:
                sms = (SmsMessage *)pcsl_mem_malloc(sizeof(SmsMessage));
                if (sms != NULL) {
                    memset(sms, 0, sizeof(SmsMessage));

                    sms->encodingType = getInt(p, &index);
                    sms->sourcePortNum = ipPort;
                    sms->destPortNum = (unsigned short)getInt(p, &index);
                    sms->timeStamp = getLongLong(p, &index);
                    /* The next field is the recipient's phone number */
                    recipientPhone = getString(p, &index);
                    /* The next field is the sender's phone number */
                    sms->msgAddr = getString(p, &index);

                    length = getInt(p, &index);
                    sms->msgLen = length;
                    if (length > 0) {
                        msg = (char*)pcsl_mem_malloc(length + 1);
                        for (i = 0; i < length; i++) {
                            msg[i] = p[index++];
                        }
                        msg[i] = '\0';
                        sms->msgBuffer = msg;
                    }

                    /*
                     * Check for a push entry for this connection.
                     */
                    filter = pushgetfilter("sms://:", sms->destPortNum);

                    /*
                     * File this message, if there is no push entry for it
                     * i.e. filter is NULL or if there is a push entry for it
                     * and it passes the check filter test. The sender's phone
                     * number is checked against the filter.
                     */
                    if (filter == NULL || checkfilter(filter, sms->msgAddr)) {

                        /*
                         * Notify Push that a message has arrived and
                         * is being cached.
                         */
                        pushsetcachedflag("sms://:", sms->destPortNum);

                        /* add message to pool */
                        jsr120_sms_pool_add_msg(sms);
                    }

                    if (filter != NULL) {
                        pcsl_mem_free(filter);
                    }
                }

                break;

            case WMA_CBS_PROTOCOL:
                cbs = (CbsMessage*)pcsl_mem_malloc(sizeof(CbsMessage));
                if (cbs != NULL) {
                    memset(cbs, 0, sizeof(CbsMessage));

                    cbs->encodingType = (ENCODING_TYPE)getInt(p, &index);
                    cbs->msgID = getInt(p, &index);

                    /* Pick up the message length and the message data. */
                    length = getInt(p, &index);
                    cbs->msgLen = length;
                    if (length > 0) {
                        msg = (char*)pcsl_mem_malloc(length);
                        for (i = 0; i < length; i++) {
                            msg[i] = p[index++];
                        }
                        cbs->msgBuffer = (unsigned char*)msg;
                    }

                    /*
                     * Notify Push that a message has arrived and
                     * is being cached.
                     */
                    pushsetcachedflag("cbs://:", cbs->msgID);

                    /* Add message to pool. */
                    jsr120_cbs_pool_add_msg(cbs);
                }
                break;

#if ENABLE_JSR_205

            case WMA_MMS_PROTOCOL:

                if (assemble_frags(p) == KNI_TRUE) {

                    /*
                     * Note:
                     *
                     * The message is currently received in whole. That is, the
                     * message header and body are contained in the single
                     * MmsMessage. Normally, the header would be received on its
                     * own via (in this case, for example), some sort of state
                     * machine that processes the header,
                     */
                    MmsHeader* mmsHeader;

                    /* Create a new MMS message */
                    mms = createMmsMessageFromBuffer(mmsBuffer);
                    pcsl_mem_free(mmsBuffer);
                    mmsBuffer = NULL;

                    /* Notify the platform that a message has arrived. */
                    mmsHeader = createMmsHeader(mms);
                    MMSNotification(mmsHeader);
                    destroyMMSHeader(mmsHeader);

                    /*
                     * Check for a push entry for this connection.
                     */
                    filter = pushgetfiltermms("mms://:", mms->appID);

                    /*
                     * File this message, if there is no push entry for it
                     * i.e. filter is NULL or if there is a push entry for it
                     * and it passes the check filter test
                     */
                    if (filter == NULL || checkfilter(filter, mms->replyToAppID)) {

                        /*
                         * Notify Push that a message has arrived and
                         * is being cached.
                         */
                        pushsetcachedflagmms("mms://:", mms->appID);

                        /* When a fetch is confirmed, add message to pool. */
                        if (jsr205_fetch_mms() == WMA_OK) {
                            jsr205_mms_pool_add_msg(mms);
                        }
                    }

                    pcsl_mem_free(filter);
                }

                break;
#endif

            default:
                /* RFC: Silently fail for unknown protocols. */
                break;

            }  /* switch*/
        }
        pcsl_mem_free(p);
    }

    return KNI_TRUE;
}
/**
 * Send an MMS message.
 *
 * @param sendingToSelf <code>1</code> if sending the message to this device;
 *      <code>0</code>, otherwise.
 * @param toAddr The recipient's MMS address.
 * @param fromAddr The sender's MMS address.
 * @param appID The application ID string associated with this message.
 * @param replyToAppID The reply-to application ID string associated with this
 *     message.
 * @param msgLen The total length, in bytes, of the MMS message.
 * @param msg A pointer to the MMS message, which contains both the message
 *     header and message body structures.
 * @param bytesWritten Returns the number of bytes written after successful
 *     write operation. This is only set if this function returns
 *     WMA_NET_SUCCESS.
 *
 * @return WMA_NET_SUCCESS for successful write operation;\n
 *	 WMA_NET_WOULDBLOCK if the operation would block,\n
 *	 WMA_NET_INTERRUPTED for an Interrupted IO Exception\n
 *	 WMA_NET_IOERROR for all other errors.
 */
WMA_STATUS jsr205_mms_write(jint sendingToSelf, char *toAddr, char* fromAddr, 
                               char* appID, char* replyToAppID, jint msgLen, char* msg, 
                               jint *bytesWritten) {

    /** The total length of all data to be written. */
    jint totalLength = 0;

    /** The buffer that will contain all data to be written. */
    char* buffer = NULL;

    /** The writing index. */
    jint index = 0;

    /** The return status. */
    WMA_STATUS status;

    if (appID == NULL) appID = "";
    if (replyToAppID == NULL) replyToAppID = "";

    /*
     * Create storage for the following:
     * - Application ID and its terminator (1 byte)
     * - The 1-byte terminator for the replyToAppID, or the 1-byte
     *   special flag when replyToAppID is NULL.
     * - The message length data
     * - The message data.
     */
    totalLength = strlen(fromAddr) + 1 +
                  strlen(appID) + 1 +
                  strlen(replyToAppID) + 1 +
                  sizeof(int) + msgLen;
    buffer = (char*)pcsl_mem_malloc(totalLength);
    if (buffer == NULL) {
        return WMA_NET_IOERROR;
    }
    memset(buffer, 0, totalLength);

    /* Populate the buffer to be written. */
    wma_put_string(buffer, &index, (char*)fromAddr);
    wma_put_string(buffer, &index, (char*)appID);
    wma_put_string(buffer, &index, (char*)replyToAppID);
    wma_put_int(buffer, &index, msgLen);
    wma_put_bytes(buffer, &index, (char *)msg, msgLen);

#if ENABLE_WMA_LOOPBACK
    (void)sendingToSelf;
    (void)toAddr;

    MmsMessage* mms =
        createMmsMessage(fromAddr, appID, replyToAppID, msgLen, msg);

    /* Add the message to the pool. */
    jsr205_mms_pool_add_msg(mms);
    /* Notify all listeners of the new message. */
    jsr205_mms_message_arrival_notifier(mms);

    /* Fake the written count as well as the "sending" status. */
    *bytesWritten = totalLength;
    status = WMA_NET_SUCCESS;

#else
    /* The buffer to be written would have the reply-to address. */
    (void)replyToAppID;

    int outputPort = mmsOutPortNumber;

    if (sendingToSelf != 0) {
        /* Talking to ourselves; redirect output to the in-port. */
        outputPort = mmsInPortNumber;
    }
    status = jsr205_datagram_write(outputPort, mmsHandle, toAddr, fromAddr,
                                   totalLength, buffer, bytesWritten);

#endif

    /* Message was sent, so free the buffer. */
    pcsl_mem_free(buffer);

    return status;
}