/** * 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; }
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; }