diff options
Diffstat (limited to 'bta/ma/bta_ma_util.c')
-rw-r--r-- | bta/ma/bta_ma_util.c | 1750 |
1 files changed, 1750 insertions, 0 deletions
diff --git a/bta/ma/bta_ma_util.c b/bta/ma/bta_ma_util.c new file mode 100644 index 0000000..6544e6a --- /dev/null +++ b/bta/ma/bta_ma_util.c @@ -0,0 +1,1750 @@ +/***************************************************************************** +** +** Name: bta_ma_util.c +** +** Description: This is the implementation file for the Message Access +** Profile (MAP) utility functions. +** +** Copyright (c) 2009, Broadcom Corp., All Rights Reserved. +** Broadcom Bluetooth Core. Proprietary and confidential. +** +*****************************************************************************/ + +#include "bt_target.h" + +#if defined(BTA_MSE_INCLUDED) && (BTA_MSE_INCLUDED) + + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "bta_ma_api.h" +#include "bta_ma_util.h" + +/* +** Static constant data declarations +*/ +/* Charset */static const char * bmsg_body_charset[] = +{ + "native", /* BMSG_CHARSET_NATIVE (native) */ + "UTF-8" /* BMSG_CHARSET_UTF-8 (UTF-8) */ +}; + +static const int num_bmsg_body_charset = sizeof(bmsg_body_charset) / sizeof(char*); + + +/* vCard property names (the order is dicated by the tBTA_MA_BMSG_VCARD_PROP enumeration in bmsg_cnt.h) */ +static const char * vcard_prop_name[] = +{ + "N", /* VCARD_PROP_N */ + "FN", /* VCARD_PROP_FN */ + "TEL", /* VCARD_PROP_TEL */ + "EMAIL" /* VCARD_PROP_EMAIL */ +}; + +/* bMessage encoding names (the order is dictated by the tBTA_MA_BMSG_ENCODING enumeration in bmsg_cnt.h) */ +static const char * bmsg_body_encoding[] = +{ + "8BIT", /* BMSG_ENC_8BIT (8-Bit-Clean encoding) */ + "G-7BIT", /* BMSG_ENC_G7BIT (GSM 7 bit Default Alphabet) */ + "G-7BITEXT", /* BMSG_ENC_G7BITEXT (GSM 7 bit Alphabet with national language extension) */ + "G-UCS2" , /* BMSG_ENC_GUCS2 */ + "G-8BIT", /* BMSG_ENC_G8BIT */ + "C-8BIT", /* BMSG_ENC_C8BIT (Octet, unspecified) */ + "C-EPM", /* BMSG_ENC_CEPM (Extended Protocol Message) */ + "C-7ASCII", /* BMSG_ENC_C7ASCII (7-bit ASCII) */ + "C-IA5", /* BMSG_ENC_CIA5 (IA5) */ + "C-UNICODE", /* BMSG_ENC_CUNICODE (UNICODE) */ + "C-SJIS", /* BMSG_ENC_CSJIS (Shift-JIS) */ + "C-KOREAN", /* BMSG_ENC_CKOREAN (Korean) */ + "C-LATINHEB", /* BMSG_ENC_CLATINHEB (Latin/Hebrew) */ + "C-LATIN" /* BMSG_ENC_CLATIN (Latin) */ +}; + +static const int num_bmsg_body_encoding = sizeof(bmsg_body_encoding) / sizeof(char*); + +static const char * bmsg_body_language[] = +{ + "", /* BMSG_LANG_UNSPECIFIED (not provided in bBody */ + "UNKNOWN", /* BMSG_LANG_UNKNOWN */ + "SPANISH", /* BMSG_LANG_SPANISH */ + "TURKISH", /* BMSG_LANG_TURKISH */ + "PORTUGUESE", /* BMSG_LANG_PORTUGUESE */ + "ENGLISH", /* BMSG_LANG_ENGLISH */ + "FRENCH", /* BMSG_LANG_FRENCH */ + "JAPANESE", /* BMSG_LANG_JAPANESE */ + "KOREAN", /* BMSG_LANG_KOREAN */ + "CHINESE", /* BMSG_LANG_CHINESE */ + "HEBREW" /* BMSG_LANG_HEBREW */ +}; + +static const int num_bmsg_body_language = sizeof(bmsg_body_language) / sizeof(char*); + +#include "bta_ma_co.h" + +#define BTA_MSE_NOTIF_TYPE_NEW_MSG_STR "NewMessage" +#define BTA_MSE_NOTIF_TYPE_DELIVERY_SUCCESS_STR "DeliverySuccess" +#define BTA_MSE_NOTIF_TYPE_SENDING_SUCCESS_STR "SendingSuccess" +#define BTA_MSE_NOTIF_TYPE_DELIVERY_FAILURE_STR "DeliveryFailure" +#define BTA_MSE_NOTIF_TYPE_SENDING_FAILURE_STR "SendingFailure" +#define BTA_MSE_NOTIF_TYPE_MEMORY_FULL_STR "MemoryFull" +#define BTA_MSE_NOTIF_TYPE_MEMORY_AVAILABLE_STR "MemoryAvailable" +#define BTA_MSE_NOTIF_TYPE_MESSAGE_DELETED_STR "MessageDeleted" +#define BTA_MSE_NOTIF_TYPE_MESSAGE_SHIFT_STR "MessageShift" + +#define BTA_MSE_MSG_TYPE_EMAIL "EMAIL" +#define BTA_MSE_MSG_TYPE_SMS_GSM "SMS_GSM" +#define BTA_MSE_MSG_TYPE_SMS_CDMA "SMS_CDMA" +#define BTA_MSE_MSG_TYPE_MMS "MMS" + +#define BTA_MSE_RCV_STATUS_COMPLETE "complete" +#define BTA_MSE_RCV_STATUS_FRACTIONED "fractioned" +#define BTA_MSE_RCV_STATUS_NOTIFICATION "notification" + +#define BTA_MSE_BOOLEAN_YES "yes" +#define BTA_MSE_BOOLEAN_NO "no" + +/******************************************************************************* +** +** Function bta_ma_evt_typ_to_string +** +** Description Utility function to return a pointer to a string holding +** the notifiction "type" for the MAP-Event-Report object. +** +** Parameters notif_type - Notification type +** +** Returns Pointer to static string representing notification type. +** +*******************************************************************************/ + +const char * bta_ma_evt_typ_to_string(tBTA_MSE_NOTIF_TYPE notif_type) +{ + switch (notif_type) + { + case BTA_MSE_NOTIF_TYPE_NEW_MSG: + return(BTA_MSE_NOTIF_TYPE_NEW_MSG_STR); + case BTA_MSE_NOTIF_TYPE_DELIVERY_SUCCESS: + return(BTA_MSE_NOTIF_TYPE_DELIVERY_SUCCESS_STR); + case BTA_MSE_NOTIF_TYPE_SENDING_SUCCESS: + return(BTA_MSE_NOTIF_TYPE_SENDING_SUCCESS_STR); + case BTA_MSE_NOTIF_TYPE_DELIVERY_FAILURE: + return(BTA_MSE_NOTIF_TYPE_DELIVERY_FAILURE_STR); + case BTA_MSE_NOTIF_TYPE_SENDING_FAILURE: + return(BTA_MSE_NOTIF_TYPE_SENDING_FAILURE_STR); + case BTA_MSE_NOTIF_TYPE_MEMORY_FULL: + return(BTA_MSE_NOTIF_TYPE_MEMORY_FULL_STR); + case BTA_MSE_NOTIF_TYPE_MEMORY_AVAILABLE: + return(BTA_MSE_NOTIF_TYPE_MEMORY_AVAILABLE_STR); + case BTA_MSE_NOTIF_TYPE_MESSAGE_DELETED: + return(BTA_MSE_NOTIF_TYPE_MESSAGE_DELETED_STR); + case BTA_MSE_NOTIF_TYPE_MESSAGE_SHIFT: + return(BTA_MSE_NOTIF_TYPE_MESSAGE_SHIFT_STR); + } + + return NULL; +} + +/******************************************************************************* +** +** Function bta_ma_msg_typ_to_string +** +** Description Utility function to return a pointer to a string holding +** the "msg_type" for the MAP-Event-Report object or or the +** the type for the MAP-msg-listing object +** +** Parameters msg_typ - Message type +** +** Returns Pointer to static string representing message type. +** +*******************************************************************************/ + +const char * bta_ma_msg_typ_to_string(tBTA_MA_MSG_TYPE msg_typ) +{ + switch (msg_typ) + { + case BTA_MA_MSG_TYPE_EMAIL: return(BTA_MSE_MSG_TYPE_EMAIL); + case BTA_MA_MSG_TYPE_SMS_GSM: return(BTA_MSE_MSG_TYPE_SMS_GSM); + case BTA_MA_MSG_TYPE_SMS_CDMA: return(BTA_MSE_MSG_TYPE_SMS_CDMA); + case BTA_MA_MSG_TYPE_MMS: return(BTA_MSE_MSG_TYPE_MMS); + } + + return NULL; +} + +/******************************************************************************* +** +** Function bta_ma_rcv_status_to_string +** +** Description Utility function to return a pointer to a string holding +** the "reception_status" for the MAP-msg-listing object +** +** Parameters rcv_status - Reception status +** +** Returns Pointer to static string representing message type. +** +*******************************************************************************/ +const char * bta_ma_rcv_status_to_string(tBTA_MSE_CO_RCV_STATUS rcv_status) +{ + switch (rcv_status) + { + case BTA_MSE_CO_RCV_STATUS_COMPLETE: + return(BTA_MSE_RCV_STATUS_COMPLETE); + case BTA_MSE_CO_RCV_STATUS_FRACTIONED: + return(BTA_MSE_RCV_STATUS_FRACTIONED); + case BTA_MSE_CO_RCV_STATUS_NOTIFICATION: + return(BTA_MSE_RCV_STATUS_NOTIFICATION); + } + + return NULL; +} + +/******************************************************************************* +** +** Function bta_ma_stream_str +** +** Description Input a string into the stream. +** +** Parameters p_stream - pointer to stream information. +** p_str - pointer to string to be put in the buffer. Only the +** string characters, and not the NULL, are put into the +** buffer. +** +** Returns TRUE if the string was successfully added into the stream. +** +*******************************************************************************/ +BOOLEAN bta_ma_stream_str(tBTA_MA_STREAM * p_stream, const char * p_str) +{ + UINT16 buf_size; + UINT16 str_size; + UINT16 size = 0; + + /* ensure stream and string are not NULL */ + if ( !p_str || !p_stream ) + return(FALSE); + + /* get length of string */ + str_size = strlen(p_str); + + switch ( p_stream->type ) + { + case STRM_TYPE_MEMORY: + /* ensure buffer is not full */ + if ( p_stream->status == STRM_SUCCESS ) + { + /* get amount of size left in buffer */ + buf_size = p_stream->u.mem.size - bta_ma_stream_used_size(p_stream); + + /* calculate the size to copy (the minimum of string and buffer size */ + if ( str_size > buf_size ) + { + size = buf_size; + p_stream->status = STRM_ERROR_OVERFLOW; + } + else + size = str_size; + + /* copy the data and move the pointer */ + memcpy(p_stream->u.mem.p_next, p_str, size); + p_stream->u.mem.p_next += size; + } + break; + + case STRM_TYPE_FILE: + /* write string */ + bta_ma_co_write(p_stream->u.file.fd, p_str, str_size); + break; + } + + /* return TRUE if stream is OK */ + return(p_stream->status == STRM_SUCCESS); +} + +/******************************************************************************* +** +** Function bta_ma_stream_buf +** +** Description Stream a buffer into the buffer. +** +** Parameters p_stream - pointer to stream information. +** len - length of buffer +** p_buf - pointer to buffer to stream. +** +** Returns TRUE if the buffer was large enough to hold the data. +** +*******************************************************************************/ +extern BOOLEAN bta_ma_stream_buf(tBTA_MA_STREAM * p_stream, + UINT16 len, + UINT8 * p_buf) +{ + UINT16 buf_size; + UINT16 size = 0; + + /* ensure stream and buffer pointer are not NULL */ + if ( !p_buf || !p_stream ) + return(FALSE); + + switch ( p_stream->type ) + { + case STRM_TYPE_MEMORY: + /* ensure buffer is not full */ + if ( p_stream->status == STRM_SUCCESS ) + { + /* get amount of size left in buffer */ + buf_size = p_stream->u.mem.size - bta_ma_stream_used_size(p_stream); + + /* calculate the size to copy (the minimum of string and buffer size */ + if ( len > buf_size ) + { + size = buf_size; + p_stream->status = STRM_ERROR_OVERFLOW; + } + else + size = len; + + /* copy the data and move the pointer */ + memcpy(p_stream->u.mem.p_next, p_buf, len); + p_stream->u.mem.p_next += size; + } + break; + case STRM_TYPE_FILE: + /* write string */ + bta_ma_co_write(p_stream->u.file.fd, p_buf, len); + break; + } + + /* return TRUE if stream is OK */ + return(p_stream->status == STRM_SUCCESS); +} + + +/******************************************************************************* +** +** Function bta_ma_stream_boolean_yes_no +** +** Description Stream a yes/no string into the buffer. +** +** Parameters p_stream - pointer to stream information. +** val - a boolean value to indicate yes or no +** +** Returns TRUE if the yes/no string was successfully added into +** the stream. +** +*******************************************************************************/ +BOOLEAN bta_ma_stream_boolean_yes_no(tBTA_MA_STREAM * p_stream, BOOLEAN val) +{ + return bta_ma_stream_str(p_stream, + val == FALSE ? BTA_MSE_BOOLEAN_NO : BTA_MSE_BOOLEAN_YES); +} + +/******************************************************************************* +** +** Function bta_ma_stream_value +** +** Description Stream an UINT32 value string into the buffer. +** +** Parameters p_stream - pointer to stream information. +** val - a UINT32 value +** +** Returns TRUE if the buffer was large enough to hold the data. +** +*******************************************************************************/ +BOOLEAN bta_ma_stream_value(tBTA_MA_STREAM * p_stream, UINT32 val) +{ + char temp[50]; + + sprintf(temp, "%lu", val); + return bta_ma_stream_str(p_stream, temp); +} + +/******************************************************************************* +** +** Function bta_ma_stream_handle +** +** Description Stream a message handle into the buffer. +** +** Parameters p_stream - pointer to stream information. +** handle - handle to be put in the buffer. +** +** Returns TRUE if the buffer was large enough to hold the data. +** +*******************************************************************************/ + +BOOLEAN bta_ma_stream_handle(tBTA_MA_STREAM * p_stream, tBTA_MA_MSG_HANDLE handle) +{ + char temp[5]; + int x; + BOOLEAN value_yet = FALSE; + + /* ensure buffer is not full */ + if ( p_stream->status == STRM_SUCCESS ) + { + for ( x=0; x < BTA_MA_HANDLE_SIZE; x++ ) + { + /* Skip any leading 0's */ + if ( (! value_yet) && (handle[x] == 0) ) + continue; + + value_yet = TRUE; + + sprintf(temp, "%02x", handle[x]); + + if ( bta_ma_stream_str(p_stream, temp) == FALSE ) + return(FALSE); + } + } + + /* return TRUE if stream is OK */ + return(p_stream->status == STRM_SUCCESS); +} + + +/******************************************************************************* +** +** Function bta_ma_stream_used_size +** +** Description Returns the used byte count. +** +** Parameters p_stream - pointer to stream information. +** +** Returns Number of bytes used in the buffer. +** +*******************************************************************************/ + +UINT16 bta_ma_stream_used_size(tBTA_MA_STREAM * p_stream) +{ + return(p_stream->u.mem.p_next - p_stream->u.mem.p_buffer); +} + +/******************************************************************************* +** +** Function bta_ma_stream_ok +** +** Description Determines if the stream is ok. +** +** Parameters p_stream - pointer to stream information. +** +** Returns TRUE if stream status is OK. +** +*******************************************************************************/ + +BOOLEAN bta_ma_stream_ok(tBTA_MA_STREAM * p_stream) +{ + return(p_stream && p_stream->status == STRM_SUCCESS); +} + +/******************************************************************************* +** +** Function bta_ma_convert_hex_str_to_64bit_handle +** +** Description Convert a hex string to a 64 bit message handle in Big Endian +** format +** +** Returns void +** +*******************************************************************************/ +void bta_ma_convert_hex_str_to_64bit_handle(char *p_hex_str, tBTA_MA_MSG_HANDLE handle) +{ + UINT32 ul1, ul2; + UINT8 *p; + char tmp[BTA_MA_32BIT_HEX_STR_SIZE]; + UINT8 str_len; + +#if BTA_MSE_DEBUG == TRUE + APPL_TRACE_EVENT0("bta_mse_convert_hex_str_to_64bit_handle"); +#endif + + str_len = strlen(p_hex_str); + memset(handle,0,sizeof(tBTA_MA_MSG_HANDLE)); + + if (str_len >= 8) + { + /* most significant 4 bytes */ + memcpy(tmp,p_hex_str,(str_len-8)); + tmp[str_len-8]='\0'; + ul1 = strtoul(tmp,0,16); + p=handle; + UINT32_TO_BE_STREAM(p, ul1); + + /* least significant 4 bytes */ + memcpy(tmp,&(p_hex_str[str_len-8]),8); + tmp[8]='\0'; + ul2 = strtoul(tmp,0,16); + p=&handle[4]; + UINT32_TO_BE_STREAM(p, ul2); + } + else + { + /* least significant 4 bytes */ + ul1 = strtoul(p_hex_str,0,16); + p=&handle[4]; + UINT32_TO_BE_STREAM(p, ul1); + } +} + +/******************************************************************************* +** +** Function bta_ma_get_char +** +** Description Gets one character from the stream. +** +** Parameters p_stream - pointer to stream information. +** p_char - pointer to where to receive the character. +** +** Returns TRUE if character was read OK. +** +*******************************************************************************/ +BOOLEAN bta_ma_get_char(tBTA_MA_STREAM * p_stream, char * p_char) +{ + BOOLEAN bStatus = FALSE; + + if ( p_char ) + { + *p_char = 0; + + if ( p_stream ) + { + switch ( p_stream->type ) + { + case STRM_TYPE_MEMORY: + if ( (p_stream->u.mem.p_next-p_stream->u.mem.p_buffer) < p_stream->u.mem.size ) + { + *p_char = *p_stream->u.mem.p_next; + p_stream->u.mem.p_next++; + + bStatus = TRUE; + } + break; + case STRM_TYPE_FILE: + /* read character */ + bStatus = bta_ma_co_read(p_stream->u.file.fd, (void *) p_char, 1) == 1; + break; + } + } + } + + return( bStatus ); +} + + +/******************************************************************************* +** +** Function bta_ma_get_tag +** +** Description Parses a tag from the stream. Basically this returns any text +** before a ':' character, ignoring leading whitespace. +** +** Parameters p_stream - Input stream. +** psz - buffer to receive the tag +** max_size - size of the receiving buffer (including space +** for the NULL character. +** +** Returns Size of tag, or 0 if there was an error. +** +*******************************************************************************/ +UINT16 bta_ma_get_tag(tBTA_MA_STREAM * p_stream, char * psz, UINT16 max_size) +{ + char c; + UINT16 count = 0; + + /* handle bad arguments */ + if ( p_stream && psz && (max_size > 0) ) + { + /* reserve last byte for NULL terminator */ + max_size--; + + while ( bta_ma_get_char(p_stream, &c) + && (c != ':') + && (count < max_size) ) + { + /* ignore leading whitespace */ + if ( !count && ((c == ' ') || (c == '\t')) ) + continue; + + /* if we hit a CR, return 0 to indicate an error */ + if ( c == '\r' ) + return( 0 ); + + psz[count++] = c; + } + + /* Either we hit a problem reading from the stream + ** or the buffer was not large enough + */ + if ( c != ':' ) + return( 0 ); + + /* terminate string */ + psz[count] = '\0'; + } + + return( count ); +} + +/******************************************************************************* +** +** Function bta_ma_get_value +** +** Description Parses a value from the stream. Basically this any text +** up to (but not including) the CR LF sequence. +** +** Parameters p_stream - Input stream. +** psz - buffer to receive the value +** max_size - size of the receiving buffer (including space +** for the NULL character. +** +** Returns Size of value, or 0 if there was an error. +** +*******************************************************************************/ +UINT16 bta_ma_get_value(tBTA_MA_STREAM * p_stream, char * psz, UINT16 max_size) +{ + char c; + UINT16 count = 0; + + /* handle bad arguments */ + if ( p_stream && psz && (max_size > 0) ) + { + /* reserve last byte for NULL terminator */ + max_size--; + + while ( bta_ma_get_char(p_stream, &c) + && (c != '\r') + && (count < max_size) ) + { + psz[count++] = c; + } + + /* Either we hit a problem reading from the stream + ** or the buffer was not large enough + */ + if ( c != '\r' ) + return( 0 ); + + /* burn the next character which must be LF */ + if ( ! bta_ma_get_char(p_stream, &c) ) + return( 0 ); + + /* terminate string */ + psz[count] = '\0'; + } + + return( count ); +} + +/******************************************************************************* +** +** Function bta_ma_get_param +** +** Description Parses the parameter from the source string. +** +** Parameters p_src - source paramter string. +** psz - buffer to receive the value +** +** Returns Size of param, or 0 if there was an error. +** +*******************************************************************************/ +UINT16 bta_ma_get_param(char *p_src, char *psz ) +{ + char c; + UINT16 count = 0; + BOOLEAN first_semicolon_found=FALSE; + + /* handle bad arguments */ + if ( p_src && psz ) + { + while ( (c = *p_src++) ) + { + + /* throw away the first ';' */ + if ( !count && (c==';') ) + { + first_semicolon_found = TRUE; + continue; + } + + /* first char should be ';' otherwise return 0 */ + if(!count && !first_semicolon_found && (c!=';')) + return (0); + + /* if we hit a CR, return 0 to indicate an error */ + if ( c == '\r' ) + return( 0 ); + + psz[count++] = c; + } + + if ( !count ) + return( 0 ); + + /* terminate string */ + psz[count] = '\0'; + } + + return( count ); +} + + + + +/******************************************************************************* +** +** Function bta_ma_parse_vcard +** +** Description Parses a vCard from the stream into a generic tBTA_MA_BMSG_VCARD +** structure. +** +** Parameters p_vcard - pointer to generic vCard structure. +** p_stream - Input stream. +** +** Returns BTA_MA_STATUS_OK if successful. BTA_MA_STATUS_FAIL if not. +** +*******************************************************************************/ +tBTA_MA_STATUS bta_ma_parse_vcard(tBTA_MA_BMSG_VCARD * p_vcard, + tBTA_MA_STREAM * p_stream) +{ + char sz[BTA_MA_MAX_SIZE]; + tBTA_MA_STATUS status = BTA_MA_STATUS_FAIL; + tBTA_MA_VCARD_VERSION version; + char * psztoken_tel = "TEL"; +// btla-specific ++ + char * psztoken_name = "N;"; +// btla-specific -- + char param[BTA_MA_MAX_SIZE]; + char *p_src; + UINT16 len; + + + while ( bta_ma_get_tag(p_stream, sz, BTA_MA_MAX_SIZE) ) + { + if ( strcmp(sz, "VERSION") == 0 ) + { + bta_ma_get_value(p_stream, sz, BTA_MA_MAX_SIZE); + if ( strcmp(sz, "3.0") == 0 ) + version = BTA_MA_VCARD_VERSION_30; + else if ( strcmp(sz, "2.1") == 0 ) + version = BTA_MA_VCARD_VERSION_21; + else + { + APPL_TRACE_ERROR1("bta_ma_parse_vcard - Invalid vcard version: '%s'", sz); + break; + } + + BTA_MaBmsgSetVcardVersion(p_vcard, version); + } + else if ( strcmp(sz, "N") == 0 ) + { + bta_ma_get_value(p_stream, sz, BTA_MA_MAX_SIZE); + BTA_MaBmsgAddVcardProp(p_vcard, BTA_MA_VCARD_PROP_N, sz, NULL); +// btla-specific ++ + } + else if ( strstr(sz, psztoken_name) == sz ) + { + p_src = sz + strlen(psztoken_name) - 1; // move to (first) semicolon, not past it + len = strlen(p_src); + if ( (len < BTA_MA_MAX_SIZE) && bta_ma_get_param(p_src, param)) + { + bta_ma_get_value(p_stream, sz, BTA_MA_MAX_SIZE); + BTA_MaBmsgAddVcardProp(p_vcard, BTA_MA_VCARD_PROP_N, sz, param); + } +// btla-specific -- + } + else if ( strcmp(sz, "FN") == 0 ) + { + bta_ma_get_value(p_stream, sz, BTA_MA_MAX_SIZE); + BTA_MaBmsgAddVcardProp(p_vcard, BTA_MA_VCARD_PROP_FN, sz, NULL); + } + else if ( strcmp(sz, psztoken_tel ) == 0 ) + { + bta_ma_get_value(p_stream, sz, BTA_MA_MAX_SIZE); + BTA_MaBmsgAddVcardProp(p_vcard, BTA_MA_VCARD_PROP_TEL, sz, NULL); + } + else if ( strstr(sz, psztoken_tel) == sz ) + { + p_src = sz + strlen(psztoken_tel); + len = strlen(p_src); + if ( (len < BTA_MA_MAX_SIZE) && bta_ma_get_param(p_src, param)) + { + bta_ma_get_value(p_stream, sz, BTA_MA_MAX_SIZE); + BTA_MaBmsgAddVcardProp(p_vcard, BTA_MA_VCARD_PROP_TEL, sz, param); + } + } + else if ( strcmp(sz, "EMAIL") == 0 ) + { + bta_ma_get_value(p_stream, sz, BTA_MA_MAX_SIZE); + BTA_MaBmsgAddVcardProp(p_vcard, BTA_MA_VCARD_PROP_EMAIL, sz, NULL); + } + else if ( strcmp(sz, "END") == 0 ) + { + bta_ma_get_value(p_stream, sz, BTA_MA_MAX_SIZE); + status = BTA_MA_STATUS_OK; + break; + } + else + { + APPL_TRACE_ERROR1("bta_ma_parse_vcard - Invalid tag: '%s'", sz); + } + } + + return( status ); +} + +/******************************************************************************* +** +** Function bta_ma_parse_content +** +** Description Parses a <bmessage-body-content> from the stream into a +** generic tBTA_MA_BMSG_CONTENT structure. This will parse text until +** we see "END:MSG" at the start of a line. +** +** Parameters p_content - pointer to generic content structure. +** p_stream - Input stream. +** +** Returns BTA_MA_STATUS_OK if successful. BTA_MA_STATUS_FAIL if not. +** +*******************************************************************************/ +tBTA_MA_STATUS bta_ma_parse_content(tBTA_MA_BMSG_CONTENT * p_content, + tBTA_MA_STREAM * p_stream) +{ +/* This constant defines the size of the work buffer used for parsing. +** It MUST be larger than the 'END:MSG<CRLF>" string size. The larger +** the buffer the more efficient this parser will be. +*/ +#define BTA_MA_PARSE_BUF_SIZE BTA_MA_MAX_SIZE + +/* These constants define the four states the parser can be in. +*/ +#define STATE_WS (0) /* checking for leading whitespace */ +#define STATE_END (1) /* checking for END:MSG */ +#define STATE_CR (2) /* checking for CRLF */ +#define STATE_TEXT (3) /* copying text */ + + static const char * END_MSG = "END:MSG\r\n"; + + char sz[BTA_MA_PARSE_BUF_SIZE+1]; + char c; + int state = STATE_WS; /* start in the 'whitespace' state */ + int idx_commit = 0; + int idx_trial = 0; + int idx_end = 0; + int x; + + /* NOTES - There are 3 primary indices used during parsing: + ** + ** 'idx_commit' these are characters that are commited to being + ** in the message text. We need to be able to save characters + ** (such as <CR><LF>, "END..", etc.) but not actually 'commit' them. + ** + ** 'idx_trial' these are characters that we are saving on a trial + ** basis until we know what to do with them. For example, if + ** we get a sequence "<CR>+<LF>+E+N", we don't want to commit + ** them until we know it is not "END:MSG<CR><LF>". + ** + ** 'idx_end' is used to index through the "END:MSG<CR><LF> string. + */ + + /* Handle bad arguments */ + if ( p_stream && p_content ) + { + /* Get one character from the stream */ + while ( bta_ma_get_char(p_stream, &c) ) + { + switch (state) + { + case STATE_WS: + /* totally ignore leading whitespace */ + if ( (c == ' ') || (c == '\t') ) + continue; + + /* Otherwise intentionaly fall through after resetting the + ** 'end' index so we start comparing from the beginning. + */ + idx_end = 0; + + case STATE_END: + /* Is the character in the "END:MSG<CR><LF> sequence? */ + if ( c == END_MSG[idx_end] ) + { + /* Yes. Did we get to the end of "END:MSG<cr><lf>"? */ + if ( ! END_MSG[++idx_end] ) + { + /* Yes. Commit any characters and get out. */ + if ( idx_commit ) + { + sz[idx_commit] = '\0'; + BTA_MaBmsgAddMsgContent(p_content, sz); + } + + return( BTA_MA_STATUS_OK ); + } + + state = STATE_END; + break; + } + /* If we fell through from the whitespace state + ** then we should commit all chars at this point. + ** It handles the case where we get consecutive CRLF. + */ + if ( state == STATE_WS ) + idx_commit = idx_trial; + + /* And intentionally fall through */ + + case STATE_CR: + /* We got <CR>, is this <LF>? */ + if ( c == '\n' ) + { + /* Now look for any whitespace */ + state = STATE_WS; + break; + } + + /* otherwise intentionally fall through */ + + case STATE_TEXT: + /* is a CR? */ + if ( c == '\r' ) + state = STATE_CR; /* Look for <LF> */ + else + state = STATE_TEXT; /* Copy the text */ + break; + } + + /* All (non-whitespace) characters are copied to + ** the buffer as 'trial' characters possibly + ** committed later. + */ + sz[idx_trial++] = c; + + /* If we are in the text copy state, then + ** commit all characters to this point. + */ + if ( state == STATE_TEXT ) + idx_commit = idx_trial; + + /* The buffer is full. Commit the good characters + ** to the message content, and rearrange the rest + ** of the text to make room for more. + */ + if ( idx_trial == BTA_MA_PARSE_BUF_SIZE ) + { + /* Do we have characters to commit? + ** If we don't we are in trouble. + */ + if ( idx_commit ) + { + /* Save the last character so we can put a NULL there. */ + c = sz[idx_commit]; + sz[idx_commit] = '\0'; + BTA_MaBmsgAddMsgContent(p_content, sz); + + /* Do we need to rearrange uncommited text? */ + if ( idx_commit != idx_trial ) + { + /* Restore character */ + sz[idx_commit] = c; + + /* Copy the 'trial' characters to the beginning of buffer */ + idx_trial -= idx_commit; + for ( x=0; x < idx_trial; x++) + sz[x] = sz[x+idx_commit]; + idx_commit = 0; + } + else + { + idx_trial = idx_commit = 0; + } + } + else + { + /* ERROR - no space to shuffle things around */ + APPL_TRACE_ERROR0("bta_ma_parse_content - work buffer too small"); + break; + } + } + } + } + + return( BTA_MA_STATUS_FAIL ); +} + +/******************************************************************************* +** +** Function bta_ma_parse_body +** +** Description Parses a <bmessage-content> (BBODY) from the stream into a +** generic tBTA_MA_BMSG_BODY structure. This will parse text until +** we see "END:BODY" at the start of a line. +** +** Parameters p_body - pointer to generic content body structure. +** p_stream - Input stream. +** +** Returns BTA_MA_STATUS_OK if successful. BTA_MA_STATUS_FAIL if not. +** +*******************************************************************************/ +tBTA_MA_STATUS bta_ma_parse_body(tBTA_MA_BMSG_BODY * p_body, + tBTA_MA_STREAM * p_stream) +{ + char sz[BTA_MA_MAX_SIZE]; + tBTA_MA_STATUS status = BTA_MA_STATUS_FAIL; + tBTA_MA_BMSG_CONTENT *p_content = NULL; + tBTA_MA_BMSG_ENCODING encoding; + tBTA_MA_BMSG_LANGUAGE language; + tBTA_MA_CHARSET charset; + + while ( bta_ma_get_tag(p_stream, sz, BTA_MA_MAX_SIZE) ) + { + if ( strcmp(sz, "PARTID") == 0 ) + { + bta_ma_get_value(p_stream, sz, BTA_MA_MAX_SIZE); + BTA_MaBmsgSetBodyPartid(p_body, (UINT16) atoi(sz)); + } + else if ( strcmp(sz, "ENCODING") == 0 ) + { + bta_ma_get_value(p_stream, sz, BTA_MA_MAX_SIZE); + if ( bta_ma_str_to_encoding(sz, &encoding) ) + BTA_MaBmsgSetBodyEncoding(p_body, encoding); + else + APPL_TRACE_ERROR1("bta_ma_parse_body - Invalid ENCODING: '%s'", sz); + } + else if ( strcmp(sz, "CHARSET") == 0 ) + { + bta_ma_get_value(p_stream, sz, BTA_MA_MAX_SIZE); + if ( bta_ma_str_to_charset(sz, &charset)) + BTA_MaBmsgSetBodyCharset(p_body, charset); + else + APPL_TRACE_ERROR1("bta_ma_parse_body - invalid CHARSET: '%s'", sz); + } + else if ( strcmp(sz, "LANGUAGE") == 0 ) + { + bta_ma_get_value(p_stream, sz, BTA_MA_MAX_SIZE); + if ( bta_ma_str_to_language(sz, &language) ) + BTA_MaBmsgSetBodyLanguage(p_body, language); + else + APPL_TRACE_ERROR1("bta_ma_parse_body - Invalid LANGUAGE: '%s'", sz); + } + else if ( strcmp(sz, "LENGTH") == 0 ) + { + bta_ma_get_value(p_stream, sz, BTA_MA_MAX_SIZE); + /* we don't really care about the length */ + } + else if ( strcmp(sz, "BEGIN") == 0 ) + { + bta_ma_get_value(p_stream, sz, BTA_MA_MAX_SIZE); + + if ( strcmp(sz, "MSG") == 0 ) + { + p_content = BTA_MaBmsgAddContentToBody(p_body); + bta_ma_parse_content(p_content, p_stream); + } + else + { + APPL_TRACE_ERROR1("bta_ma_parse_body - Invalid BEGIN: '%s'", sz); + } + } + else if ( strcmp(sz, "END") == 0 ) + { + bta_ma_get_value(p_stream, sz, BTA_MA_MAX_SIZE); + status = BTA_MA_STATUS_OK; + break; + } + else + { + APPL_TRACE_ERROR1("bta_ma_parse_body - Invalid tag: '%s'", sz); + } + } + + return( status ); +} + +/******************************************************************************* +** +** Function bta_ma_parse_envelope +** +** Description Parses a <bmessage-envelope> from the stream into a +** generic tBTA_MA_BMSG_ENVELOPE structure. This will parse text +** until we see "END:BENV" at the start of a line. +** +** Parameters p_envelope - pointer to generic envelope structure. +** p_stream - Input stream. +** +** Returns BTA_MA_STATUS_OK if successful. BTA_MA_STATUS_FAIL if not. +** +*******************************************************************************/ +tBTA_MA_STATUS bta_ma_parse_envelope(tBTA_MA_BMSG_ENVELOPE * p_envelope, + tBTA_MA_STREAM * p_stream) +{ + char sz[BTA_MA_MAX_SIZE]; + tBTA_MA_STATUS status = BTA_MA_STATUS_FAIL; + tBTA_MA_BMSG_VCARD * p_vcard = NULL; + tBTA_MA_BMSG_ENVELOPE * p_new_envelope = NULL; + tBTA_MA_BMSG_BODY * p_body = NULL; + + while ( bta_ma_get_tag(p_stream, sz, BTA_MA_MAX_SIZE) ) + { + if ( strcmp(sz, "BEGIN") == 0 ) + { + bta_ma_get_value(p_stream, sz, BTA_MA_MAX_SIZE); + + if ( strcmp(sz, "VCARD") == 0 ) + { + p_vcard = BTA_MaBmsgAddRecipToEnv(p_envelope); + bta_ma_parse_vcard(p_vcard, p_stream); + } + else if ( strcmp(sz, "BENV") == 0 ) + { + p_new_envelope = BTA_MaBmsgAddEnvToEnv(p_envelope); + bta_ma_parse_envelope(p_new_envelope, p_stream); + } + else if ( strcmp(sz, "BBODY") == 0 ) + { + p_body = BTA_MaBmsgAddBodyToEnv(p_envelope); + bta_ma_parse_body(p_body, p_stream); + } + else + { + APPL_TRACE_ERROR1("bta_ma_parse_envelope - Invalid BEGIN: '%s'", sz); + } + + } + else if ( strcmp(sz, "END") == 0 ) + { + bta_ma_get_value(p_stream, sz, BTA_MA_MAX_SIZE); + status = BTA_MA_STATUS_OK; + break; + } + else + { + APPL_TRACE_ERROR1("bta_ma_parse_envelope - Invalid tag: '%s'", sz); + } + } + + return( status ); +} + +/******************************************************************************* +** +** Function bta_ma_stream_vcards +** +** Description Builds vCards into a stream. +** +** Parameters p_stream - Output stream. +** p_vcard - pointer to single vCard that may be linked to +** additional vCards. +** +** Returns void +** +*******************************************************************************/ +void bta_ma_stream_vcards(tBTA_MA_STREAM * p_stream, + tBTA_MA_BMSG_VCARD * p_vcard) +{ + int x; + + /* vCards are formatted one after another */ + while ( p_stream && p_vcard ) + { + bta_ma_stream_str(p_stream, "\r\nBEGIN:VCARD"); + + /* version */ + bta_ma_stream_str(p_stream, "\r\nVERSION:"); + bta_ma_stream_str(p_stream, + p_vcard->version == BTA_MA_VCARD_VERSION_21 ? "2.1" : "3.0"); + + /* vcard properties */ + for (x=0; x < BTA_MA_VCARD_PROP_MAX; x++) + bta_ma_stream_vcard_prop(p_stream, p_vcard,(tBTA_MA_VCARD_PROP) x); + + bta_ma_stream_str(p_stream, "\r\nEND:VCARD"); + + /* Get the next vCard and repeat */ + p_vcard = BTA_MaBmsgGetNextVcard(p_vcard); + } +} + +/******************************************************************************* +** +** Function bta_ma_stream_vcard_prop +** +** Description Builds a property and values into a stream. This will +** build all of the property/values for one property (i.e. +** can be multiple EMAIL propeties set). It will only +** format the property if it has a value (except the N/name +** if a 2.1 vCard and FN/fullname property of a 3.0 vCard +** will always be output). +** +** Parameters p_stream - Output stream. +** p_vcard - pointer to vCard. +** prop - property. +** +** Returns void +** +*******************************************************************************/ +void bta_ma_stream_vcard_prop(tBTA_MA_STREAM * p_stream, + tBTA_MA_BMSG_VCARD * p_vcard, + tBTA_MA_VCARD_PROP prop) +{ + tBTA_MA_VCARD_PROPERTY * p_prop; + tBTA_MA_VCARD_VERSION version; + char * p_param; + char * p_value; + + if ( p_vcard && prop < BTA_MA_VCARD_PROP_MAX ) + { + p_prop = BTA_MaBmsgGetVcardProp(p_vcard, prop); + + do + { + p_param = BTA_MaBmsgGetVcardPropParam(p_prop); + p_value = BTA_MaBmsgGetVcardPropValue(p_prop); + version = BTA_MaBmsgGetVcardVersion(p_vcard); + + if ( (p_value && strlen(p_value)) + || ((version == BTA_MA_VCARD_VERSION_21) && (prop == BTA_MA_VCARD_PROP_N)) + || ((version == BTA_MA_VCARD_VERSION_30) && (prop <= BTA_MA_VCARD_PROP_FN)) ) + { + /* property name */ + bta_ma_stream_str(p_stream, "\r\n"); + bta_ma_stream_str(p_stream, vcard_prop_name[prop]); + + + /* property parameter */ + if ( p_param ) + { + bta_ma_stream_str(p_stream, ";"); + bta_ma_stream_str(p_stream, p_param); + } + + /* property value */ + bta_ma_stream_str(p_stream, ":"); + bta_ma_stream_str(p_stream, p_value); + } + + /* There may be multiple instances of a property (e.g. 2 TEL numbers */ + p_prop = BTA_MaBmsgGetNextVcardProp(p_prop); + + } while ( p_prop ); + } +} + +/******************************************************************************* +** +** Function bta_ma_stream_envelopes +** +** Description Builds a envelope <bmessage-envelope> (or series of +** envelopes) into a stream. +** +** Parameters p_stream - Output stream. +** p_envelope - pointer to envelope structure. +** +** Returns void +** +*******************************************************************************/ +void bta_ma_stream_envelopes(tBTA_MA_STREAM * p_stream, + tBTA_MA_BMSG_ENVELOPE * p_envelope) +{ + tBTA_MA_BMSG_BODY * p_body; + + if ( p_stream && p_envelope ) + { + bta_ma_stream_str(p_stream, "\r\nBEGIN:BENV"); + + /* Recipients */ + bta_ma_stream_vcards(p_stream, BTA_MaBmsgGetRecipFromEnv(p_envelope)); + + /* It will either be another (nested) envelope or the body */ + p_body = BTA_MaBmsgGetBodyFromEnv(p_envelope); + + if ( p_body ) + bta_ma_stream_body(p_stream, p_body); + else + bta_ma_stream_envelopes(p_stream, BTA_MaBmsgGetNextEnv(p_envelope)); + + bta_ma_stream_str(p_stream, "\r\nEND:BENV"); + } +} + +/******************************************************************************* +** +** Function bta_ma_stream_body +** +** Description Builds a bMessage content <bmessage-content> into a stream. +** +** Parameters p_stream - Output stream. +** p_body - pointer to bBody structure. +** +** Returns void +** +*******************************************************************************/ +void bta_ma_stream_body(tBTA_MA_STREAM * p_stream, tBTA_MA_BMSG_BODY * p_body) +{ + UINT16 part_id = 0; + tBTA_MA_BMSG_LANGUAGE language; + tBTA_MA_CHARSET charset; + + if ( p_stream && p_body ) + { + bta_ma_stream_str(p_stream, "\r\nBEGIN:BBODY"); + + /* Part ID (optional) */ + part_id = BTA_MaBmsgGetBodyPartid(p_body); + if ( part_id != 0 ) + { + bta_ma_stream_str(p_stream, "\r\nPARTID:"); + bta_ma_stream_value(p_stream, part_id); + } + + /* Character set */ + charset = BTA_MaBmsgGetBodyCharset(p_body); + switch ( charset) + { + case BTA_MA_CHARSET_UTF_8: + bta_ma_stream_str(p_stream, "\r\nCHARSET:UTF-8"); + break; + case BTA_MA_CHARSET_NATIVE: + bta_ma_stream_str(p_stream, "\r\nCHARSET:NATIVE"); + /* Encoding */ + bta_ma_stream_str(p_stream, "\r\nENCODING:"); + bta_ma_stream_str(p_stream, bmsg_body_encoding[BTA_MaBmsgGetBodyEncoding(p_body)]); + break; + default: + break; + } + + /* Language */ + language = BTA_MaBmsgGetBodyLanguage(p_body); + if ( language != BTA_MA_BMSG_LANG_UNSPECIFIED ) + { + bta_ma_stream_str(p_stream, "\r\nLANGUAGE:"); + bta_ma_stream_str(p_stream, bmsg_body_language[language]); + } + + /* Body content length */ + bta_ma_stream_str(p_stream, "\r\nLENGTH:"); + bta_ma_stream_value(p_stream, bta_ma_get_body_length(p_body)); + + /* Content */ + bta_ma_stream_body_content(p_stream, BTA_MaBmsgGetContentFromBody(p_body)); + + bta_ma_stream_str(p_stream, "\r\nEND:BBODY"); + } +} + +/******************************************************************************* +** +** Function bta_ma_stream_body_content +** +** Description Builds a body content <bmessage-body-content> into a stream. +** +** Parameters p_stream - Output stream. +** p_content - pointer to content structure. +** +** Returns void +** +*******************************************************************************/ +void bta_ma_stream_body_content(tBTA_MA_STREAM * p_stream, + tBTA_MA_BMSG_CONTENT * p_content) +{ + char * p_text; + + APPL_TRACE_EVENT0("bta_ma_stream_body_content"); + while ( p_stream && p_content ) + { + bta_ma_stream_str(p_stream, "\r\nBEGIN:MSG"); + + p_text = BTA_MaBmsgGetMsgContent(p_content); + if ( p_text ) + { + bta_ma_stream_str(p_stream, "\r\n"); + + while ( p_text ) + { + bta_ma_stream_str(p_stream, p_text); + p_text = BTA_MaBmsgGetNextMsgContent(p_content); + } + } + + bta_ma_stream_str(p_stream, "\r\nEND:MSG"); + + p_content = BTA_MaBmsgGetNextContent(p_content); + } +} + +/******************************************************************************* +** +** Function bta_ma_str_to_charset +** +** Description Returns the charset enumeration (tBTA_MA_CHARSET) that +** corresponds to the provided string. +** +** Parameters psz - Input string. +** p_charset - pointer to the charset value to be received. +** +** Returns TRUE if there is a match, otherwise FALSE. +** +*******************************************************************************/ +BOOLEAN bta_ma_str_to_charset(char * psz, tBTA_MA_CHARSET * p_charset) +{ + + tBTA_MA_CHARSET e; + + if ( psz && p_charset ) + { + for (e= BTA_MA_CHARSET_NATIVE; e < num_bmsg_body_charset; e++) + { + if ( strcmp(psz, bmsg_body_charset[e]) == 0 ) + { + *p_charset = e; + return( TRUE ); + } + } + } + + return( FALSE ); +} + + +/******************************************************************************* +** +** Function bta_ma_str_to_encoding +** +** Description Returns the encoding enumeration (tBTA_MA_BMSG_ENCODING) that +** corresponds to the provided string. +** +** Parameters psz - Input string. +** p_encoding - pointer to the encoding value to be received. +** +** Returns TRUE if there is a match, otherwise FALSE. +** +*******************************************************************************/ +BOOLEAN bta_ma_str_to_encoding(char * psz, tBTA_MA_BMSG_ENCODING * p_encoding) +{ + tBTA_MA_BMSG_ENCODING e; + + if ( psz && p_encoding ) + { + for (e= BTA_MA_BMSG_ENC_8BIT; e < num_bmsg_body_encoding; e++) + { + if ( strcmp(psz, bmsg_body_encoding[e]) == 0 ) + { + *p_encoding = e; + return( TRUE ); + } + } + } + + return( FALSE ); +} + +/******************************************************************************* +** +** Function bta_ma_str_to_language +** +** Description Returns the language enumeration (tBTA_MA_BMSG_LANGUAGE) that +** corresponds to the provided string. +** +** Parameters psz - Input string. +** p_language - pointer to the language value to be received. +** +** Returns TRUE if there is a match, otherwise FALSE. +** +*******************************************************************************/ +BOOLEAN bta_ma_str_to_language(char * psz, tBTA_MA_BMSG_LANGUAGE * p_language) +{ + tBTA_MA_BMSG_LANGUAGE l; + + if ( psz && p_language ) + { + for (l=BTA_MA_BMSG_LANG_UNSPECIFIED; l < num_bmsg_body_language; l++) + { + if ( strcmp(psz, bmsg_body_language[l]) == 0 ) + { + *p_language = l; + return( TRUE ); + } + } + } + + return( FALSE ); +} + +/******************************************************************************* +** +** Function bta_ma_str_to_msg_typ +** +** Description Returns the message type enumeration (tBTA_MA_MSG_TYPE) +** that corresponds to the provided string. +** +** Parameters psz - Input string. +** p_msg_type - pointer to the message type value to be +** received. +** +** Returns TRUE if there is a match, otherwise FALSE. +** +*******************************************************************************/ +BOOLEAN bta_ma_str_to_msg_typ(char * psz, tBTA_MA_MSG_TYPE * p_msg_type) +{ + if ( psz && p_msg_type ) + { + if ( strcmp(psz, "EMAIL") == 0 ) + *p_msg_type = BTA_MA_MSG_TYPE_EMAIL; + else if ( strcmp(psz, "SMS_GSM") == 0 ) + *p_msg_type = BTA_MA_MSG_TYPE_SMS_GSM; + else if ( strcmp(psz, "SMS_CDMA") == 0 ) + *p_msg_type = BTA_MA_MSG_TYPE_SMS_CDMA; + else if ( strcmp(psz, "MMS") == 0 ) + *p_msg_type = BTA_MA_MSG_TYPE_MMS; + else + return FALSE; + } + + return( TRUE ); +} + +/******************************************************************************* +** +** Function bta_ma_get_body_length +** +** Description Returns the combined length in characters of the message +** content. +** +** Parameters p_body - pointer to bBody structure. +** +** Returns Length of the body message text. +** +*******************************************************************************/ +UINT32 bta_ma_get_body_length(tBTA_MA_BMSG_BODY * p_body) +{ + UINT32 length = 0, len=0; + tBTA_MA_BMSG_CONTENT * p_content; + char * p_text; + + APPL_TRACE_EVENT0("bta_ma_get_body_length"); + + p_content = BTA_MaBmsgGetContentFromBody(p_body); + + while ( p_content ) + { + p_text= BTA_MaBmsgGetMsgContent(p_content); + + while ( p_text ) + { + len = strlen(p_text); + length += (len + BTA_MA_BMSG_BODY_TAG_CTL_LENGTH); + + APPL_TRACE_EVENT3("total=%d len=%d text=%s",length, len, p_text); + + p_text = BTA_MaBmsgGetNextMsgContent(p_content); + } + + p_content = BTA_MaBmsgGetNextContent(p_content); + } + + APPL_TRACE_EVENT1("bta_ma_get_body_length len=%d", length); + return( length ); + + +} + +/******************************************************************************* +** +** Function bta_ma_bmsg_free_vcards +** +** Description Free buffers used by vVards +** +** Parameters p_vcard - Pointer to the first vCard in the linked vCards +** +** Returns None +** +*******************************************************************************/ + +void bta_ma_bmsg_free_vcards(tBTA_MA_BMSG_VCARD * p_vcard) +{ + int x; + + if ( p_vcard ) + { + /* recursively free any linked vCards */ + bta_ma_bmsg_free_vcards((tBTA_MA_BMSG_VCARD *)p_vcard->p_next); + + /* Free properties */ + for (x=0; x < BTA_MA_VCARD_PROP_MAX; x++) + bta_ma_bmsg_free_vcard_prop(p_vcard->p_prop[x]); + + /* free vcard structure itself */ + bta_ma_bmsg_free(p_vcard); + } +} +/******************************************************************************* +** +** Function bta_ma_bmsg_free_envelope +** +** Description Free buffers used by envelopes +** +** Parameters p_envelope - Pointer to the first envelope in the linked envelopes +** +** Returns None +** +*******************************************************************************/ +void bta_ma_bmsg_free_envelope(tBTA_MA_BMSG_ENVELOPE * p_envelope) +{ + if ( p_envelope ) + { + /* recursively free any linked envelopes */ + bta_ma_bmsg_free_envelope((tBTA_MA_BMSG_ENVELOPE *)p_envelope->p_next); + + /* free the body */ + bta_ma_bmsg_free_body(p_envelope->p_body); + + /* free recipients */ + bta_ma_bmsg_free_vcards(p_envelope->p_recip); + + /* free envelope structure itself */ + bta_ma_bmsg_free(p_envelope); + } +} +/******************************************************************************* +** +** Function bta_ma_bmsg_free_body +** +** Description Free buffers used by a message body +** +** Parameters p_body - Pointer to a message body +** +** Returns None +** +*******************************************************************************/ +void bta_ma_bmsg_free_body(tBTA_MA_BMSG_BODY * p_body) +{ + if ( p_body ) + { + bta_ma_bmsg_free_content(p_body->p_content); + + /* free body structure itself */ + bta_ma_bmsg_free(p_body); + } +} +/******************************************************************************* +** +** Function bta_ma_bmsg_free_content +** +** Description Free buffers used by message contents +** +** Parameters p_envelope - Pointer to the first message content in the +** linked message contents +** +** Returns None +** +*******************************************************************************/ +void bta_ma_bmsg_free_content(tBTA_MA_BMSG_CONTENT * p_content) +{ + if ( p_content ) + { + /* recursively free any linked content */ + bta_ma_bmsg_free_content((tBTA_MA_BMSG_CONTENT *)p_content->p_next); + + /* free all of the message text */ + bta_ma_bmsg_free_message_text(p_content->p_message); + + /* free content structure itself */ + bta_ma_bmsg_free(p_content); + } +} +/******************************************************************************* +** +** Function bta_ma_bmsg_free_message_text +** +** Description Free text string buffers used by a message +** +** Parameters p_envelope - Pointer to a message +** +** Returns None +** +*******************************************************************************/ +void bta_ma_bmsg_free_message_text(tBTA_MA_BMSG_MESSAGE * p_message) +{ + tBTA_MA_BMSG_MESSAGE * p_temp; + + while ( p_message ) + { + p_temp = (tBTA_MA_BMSG_MESSAGE *)p_message->p_next; + + /* free message string */ + bta_ma_bmsg_free(p_message->p_text); + + /* free message text structure */ + bta_ma_bmsg_free(p_message); + + /* now point to the next one */ + p_message = p_temp; + } +} +/******************************************************************************* +** +** Function bta_ma_bmsg_free_vcard_prop +** +** Description Free buffers used by a vCard property +** +** Parameters p_envelope - Pointer to a vCard property +** +** Returns None +** +*******************************************************************************/ +void bta_ma_bmsg_free_vcard_prop(tBTA_MA_VCARD_PROPERTY * p_prop) +{ + if ( p_prop ) + { + /* free the value and the parameter */ + if ( p_prop->p_value ) + bta_ma_bmsg_free(p_prop->p_value); + + if ( p_prop->p_param ) + bta_ma_bmsg_free(p_prop->p_param); + + /* recursively free any linked content */ + if ( p_prop->p_next ) + bta_ma_bmsg_free_vcard_prop((tBTA_MA_VCARD_PROPERTY *)p_prop->p_next); + + /* free property structure itself */ + bta_ma_bmsg_free(p_prop); + } +} + +/******************************************************************************* +** +** Function bta_ma_bmsg_alloc +** +** Description Allocate buffer for the specified size +** +** Parameters cb - request buffer size +** +** Returns None +** +*******************************************************************************/ + +void * bta_ma_bmsg_alloc(size_t cb) +{ + void * p_buf; + + if ((p_buf = GKI_getbuf((UINT16) cb)) == NULL ) + { + APPL_TRACE_ERROR1("Unable to allocate buffer for size=%", (UINT16) cb); + } + return(p_buf); +} +/******************************************************************************* +** +** Function bta_ma_bmsg_free +** +** Description Free buffer +** +** Parameters p - pointer to a buffer +** +** Returns None +** +*******************************************************************************/ +void bta_ma_bmsg_free(void * p) +{ + if ( p ) + GKI_freebuf(p); +} + + +#endif /* BTA_MSE_INCLUDED */ |