summaryrefslogtreecommitdiffstats
path: root/bta/ma
diff options
context:
space:
mode:
authorAndre Eisenbach <andre@broadcom.com>2012-02-22 13:18:21 -0800
committerMatthew Xie <mattx@google.com>2012-07-14 11:19:11 -0700
commite448862a47c08eb23185aaed574b39264f5005fc (patch)
tree2bc6246e3091315e77224fd798ea2fe8074ef972 /bta/ma
parenta2ca4b83ab8bbbfd8d5f6693e927ed4b82094624 (diff)
downloadexternal_bluetooth_bluedroid-e448862a47c08eb23185aaed574b39264f5005fc.zip
external_bluetooth_bluedroid-e448862a47c08eb23185aaed574b39264f5005fc.tar.gz
external_bluetooth_bluedroid-e448862a47c08eb23185aaed574b39264f5005fc.tar.bz2
Initial Bluedroid stack commit
Diffstat (limited to 'bta/ma')
-rw-r--r--bta/ma/bta_ma_api.c1203
-rw-r--r--bta/ma/bta_ma_util.c1750
-rw-r--r--bta/ma/bta_ma_util.h93
-rw-r--r--bta/ma/bta_mse_act.c2763
-rw-r--r--bta/ma/bta_mse_api.c437
-rw-r--r--bta/ma/bta_mse_cfg.c31
-rw-r--r--bta/ma/bta_mse_ci.c251
-rw-r--r--bta/ma/bta_mse_int.h835
-rw-r--r--bta/ma/bta_mse_main.c1367
-rw-r--r--bta/ma/bta_mse_sdp.c63
-rw-r--r--bta/ma/bta_mse_utils.c3867
11 files changed, 12660 insertions, 0 deletions
diff --git a/bta/ma/bta_ma_api.c b/bta/ma/bta_ma_api.c
new file mode 100644
index 0000000..2157447
--- /dev/null
+++ b/bta/ma/bta_ma_api.c
@@ -0,0 +1,1203 @@
+/*****************************************************************************
+**
+** Name: bta_mse_api.c
+**
+** Description: This is the implementation of the common API for the Message
+** Acess Profile of BTA, Broadcom Corp's Bluetooth
+** application layer for mobile phones.
+**
+** Copyright (c) 2009-2011 Broadcom Corp., All Rights Reserved.
+** Broadcom Bluetooth Core. Proprietary and confidential.
+**
+*****************************************************************************/
+
+#include "bt_target.h"
+
+#if defined(BTA_MSE_INCLUDED) && (BTA_MSE_INCLUDED == TRUE)
+
+
+#include <string.h>
+#include "bta_ma_api.h"
+#include "bta_ma_util.h"
+#include "bta_ma_co.h"
+/*******************************************************************************
+**
+** Function BTA_MaBmsgCreate
+**
+** Description Create and initialize an instance of a tBTA_MA_BMSG structure.
+**
+** Parameters None
+**
+** Returns Pointer to a bMessage object, or NULL if this fails.
+**
+*******************************************************************************/
+tBTA_MA_BMSG * BTA_MaBmsgCreate(void)
+{
+ tBTA_MA_BMSG *p_msg = (tBTA_MA_BMSG *) bta_ma_bmsg_alloc(sizeof(tBTA_MA_BMSG));
+
+ if ( p_msg )
+ {
+ memset(p_msg, 0, sizeof(tBTA_MA_BMSG));
+ }
+ else
+ {
+ APPL_TRACE_ERROR0("BTA_MaBmsgCreate failed");
+ }
+
+ return(p_msg);
+}
+
+/*******************************************************************************
+**
+** Function BTA_MaBmsgFree
+**
+** Description Destroy (free) the contents of a tBTA_MA_BMSG structure.
+**
+** Parameters p_bmsg - Pointer to a bMessage object
+**
+** Returns None
+**
+*******************************************************************************/
+void BTA_MaBmsgFree(tBTA_MA_BMSG * p_msg)
+{
+ if ( p_msg )
+ {
+ /* free folder string */
+ bta_ma_bmsg_free(p_msg->p_folder);
+
+ /* free all the vCards */
+ bta_ma_bmsg_free_vcards(p_msg->p_orig);
+
+ /* free the envelopes */
+ bta_ma_bmsg_free_envelope(p_msg->p_envelope);
+
+ /* free b-message structure itself */
+ bta_ma_bmsg_free(p_msg);
+ }
+}
+
+/*******************************************************************************
+**
+** Function BTA_MaBmsgSetReadSts
+**
+** Description Set the bmessage-readstatus-property value for the bMessage
+** object. If the 'read_sts' is TRUE then value will be "READ",
+** otherwise it is "UNREAD".
+**
+** Parameters p_bmsg - Pointer to a bMessage object
+** read_sts - Read status TRUE- read FALSE - unread
+**
+** Returns None
+**
+*******************************************************************************/
+void BTA_MaBmsgSetReadSts(tBTA_MA_BMSG * p_msg, BOOLEAN read_sts)
+{
+ if ( p_msg )
+ p_msg->read_sts = read_sts;
+}
+
+/*******************************************************************************
+**
+** Function BTA_MaBmsgGetReadSts
+**
+** Description Get the bmessage-readstatus-property value for the bMessage
+** object
+**
+** Parameters p_bmsg - Pointer to a bMessage object
+**
+** Returns Read status (TRUE/FALSE) for the specified bMessage.
+**
+*******************************************************************************/
+BOOLEAN BTA_MaBmsgGetReadSts(tBTA_MA_BMSG * p_msg)
+{
+ return( p_msg ? p_msg->read_sts : FALSE);
+}
+
+/*******************************************************************************
+**
+** Function BTA_MaBmsgSetMsgType
+**
+** Description Set the bmessage-type-property value for the bMessage object
+**
+** Parameters p_bmsg - Pointer to a bMessage object
+** msg_type - Message type
+**
+** Returns None
+**
+*******************************************************************************/
+void BTA_MaBmsgSetMsgType(tBTA_MA_BMSG * p_msg, tBTA_MA_MSG_TYPE msg_type)
+{
+ if ( p_msg )
+ p_msg->msg_type = msg_type;
+}
+
+/*******************************************************************************
+**
+** Function BTA_MaBmsgGetMsgType
+**
+** Description Get the bmessage-type-property value for the specified
+** bMessage object
+**
+** Parameters p_bmsg - Pointer to a bMessage object
+**
+** Returns Message type
+**
+*******************************************************************************/
+tBTA_MA_MSG_TYPE BTA_MaBmsgGetMsgType(tBTA_MA_BMSG * p_msg)
+{
+ /* return 0 (for lack of a better value) */
+ return( p_msg ? p_msg->msg_type : 0);
+}
+
+/*******************************************************************************
+**
+** Function BTA_MaBmsgSetFolder
+**
+** Description Set the bmessage-folder-property value for the bMessage object
+**
+** Parameters p_bmsg - Pointer to a bMessage object
+** p_folder - Pointer to a folder path
+**
+** Returns None
+**
+*******************************************************************************/
+void BTA_MaBmsgSetFolder(tBTA_MA_BMSG *p_msg, char *p_folder)
+{
+ if ( p_msg && p_folder )
+ {
+ /* free any existing string */
+ if ( p_msg->p_folder )
+ bta_ma_bmsg_free(p_msg->p_folder);
+
+ /* allocate a new one */
+ p_msg->p_folder = (char *) bta_ma_bmsg_alloc(strlen(p_folder)+1);
+ if ( p_msg->p_folder )
+ BCM_STRNCPY_S(p_msg->p_folder, strlen(p_folder)+1, p_folder, strlen(p_folder)+1);
+ }
+}
+
+/*******************************************************************************
+**
+** Function BTA_MaBmsgGetFolder
+**
+** Description Get the bmessage-folder-property value for the specified
+** bMessage object
+**
+** Parameters p_bmsg - Pointer to a bMessage object
+**
+** Returns Pointer to folder path string, or NULL if it has not been set.
+**
+*******************************************************************************/
+char * BTA_MaBmsgGetFolder(tBTA_MA_BMSG * p_msg)
+{
+ return(p_msg ? (char *) p_msg->p_folder : NULL);
+}
+
+/*******************************************************************************
+**
+** Function BTA_MaBmsgAddOrigToBmsg
+**
+** Description Add an originator to the bMessage object
+**
+** Parameters p_bmsg - Pointer to a bMessage object
+**
+** Returns Pointer to a new vCard structure, or NULL if this function
+** fails.
+**
+*******************************************************************************/
+tBTA_MA_BMSG_VCARD * BTA_MaBmsgAddOrigToBmsg(tBTA_MA_BMSG * p_msg)
+{
+ tBTA_MA_BMSG_VCARD * p_vcard = NULL;
+ tBTA_MA_BMSG_VCARD * p_last_vcard = NULL;
+
+ if ( p_msg )
+ {
+ p_vcard = (tBTA_MA_BMSG_VCARD *)bta_ma_bmsg_alloc(sizeof(tBTA_MA_BMSG_VCARD));
+ if ( p_vcard )
+ {
+ memset(p_vcard, 0, sizeof(tBTA_MA_BMSG_VCARD));
+ p_vcard->version = BTA_MA_VCARD_VERSION_21; /* default to 2.1 */
+
+ if ( p_msg->p_orig )
+ {
+ /* set pointer to the last entry in the list */
+ p_last_vcard = p_msg->p_orig;
+ while ( p_last_vcard->p_next )
+ p_last_vcard = (tBTA_MA_BMSG_VCARD *) p_last_vcard->p_next;
+
+ p_last_vcard->p_next = p_vcard;
+ }
+ else
+ p_msg->p_orig = p_vcard;
+ }
+ }
+
+ return(p_vcard);
+}
+
+/*******************************************************************************
+**
+** Function BTA_MaBmsgGetOrigFromBmsg
+**
+** Description Get the first originator vCard information from the specified
+** bMessage object
+**
+** Parameters p_bmsg - Pointer to a bMessage object
+**
+** Returns Pointer to first 'originator vCard, or NULL not used.
+**
+*******************************************************************************/
+tBTA_MA_BMSG_VCARD * BTA_MaBmsgGetOrigFromBmsg(tBTA_MA_BMSG * p_msg)
+{
+ return(p_msg ? (tBTA_MA_BMSG_VCARD *) p_msg->p_orig : NULL);
+}
+
+/*******************************************************************************
+**
+** Function BTA_MaBmsgAddEnvToBmsg
+**
+** Description Add a new envelope to the bMessage object. This is the first
+** (top) level envelope. bMessage allows up to 3 levels of envelopes.
+** application should call BTA_MaBmsgAddEnvToEnv to add the 2nd
+** 3rd level enevelope.
+**
+** Parameters p_bmsg - Pointer to a bMessage object
+**
+** Returns Pointer to a new envelope structure, or NULL if this
+** function fails.
+**
+*******************************************************************************/
+tBTA_MA_BMSG_ENVELOPE * BTA_MaBmsgAddEnvToBmsg(tBTA_MA_BMSG * p_msg)
+{
+ tBTA_MA_BMSG_ENVELOPE * p_envelope = NULL;
+
+ if ( p_msg )
+ {
+ p_envelope = (tBTA_MA_BMSG_ENVELOPE *)bta_ma_bmsg_alloc(sizeof(tBTA_MA_BMSG_ENVELOPE));
+ if ( p_envelope )
+ {
+ memset(p_envelope, 0, sizeof(tBTA_MA_BMSG_ENVELOPE));
+ p_msg->p_envelope = p_envelope;
+ }
+ }
+
+ return( p_envelope );
+}
+/*******************************************************************************
+**
+** Function BTA_MaBmsgAddEnvToEnv
+**
+** Description Add a child envelope to an existing envelope.
+**
+** Parameters p_envelope - Pointer to a parent envelope
+**
+** Returns Pointer to an envelope structure, or NULL if this
+** function fails.
+**
+*******************************************************************************/
+tBTA_MA_BMSG_ENVELOPE * BTA_MaBmsgAddEnvToEnv(tBTA_MA_BMSG_ENVELOPE * p_envelope)
+{
+ tBTA_MA_BMSG_ENVELOPE * p_new_envelope = NULL;
+
+ if ( p_envelope )
+ {
+ p_new_envelope = (tBTA_MA_BMSG_ENVELOPE *)bta_ma_bmsg_alloc(sizeof(tBTA_MA_BMSG_ENVELOPE));
+ if ( p_new_envelope )
+ {
+ memset(p_new_envelope, 0, sizeof(tBTA_MA_BMSG_ENVELOPE));
+ p_envelope->p_next = p_new_envelope;
+ }
+ }
+
+ return( p_new_envelope );
+}
+
+/*******************************************************************************
+**
+** Function BTA_MaBmsgGetEnv
+**
+** Description Get the pointer of the first level envelope.
+**
+** Parameters p_bmsg - Pointer to a bMessage object
+**
+** Returns Pointer to the first level envelope structure, or NULL if it
+** does not exist
+**
+*******************************************************************************/
+tBTA_MA_BMSG_ENVELOPE * BTA_MaBmsgGetEnv(tBTA_MA_BMSG * p_msg)
+{
+ return(p_msg ? (tBTA_MA_BMSG_ENVELOPE *) p_msg->p_envelope : NULL);
+}
+
+/*******************************************************************************
+**
+** Function BTA_MaBmsgGetNextEnv
+**
+** Description Get the child envelope of the specified parent envelope.
+**
+** Parameters p_env - Pointer to a parent envelope
+**
+** Returns Pointer to a child enevelope. NULL if the
+** envelope does not have a 'child' envelope.
+**
+*******************************************************************************/
+tBTA_MA_BMSG_ENVELOPE * BTA_MaBmsgGetNextEnv(tBTA_MA_BMSG_ENVELOPE * p_env)
+{
+ return(p_env ? (tBTA_MA_BMSG_ENVELOPE *)p_env->p_next : NULL);
+}
+/*******************************************************************************
+**
+** Function BTA_MaBmsgAddRecipToEnv
+**
+** Description Add recipient to the specified envelope.
+**
+** Parameters p_env - Pointer to a envelope
+**
+** Returns Pointer to a vCard structure. NULL if it
+** fails to allocate a vCard structure.
+**
+*******************************************************************************/
+tBTA_MA_BMSG_VCARD * BTA_MaBmsgAddRecipToEnv(tBTA_MA_BMSG_ENVELOPE * p_env)
+{
+ tBTA_MA_BMSG_VCARD * p_vcard = NULL;
+ tBTA_MA_BMSG_VCARD * p_last_vcard = NULL;
+
+ if ( p_env )
+ {
+ p_vcard = (tBTA_MA_BMSG_VCARD *)bta_ma_bmsg_alloc(sizeof(tBTA_MA_BMSG_VCARD));
+ if ( p_vcard )
+ {
+ memset(p_vcard, 0, sizeof(tBTA_MA_BMSG_VCARD));
+ p_vcard->version = BTA_MA_VCARD_VERSION_21; /* default to 2.1 */
+
+ if ( p_env->p_recip )
+ {
+ /* set pointer to the last entry in the list */
+ p_last_vcard = p_env->p_recip;
+ while ( p_last_vcard->p_next )
+ p_last_vcard = (tBTA_MA_BMSG_VCARD *) p_last_vcard->p_next;
+
+ p_last_vcard->p_next = p_vcard;
+ }
+ else
+ p_env->p_recip = p_vcard;
+ }
+ }
+
+ return(p_vcard);
+}
+/*******************************************************************************
+**
+** Function BTA_MaBmsgGetRecipFromEnv
+**
+** Description Get the first recipient's vCard from the specified envelope.
+**
+** Parameters p_env - Pointer to a envelope
+**
+** Returns Pointer to the first recipient's vCard structure. NULL if it
+** has not be set.
+**
+*******************************************************************************/
+tBTA_MA_BMSG_VCARD * BTA_MaBmsgGetRecipFromEnv(tBTA_MA_BMSG_ENVELOPE * p_env)
+{
+ return(p_env ? p_env->p_recip : NULL);
+}
+/*******************************************************************************
+**
+** Function BTA_MaBmsgAddBodyToEnv
+**
+** Description Add a message body to the specified envelope.
+**
+** Parameters p_env - Pointer to a envelope
+**
+** Returns Pointer to a message body structure.
+** NULL if it fails to allocate a message body structure.
+**
+*******************************************************************************/
+tBTA_MA_BMSG_BODY * BTA_MaBmsgAddBodyToEnv(tBTA_MA_BMSG_ENVELOPE * p_env)
+{
+ tBTA_MA_BMSG_BODY * p_body = NULL;
+
+ if ( p_env )
+ {
+ /* free any existing body */
+ if ( p_env->p_body )
+ bta_ma_bmsg_free_body(p_env->p_body);
+
+ /* allocate a new one */
+ p_body = (tBTA_MA_BMSG_BODY *)bta_ma_bmsg_alloc(sizeof(tBTA_MA_BMSG_BODY));
+ if ( p_body )
+ {
+ memset(p_body, 0, sizeof(tBTA_MA_BMSG_BODY));
+ p_body->encoding = BTA_MA_BMSG_ENC_8BIT; /* default */
+ }
+
+ p_env->p_body = p_body;
+ }
+
+ return(p_body);
+}
+/*******************************************************************************
+**
+** Function BTA_MaBmsgGetBodyFromEnv
+**
+** Description Get the message body pointer from the specified envelope.
+**
+** Parameters p_env - Pointer to a envelope
+**
+** Returns Pointer to a message body structure.
+** NULL if it has not been set.
+**
+*******************************************************************************/
+tBTA_MA_BMSG_BODY * BTA_MaBmsgGetBodyFromEnv(tBTA_MA_BMSG_ENVELOPE * p_env)
+{
+ return( p_env ? p_env->p_body : NULL);
+}
+
+/*******************************************************************************
+**
+** Function BTA_MaBmsgSetBodyEncoding
+**
+** Description Set the bmessage-body-encoding-property value for the bMessage
+** body.
+**
+** Parameters p_body - Pointer to a bMessage body
+** encoding - encoding scheme
+**
+** Returns None
+**
+*******************************************************************************/
+void BTA_MaBmsgSetBodyEncoding(tBTA_MA_BMSG_BODY * p_body, tBTA_MA_BMSG_ENCODING encoding)
+{
+ if ( p_body )
+ p_body->encoding = encoding;
+}
+
+/*******************************************************************************
+**
+** Function BTA_MaBmsgGetBodyEncoding
+**
+** Description Get the bmessage-body-encoding-property value for the specified
+** bMessage body.
+**
+** Parameters p_body - Pointer to a bMessage body
+**
+** Returns Message encoding scheme
+**
+*******************************************************************************/
+tBTA_MA_BMSG_ENCODING BTA_MaBmsgGetBodyEncoding(tBTA_MA_BMSG_BODY * p_body)
+{
+ return( p_body ? p_body->encoding : BTA_MA_BMSG_ENC_8BIT );
+}
+/*******************************************************************************
+**
+** Function BTA_MaBmsgSetBodyPartid
+**
+** Description Set the bmessage-body-part-ID value for the speicified
+** bMessage body.
+**
+** Parameters p_body - Pointer to a bMessage body
+** part_id - Part ID (range: from 0 to 65535)
+**
+** Returns None
+**
+*******************************************************************************/
+void BTA_MaBmsgSetBodyPartid(tBTA_MA_BMSG_BODY * p_body, UINT16 part_id)
+{
+ if ( p_body )
+ {
+ p_body->part_id = part_id;
+ p_body->is_multipart = TRUE;
+ }
+}
+
+/*******************************************************************************
+**
+** Function BTA_MaBmsgGetBodyPartid
+**
+** Description Get the bmessage-body-part-ID value for the specified
+** bMessage body.
+**
+** Parameters p_body - Pointer to a bMessage body
+**
+** Returns The value of the Part ID
+**
+*******************************************************************************/
+UINT16 BTA_MaBmsgGetBodyPartid(tBTA_MA_BMSG_BODY * p_body)
+{
+ return( p_body ? p_body->part_id : 0 );
+}
+/*******************************************************************************
+**
+** Function BTA_MaBmsgIsBodyMultiPart
+**
+** Description Is this a multi-part body
+**
+** Parameters p_body - Pointer to a bMessage body
+**
+** Returns TURE - if this is a multi-part body
+**
+*******************************************************************************/
+BOOLEAN BTA_MaBmsgIsBodyMultiPart(tBTA_MA_BMSG_BODY * p_body)
+{
+ return( p_body ? p_body->is_multipart : FALSE );
+}
+
+/*******************************************************************************
+**
+** Function BTA_MaBmsgSetBodyCharset
+**
+** Description Set the bmessage-body-charset-property value for the speicified
+** bMessage body.
+**
+** Parameters p_body - Pointer to a bMessage body
+** charset - Charset
+**
+** Returns None
+**
+*******************************************************************************/
+void BTA_MaBmsgSetBodyCharset(tBTA_MA_BMSG_BODY * p_body, tBTA_MA_CHARSET charset)
+{
+ if ( p_body )
+ p_body->charset = charset;
+}
+/*******************************************************************************
+**
+** Function BTA_MaBmsgGetBodyCharset
+**
+** Description Get the bmessage-body-charset-property value for the speicified
+** bMessage body.
+**
+** Parameters p_body - Pointer to a bMessage body
+**
+** Returns Charset
+**
+*******************************************************************************/
+tBTA_MA_CHARSET BTA_MaBmsgGetBodyCharset(tBTA_MA_BMSG_BODY * p_body)
+{
+ return( p_body ? p_body->charset : BTA_MA_CHARSET_UNKNOWN );
+}
+/*******************************************************************************
+**
+** Function BTA_MaBmsgSetBodyLanguage
+**
+** Description Set the bmessage-body-language-property value for the speicified
+** bMessage body.
+**
+** Parameters p_body - Pointer to a bMessage body
+** Language - the language of the message
+**
+** Returns None
+**
+*******************************************************************************/
+void BTA_MaBmsgSetBodyLanguage(tBTA_MA_BMSG_BODY * p_body, tBTA_MA_BMSG_LANGUAGE language)
+{
+ if ( p_body )
+ p_body->language = language;
+}
+/*******************************************************************************
+**
+** Function BTA_MaBmsgGetBodyLanguage
+**
+** Description Get the bmessage-body-language-property value for the speicified
+** bMessage body.
+**
+** Parameters p_body - Pointer to a bMessage body
+**
+** Returns the language of the message
+**
+*******************************************************************************/
+tBTA_MA_BMSG_LANGUAGE BTA_MaBmsgGetBodyLanguage(tBTA_MA_BMSG_BODY * p_body)
+{
+ return( p_body ? p_body->language : BTA_MA_BMSG_LANG_UNSPECIFIED );
+}
+/*******************************************************************************
+**
+** Function BTA_MaBmsgAddContentToBody
+**
+** Description Add a message content to the speicified bMessage body.
+**
+** Parameters p_body - Pointer to a bMessage body
+**
+** Returns Pointer to a message content.
+** NULL if it fails to allocate a message content buffer
+**
+*******************************************************************************/
+tBTA_MA_BMSG_CONTENT * BTA_MaBmsgAddContentToBody(tBTA_MA_BMSG_BODY * p_body)
+{
+ tBTA_MA_BMSG_CONTENT * p_content = NULL;
+ tBTA_MA_BMSG_CONTENT * p_last_content = NULL;
+
+ if ( p_body )
+ {
+ p_content = (tBTA_MA_BMSG_CONTENT *)bta_ma_bmsg_alloc(sizeof(tBTA_MA_BMSG_CONTENT));
+ if ( p_content )
+ {
+ memset(p_content, 0, sizeof(tBTA_MA_BMSG_CONTENT));
+
+ if ( p_body->p_content )
+ {
+ /* set pointer to the last entry in the list */
+ p_last_content = p_body->p_content;
+ while ( p_last_content->p_next )
+ p_last_content = (tBTA_MA_BMSG_CONTENT *)p_last_content->p_next;
+
+ p_last_content->p_next = p_content;
+ }
+ else
+ p_body->p_content = p_content;
+ }
+ }
+
+ return(p_content);
+}
+/*******************************************************************************
+**
+** Function BTA_MaBmsgGetContentFromBody
+**
+** Description Get a message content from the speicified bMessage body.
+**
+** Parameters p_body - Pointer to a bMessage body
+**
+** Returns Pointer to a message content.
+** NULL if it has not been set.
+**
+*******************************************************************************/
+tBTA_MA_BMSG_CONTENT * BTA_MaBmsgGetContentFromBody(tBTA_MA_BMSG_BODY * p_body)
+{
+ return(p_body ? p_body->p_content : NULL);
+}
+/*******************************************************************************
+**
+** Function BTA_MaBmsgGetNextContent
+**
+** Description Get the next message content from the speicified message content.
+**
+** Parameters p_content - Pointer to a message content
+**
+** Returns Pointer to a message content.
+** NULL if it has not been set.
+**
+*******************************************************************************/
+tBTA_MA_BMSG_CONTENT * BTA_MaBmsgGetNextContent(tBTA_MA_BMSG_CONTENT * p_content)
+{
+ return(p_content ? (tBTA_MA_BMSG_CONTENT *)p_content->p_next : NULL);
+}
+
+/*******************************************************************************
+**
+** Function BTA_MaBmsgAddMsgContent
+**
+** Description Add a text string to the speicified message content.
+**
+** Parameters p_content - Pointer to a message content
+** p_text - Pointer to a text string
+**
+** Returns None
+**
+*******************************************************************************/
+void BTA_MaBmsgAddMsgContent(tBTA_MA_BMSG_CONTENT * p_content, char * p_text)
+{
+ tBTA_MA_BMSG_MESSAGE * p_message;
+
+ if ( p_content )
+ {
+ p_message = (tBTA_MA_BMSG_MESSAGE *)bta_ma_bmsg_alloc(sizeof(tBTA_MA_BMSG_MESSAGE));
+ if ( p_message )
+ {
+ memset(p_message, 0, sizeof(tBTA_MA_BMSG_MESSAGE));
+
+ p_message->p_text = (char *)bta_ma_bmsg_alloc(strlen(p_text)+1);
+
+ if ( p_message->p_text )
+ {
+ BCM_STRNCPY_S(p_message->p_text, strlen(p_text)+1, p_text, strlen(p_text)+1);
+
+ /* if the content already points to a message,
+ ** then we tack it on the end of the message list.
+ */
+ if ( p_content->p_message && p_content->p_last )
+ p_content->p_last->p_next = p_message;
+ else
+ p_content->p_message = p_message;
+
+ /* keep track of the last message text we added */
+ p_content->p_last = p_message;
+ }
+ else
+ bta_ma_bmsg_free(p_message);
+ }
+ }
+}
+
+/*******************************************************************************
+**
+** Function BTA_MaBmsgGetMsgContent
+**
+** Description Get the first text string from the speicified message content.
+**
+** Parameters p_content - Pointer to a message content
+**
+** Returns Pointer to the first text string.
+** NULL if it has not been set.
+**
+*******************************************************************************/
+char * BTA_MaBmsgGetMsgContent(tBTA_MA_BMSG_CONTENT * p_content)
+{
+ char * p_text = NULL;
+ if ( p_content && p_content->p_message )
+ {
+ /* reset 'last' pointer for when 'get_next' is called. */
+ p_content->p_last = p_content->p_message;
+
+ p_text = p_content->p_message->p_text;
+ }
+
+ return( p_text );
+}
+/*******************************************************************************
+**
+** Function BTA_MaBmsgGetMsgContent
+**
+** Description Get the next text string from the speicified message content.
+**
+** Parameters p_content - Pointer to a message content
+**
+** Returns Pointer to the next text string.
+** NULL if it has not been set.
+**
+*******************************************************************************/
+char * BTA_MaBmsgGetNextMsgContent(tBTA_MA_BMSG_CONTENT * p_content)
+{
+ char * p_text = NULL;
+
+ if ( p_content && p_content->p_last )
+ {
+ /* advance pointer */
+ p_content->p_last = ( tBTA_MA_BMSG_MESSAGE *)p_content->p_last->p_next;
+
+ if ( p_content->p_last )
+ p_text = p_content->p_last->p_text;
+ }
+
+ return( p_text );
+}
+
+
+/*******************************************************************************
+**
+** Function BTA_MaBmsgGetNextVcard
+**
+** Description Get the next vCard from the speicified vCard.
+**
+** Parameters p_vcard - Pointer to a vCard
+**
+** Returns Pointer to the next vCard.
+** NULL if it has not been set.
+**
+*******************************************************************************/
+tBTA_MA_BMSG_VCARD * BTA_MaBmsgGetNextVcard(tBTA_MA_BMSG_VCARD * p_vcard)
+{
+ return(p_vcard ? (tBTA_MA_BMSG_VCARD *)p_vcard->p_next : NULL);
+}
+
+
+/*******************************************************************************
+**
+** Function BTA_MaBmsgSetVcardVersion
+**
+** Description Set the vCard version for the speicified vCard.
+**
+** Parameters p_vcard - Pointer to a vCard
+** version - vcard version
+**
+** Returns None
+**
+*******************************************************************************/
+void BTA_MaBmsgSetVcardVersion(tBTA_MA_BMSG_VCARD * p_vcard, tBTA_MA_VCARD_VERSION version)
+{
+ if ( p_vcard )
+ p_vcard->version = version;
+}
+/*******************************************************************************
+**
+** Function BTA_MaBmsgGetVcardVersion
+**
+** Description Get the vCard version from the speicified vCard.
+**
+** Parameters p_vcard - Pointer to a vCard
+**
+** Returns vCard version number
+**
+*******************************************************************************/
+tBTA_MA_VCARD_VERSION BTA_MaBmsgGetVcardVersion(tBTA_MA_BMSG_VCARD * p_vcard)
+{
+ return(p_vcard ? p_vcard->version : 0);
+}
+/*******************************************************************************
+**
+** Function BTA_MaBmsgAddVcardProp
+**
+** Description Add a property to the speicified vCard.
+**
+** Parameters p_vcard - Pointer to a vCard
+** prop - Indicate which vCard peoperty
+** p_value - Pointer to the vCard property value
+** p_param - Pointer to the vCard property parameter
+**
+** Returns Pointer to the vCard peoperty
+**
+*******************************************************************************/
+tBTA_MA_VCARD_PROPERTY * BTA_MaBmsgAddVcardProp(tBTA_MA_BMSG_VCARD *p_vcard, tBTA_MA_VCARD_PROP prop, char *p_value, char *p_param)
+{
+ tBTA_MA_VCARD_PROPERTY * p_prop = NULL;
+ tBTA_MA_VCARD_PROPERTY * p_last_prop = NULL;
+
+ if ( p_vcard && prop < BTA_MA_VCARD_PROP_MAX )
+ {
+ p_prop = (tBTA_MA_VCARD_PROPERTY *) bta_ma_bmsg_alloc(sizeof(tBTA_MA_VCARD_PROPERTY));
+ if ( p_prop )
+ {
+ memset(p_prop, 0, sizeof(tBTA_MA_VCARD_PROPERTY));
+
+ /* Set the value (if given) */
+ if ( p_value )
+ {
+ p_prop->p_value = (char *)bta_ma_bmsg_alloc(strlen(p_value)+1);
+ if ( p_prop->p_value )
+ BCM_STRNCPY_S(p_prop->p_value, strlen(p_value)+1, p_value, strlen(p_value)+1);
+ }
+
+ /* Set the parameter (if given) */
+ if ( p_param )
+ {
+ p_prop->p_param = (char *)bta_ma_bmsg_alloc(strlen(p_param)+1);
+ if ( p_prop->p_param )
+ BCM_STRNCPY_S(p_prop->p_param, strlen(p_param)+1, p_param, strlen(p_param)+1);
+ }
+
+ /* There can be more than one of a property. So add this property to the end of the list. */
+ if ( p_vcard->p_prop[prop] == NULL )
+ p_vcard->p_prop[prop] = p_prop;
+ else
+ {
+ p_last_prop = p_vcard->p_prop[prop];
+ while ( p_last_prop->p_next )
+ p_last_prop = (tBTA_MA_VCARD_PROPERTY *)p_last_prop->p_next;
+
+ p_last_prop->p_next = p_prop;
+ }
+ }
+ }
+
+ return(p_prop);
+}
+/*******************************************************************************
+**
+** Function BTA_MaBmsgGetVcardProp
+**
+** Description Get the vCard property from the speicified vCard peoperty enum.
+**
+** Parameters p_vcard - Pointer to a vCard
+** prop - Indicate which vCard peoperty
+**
+** Returns Pointer to the vCard peoperty.
+** NULL if the vCard peoperty does not exist
+**
+*******************************************************************************/
+tBTA_MA_VCARD_PROPERTY * BTA_MaBmsgGetVcardProp(tBTA_MA_BMSG_VCARD * p_vcard, tBTA_MA_VCARD_PROP prop)
+{
+ return( p_vcard && prop < BTA_MA_VCARD_PROP_MAX ? p_vcard->p_prop[prop] : NULL);
+}
+/*******************************************************************************
+**
+** Function BTA_MaBmsgGetNextVcardProp
+**
+** Description Get the next vCard property from the speicified vCard peoperty.
+**
+** Parameters p_prop - Pointer to a vCard property
+**
+** Returns Pointer to the next vCard peoperty.
+** NULL if the next vCard peoperty does not exist
+**
+*******************************************************************************/
+tBTA_MA_VCARD_PROPERTY * BTA_MaBmsgGetNextVcardProp(tBTA_MA_VCARD_PROPERTY * p_prop)
+{
+ return(p_prop ? (tBTA_MA_VCARD_PROPERTY *)p_prop->p_next : NULL);
+}
+/*******************************************************************************
+**
+** Function BTA_MaBmsgGetVcardPropValue
+**
+** Description Get the vCard property value from the speicified vCard peoperty.
+**
+** Parameters p_prop - Pointer to a vCard property
+**
+** Returns Pointer to the vCard peoperty value.
+** NULL if the vCard peoperty value has not been set.
+**
+*******************************************************************************/
+char * BTA_MaBmsgGetVcardPropValue(tBTA_MA_VCARD_PROPERTY * p_prop)
+{
+ return(p_prop ? p_prop->p_value : NULL);
+}
+/*******************************************************************************
+**
+** Function BTA_MaBmsgGetVcardPropParam
+**
+** Description Get the vCard property parameter from the speicified vCard peoperty.
+**
+** Parameters p_prop - Pointer to a vCard property
+**
+** Returns Poiter to the vCard peoperty parameter.
+** NULL if the vCard peoperty parameter has not been set.
+**
+*******************************************************************************/
+char * BTA_MaBmsgGetVcardPropParam(tBTA_MA_VCARD_PROPERTY * p_prop)
+{
+ return(p_prop ? p_prop->p_param : NULL);
+}
+
+/*******************************************************************************
+**
+** Function BTA_MaBuildMapBmsgObj
+**
+** Description Builds a specification compliant bMessage object given a
+** generic bMessage internal structure.
+**
+** Parameters p_msg - pointer to bMessage object structure (input).
+** p_stream - Output stream.
+**
+** Returns BTA_MA_STATUS_OK if successful. BTA_MA_STATUS_FAIL if not.
+**
+*******************************************************************************/
+tBTA_MA_STATUS BTA_MaBuildMapBmsgObj(tBTA_MA_BMSG * p_msg,
+ tBTA_MA_STREAM * p_stream)
+{
+ tBTA_MA_STATUS status = BTA_MA_STATUS_FAIL;
+
+
+ if ( p_msg && p_stream )
+ {
+ bta_ma_stream_str(p_stream, "BEGIN:BMSG");
+ bta_ma_stream_str(p_stream, "\r\nVERSION:1.0");
+
+ /* Read Status */
+ bta_ma_stream_str(p_stream, "\r\nSTATUS:");
+ bta_ma_stream_str(p_stream, (BTA_MaBmsgGetReadSts(p_msg) ? "READ" : "UNREAD"));
+
+ /* Type */
+ bta_ma_stream_str(p_stream, "\r\nTYPE:");
+ bta_ma_stream_str(p_stream, bta_ma_msg_typ_to_string(BTA_MaBmsgGetMsgType(p_msg)));
+
+ /* Folder */
+ bta_ma_stream_str(p_stream, "\r\nFOLDER:");
+ bta_ma_stream_str(p_stream, BTA_MaBmsgGetFolder(p_msg));
+
+ /* Originator(s) */
+ bta_ma_stream_vcards(p_stream, BTA_MaBmsgGetOrigFromBmsg(p_msg));
+
+ /* Envelopes (nested) */
+ bta_ma_stream_envelopes(p_stream, BTA_MaBmsgGetEnv(p_msg));
+
+ bta_ma_stream_str(p_stream, "\r\nEND:BMSG\r\n");
+
+ /* if buffer overflowed then return failure */
+ status = bta_ma_stream_ok(p_stream)
+ ? BTA_MA_STATUS_OK
+ : BTA_MA_STATUS_FAIL;
+ }
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT1("BTA_MA_STATUS =%d (0-OK) BTA_MaBuildMapBmsgObj", status);
+#endif
+ return( status );
+}
+/*******************************************************************************
+**
+** Function bta_ma_parse_map_bmsg_obj
+**
+** Description Parses a bMessage object from a stream into a generic
+** bMessage internal structure.
+**
+** Parameters p_msg - pointer to bMessage object structure (output).
+** p_stream - Input stream.
+**
+** Returns BTA_MA_STATUS_OK if successful. BTA_MA_STATUS_FAIL if not.
+**
+*******************************************************************************/
+tBTA_MA_STATUS BTA_MaParseMapBmsgObj(tBTA_MA_BMSG * p_msg,
+ tBTA_MA_STREAM * p_stream)
+{
+ char sz[BTA_MA_MAX_SIZE];
+ UINT32 prop_mask = 0;
+ tBTA_MA_STATUS status = BTA_MA_STATUS_FAIL;
+ tBTA_MA_BMSG_VCARD * p_vcard = NULL;
+ tBTA_MA_BMSG_ENVELOPE * p_envelope = NULL;
+ tBTA_MA_MSG_TYPE msg_type = 0;
+
+ APPL_TRACE_EVENT0("BTA_MaParseMapBmsgObj");
+ if ( p_msg && p_stream )
+ {
+ /* Must start with BEGIN:MSG */
+ if ( bta_ma_get_tag(p_stream, sz, BTA_MA_MAX_SIZE)
+ && (strcmp(sz, "BEGIN") == 0)
+ && bta_ma_get_value(p_stream, sz, BTA_MA_MAX_SIZE)
+ && (strcmp(sz, "BMSG") == 0) )
+ {
+ while ( bta_ma_get_tag(p_stream, sz, BTA_MA_MAX_SIZE) )
+ {
+ /* VERSION */
+ if ( strcmp(sz, "VERSION") == 0 )
+ {
+ if ( bta_ma_get_value(p_stream, sz, BTA_MA_MAX_SIZE)
+ && (strcmp(sz, "1.0") == 0) )
+ {
+ prop_mask |= BTA_MA_PROP_VERSION;
+ }
+ else
+ break; /* incorrect VERSION */
+ }
+ else if ( strcmp(sz, "STATUS") == 0 )
+ {
+ bta_ma_get_value(p_stream, sz, BTA_MA_MAX_SIZE);
+ BTA_MaBmsgSetReadSts(p_msg, (BOOLEAN) (strcmp(sz, "READ") == 0));
+ }
+ else if ( strcmp(sz, "TYPE") == 0 )
+ {
+ bta_ma_get_value(p_stream, sz, BTA_MA_MAX_SIZE);
+ if ( bta_ma_str_to_msg_typ(sz, &msg_type) )
+ BTA_MaBmsgSetMsgType(p_msg, msg_type);
+
+ }
+ else if ( strcmp(sz, "FOLDER") == 0 )
+ {
+ bta_ma_get_value(p_stream, sz, BTA_MA_MAX_SIZE);
+ BTA_MaBmsgSetFolder(p_msg, sz);
+ }
+ else if ( strcmp(sz, "BEGIN") == 0 )
+ {
+ bta_ma_get_value(p_stream, sz, BTA_MA_MAX_SIZE);
+
+ if ( strcmp(sz, "VCARD") == 0 )
+ {
+ p_vcard = BTA_MaBmsgAddOrigToBmsg(p_msg);
+ bta_ma_parse_vcard(p_vcard, p_stream);
+ }
+ else if ( strcmp(sz, "BENV") == 0 )
+ {
+ p_envelope = BTA_MaBmsgAddEnvToBmsg(p_msg);
+ bta_ma_parse_envelope(p_envelope, p_stream);
+ }
+ else
+ {
+ APPL_TRACE_ERROR1("bta_ma_parse_map_bmsg_obj - 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_map_bmsg_obj - Invalid tag: '%s'", sz);
+ }
+ }
+ }
+ }
+
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT1("BTA_MaParseMapBmsgObj status=%d(0-OK)", status);
+#endif
+ return( status );
+}
+
+/*******************************************************************************
+**
+** Function BTA_MaInitMemStream
+**
+** Description Initializes a memory based stream
+**
+** Parameters p_stream - pointer to stream information.
+** p_buffer - pointer to buffer to be manipulated.
+** size - size of buffer pointed to by 'p_buffer'.
+**
+** Returns TRUE if stream is opened.
+**
+*******************************************************************************/
+BOOLEAN BTA_MaInitMemStream(tBTA_MA_STREAM * p_stream,
+ UINT8 * p_buffer,
+ UINT16 size)
+{
+ if ( !p_stream )
+ return(FALSE);
+
+ memset(p_stream, 0, sizeof(tBTA_MA_STREAM));
+
+ p_stream->type = STRM_TYPE_MEMORY;
+ p_stream->u.mem.p_buffer = p_stream->u.mem.p_next = p_buffer;
+ p_stream->u.mem.size = size;
+
+ return(TRUE);
+}
+
+/*******************************************************************************
+**
+** Function BTA_MaInitFileStream
+**
+** Description Initializes a file stream
+**
+** Parameters p_stream - pointer to stream information.
+** p_path - Full pathname to file to use.
+** oflags - permissions and mode
+**
+** Returns TRUE if file stream is opened.
+**
+*******************************************************************************/
+BOOLEAN BTA_MaInitFileStream(tBTA_MA_STREAM * p_stream,
+ const char *p_path,
+ int oflags)
+{
+ if ( !p_stream )
+ {
+ APPL_TRACE_ERROR0("Invalid stream pointer");
+ return(FALSE);
+ }
+
+ memset(p_stream, 0, sizeof(tBTA_MA_STREAM));
+
+ p_stream->type = STRM_TYPE_FILE;
+
+ p_stream->u.file.fd = bta_ma_co_open(p_path, oflags);
+
+ if ( p_stream->u.file.fd == -1 )
+ {
+ APPL_TRACE_ERROR0("Unable to open file ");
+ p_stream->status = STRM_ERROR_FILE;
+ }
+
+ /* return TRUE if stream is OK */
+ return(p_stream->status == STRM_SUCCESS);
+}
+
+/*******************************************************************************
+**
+** Function BTA_MaCloseStream
+**
+** Description Close a stream (do any necessary clean-up).
+**
+** Parameters p_stream - pointer to stream information.
+**
+** Returns void
+**
+*******************************************************************************/
+void BTA_MaCloseStream(tBTA_MA_STREAM * p_stream)
+{
+ if ( p_stream->type == STRM_TYPE_FILE )
+ {
+ bta_ma_co_close(p_stream->u.file.fd);
+ p_stream->u.file.fd = BTA_FS_INVALID_FD;
+ }
+}
+#endif /* BTA_MSE_INCLUDED */
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 */
diff --git a/bta/ma/bta_ma_util.h b/bta/ma/bta_ma_util.h
new file mode 100644
index 0000000..9040201
--- /dev/null
+++ b/bta/ma/bta_ma_util.h
@@ -0,0 +1,93 @@
+/*****************************************************************************
+**
+** Name: bta_ma_util.h
+**
+** Description: This is the interface file for the Message Access Profile
+** (MAP) utility functions.
+**
+** Copyright (c) 2009, Broadcom Corp., All Rights Reserved.
+** Broadcom Bluetooth Core. Proprietary and confidential.
+**
+*****************************************************************************/
+#ifndef BTA_MA_UTIL_H
+#define BTA_MA_UTIL_H
+
+#include "bta_ma_def.h"
+#include "bta_mse_api.h"
+#include "bta_mse_co.h"
+#include "bta_ma_api.h"
+
+
+#define BTA_MA_MAX_SIZE (100)
+
+/* Here are a set of property flags used to keep track
+** of properties that are successfully parsed. We use
+** this information to determine if all the *required*
+** properties have been provided in the parsed object.
+*/
+#define BTA_MA_PROP_VERSION 0x00000001
+#define BTA_MA_BMSG_BODY_TAG_CTL_LENGTH 22 /* see MAP Spec. Errata 3603 */
+ /* BEGIN:MSG<CRTL>+<CRTL>+END:MSG<CRTL> */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+ extern const char * bta_ma_evt_typ_to_string(tBTA_MSE_NOTIF_TYPE notif_type);
+ extern const char * bta_ma_msg_typ_to_string(tBTA_MA_MSG_TYPE msg_typ);
+ extern const char * bta_ma_rcv_status_to_string(tBTA_MSE_CO_RCV_STATUS rcv_status);
+
+ extern BOOLEAN bta_ma_stream_str(tBTA_MA_STREAM * p_stream,
+ const char * p_str);
+
+ extern BOOLEAN bta_ma_stream_buf(tBTA_MA_STREAM * p_stream,
+ UINT16 len,
+ UINT8 * p_buf);
+
+ extern BOOLEAN bta_ma_stream_boolean_yes_no(tBTA_MA_STREAM * p_stream, BOOLEAN val);
+
+ extern BOOLEAN bta_ma_stream_value(tBTA_MA_STREAM * p_stream, UINT32 val);
+
+ extern BOOLEAN bta_ma_stream_handle(tBTA_MA_STREAM * p_stream,
+ tBTA_MA_MSG_HANDLE handle);
+
+ extern UINT16 bta_ma_stream_used_size(tBTA_MA_STREAM * p_stream);
+
+ extern BOOLEAN bta_ma_stream_ok(tBTA_MA_STREAM * p_stream);
+
+ extern void bta_ma_convert_hex_str_to_64bit_handle(char *p_hex_str, tBTA_MA_MSG_HANDLE handle);
+
+ extern BOOLEAN bta_ma_get_char(tBTA_MA_STREAM * p_stream, char * p_char);
+ extern BOOLEAN bta_ma_str_to_charset(char * psz, tBTA_MA_CHARSET * p_charset);
+ extern BOOLEAN bta_ma_str_to_encoding(char * psz, tBTA_MA_BMSG_ENCODING * p_encoding);
+ extern BOOLEAN bta_ma_str_to_language(char * psz, tBTA_MA_BMSG_LANGUAGE * p_language);
+ extern BOOLEAN bta_ma_str_to_msg_typ(char * psz, tBTA_MA_MSG_TYPE * p_msg_type);
+
+ extern void bta_ma_stream_vcards(tBTA_MA_STREAM *, tBTA_MA_BMSG_VCARD *);
+ extern void bta_ma_stream_envelopes(tBTA_MA_STREAM * p_stream, tBTA_MA_BMSG_ENVELOPE * p_envelope);
+ extern void bta_ma_stream_body(tBTA_MA_STREAM * p_stream, tBTA_MA_BMSG_BODY * p_body);
+ extern void bta_ma_stream_body_content(tBTA_MA_STREAM * p_stream, tBTA_MA_BMSG_CONTENT * p_content);
+ extern void bta_ma_stream_vcard_prop(tBTA_MA_STREAM * p_stream, tBTA_MA_BMSG_VCARD * p_vcard, tBTA_MA_VCARD_PROP prop);
+
+ extern UINT32 bta_ma_get_body_length(tBTA_MA_BMSG_BODY * p_body);
+
+ extern UINT16 bta_ma_get_tag(tBTA_MA_STREAM * p_stream, char * psz, UINT16 max_size);
+ extern UINT16 bta_ma_get_value(tBTA_MA_STREAM * p_stream, char * psz, UINT16 max_size);
+
+ extern tBTA_MA_STATUS bta_ma_parse_vcard(tBTA_MA_BMSG_VCARD * p_vcard, tBTA_MA_STREAM * p_stream);
+ extern tBTA_MA_STATUS bta_ma_parse_envelope(tBTA_MA_BMSG_ENVELOPE * p_envelope, tBTA_MA_STREAM * p_stream);
+
+ extern void * bta_ma_bmsg_alloc(size_t cb);
+ extern void bta_ma_bmsg_free(void * p);
+ extern void bta_ma_bmsg_free_vcards(tBTA_MA_BMSG_VCARD * p_vcard);
+ extern void bta_ma_bmsg_free_envelope(tBTA_MA_BMSG_ENVELOPE * p_envelope);
+ extern void bta_ma_bmsg_free_body(tBTA_MA_BMSG_BODY * p_body);
+ extern void bta_ma_bmsg_free_content(tBTA_MA_BMSG_CONTENT * p_content);
+ extern void bta_ma_bmsg_free_message_text(tBTA_MA_BMSG_MESSAGE * p_message);
+ extern void bta_ma_bmsg_free_vcard_prop(tBTA_MA_VCARD_PROPERTY * p_prop);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* BTA_MA_UTIL_H */
diff --git a/bta/ma/bta_mse_act.c b/bta/ma/bta_mse_act.c
new file mode 100644
index 0000000..c8ec487
--- /dev/null
+++ b/bta/ma/bta_mse_act.c
@@ -0,0 +1,2763 @@
+/*****************************************************************************
+**
+** Name: bta_mse_act.c
+**
+** Description: This file contains the message access server action
+** functions for the state machine.
+**
+** Copyright (c) 2003-2011, Broadcom Corp., All Rights Reserved.
+** Broadcom Bluetooth Core. Proprietary and confidential.
+**
+*****************************************************************************/
+
+#include "bt_target.h"
+
+#if defined(BTA_MSE_INCLUDED) && (BTA_MSE_INCLUDED == TRUE)
+
+#include <string.h>
+#include "gki.h"
+#include "sdp_api.h"
+#include "bta_sys.h"
+#include "port_api.h"
+#include "obx_api.h"
+#include "sdp_api.h"
+#include "bta_fs_api.h"
+#include "bta_mse_api.h"
+#include "bta_mse_int.h"
+#include "bta_fs_co.h"
+#include "utl.h"
+#include "bd.h"
+#include "bta_ma_def.h"
+
+
+/*****************************************************************************
+** Local Function prototypes
+*****************************************************************************/
+void bta_mse_req_app_access(UINT8 inst_idx, UINT8 sess_idx, tBTA_MSE_DATA *p_data);
+static void bta_mse_mn_sdp_cback0(UINT16 status);
+static void bta_mse_mn_sdp_cback1(UINT16 status);
+static void bta_mse_mn_sdp_cback2(UINT16 status);
+static void bta_mse_mn_sdp_cback3(UINT16 status);
+static void bta_mse_mn_sdp_cback4(UINT16 status);
+static void bta_mse_mn_sdp_cback5(UINT16 status);
+static void bta_mse_mn_sdp_cback6(UINT16 status);
+
+static tSDP_DISC_CMPL_CB * const bta_mse_mn_sdp_cback_arr[] = {
+ bta_mse_mn_sdp_cback0,
+ bta_mse_mn_sdp_cback1,
+ bta_mse_mn_sdp_cback2,
+ bta_mse_mn_sdp_cback3,
+ bta_mse_mn_sdp_cback4,
+ bta_mse_mn_sdp_cback5,
+ bta_mse_mn_sdp_cback6
+};
+
+#if (BTA_MSE_DEBUG == TRUE) && (BT_USE_TRACES == TRUE)
+static char *bta_mse_obx_evt_code(UINT16 evt_code);
+#endif
+
+
+/*******************************************************************************
+** Message Access Server (MAS) Action functions
+**
+*******************************************************************************/
+
+/*******************************************************************************
+**
+** Function bta_mse_ma_int_close
+**
+** Description Porcesses the Internal MAS session close event
+**
+** Parameters inst_idx - Index to the MA instance control block
+** sess_idx - Index to the MA session control block
+** p_data - Pointer to the event data
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_mse_ma_int_close(UINT8 inst_idx, UINT8 sess_idx, tBTA_MSE_DATA *p_data)
+{
+ tBTA_MSE_MA_SESS_CB *p_cb = BTA_MSE_GET_SESS_CB_PTR(inst_idx, sess_idx);
+ BD_ADDR bd_addr;
+
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT2("bta_mse_ma_int_close inst idx=%d sess idx=%d",inst_idx, sess_idx);
+#endif
+
+ if (OBX_GetPeerAddr(p_cb->obx_handle, bd_addr) != 0)
+ {
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT1("Send Obx Discon rsp obx session id=%d",
+ p_cb->obx_handle);
+#endif
+ /* resources will be freed at BTA_MSE_MA_OBX_CLOSE_EVT */
+ OBX_DisconnectRsp(p_cb->obx_handle, OBX_RSP_SERVICE_UNAVL, NULL);
+ }
+ else
+ {
+ /* OBX close already */
+ bta_mse_ma_sm_execute(inst_idx, sess_idx, BTA_MSE_MA_OBX_CLOSE_EVT, p_data);
+ }
+}
+
+/*******************************************************************************
+**
+** Function bta_mse_ma_api_upd_ibx_rsp
+**
+** Description Processes the API update inbox response event.
+** If permission had been granted, continue the operation,
+** otherwise stop the operation.
+**
+** Parameters inst_idx - Index to the MA instance control block
+** sess_idx - Index to the MA session control block
+** p_data - Pointer to the event data
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_mse_ma_api_upd_ibx_rsp(UINT8 inst_idx, UINT8 sess_idx, tBTA_MSE_DATA *p_data)
+{
+ tBTA_MSE_MA_SESS_CB *p_cb = BTA_MSE_GET_SESS_CB_PTR(inst_idx, sess_idx);
+ UINT8 rsp_code = OBX_RSP_UNAUTHORIZED;
+
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT2("bta_mse_ma_api_upd_ibx_rsp inst idx=%d sess idx=%d",inst_idx, sess_idx);
+#endif
+
+ /* Process the currently active access response */
+ if (p_cb->oper == BTA_MSE_OPER_UPDATE_INBOX)
+ {
+ bta_mse_set_ma_oper(inst_idx, sess_idx, BTA_MSE_OPER_NONE);
+ if (p_data->api_upd_ibx_rsp.rsp == BTA_MSE_UPDATE_INBOX_ALLOW)
+ {
+ bta_mse_co_update_inbox(p_cb->obx_handle, bta_mse_cb.app_id);
+ rsp_code = OBX_RSP_OK;
+ }
+ OBX_PutRsp(p_cb->obx_handle, rsp_code, (BT_HDR *)NULL);
+ }
+ else
+ {
+ APPL_TRACE_WARNING1("MSE UPDIBXRSP: Unknown tBTA_MSE_OPER value (%d)",
+ p_cb->oper);
+ }
+}
+
+
+/*******************************************************************************
+**
+** Function bta_mse_ma_api_set_notif_reg_rsp
+**
+** Description Processes the API set notification registration response event.
+** If permission had been granted, continue the operation,
+** otherwise stop the operation.
+**
+** Parameters inst_idx - Index to the MA instance control block
+** sess_idx - Index to the MA session control block
+** p_data - Pointer to the event data
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_mse_ma_api_set_notif_reg_rsp(UINT8 inst_idx, UINT8 sess_idx, tBTA_MSE_DATA *p_data)
+{
+ tBTA_MSE_MA_SESS_CB *p_cb = BTA_MSE_GET_SESS_CB_PTR(inst_idx, sess_idx);
+ UINT8 rsp_code = OBX_RSP_SERVICE_UNAVL;
+
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT2("bta_mse_ma_api_set_notif_reg_rsp inst idx=%d sess idx=%d",inst_idx, sess_idx);
+#endif
+
+ /* Process the currently active access response */
+ if ( p_cb->oper == BTA_MSE_OPER_NOTIF_REG)
+ {
+ bta_mse_set_ma_oper(inst_idx, sess_idx, BTA_MSE_OPER_NONE);
+ if (p_data->api_set_notif_reg_rsp.rsp == BTA_MSE_SET_NOTIF_REG_ALLOW)
+ {
+ bta_mse_proc_notif_reg_status(p_cb->notif_reg_req.notif_status,
+ inst_idx, sess_idx);
+ }
+ else
+ {
+ OBX_PutRsp(p_cb->obx_handle, rsp_code, (BT_HDR *)NULL);
+ }
+ }
+ else
+ {
+ APPL_TRACE_WARNING1("MSE SETNOTIFREGRSP: Unknown tBTA_MSE_OPER value (%d)",
+ p_cb->oper);
+ }
+}
+
+
+/*******************************************************************************
+**
+** Function bta_mse_ma_api_accessrsp
+**
+** Description Processes the API access response event.
+** If permission had been granted, continue the operation,
+** otherwise stop the operation.
+**
+** Parameters inst_idx - Index to the MA instance control block
+** sess_idx - Index to the MA session control block
+** p_data - Pointer to the event data
+**
+** Returns void
+**
+*******************************************************************************/
+
+void bta_mse_ma_api_accessrsp(UINT8 inst_idx, UINT8 sess_idx, tBTA_MSE_DATA *p_data)
+{
+ tBTA_MSE_MA_SESS_CB *p_cb = BTA_MSE_GET_SESS_CB_PTR(inst_idx, sess_idx);
+ UINT8 rsp_code = OBX_RSP_OK;
+
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT3("bta_mse_ma_api_accessrsp inst idx=%d sess idx=%d access_rsp=%d",
+ inst_idx, sess_idx,
+ p_data->api_access_rsp.rsp);
+#endif
+
+ if (p_cb->oper != p_data->api_access_rsp.oper )
+ {
+ APPL_TRACE_WARNING2("MSE MA ACCRSP: not match active:%d, rsp:%d",
+ p_cb->oper, p_data->api_access_rsp.oper);
+ return;
+ }
+
+ /* Process the currently active access response */
+ switch (p_cb->oper)
+ {
+ case BTA_MSE_OPER_SETPATH:
+
+ if (p_data->api_access_rsp.rsp == BTA_MA_ACCESS_TYPE_ALLOW)
+ {
+ bta_mse_co_set_folder( p_cb->obx_handle, p_cb->sp.p_path, bta_mse_cb.app_id);
+ /* updat the working dir */
+ BCM_STRNCPY_S(p_cb->p_workdir, p_bta_fs_cfg->max_path_len+1, p_cb->sp.p_path, p_bta_fs_cfg->max_path_len);
+ }
+ else
+ {
+ rsp_code = OBX_RSP_UNAUTHORIZED;
+ }
+
+ utl_freebuf((void**)&(p_cb->sp.p_path));
+ utl_freebuf((void**)&(p_cb->sp.p_name));
+ OBX_SetPathRsp(p_cb->obx_handle, rsp_code, (BT_HDR *)NULL);
+ bta_mse_set_ma_oper(inst_idx, sess_idx, BTA_MSE_OPER_NONE);
+ break;
+
+ case BTA_MSE_OPER_GET_MSG_LIST:
+
+ if (p_data->api_access_rsp.rsp == BTA_MA_ACCESS_TYPE_ALLOW)
+ {
+ bta_mse_getmsglist(inst_idx,sess_idx, TRUE);
+ }
+ else
+ {
+ OBX_GetRsp(p_cb->obx_handle, OBX_RSP_UNAUTHORIZED, (BT_HDR *)NULL);
+ bta_mse_clean_msg_list(inst_idx,sess_idx);
+ }
+ break;
+
+ case BTA_MSE_OPER_GET_MSG:
+
+ if (p_data->api_access_rsp.rsp == BTA_MA_ACCESS_TYPE_ALLOW)
+ {
+ bta_mse_getmsg(inst_idx,sess_idx, TRUE);
+ }
+ else
+ {
+ OBX_GetRsp(p_cb->obx_handle, OBX_RSP_UNAUTHORIZED, (BT_HDR *)NULL);
+ bta_mse_clean_msg(inst_idx,sess_idx);
+ }
+ break;
+
+ case BTA_MSE_OPER_PUSH_MSG:
+
+ if (p_data->api_access_rsp.rsp == BTA_MA_ACCESS_TYPE_ALLOW)
+ {
+ bta_mse_pushmsg(inst_idx, sess_idx, TRUE);
+ }
+ else
+ {
+ OBX_PutRsp(p_cb->obx_handle, OBX_RSP_UNAUTHORIZED, (BT_HDR *)NULL);
+ bta_mse_clean_push_msg(inst_idx,sess_idx);
+ }
+ break;
+
+ case BTA_MSE_OPER_DEL_MSG:
+
+ if (p_data->api_access_rsp.rsp == BTA_MA_ACCESS_TYPE_ALLOW)
+ {
+ p_cb->cout_active = TRUE;
+ bta_mse_co_set_msg_delete_status((tBTA_MA_SESS_HANDLE) p_cb->obx_handle,
+ p_cb->set_msg_sts.handle,
+ p_cb->set_msg_sts.sts_val,
+ BTA_MSE_CI_DEL_MSG_EVT,
+ bta_mse_cb.app_id);
+ }
+ else
+ {
+ OBX_PutRsp(p_cb->obx_handle, OBX_RSP_UNAUTHORIZED, (BT_HDR *)NULL);
+ bta_mse_clean_set_msg_sts(inst_idx,sess_idx);
+ }
+ break;
+
+ default:
+ APPL_TRACE_WARNING1("MSE ACCRSP: Unknown tBTA_MSE_OPER value (%d)",
+ p_cb->oper);
+ break;
+ }
+}
+
+/*******************************************************************************
+**
+** Function bta_mse_ma_ci_get_folder_entry
+**
+** Description Proceses the get folder entry call-in event
+**
+** Parameters inst_idx - Index to the MA instance control block
+** sess_idx - Index to the MA session control block
+** p_data - Pointer to the event data
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_mse_ma_ci_get_folder_entry(UINT8 inst_idx, UINT8 sess_idx, tBTA_MSE_DATA *p_data)
+{
+ tBTA_MSE_MA_SESS_CB *p_cb = BTA_MSE_GET_SESS_CB_PTR(inst_idx, sess_idx);
+ UINT8 rsp_code = OBX_RSP_PART_CONTENT;
+ BOOLEAN free_pkt = TRUE;
+
+
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT2("bta_mse_ma_ci_get_folder_entry inst idx=%d sess idx=%d",
+ inst_idx, sess_idx);
+#endif
+
+ p_cb->cout_active = FALSE;
+
+ if (p_cb->aborting)
+ {
+ bta_mse_clean_getput(inst_idx,sess_idx, BTA_MA_STATUS_ABORTED);
+ return;
+ }
+
+ /* Process dirent listing call-in event if operation is still active */
+ if (p_cb->oper == BTA_MSE_OPER_GET_FOLDER_LIST)
+ {
+ switch (p_data->ci_get_fentry.status)
+ {
+ case BTA_MA_STATUS_OK: /* Valid new entry */
+ free_pkt = FALSE;
+ rsp_code = bta_mse_add_list_entry(inst_idx, sess_idx);
+ break;
+
+ case BTA_MA_STATUS_EODIR: /* End of list (entry not valid) */
+ free_pkt = FALSE;
+ rsp_code = OBX_RSP_OK;
+ break;
+
+ case BTA_MA_STATUS_FAIL: /* Error occurred */
+ rsp_code = OBX_RSP_NOT_FOUND;
+ break;
+
+ default:
+ APPL_TRACE_ERROR1("bta_mse_ma_ci_get_folder_entry Unknown status=%d ",
+ p_data->ci_get_fentry.status );
+ rsp_code = OBX_RSP_NOT_FOUND;
+ break;
+ }
+ }
+
+ if (rsp_code != OBX_RSP_PART_CONTENT)
+ bta_mse_end_of_list(inst_idx, sess_idx,rsp_code);
+
+ if (free_pkt)
+ utl_freebuf((void **)&p_cb->obx.p_pkt);
+}
+
+
+/*******************************************************************************
+**
+** Function bta_mse_ma_ci_get_ml_info
+**
+** Description Proceses the get message list info call-in event
+**
+** Parameters inst_idx - Index to the MA instance control block
+** sess_idx - Index to the MA session control block
+** p_data - Pointer to the event data
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_mse_ma_ci_get_ml_info(UINT8 inst_idx, UINT8 sess_idx, tBTA_MSE_DATA *p_data)
+{
+ tBTA_MSE_MA_SESS_CB *p_cb = BTA_MSE_GET_SESS_CB_PTR(inst_idx, sess_idx);
+ UINT8 rsp_code = OBX_RSP_PART_CONTENT;
+ BOOLEAN free_pkt = TRUE;
+
+
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT2("bta_mse_ma_ci_get_ml_info inst idx=%d sess idx=%d",
+ inst_idx, sess_idx);
+#endif
+
+ p_cb->cout_active = FALSE;
+
+ if (p_cb->aborting)
+ {
+ bta_mse_clean_getput(inst_idx,sess_idx, BTA_MA_STATUS_ABORTED);
+ return;
+ }
+
+ /* Process dirent listing call-in event if operation is still active */
+ if (p_cb->oper == BTA_MSE_OPER_GET_MSG_LIST)
+ {
+ switch (p_data->ci_get_ml_info.status)
+ {
+ case BTA_MA_STATUS_OK: /* Valid new entry */
+ free_pkt = FALSE;
+ rsp_code = bta_mse_add_msg_list_info(inst_idx, sess_idx);
+ break;
+
+ case BTA_MA_STATUS_EODIR: /* End of list (entry not valid) */
+ free_pkt = FALSE;
+ rsp_code = OBX_RSP_OK;
+ break;
+
+ case BTA_MA_STATUS_FAIL: /* Error occurred */
+ rsp_code = OBX_RSP_NOT_FOUND;
+ break;
+
+ default:
+ APPL_TRACE_ERROR1("bta_mse_ma_ci_get_ml_info Unknown status=%d ",
+ p_data->ci_get_ml_info.status );
+ rsp_code = OBX_RSP_NOT_FOUND;
+ break;
+ }
+ }
+
+ if (rsp_code != OBX_RSP_PART_CONTENT)
+ bta_mse_end_of_msg_list(inst_idx, sess_idx,rsp_code);
+
+ if (free_pkt)
+ utl_freebuf((void **)&p_cb->obx.p_pkt);
+}
+
+/*******************************************************************************
+**
+** Function bta_mse_ma_ci_get_msg_entry
+**
+** Description Proceses the get message entry call-in event
+**
+** Parameters inst_idx - Index to the MA instance control block
+** sess_idx - Index to the MA session control block
+** p_data - Pointer to the event data
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_mse_ma_ci_get_ml_entry(UINT8 inst_idx, UINT8 sess_idx, tBTA_MSE_DATA *p_data)
+{
+ tBTA_MSE_MA_SESS_CB *p_cb = BTA_MSE_GET_SESS_CB_PTR(inst_idx, sess_idx);
+ UINT8 rsp_code = OBX_RSP_PART_CONTENT;
+ BOOLEAN free_pkt = TRUE;
+
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT2("bta_mse_ma_ci_get_msg_entry inst idx=%d sess idx=%d",inst_idx, sess_idx);
+ APPL_TRACE_EVENT1(" status=%d",p_data->ci_get_ml_entry.status);
+#endif
+
+ p_cb->cout_active = FALSE;
+
+ if (p_cb->aborting)
+ {
+ bta_mse_clean_getput(inst_idx,sess_idx, BTA_MA_STATUS_ABORTED);
+ return;
+ }
+
+ /* Process dirent listing call-in event if operation is still active */
+ if (p_cb->oper == BTA_MSE_OPER_GET_MSG_LIST)
+ {
+ switch (p_data->ci_get_ml_entry.status)
+ {
+ case BTA_MA_STATUS_OK: /* Valid new entry */
+ free_pkt = FALSE;
+ rsp_code = bta_mse_add_msg_list_entry(inst_idx, sess_idx);
+ break;
+
+ case BTA_MA_STATUS_EODIR: /* End of list (entry not valid) */
+ free_pkt = FALSE;
+ rsp_code = OBX_RSP_OK;
+ break;
+
+ case BTA_MA_STATUS_FAIL: /* Error occurred */
+ rsp_code = OBX_RSP_NOT_FOUND;
+ break;
+
+ default:
+ APPL_TRACE_ERROR1("bta_mse_ma_ci_get_ml_entry Unknown status=%d ",
+ p_data->ci_get_ml_entry.status);
+ rsp_code = OBX_RSP_NOT_FOUND;
+ break;
+ }
+ }
+
+ if (rsp_code != OBX_RSP_PART_CONTENT)
+ bta_mse_end_of_msg_list(inst_idx, sess_idx,rsp_code);
+
+ if (free_pkt)
+ utl_freebuf((void **)&p_cb->obx.p_pkt);
+}
+
+
+/*******************************************************************************
+**
+** Function bta_mse_ma_ci_get_msg
+**
+** Description Proceses the get message call-in event
+**
+** Parameters inst_idx - Index to the MA instance control block
+** sess_idx - Index to the MA session control block
+** p_data - Pointer to the event data
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_mse_ma_ci_get_msg(UINT8 inst_idx, UINT8 sess_idx, tBTA_MSE_DATA *p_data)
+{
+ tBTA_MSE_MA_SESS_CB *p_cb = BTA_MSE_GET_SESS_CB_PTR(inst_idx, sess_idx);
+ tBTA_MSE_OPER_MSG_PARAM *p_param = &p_cb->msg_param;
+ tBTA_MSE_CI_GET_MSG *p_ci_get_msg = &p_data->ci_get_msg;
+ UINT8 rsp_code = OBX_RSP_NOT_FOUND;
+ BOOLEAN free_pkt = TRUE, end_of_msg= TRUE;
+
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT2("bta_mse_ma_ci_get_msg inst idx=%d sess idx=%d",
+ inst_idx, sess_idx);
+ APPL_TRACE_EVENT1("status=%d",p_data->ci_get_ml_entry.status);
+#endif
+
+ p_cb->cout_active = FALSE;
+
+ if (p_cb->aborting)
+ {
+ bta_mse_clean_getput(inst_idx,sess_idx, BTA_MA_STATUS_ABORTED);
+ return;
+ }
+
+ /* Process get msg call-in event if operation is still active */
+ if (p_cb->oper == BTA_MSE_OPER_GET_MSG)
+ {
+ switch (p_data->ci_get_msg.status)
+ {
+ case BTA_MA_STATUS_OK: /* Valid new entry */
+ free_pkt = FALSE;
+ p_param->frac_deliver_status = p_ci_get_msg->frac_deliver_status;
+ p_param->filled_buff_size = p_ci_get_msg->filled_buff_size;
+
+ if ( p_ci_get_msg->multi_pkt_status == BTA_MA_MPKT_STATUS_MORE)
+ {
+ p_param->byte_get_cnt += p_param->filled_buff_size;
+ rsp_code = OBX_RSP_CONTINUE;
+ }
+ else
+ rsp_code = OBX_RSP_OK;
+
+ break;
+
+ case BTA_MA_STATUS_FAIL: /* Error occurred */
+ break;
+
+ default:
+ end_of_msg = FALSE;
+ break;
+ }
+ }
+
+ if (end_of_msg)
+ bta_mse_end_of_msg(inst_idx, sess_idx,rsp_code);
+
+ if (free_pkt)
+ utl_freebuf((void **)&p_cb->obx.p_pkt);
+}
+
+
+/*******************************************************************************
+**
+** Function bta_mse_ma_ci_push_msg
+**
+** Description Proceses the push message call-in event
+**
+** Parameters inst_idx - Index to the MA instance control block
+** sess_idx - Index to the MA session control block
+** p_data - Pointer to the event data
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_mse_ma_ci_push_msg(UINT8 inst_idx, UINT8 sess_idx, tBTA_MSE_DATA *p_data)
+{
+ tBTA_MSE_MA_SESS_CB *p_cb = BTA_MSE_GET_SESS_CB_PTR(inst_idx, sess_idx);
+ tBTA_MSE_OBX_PKT *p_obx = &p_cb->obx;
+ UINT8 rsp_code = OBX_RSP_INTRNL_SRVR_ERR;
+ BOOLEAN free_pkt = TRUE;
+ char handle_buf[BTA_MSE_64BIT_HEX_STR_SIZE];
+ tBTA_MA_STREAM strm;
+
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT2("bta_mse_ma_ci_push_msg inst idx=%d sess idx=%d",
+ inst_idx, sess_idx);
+ APPL_TRACE_EVENT4(" status=%d ci_last_pkt=%d obx_final=%d oper=%d",
+ p_data->ci_push_msg.status,
+ p_data->ci_push_msg.last_packet,
+ p_obx->final_pkt,
+ p_cb->oper);
+#endif
+
+ p_cb->cout_active = FALSE;
+
+ if (p_cb->aborting)
+ {
+ bta_mse_clean_getput(inst_idx,sess_idx, BTA_MA_STATUS_ABORTED);
+ return;
+ }
+
+ /* Process get msg call-in event if operation is still active */
+ if (p_cb->oper == BTA_MSE_OPER_PUSH_MSG)
+ {
+ switch (p_data->ci_push_msg.status)
+ {
+ case BTA_MA_STATUS_OK: /* Valid new entry */
+ if (p_obx->final_pkt)
+ {
+ APPL_TRACE_EVENT2("final pkt: status=%d oper=%d",
+ p_data->ci_push_msg.status, p_cb->oper);
+
+ utl_freebuf((void**)&p_obx->p_pkt);
+
+ rsp_code = OBX_RSP_OK;
+
+ p_obx->p_pkt = (BT_HDR *)OBX_HdrInit(p_cb->obx_handle,
+ /* p_cb->peer_mtu */ HCI_CMD_POOL_BUF_SIZE);
+ if (p_obx->p_pkt)
+ {
+ memset(handle_buf, 0,BTA_MSE_64BIT_HEX_STR_SIZE);
+ BTA_MaInitMemStream(&strm,(UINT8 *) handle_buf, BTA_MSE_64BIT_HEX_STR_SIZE);
+ bta_ma_stream_handle(&strm, p_data->ci_push_msg.handle);
+ if (OBX_AddUtf8NameHdr(p_obx->p_pkt, (UINT8 *)handle_buf))
+ {
+ rsp_code = OBX_RSP_OK;
+ free_pkt = FALSE;
+ }
+ else
+ {
+ rsp_code = OBX_RSP_INTRNL_SRVR_ERR;
+ }
+ }
+ else
+ {
+ rsp_code = OBX_RSP_INTRNL_SRVR_ERR;
+ }
+ }
+ else
+ rsp_code = OBX_RSP_CONTINUE;
+ break;
+
+ case BTA_MA_STATUS_FAIL: /* Error occurred */
+ rsp_code = OBX_RSP_UNAUTHORIZED;
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (rsp_code==OBX_RSP_OK)
+ {
+ OBX_PutRsp(p_cb->obx_handle, rsp_code, (BT_HDR *)p_obx->p_pkt);
+ p_obx->p_pkt = NULL; /* Do not deallocate buffer; OBX will */
+ }
+ else
+ {
+ OBX_PutRsp(p_cb->obx_handle, rsp_code, (BT_HDR *)NULL);
+ }
+
+
+ if (rsp_code == OBX_RSP_CONTINUE)
+ {
+ bta_mse_send_push_msg_in_prog_evt(inst_idx,sess_idx);
+ }
+ else
+ {
+ if ((rsp_code != OBX_RSP_OK) ||
+ ((p_obx->final_pkt) &&(rsp_code == OBX_RSP_OK)))
+ {
+ bta_mse_send_oper_cmpl_evt(inst_idx,sess_idx, p_data->ci_push_msg.status);
+ bta_mse_clean_push_msg(inst_idx,sess_idx);
+ }
+ }
+
+ if (free_pkt) utl_freebuf((void**)&p_obx->p_pkt);
+
+}
+
+/*******************************************************************************
+**
+** Function bta_mse_ma_ci_del_msg
+**
+** Description Proceses the delete message call-in event
+**
+** Parameters inst_idx - Index to the MA instance control block
+** sess_idx - Index to the MA session control block
+** p_data - Pointer to the event data
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_mse_ma_ci_del_msg(UINT8 inst_idx, UINT8 sess_idx, tBTA_MSE_DATA *p_data)
+{
+ tBTA_MSE_MA_SESS_CB *p_cb = BTA_MSE_GET_SESS_CB_PTR(inst_idx, sess_idx);
+ UINT8 rsp_code = OBX_RSP_OK;
+
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT2("bta_mse_ma_ci_del_msg inst idx=%d sess idx=%d",
+ inst_idx, sess_idx);
+ APPL_TRACE_EVENT2(" status=%d oper=%d",p_data->ci_del_msg.status, p_cb->oper);
+#endif
+
+ p_cb->cout_active = FALSE;
+
+ if (p_cb->aborting)
+ {
+ /* too late to abort now*/
+ bta_mse_abort_too_late(inst_idx,sess_idx);
+ }
+
+ /* Process get msg call-in event if operation is still active */
+ if (p_cb->oper == BTA_MSE_OPER_DEL_MSG)
+ {
+ switch (p_data->ci_del_msg.status)
+ {
+ case BTA_MA_STATUS_OK:
+ rsp_code = OBX_RSP_OK;
+ break;
+
+ case BTA_MA_STATUS_FAIL: /* Error occurred */
+ rsp_code = OBX_RSP_FORBIDDEN;
+ break;
+ default:
+ break;
+ }
+ }
+
+ OBX_PutRsp(p_cb->obx_handle, rsp_code, (BT_HDR *)NULL);
+ bta_mse_clean_set_msg_sts(inst_idx,sess_idx);
+
+}
+/*******************************************************************************
+**
+** Function bta_mse_ma_obx_connect
+**
+** Description Proceses the obx connect request to open a MAS session
+**
+** Parameters inst_idx - Index to the MA instance control block
+** sess_idx - Index to the MA session control block
+** p_data - Pointer to the event data
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_mse_ma_obx_connect(UINT8 inst_idx, UINT8 sess_idx, tBTA_MSE_DATA *p_data)
+{
+ tBTA_MSE_MA_CB *p_scb = BTA_MSE_GET_INST_CB_PTR(inst_idx);
+ tBTA_MSE_MA_SESS_CB *p_cb = BTA_MSE_GET_SESS_CB_PTR(inst_idx, sess_idx);
+ tBTA_MSE_OBX_EVT *p_evt = &p_data->obx_evt;
+ tBTA_MSE cback_evt_data;
+
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT2("bta_mse_ma_obx_connect inst idx=%d sess idx=%d",
+ inst_idx, sess_idx);
+#endif
+
+ p_cb->peer_mtu = p_evt->param.conn.mtu;
+ p_cb->obx_handle = p_evt->handle;
+ memcpy(p_cb->bd_addr, p_evt->param.conn.peer_addr, BD_ADDR_LEN);
+
+ OBX_ConnectRsp(p_evt->handle, OBX_RSP_OK, (BT_HDR *)NULL);
+
+ /* Reset to the root directory */
+ BCM_STRNCPY_S(p_cb->p_workdir, p_bta_fs_cfg->max_path_len+1, p_scb->p_rootpath, p_bta_fs_cfg->max_path_len);
+
+ /* inform role manager */
+ bta_mse_pm_conn_open(p_cb->bd_addr);
+
+ bdcpy(cback_evt_data.ma_open.bd_addr, p_cb->bd_addr);
+ BCM_STRNCPY_S((char *)cback_evt_data.ma_open.dev_name, sizeof(cback_evt_data.ma_open.dev_name),
+ "", BTM_MAX_REM_BD_NAME_LEN);
+ cback_evt_data.ma_open.mas_instance_id = p_scb->mas_inst_id;
+ cback_evt_data.ma_open.mas_session_id = p_cb->obx_handle;
+
+ bta_mse_cb.p_cback(BTA_MSE_MA_OPEN_EVT, (tBTA_MSE *) &cback_evt_data);
+
+ /* Done with Obex packet */
+ utl_freebuf((void**)&p_evt->p_pkt);
+
+}
+/*******************************************************************************
+**
+** Function bta_mse_ma_obx_disc
+**
+** Description Proceses the obx disconnect request to close a MAS session
+**
+** Parameters inst_idx - Index to the MA instance control block
+** sess_idx - Index to the MA session control block
+** p_data - Pointer to the event data
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_mse_ma_obx_disc(UINT8 inst_idx, UINT8 sess_idx, tBTA_MSE_DATA *p_data)
+{
+ tBTA_MSE_OBX_EVT *p_evt = &p_data->obx_evt;
+ UINT8 rsp_code;
+
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT2("bta_mse_ma_obx_disc inst idx=%d sess idx=%d",
+ inst_idx, sess_idx);
+#endif
+ rsp_code = (p_evt->obx_event == OBX_DISCONNECT_REQ_EVT) ? OBX_RSP_OK
+ : OBX_RSP_BAD_REQUEST;
+ OBX_DisconnectRsp(p_evt->handle, rsp_code, (BT_HDR *)NULL);
+
+ /* Done with Obex packet */
+ utl_freebuf((void**)&p_evt->p_pkt);
+}
+/*******************************************************************************
+**
+** Function bta_mse_ma_obx_close
+**
+** Description Proceses the obx close indication to close a MAS connection
+**
+** Parameters inst_idx - Index to the MA instance control block
+** sess_idx - Index to the MA session control block
+** p_data - Pointer to the event data
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_mse_ma_obx_close(UINT8 inst_idx, UINT8 sess_idx, tBTA_MSE_DATA *p_data)
+{
+ tBTA_MSE_MA_SESS_CB *p_cb = BTA_MSE_GET_SESS_CB_PTR(inst_idx, sess_idx);
+
+
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT2("bta_mse_ma_obx_close inst idx=%d sess idx=%d",
+ inst_idx, sess_idx);
+#endif
+ /* finished if not waiting on a call-in function */
+ if (!p_cb->cout_active)
+ bta_mse_ma_sm_execute(inst_idx, sess_idx, BTA_MSE_CLOSE_CMPL_EVT, p_data);
+
+}
+
+/*******************************************************************************
+**
+** Function bta_mse_ma_obx_abort
+**
+** Description Proceses the obx abort request
+**
+** Parameters inst_idx - Index to the MA instance control block
+** sess_idx - Index to the MA session control block
+** p_data - Pointer to the event data
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_mse_ma_obx_abort(UINT8 inst_idx, UINT8 sess_idx, tBTA_MSE_DATA *p_data)
+{
+ tBTA_MSE_MA_SESS_CB *p_cb = BTA_MSE_GET_SESS_CB_PTR(inst_idx, sess_idx);
+ tBTA_MSE_OBX_EVT *p_evt = &p_data->obx_evt;
+
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT3("bta_mse_ma_obx_abort inst idx=%d sess idx=%d oper=%d",
+ inst_idx, sess_idx, p_cb->oper);
+#endif
+
+ utl_freebuf((void**)&p_evt->p_pkt);
+
+ switch (p_cb->oper)
+ {
+ case BTA_MSE_OPER_SETPATH:
+ case BTA_MSE_OPER_NONE:
+ OBX_AbortRsp(p_evt->handle, OBX_RSP_BAD_REQUEST, (BT_HDR *)NULL);
+ return;
+ default:
+ break;
+
+ }
+
+ if (!p_cb->cout_active)
+ {
+ bta_mse_clean_getput(inst_idx,sess_idx, BTA_MA_STATUS_ABORTED);
+ }
+ else /* Delay the response if a call-out function is active */
+ p_cb->aborting = TRUE;
+
+}
+/*******************************************************************************
+**
+** Function bta_mse_ma_obx_put
+**
+** Description Proceses the obx put request
+**
+** Parameters inst_idx - Index to the MA instance control block
+** sess_idx - Index to the MA session control block
+** p_data - Pointer to the event data
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_mse_ma_obx_put(UINT8 inst_idx, UINT8 sess_idx, tBTA_MSE_DATA *p_data)
+{
+ tBTA_MSE_MA_SESS_CB *p_cb = BTA_MSE_GET_SESS_CB_PTR(inst_idx, sess_idx);
+ tBTA_MSE_OBX_EVT *p_evt = &p_data->obx_evt;
+ tBTA_MSE_OBX_PKT *p_obx = &p_cb->obx;
+ tBTA_MSE_OPER_PUSH_MSG *p_push_msg = &p_cb->push_msg;
+ tBTA_MSE_OPER_SET_MSG_STS *p_set_msg_sts = &p_cb->set_msg_sts;
+ tBTA_MA_SESS_HANDLE mas_session_id;
+ UINT16 len;
+ UINT8 *p_type;
+ UINT8 *p_param;
+ UINT8 rsp_code = OBX_RSP_OK;
+ UINT8 num_hdrs;
+ BOOLEAN free_pkt = TRUE;
+ BOOLEAN send_rsp = TRUE;
+ BOOLEAN send_ok_rsp = FALSE;
+
+
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT2("bta_mse_ma_obx_put inst idx=%d sess idx=%d",
+ inst_idx, sess_idx);
+#endif
+
+ if (OBX_ReadTypeHdr(p_evt->p_pkt, &p_type, &len))
+ {
+ if (!memcmp(p_type, BTA_MA_HDR_TYPE_NOTIF_REG, len))
+ {
+ bta_mse_set_ma_oper(inst_idx, sess_idx, BTA_MSE_OPER_NOTIF_REG);
+ }
+ else if (!memcmp(p_type, BTA_MA_HDR_TYPE_MSG, len))
+ {
+ bta_mse_set_ma_oper(inst_idx, sess_idx, BTA_MSE_OPER_PUSH_MSG);
+ bta_mse_init_push_msg(inst_idx, sess_idx, &rsp_code);
+ if (rsp_code != OBX_RSP_OK)
+ {
+ OBX_PutRsp(p_evt->handle, rsp_code, (BT_HDR *)NULL);
+ bta_mse_clean_push_msg(inst_idx, sess_idx);
+ return;
+ }
+ }
+ else if (!memcmp(p_type, BTA_MA_HDR_TYPE_MSG_UPDATE, len))
+ {
+ bta_mse_set_ma_oper(inst_idx, sess_idx, BTA_MSE_OPER_UPDATE_INBOX);
+ }
+ else if (!memcmp(p_type, BTA_MA_HDR_TYPE_MSG_STATUS, len))
+ {
+ bta_mse_set_ma_oper(inst_idx, sess_idx, BTA_MSE_OPER_SET_MSG_STATUS);
+ bta_mse_init_set_msg_sts(inst_idx, sess_idx, &rsp_code);
+ if (rsp_code != OBX_RSP_OK)
+ {
+ OBX_PutRsp(p_evt->handle, rsp_code, (BT_HDR *)NULL);
+ bta_mse_clean_set_msg_sts(inst_idx, sess_idx);
+ return;
+ }
+ }
+ }
+
+ switch ( p_cb->oper)
+ {
+ case BTA_MSE_OPER_NOTIF_REG:
+
+ p_param = bta_mse_read_app_params(p_evt->p_pkt, BTA_MA_APH_NOTIF_STATUS, &len);
+ if (p_param)
+ {
+ p_cb->notif_reg_req.notif_status_rcv = TRUE;
+ BE_STREAM_TO_UINT8(p_cb->notif_reg_req.notif_status, p_param);
+ }
+
+ if (p_evt->param.put.final)
+ {
+ /* check end of body is included or not */
+
+ if ((num_hdrs = OBX_ReadBodyHdr(p_evt->p_pkt, &p_obx->p_start, &p_obx->offset, &p_obx->final_pkt)) &&
+ p_obx->final_pkt)
+ {
+ if (p_cb->notif_reg_req.notif_status_rcv)
+ {
+ if (!bta_mse_send_set_notif_reg(p_cb->notif_reg_req.notif_status,
+ inst_idx, sess_idx))
+ {
+ OBX_PutRsp(p_evt->handle, OBX_RSP_BAD_REQUEST, (BT_HDR *)NULL);
+ }
+ else
+ {
+ /* wait for the set notif reg response from the application*/
+ break;
+ }
+ }
+ else
+ {
+ OBX_PutRsp(p_evt->handle, OBX_RSP_BAD_REQUEST, (BT_HDR *)NULL);
+ }
+ }
+ else
+ {
+ OBX_PutRsp(p_evt->handle, OBX_RSP_BAD_REQUEST, (BT_HDR *)NULL);
+ }
+ /* if reach here this is a bad request case so clean up*/
+ bta_mse_clean_set_notif_reg(inst_idx,sess_idx);
+ }
+ else
+ {
+ OBX_PutRsp(p_evt->handle, OBX_RSP_CONTINUE, (BT_HDR *)NULL);
+ }
+
+ break;
+ case BTA_MSE_OPER_PUSH_MSG:
+
+ if ((!p_push_msg->rcv_folder_name) &&
+ (OBX_ReadUtf8NameHdr(p_evt->p_pkt, (UINT8 *)p_push_msg->param.p_folder,
+ p_bta_mse_cfg->max_name_len)))
+ {
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT2("Rcv folder len=%d, name=%s ",
+ strlen( p_push_msg->param.p_folder),
+ p_push_msg->param.p_folder);
+#endif
+ p_push_msg->rcv_folder_name = TRUE;
+ }
+
+ if (!p_push_msg->rcv_charset)
+ {
+ p_param = bta_mse_read_app_params(p_evt->p_pkt, BTA_MA_APH_CHARSET, &len);
+ if (p_param)
+ {
+
+ p_push_msg->rcv_charset = TRUE;
+ BE_STREAM_TO_UINT8(p_push_msg->param.charset, p_param);
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT1("Rcv Charset=%d(0-native 1-UTF8)",p_push_msg->param.charset);
+#endif
+ }
+ }
+
+ if (!p_push_msg->rcv_transparent)
+ {
+ p_param = bta_mse_read_app_params(p_evt->p_pkt, BTA_MA_APH_TRANSPARENT, &len);
+ if (p_param)
+ {
+ p_push_msg->rcv_transparent = TRUE;
+ BE_STREAM_TO_UINT8(p_push_msg->param.transparent, p_param);
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT1("Rcv Transparent=%d",p_push_msg->param.transparent);
+#endif
+ }
+ }
+
+ if (!p_push_msg->rcv_retry)
+ {
+ p_param = bta_mse_read_app_params(p_evt->p_pkt, BTA_MA_APH_RETRY, &len);
+ if (p_param)
+ {
+ p_push_msg->rcv_retry = TRUE;
+ BE_STREAM_TO_UINT8(p_push_msg->param.retry, p_param);
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT1("Rcv Retry=%d",p_push_msg->param.retry);
+#endif
+ }
+ }
+
+ /* Read the body header from the obx packet */
+ num_hdrs = OBX_ReadBodyHdr(p_evt->p_pkt, &p_obx->p_start, &p_obx->offset,
+ &p_obx->final_pkt);
+ /* process body or end of body header */
+ if (num_hdrs >= 1 )
+ {
+
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT3("Rcv Body or EndOfBody body_hdr=%d len=%d final=%d",
+ num_hdrs,
+ p_obx->offset,
+ p_obx->final_pkt);
+#endif
+
+ if (p_push_msg->rcv_charset && p_push_msg->rcv_folder_name)
+ {
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT0("Rcv all Required params");
+#endif
+
+ free_pkt = FALSE;
+ p_obx->p_pkt = p_evt->p_pkt;
+ if (p_push_msg->first_req_pkt)
+ {
+ p_push_msg->first_req_pkt = FALSE;
+ bta_mse_req_app_access( inst_idx, sess_idx, p_data);
+ }
+ else
+ {
+ bta_mse_pushmsg(inst_idx, sess_idx, FALSE);
+ }
+ send_rsp = FALSE;
+ }
+ else
+ {
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_ERROR0("Not all Mandatory params are rcv before body/EndofBody: bad request");
+#endif
+ rsp_code = OBX_RSP_BAD_REQUEST;
+ }
+ }
+ else
+ {
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT0("No Body or End of Body in this push msg pkt");
+#endif
+ }
+
+ if (!p_obx->final_pkt)
+ {
+ if (rsp_code != OBX_RSP_BAD_REQUEST)
+ {
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT0("Not a final pkt and no error set rsp_code=Continue");
+#endif
+ rsp_code = OBX_RSP_CONTINUE;
+ }
+ }
+
+ if (send_rsp) OBX_PutRsp(p_evt->handle, rsp_code, (BT_HDR *)NULL);
+ if (rsp_code == OBX_RSP_BAD_REQUEST )
+ {
+ if (!p_push_msg->first_req_pkt)
+ bta_mse_send_oper_cmpl_evt(inst_idx,sess_idx, BTA_MA_STATUS_FAIL);
+ bta_mse_clean_push_msg(inst_idx,sess_idx);
+ }
+ break;
+ case BTA_MSE_OPER_UPDATE_INBOX:
+
+ if (p_evt->param.put.final)
+ {
+ /* check enod of body is included or not */
+
+ if ((num_hdrs = OBX_ReadBodyHdr(p_evt->p_pkt, &p_obx->p_start, &p_obx->offset, &p_obx->final_pkt)) &&
+ p_obx->final_pkt)
+ {
+
+ mas_session_id = (tBTA_MA_SESS_HANDLE) p_cb->obx_handle;
+ bta_mse_cb.p_cback(BTA_MSE_UPDATE_INBOX_EVT, (tBTA_MSE *)&mas_session_id);
+ }
+ else
+ {
+ OBX_PutRsp(p_evt->handle, OBX_RSP_BAD_REQUEST, (BT_HDR *)NULL);
+ }
+ }
+ else
+ {
+ OBX_PutRsp(p_evt->handle, OBX_RSP_CONTINUE, (BT_HDR *)NULL);
+ }
+
+
+ break;
+ case BTA_MSE_OPER_SET_MSG_STATUS:
+
+
+ if ((!p_set_msg_sts->rcv_msg_handle) &&
+ (OBX_ReadUtf8NameHdr(p_evt->p_pkt, (UINT8 *)p_set_msg_sts->p_msg_handle,
+ BTA_MSE_64BIT_HEX_STR_SIZE)))
+ {
+ bta_ma_convert_hex_str_to_64bit_handle(p_set_msg_sts->p_msg_handle,
+ p_set_msg_sts->handle);
+ p_set_msg_sts->rcv_msg_handle = TRUE;
+ }
+
+ if (!p_set_msg_sts->rcv_sts_ind)
+ {
+ p_param = bta_mse_read_app_params(p_evt->p_pkt, BTA_MA_APH_STS_INDCTR, &len);
+ if (p_param)
+ {
+ p_set_msg_sts->rcv_sts_ind = TRUE;
+ BE_STREAM_TO_UINT8(p_set_msg_sts->sts_ind, p_param);
+ }
+ }
+
+ if (!p_set_msg_sts->rcv_sts_val)
+ {
+ p_param = bta_mse_read_app_params(p_evt->p_pkt, BTA_MA_APH_STS_VALUE, &len);
+ if (p_param)
+ {
+ p_set_msg_sts->rcv_sts_val = TRUE;
+ BE_STREAM_TO_UINT8(p_set_msg_sts->sts_val, p_param);
+ }
+ }
+
+ /* Read the body header from the obx packet */
+ num_hdrs = OBX_ReadBodyHdr(p_evt->p_pkt, &p_obx->p_start, &p_obx->offset,
+ &p_obx->final_pkt);
+ /* process body or end of body header */
+ if ((num_hdrs >= 1 && p_obx->final_pkt ) )
+ {
+ if (p_set_msg_sts->rcv_msg_handle && p_set_msg_sts->rcv_sts_ind &&
+ p_set_msg_sts->rcv_sts_val)
+ {
+ if (p_set_msg_sts->sts_ind == BTA_MA_STS_INDTR_DELETE)
+ {
+ p_cb->oper = BTA_MSE_OPER_DEL_MSG;
+ bta_mse_req_app_access( inst_idx, sess_idx, p_data);
+ }
+ else
+ {
+ if (bta_mse_co_set_msg_read_status((tBTA_MA_SESS_HANDLE) p_cb->obx_handle,
+ p_set_msg_sts->handle,
+ p_set_msg_sts->sts_val,
+ bta_mse_cb.app_id) != BTA_MA_STATUS_OK)
+ {
+ rsp_code = OBX_RSP_FORBIDDEN;
+ }
+ send_ok_rsp = TRUE;
+ }
+ }
+ else
+ {
+ rsp_code = OBX_RSP_BAD_REQUEST;
+ }
+ }
+
+ if (!p_obx->final_pkt)
+ {
+ if (rsp_code != OBX_RSP_BAD_REQUEST)
+ {
+ rsp_code = OBX_RSP_CONTINUE;
+ }
+ }
+
+ if (rsp_code != OBX_RSP_OK)
+ {
+ OBX_PutRsp(p_evt->handle, rsp_code, (BT_HDR *)NULL);
+ if (rsp_code == OBX_RSP_BAD_REQUEST )
+ {
+ bta_mse_clean_set_msg_sts(inst_idx,sess_idx);
+ }
+ }
+ else
+ {
+ if (send_ok_rsp)
+ {
+ OBX_PutRsp(p_evt->handle, rsp_code, (BT_HDR *)NULL);
+ bta_mse_clean_set_msg_sts(inst_idx,sess_idx);
+ }
+ }
+ break;
+ default:
+ OBX_PutRsp(p_evt->handle, OBX_RSP_BAD_REQUEST, (BT_HDR *)NULL);
+ break;
+ }
+
+ /* Done with Obex packet */
+ if (free_pkt) utl_freebuf((void**)&p_evt->p_pkt);
+}
+
+/*******************************************************************************
+**
+** Function bta_mse_ma_obx_get
+**
+** Description Proceses the obx get request
+**
+** Parameters inst_idx - Index to the MA instance control block
+** sess_idx - Index to the MA session control block
+** p_data - Pointer to the event data
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_mse_ma_obx_get(UINT8 inst_idx, UINT8 sess_idx, tBTA_MSE_DATA *p_data)
+{
+ tBTA_MSE_MA_SESS_CB *p_cb = BTA_MSE_GET_SESS_CB_PTR(inst_idx, sess_idx);
+ tBTA_MSE_OBX_EVT *p_evt = &p_data->obx_evt;
+ UINT16 len;
+ UINT8 *p_type;
+ tBTA_MSE_MA_GET_ACT get_act = BTA_MSE_MA_GET_ACT_NONE;
+ tBTA_MSE_MA_GET_TYPE get_type = BTA_MSE_MA_GET_TYPE_NONE;
+ UINT8 rsp_code = OBX_RSP_BAD_REQUEST;
+
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT2("bta_mse_ma_obx_get inst idx=%d sess idx=%d",inst_idx, sess_idx);
+ APPL_TRACE_EVENT1(" oper=%d",p_cb->oper );
+#endif
+ switch (p_cb->oper)
+ {
+ case BTA_MSE_OPER_GET_FOLDER_LIST:
+ get_type = BTA_MSE_MA_GET_TYPE_CON_FOLDER_LIST;
+ break;
+ case BTA_MSE_OPER_GET_MSG_LIST:
+ get_type = BTA_MSE_MA_GET_TYPE_CON_MSG_LIST;
+ break;
+ case BTA_MSE_OPER_GET_MSG:
+ get_type = BTA_MSE_MA_GET_TYPE_CON_MSG;
+ break;
+ case BTA_MSE_OPER_NONE:
+ if (OBX_ReadTypeHdr(p_evt->p_pkt, &p_type, &len))
+ {
+ if (!memcmp(p_type, BTA_MA_HDR_TYPE_FOLDER_LIST, len))
+ {
+ get_type = BTA_MSE_MA_GET_TYPE_FOLDER_LIST;
+ }
+ else if (!memcmp(p_type, BTA_MA_HDR_TYPE_MSG_LIST, len) )
+ {
+ get_type = BTA_MSE_MA_GET_TYPE_MSG_LIST;
+ }
+ else if (!memcmp(p_type, BTA_MA_HDR_TYPE_MSG, len) )
+ {
+
+ get_type = BTA_MSE_MA_GET_TYPE_MSG;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT1("bta_mse_ma_obx_get get_type=%d",get_type);
+#endif
+ switch (get_type)
+ {
+ case BTA_MSE_MA_GET_TYPE_FOLDER_LIST:
+ bta_mse_ma_fl_read_app_params(inst_idx, sess_idx, p_evt->p_pkt);
+ get_act = BTA_MSE_MA_GET_ACT_NEW_FOLDER_LIST;
+ break;
+
+ case BTA_MSE_MA_GET_TYPE_MSG_LIST:
+ if (!p_cb->ml_param.p_name)
+ {
+ p_cb->ml_param.p_name = (char *)GKI_getbuf((UINT16)(p_bta_mse_cfg->max_name_len + 1));
+ }
+
+ if (!p_cb->ml_param.p_path)
+ {
+ p_cb->ml_param.p_path = (char *)GKI_getbuf((UINT16)(p_bta_fs_cfg->max_path_len + 1));
+ }
+
+ if ((p_cb->ml_param.p_name != NULL) && (p_cb->ml_param.p_path != NULL))
+ {
+ if (!OBX_ReadUtf8NameHdr(p_evt->p_pkt, (UINT8 *)p_cb->ml_param.p_name,
+ p_bta_mse_cfg->max_name_len))
+ {
+ rsp_code = OBX_RSP_BAD_REQUEST;
+ break;
+ }
+ else
+ {
+ if (!bta_mse_get_msglist_path(inst_idx, sess_idx))
+ {
+ rsp_code = OBX_RSP_NOT_FOUND;
+ break;
+ }
+ }
+ }
+ else
+ {
+ rsp_code = OBX_RSP_INTRNL_SRVR_ERR;
+ break;
+ }
+
+ bta_mse_ma_ml_read_app_params(inst_idx, sess_idx,p_evt->p_pkt);
+ get_act = BTA_MSE_MA_GET_ACT_NEW_MSG_LIST;
+ break;
+
+ case BTA_MSE_MA_GET_TYPE_MSG:
+
+ if (!p_cb->msg_param.p_msg_handle)
+ {
+ if ((p_cb->msg_param.p_msg_handle = (char *)GKI_getbuf((UINT16)(BTA_MSE_64BIT_HEX_STR_SIZE))) == NULL )
+ {
+ rsp_code = OBX_RSP_INTRNL_SRVR_ERR;
+ get_act = BTA_MSE_MA_GET_ACT_ERR;
+ break;
+ }
+ }
+
+ if (OBX_ReadUtf8NameHdr(p_evt->p_pkt, (UINT8 *)p_cb->msg_param.p_msg_handle,
+ BTA_MSE_64BIT_HEX_STR_SIZE))
+ {
+ bta_ma_convert_hex_str_to_64bit_handle(p_cb->msg_param.p_msg_handle,
+ p_cb->msg_param.data.handle);
+ }
+ else
+ {
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT0("Unable to decode or find Name Header for Message Handle");
+#endif
+
+ get_act = BTA_MSE_MA_GET_ACT_ERR;
+ break;
+ }
+
+ if (!bta_mse_ma_msg_read_app_params(inst_idx, sess_idx, p_evt->p_pkt))
+ {
+ get_act = BTA_MSE_MA_GET_ACT_ERR;
+ break;
+ }
+ get_act = BTA_MSE_MA_GET_ACT_NEW_MSG;
+ break;
+
+ case BTA_MSE_MA_GET_TYPE_CON_FOLDER_LIST:
+ get_act = BTA_MSE_MA_GET_ACT_CON_FOLDER_LIST;
+ break;
+
+ case BTA_MSE_MA_GET_TYPE_CON_MSG_LIST:
+ get_act = BTA_MSE_MA_GET_ACT_CON_MSG_LIST;
+ break;
+
+ case BTA_MSE_MA_GET_TYPE_CON_MSG:
+ get_act = BTA_MSE_MA_GET_ACT_CON_MSG;
+ break;
+ default:
+ break;
+ }
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT1(" get_act=%d",get_act);
+#endif
+ switch (get_act)
+ {
+ case BTA_MSE_MA_GET_ACT_NEW_FOLDER_LIST:
+ bta_mse_set_ma_oper(inst_idx, sess_idx, BTA_MSE_OPER_GET_FOLDER_LIST);
+ bta_mse_getfolderlist(inst_idx,sess_idx, TRUE);
+ break;
+ case BTA_MSE_MA_GET_ACT_CON_FOLDER_LIST:
+ bta_mse_getfolderlist(inst_idx,sess_idx, FALSE);
+ break;
+
+ case BTA_MSE_MA_GET_ACT_NEW_MSG_LIST:
+ bta_mse_set_ma_oper(inst_idx, sess_idx, BTA_MSE_OPER_GET_MSG_LIST);
+ bta_mse_req_app_access( inst_idx, sess_idx, p_data);
+ break;
+ case BTA_MSE_MA_GET_ACT_CON_MSG_LIST:
+ bta_mse_getmsglist(inst_idx,sess_idx, FALSE);
+ break;
+
+ case BTA_MSE_MA_GET_ACT_NEW_MSG:
+ bta_mse_set_ma_oper(inst_idx, sess_idx, BTA_MSE_OPER_GET_MSG);
+ if (p_cb->msg_param.data.fraction_request == BTA_MA_FRAC_REQ_FIRST ||
+ p_cb->msg_param.data.fraction_request == BTA_MA_FRAC_REQ_NEXT)
+ {
+ p_cb->msg_param.add_frac_del_hdr = TRUE;
+ }
+ p_cb->msg_param.byte_get_cnt = 0;
+ bta_mse_req_app_access( inst_idx, sess_idx, p_data);
+ break;
+ case BTA_MSE_MA_GET_ACT_CON_MSG:
+ bta_mse_getmsg(inst_idx,sess_idx, FALSE);
+ break;
+
+ case BTA_MSE_MA_GET_ACT_ERR:
+ default:
+ OBX_GetRsp(p_evt->handle, rsp_code, (BT_HDR *)NULL);
+ utl_freebuf((void**)&p_cb->ml_param.p_name);
+ utl_freebuf((void**)&p_cb->ml_param.p_path);
+ break;
+ }
+ /* Done with Obex packet */
+ utl_freebuf((void**)&p_evt->p_pkt);
+}
+/*******************************************************************************
+**
+** Function bta_mse_ma_obx_setpath
+**
+** Description Proceses the obx setpath request
+**
+** Parameters inst_idx - Index to the MA instance control block
+** sess_idx - Index to the MA session control block
+** p_data - Pointer to the event data
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_mse_ma_obx_setpath(UINT8 inst_idx, UINT8 sess_idx, tBTA_MSE_DATA *p_data)
+{
+
+ tBTA_MSE_MA_SESS_CB *p_cb = BTA_MSE_GET_SESS_CB_PTR(inst_idx, sess_idx);
+ tBTA_MSE_OBX_EVT *p_evt = &p_data->obx_evt;
+ tBTA_MA_DIR_NAV flags = (tBTA_MA_DIR_NAV)p_evt->param.sp.flag;
+ UINT8 rsp_code = OBX_RSP_BAD_REQUEST;
+ tBTA_MSE_OPER mse_oper = BTA_MSE_OPER_NONE;
+
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT2("bta_mse_ma_obx_setpath inst idx=%d sess idx=%d",
+ inst_idx, sess_idx);
+ APPL_TRACE_EVENT1(" flags=%d ", flags);
+#endif
+
+ /* Verify flags and handle before accepting */
+ if ((flags == BTA_MA_DIR_NAV_ROOT_OR_DOWN_ONE_LVL) ||
+ (flags == BTA_MA_DIR_NAV_UP_ONE_LVL))
+ {
+
+ p_cb->sp.p_path = (char *)GKI_getbuf((UINT16)(p_bta_fs_cfg->max_path_len + 1));
+ p_cb->sp.p_name = (char *)GKI_getbuf((UINT16)(p_bta_mse_cfg->max_name_len + 1));
+ if (p_cb->sp.p_name != NULL )
+ {
+ p_cb->sp.flags = flags;
+
+ if (!OBX_ReadUtf8NameHdr(p_evt->p_pkt, (UINT8 *)p_cb->sp.p_name,
+ p_bta_fs_cfg->max_path_len))
+ {
+ p_cb->sp.p_name[0] = '\0';
+ }
+
+ rsp_code = bta_mse_chdir( inst_idx, sess_idx, &mse_oper);
+
+ }
+ else
+ {
+ rsp_code = OBX_RSP_INTRNL_SRVR_ERR;
+ }
+ }
+
+ bta_mse_set_ma_oper(inst_idx, sess_idx, mse_oper);
+ if (mse_oper != BTA_MSE_OPER_NONE)
+ {
+ bta_mse_req_app_access( inst_idx, sess_idx, p_data);
+ }
+ else
+ {
+ OBX_SetPathRsp(p_evt->handle, rsp_code, (BT_HDR *)NULL);
+ utl_freebuf((void**)&p_cb->sp.p_name);
+ }
+
+ /* Done with Obex packet */
+ utl_freebuf((void**)&p_evt->p_pkt);
+}
+/*******************************************************************************
+**
+** Function bta_mse_ma_conn_err_rsp
+**
+** Description Proceses the inavlid obx connection request
+**
+** Parameters inst_idx - Index to the MA instance control block
+** sess_idx - Index to the MA session control block
+** p_data - Pointer to the event data
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_mse_ma_conn_err_rsp(UINT8 inst_idx, UINT8 sess_idx, tBTA_MSE_DATA *p_data)
+{
+
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT2("bta_mse_ma_conn_err_rsp inst idx=%d sess idx=%d",inst_idx, sess_idx);
+#endif
+
+ OBX_ConnectRsp(p_data->obx_evt.handle, OBX_RSP_BAD_REQUEST, (BT_HDR *)NULL);
+ /* Done with Obex packet */
+ utl_freebuf((void**)&(p_data->obx_evt.p_pkt));
+}
+
+/*******************************************************************************
+**
+** Function bta_mse_ma_close_complete
+**
+** Description Proceses the connection close complete event.
+**
+** Parameters inst_idx - Index to the MA instance control block
+** sess_idx - Index to the MA session control block
+** p_data - Pointer to the event data
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_mse_ma_close_complete(UINT8 inst_idx, UINT8 sess_idx, tBTA_MSE_DATA *p_data)
+{
+ tBTA_MSE_MA_CB *p_scb = BTA_MSE_GET_INST_CB_PTR(inst_idx);
+ tBTA_MSE_MA_SESS_CB *p_cb = BTA_MSE_GET_SESS_CB_PTR(inst_idx, sess_idx);
+ tBTA_MSE cback_evt_data;
+ tBTA_MSE *p_cevt = &cback_evt_data;
+ UINT8 num_act_mas=0, num_act_sess=0, i;
+ tBTA_MA_STATUS clean_getput_status = BTA_MA_STATUS_OK;
+ UINT8 ccb_idx;
+ BD_ADDR bd_addr;
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT2("bta_mse_ma_close_complete inst idx=%d sess idx=%d",inst_idx, sess_idx);
+#endif
+
+
+ p_cb->cout_active = FALSE;
+
+ if (p_cb->aborting) clean_getput_status = BTA_MA_STATUS_ABORTED;
+ bta_mse_clean_getput(inst_idx, sess_idx, clean_getput_status);
+ utl_freebuf((void**)&p_cb->p_workdir);
+
+ /* inform role manager */
+
+ bta_mse_pm_conn_close(p_cb->bd_addr);
+ bdcpy(bd_addr, p_cb->bd_addr);
+ memset(p_cb->bd_addr, 0, BD_ADDR_LEN);
+ p_cb->peer_mtu = 0;
+
+ /* We now done with the close this seesion so issue a BTA_MSE_MA_CLOSE_EVT*/
+ p_cevt->ma_close.mas_session_id = p_cb->obx_handle;
+ p_cevt->ma_close.mas_instance_id = p_scb->mas_inst_id;
+ p_cevt->ma_close.status = BTA_MA_STATUS_OK ;
+ bta_mse_cb.p_cback(BTA_MSE_MA_CLOSE_EVT, (tBTA_MSE *) p_cevt);
+
+
+ /* turn off the registration status for the associated MAs instance
+ and also check whether MN connection needs to be closed or not */
+ if (bta_mse_find_bd_addr_match_mn_cb_index(bd_addr, &ccb_idx) &&
+ bta_mse_mn_is_inst_id_exist(ccb_idx, p_scb->mas_inst_id))
+ {
+ bta_mse_mn_remove_inst_id(ccb_idx, p_scb->mas_inst_id);
+ if (!bta_mse_mn_find_num_of_act_inst_id(ccb_idx))
+ {
+ bta_mse_mn_sm_execute(ccb_idx,BTA_MSE_MN_INT_CLOSE_EVT, NULL);
+ }
+ }
+
+ /* Check Any MAS instance need to be stopped */
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT2("stopping=%d MAS in use=%d", p_scb->stopping,p_scb->in_use);
+#endif
+ if (p_scb->stopping && p_scb->in_use)
+ {
+ num_act_sess = 0;
+ for (i=0; i < BTA_MSE_NUM_SESS; i ++)
+ {
+ p_cb = BTA_MSE_GET_SESS_CB_PTR(inst_idx, i);
+ if (p_cb->state != BTA_MSE_MA_LISTEN_ST)
+ num_act_sess++;
+ }
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT1("num_act_sess=%d ", num_act_sess);
+#endif
+ if (!num_act_sess)
+ {
+ p_cevt->stop.status = BTA_MA_STATUS_OK;
+ p_cevt->stop.mas_instance_id = p_scb->mas_inst_id;
+ bta_mse_cb.p_cback(BTA_MSE_STOP_EVT, (tBTA_MSE *) p_cevt);
+ bta_mse_clean_mas_service(inst_idx);
+ }
+ }
+
+ if (bta_mse_cb.disabling && bta_mse_cb.enable)
+ {
+ num_act_mas=0;
+ for (i=0; i < BTA_MSE_NUM_INST ; i ++)
+ {
+ p_scb = BTA_MSE_GET_INST_CB_PTR(i);
+ if (p_scb->in_use )
+ num_act_mas++;
+ }
+
+ if (!num_act_mas)
+ {
+ bta_mse_cb.enable = FALSE;
+ p_cevt->disable.status = BTA_MA_STATUS_OK;
+ p_cevt->disable.app_id = bta_mse_cb.app_id;
+ bta_mse_cb.p_cback(BTA_MSE_DISABLE_EVT, (tBTA_MSE *) p_cevt);
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT0("MSE Disabled location-2");
+#endif
+ }
+ }
+}
+
+/*******************************************************************************
+**
+** Function bta_mse_ignore_obx
+**
+** Description Ignores the obx event
+**
+** Parameters inst_idx - Index to the MA instance control block
+** sess_idx - Index to the MA session control block
+** p_data - Pointer to the event data
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_mse_ignore_obx(UINT8 inst_idx, UINT8 sess_idx, tBTA_MSE_DATA *p_data)
+{
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT2("bta_mse_ignore_obx inst idx=%d sess idx=%d",inst_idx, sess_idx);
+#endif
+
+ utl_freebuf((void**)&p_data->obx_evt.p_pkt);
+}
+/*******************************************************************************
+**
+** Function bta_mse_ma_obx_cback
+**
+** Description OBX callback function for MA.
+**
+** Parameters handle - Handle for Obex session
+** obx_event - Obex event
+** param - event parameters
+** p_pkt - pointer to Obex packet
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_mse_ma_obx_cback (tOBX_HANDLE handle, tOBX_EVENT obx_event,
+ tOBX_EVT_PARAM param, BT_HDR *p_pkt)
+{
+ tBTA_MSE_OBX_EVT *p_obx_msg;
+ UINT16 event = 0;
+
+ switch (obx_event)
+ {
+ case OBX_CONNECT_REQ_EVT:
+ event = BTA_MSE_MA_OBX_CONN_EVT;
+ break;
+ case OBX_DISCONNECT_REQ_EVT:
+ event = BTA_MSE_MA_OBX_DISC_EVT;
+ break;
+ case OBX_PUT_REQ_EVT:
+ event = BTA_MSE_MA_OBX_PUT_EVT;
+ break;
+ case OBX_GET_REQ_EVT:
+ event = BTA_MSE_MA_OBX_GET_EVT;
+ break;
+ case OBX_SETPATH_REQ_EVT:
+ event = BTA_MSE_MA_OBX_SETPATH_EVT;
+ break;
+ case OBX_ABORT_REQ_EVT:
+ event = BTA_MSE_MA_OBX_ABORT_EVT;
+ break;
+ case OBX_CLOSE_IND_EVT:
+ event = BTA_MSE_MA_OBX_CLOSE_EVT;
+ break;
+ case OBX_TIMEOUT_EVT:
+ break;
+ case OBX_PASSWORD_EVT:
+ break;
+ default:
+ /* Unrecognized packet; disconnect the session */
+ if (p_pkt)
+ event = BTA_MSE_MA_OBX_DISC_EVT;
+ }
+
+ /* send event to BTA, if any */
+ if (event && (p_obx_msg =
+ (tBTA_MSE_OBX_EVT *) GKI_getbuf(sizeof(tBTA_MSE_OBX_EVT))) != NULL)
+ {
+#if (BTA_MSE_DEBUG == TRUE) && (BT_USE_TRACES == TRUE)
+ APPL_TRACE_DEBUG1("MA OBX Event Callback: mse_obx_event [%s]", bta_mse_obx_evt_code(event));
+#endif
+ p_obx_msg->hdr.event = event;
+ p_obx_msg->obx_event = obx_event;
+ p_obx_msg->handle = handle;
+ p_obx_msg->param = param;
+ p_obx_msg->p_pkt = p_pkt;
+ p_obx_msg->hdr.layer_specific = 0xFFFF;
+
+ bta_sys_sendmsg(p_obx_msg);
+ }
+}
+/*******************************************************************************
+** Message Notification Client (MNC) Action functions
+**
+*******************************************************************************/
+/******************************************************************************
+**
+** Function bta_mse_mn_sdp_cback
+**
+** Description This is the SDP callback function used by MSE.
+** This function will be executed by SDP when the service
+** search is completed. If the search is successful, it
+** finds the first record in the database that matches the
+** UUID of the search. Then retrieves the scn from the
+** record.
+**
+** Parameters ccb_idx - Index to the MN control block
+** status - status of the SDP callabck
+**
+** Returns void.
+**
+******************************************************************************/
+static void bta_mse_mn_sdp_cback(UINT8 ccb_idx, UINT16 status)
+{
+ tBTA_MSE_MN_CB *p_cb = BTA_MSE_GET_MN_CB_PTR(ccb_idx);
+ tBTA_MSE_MN_SDP_OK *p_buf;
+ tSDP_DISC_REC *p_rec = NULL;
+ tSDP_PROTOCOL_ELEM pe;
+ UINT8 scn = 0;
+ BOOLEAN found = FALSE;
+
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT1("bta_mse_mn_sdp_cback status:%d", status);
+#endif
+ if (status == SDP_SUCCESS || status == SDP_DB_FULL)
+ {
+ /* loop through all records we found */
+ do
+ {
+ /* get next record; if none found, we're done */
+ if ((p_rec = SDP_FindServiceInDb(p_cb->p_db, p_cb->sdp_service,
+ p_rec)) == NULL)
+ {
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT0("SDP Not Found");
+#endif
+ break;
+ }
+
+ /* get scn from proto desc list; if not found, go to next record */
+ if (SDP_FindProtocolListElemInRec(p_rec, UUID_PROTOCOL_RFCOMM, &pe))
+ {
+ found = TRUE;
+ scn = (UINT8) pe.params[0];
+
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT1("SDP found scn=%d", scn);
+#endif
+ /* we've got everything, we're done */
+ break;
+ }
+ else
+ continue;
+ } while (TRUE);
+ }
+
+ /* send result in event back to BTA */
+ if ((p_buf = (tBTA_MSE_MN_SDP_OK *) GKI_getbuf(sizeof(tBTA_MSE_MN_SDP_OK))) != NULL)
+ {
+ p_buf->hdr.event = BTA_MSE_MN_SDP_FAIL_EVT;
+ p_buf->ccb_idx = ccb_idx;
+ if (status == SDP_SUCCESS || status == SDP_DB_FULL)
+ {
+ if (found == TRUE)
+ {
+ p_buf->hdr.event = BTA_MSE_MN_SDP_OK_EVT;
+ p_buf->scn = scn;
+ }
+ else
+ {
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT0("SDP 1 BTA_MSE_MN_SDP_FAIL_EVT");
+#endif
+ }
+ }
+ else
+ {
+
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT0("SDP 2 BTA_MSE_MN_SDP_FAIL_EVT");
+#endif
+ }
+
+ bta_sys_sendmsg(p_buf);
+ }
+}
+
+/******************************************************************************
+**
+** Function bta_mse_mn_sdp_cback0
+**
+** Description This is the SDP callback function used by MN indx = 0
+**
+** Parameters status - status of the SDP callabck
+**
+** Returns void.
+**
+******************************************************************************/
+static void bta_mse_mn_sdp_cback0(UINT16 status)
+{
+ bta_mse_mn_sdp_cback(0, status);
+}
+
+/******************************************************************************
+**
+** Function bta_mse_mn_sdp_cback1
+**
+** Description This is the SDP callback function used by MN indx = 1
+**
+** Parameters status - status of the SDP callabck
+**
+** Returns void.
+**
+******************************************************************************/
+static void bta_mse_mn_sdp_cback1(UINT16 status)
+{
+ bta_mse_mn_sdp_cback(1, status);
+}
+
+/******************************************************************************
+**
+** Function bta_mse_mn_sdp_cback2
+**
+** Description This is the SDP callback function used by MN indx = 2
+**
+** Parameters status - status of the SDP callabck
+**
+** Returns void.
+**
+******************************************************************************/
+static void bta_mse_mn_sdp_cback2(UINT16 status)
+{
+ bta_mse_mn_sdp_cback(2, status);
+}
+
+/******************************************************************************
+**
+** Function bta_mse_mn_sdp_cback3
+**
+** Description This is the SDP callback function used by MN indx = 3
+**
+** Parameters status - status of the SDP callabck
+**
+** Returns void.
+**
+******************************************************************************/
+static void bta_mse_mn_sdp_cback3(UINT16 status)
+{
+ bta_mse_mn_sdp_cback(3, status);
+}
+
+/******************************************************************************
+**
+** Function bta_mse_mn_sdp_cback4
+**
+** Description This is the SDP callback function used by MN indx = 4
+**
+** Parameters status - status of the SDP callabck
+**
+** Returns void.
+**
+******************************************************************************/
+static void bta_mse_mn_sdp_cback4(UINT16 status)
+{
+ bta_mse_mn_sdp_cback(4, status);
+}
+
+/******************************************************************************
+**
+** Function bta_mse_mn_sdp_cback5
+**
+** Description This is the SDP callback function used by MN indx = 5
+**
+** Parameters status - status of the SDP callabck
+**
+** Returns void.
+**
+******************************************************************************/
+static void bta_mse_mn_sdp_cback5(UINT16 status)
+{
+ bta_mse_mn_sdp_cback(5, status);
+}
+
+/******************************************************************************
+**
+** Function bta_mse_mn_sdp_cback6
+**
+** Description This is the SDP callback function used by MN indx = 6
+**
+** Parameters status - status of the SDP callabck
+**
+** Returns void.
+**
+******************************************************************************/
+static void bta_mse_mn_sdp_cback6(UINT16 status)
+{
+ bta_mse_mn_sdp_cback(6, status);
+}
+/*******************************************************************************
+**
+** Function bta_mse_mn_init_sdp
+**
+** Description Initialize SDP on message notification server device.
+**
+** Parameters ccb_idx - Index to the MN control block
+** p_data - Pointer to the MN event data
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_mse_mn_init_sdp(UINT8 ccb_idx, tBTA_MSE_DATA *p_data)
+{
+ tBTA_MSE_MN_CB *p_cb = &(bta_mse_cb.ccb[ccb_idx]);
+ tBTA_MSE_MN_INT_OPEN *p_evt = &p_data->mn_int_open;
+
+ tSDP_UUID uuid_list;
+ UINT16 attr_list[3];
+ UINT16 num_attrs = 2;
+
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT0("bta_mse_mn_init_sdp");
+#endif
+
+ p_cb->in_use = TRUE;
+ p_cb->sec_mask = p_evt->sec_mask;
+ bdcpy(p_cb->bd_addr,p_evt->bd_addr);
+ p_cb->sdp_pending = TRUE;
+ p_cb->sdp_cback = bta_mse_mn_sdp_cback_arr[ccb_idx];
+
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT6("SDP INIT BD_ADDR= %x:%x:%x:%x:%x:%x",
+ p_cb->bd_addr[0],
+ p_cb->bd_addr[1],
+ p_cb->bd_addr[2],
+ p_cb->bd_addr[3],
+ p_cb->bd_addr[4],
+ p_cb->bd_addr[5]);
+#endif
+
+ if ((p_cb->p_db = (tSDP_DISCOVERY_DB *) GKI_getbuf(BTA_MSE_MN_DISC_SIZE)) != NULL)
+ {
+ attr_list[0] = ATTR_ID_SERVICE_CLASS_ID_LIST;
+ attr_list[1] = ATTR_ID_PROTOCOL_DESC_LIST;
+
+ uuid_list.len = LEN_UUID_16;
+
+ p_cb->sdp_service = UUID_SERVCLASS_MESSAGE_NOTIFICATION;
+ uuid_list.uu.uuid16 = UUID_SERVCLASS_MESSAGE_NOTIFICATION;
+
+ SDP_InitDiscoveryDb(p_cb->p_db, BTA_MSE_MN_DISC_SIZE, 1, &uuid_list, num_attrs, attr_list);
+ if (!SDP_ServiceSearchAttributeRequest(p_cb->bd_addr, p_cb->p_db, p_cb->sdp_cback))
+ {
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT0("SDP Init failed ");
+#endif
+ bta_mse_mn_sm_execute(ccb_idx, BTA_MSE_MN_SDP_FAIL_EVT, p_data);
+ }
+ else
+ {
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT0("SDP Init Success ");
+#endif
+ }
+ }
+}
+
+/*******************************************************************************
+**
+** Function bta_mse_mn_start_client
+**
+** Description Starts the OBEX client for Message Notification service.
+**
+** Parameters ccb_idx - Index to the MN control block
+** p_data - Pointer to the MN event data
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_mse_mn_start_client(UINT8 ccb_idx, tBTA_MSE_DATA *p_data)
+{
+
+ tBTA_MSE_MN_CB *p_cb = BTA_MSE_GET_MN_CB_PTR(ccb_idx);
+ tBTA_MSE_OBX_PKT *p_obx = &p_cb->obx;
+ BOOLEAN connect_fail = TRUE;
+
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT1("bta_mse_mn_start_client ccb idx=%d ",ccb_idx);
+#endif
+
+ /* free discovery data base */
+ utl_freebuf((void**)&p_cb->p_db);
+ p_cb->sdp_pending = FALSE;
+ /* Allocate an OBX packet */
+ if ((p_obx->p_pkt = (BT_HDR *)OBX_HdrInit(OBX_HANDLE_NULL, OBX_CMD_POOL_SIZE)) != NULL)
+ {
+ /* set security level */
+ BTM_SetSecurityLevel (TRUE, "BTA_MNC", BTM_SEC_SERVICE_MAP,
+ p_cb->sec_mask, BT_PSM_RFCOMM,
+ BTM_SEC_PROTO_RFCOMM, p_data->mn_sdp_ok.scn);
+
+ if (p_cb->sdp_service == UUID_SERVCLASS_MESSAGE_NOTIFICATION)
+ {
+ OBX_AddTargetHdr(p_obx->p_pkt, (UINT8 *)BTA_MAS_MESSAGE_NOTIFICATION_TARGET_UUID,
+ BTA_MAS_UUID_LENGTH);
+ }
+ if (OBX_ConnectReq(p_cb->bd_addr, p_data->mn_sdp_ok.scn, OBX_MAX_MTU,
+ bta_mse_mn_obx_cback, &p_cb->obx_handle, p_obx->p_pkt) == OBX_SUCCESS)
+ {
+ p_obx->p_pkt = NULL; /* OBX will free the memory */
+ connect_fail = FALSE;
+ }
+ else
+ {
+ utl_freebuf((void**)&p_obx->p_pkt);
+ }
+ }
+
+ if (connect_fail)
+ {
+ bta_mse_mn_sm_execute(ccb_idx, BTA_MSE_MN_OBX_CLOSE_EVT, p_data);
+ }
+}
+
+/*******************************************************************************
+**
+** Function bta_mse_mn_rsp_timeout
+**
+** Description Process the OBX response timeout event
+**
+** Parameters ccb_idx - Index to the MN control block
+** p_data - Pointer to the MN event data
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_mse_mn_rsp_timeout(UINT8 ccb_idx, tBTA_MSE_DATA *p_data)
+{
+ tBTA_MSE_MN_CB *p_cb = BTA_MSE_GET_MN_CB_PTR(ccb_idx);
+
+ if (p_cb->timer_oper == BTA_MSE_TIMER_OP_ABORT)
+ {
+ /* Start stop response timer */
+ bta_mse_mn_start_timer(ccb_idx, BTA_MSE_TIMER_OP_STOP);
+
+ OBX_DisconnectReq(p_cb->obx_handle, NULL);
+ }
+ else /* Timeout waiting for disconnect response */
+ {
+ bta_mse_mn_sm_execute(ccb_idx, BTA_MSE_MN_OBX_CLOSE_EVT, p_data);
+
+ }
+}
+/*******************************************************************************
+**
+** Function bta_mse_mn_stop_client
+**
+** Description Stop the OBX client for Message Notification service.
+**
+** Parameters ccb_idx - Index to the MN control block
+** p_data - Pointer to the MN event data
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_mse_mn_stop_client(UINT8 ccb_idx, tBTA_MSE_DATA *p_data)
+{
+ tBTA_MSE_MN_CB *p_cb = BTA_MSE_GET_MN_CB_PTR(ccb_idx);
+
+
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT1("bta_mse_mn_stop_client ccb idx=%d ",ccb_idx);
+#endif
+
+ if (!p_cb->sdp_pending)
+ {
+ /* Start stop response timer */
+ bta_mse_mn_start_timer(ccb_idx, BTA_MSE_TIMER_OP_STOP);
+ OBX_DisconnectReq(p_cb->obx_handle, NULL);
+ }
+ else
+ {
+ APPL_TRACE_WARNING0("bta_mase_mn_stop_client: Waiting for SDP to complete");
+ }
+}
+/*******************************************************************************
+**
+** Function bta_mse_mn_obx_conn_rsp
+**
+** Description Process OBX connection response.
+**
+** Parameters ccb_idx - Index to the MN control block
+** p_data - Pointer to the MN event data
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_mse_mn_obx_conn_rsp(UINT8 ccb_idx, tBTA_MSE_DATA *p_data)
+{
+ tBTA_MSE_MN_CB *p_cb = BTA_MSE_GET_MN_CB_PTR(ccb_idx);
+ tBTA_MSE_OBX_EVT *p_evt = &p_data->obx_evt;
+ tBTA_MSE param;
+ UINT8 mas_insatnce_id;
+
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT1("bta_mse_mn_obx_conn_rsp ccb idx=%d ",ccb_idx);
+#endif
+
+ p_cb->peer_mtu = p_data->obx_evt.param.conn.mtu;
+ p_cb->obx_handle = p_evt->handle;
+
+ if (p_cb->sdp_service == UUID_SERVCLASS_MESSAGE_NOTIFICATION)
+ {
+ bdcpy(param.mn_open.bd_addr ,p_cb->bd_addr);
+ BCM_STRNCPY_S((char *)param.mn_open.dev_name, sizeof(param.mn_open.dev_name), "",
+ BTM_MAX_REM_BD_NAME_LEN);
+ if (bta_mse_mn_get_first_inst_id(ccb_idx, &mas_insatnce_id))
+ {
+ param.mn_open.first_mas_instance_id = mas_insatnce_id;
+ }
+ else
+ {
+ APPL_TRACE_ERROR0("Unable to find the first instance ID");
+ }
+ }
+
+ /* inform role manager */
+ bta_mse_pm_conn_open(p_cb->bd_addr);
+
+ bta_mse_cb.p_cback(BTA_MSE_MN_OPEN_EVT, &param);
+
+ /* Done with Obex packet */
+ utl_freebuf((void**)&p_evt->p_pkt);
+}
+/*******************************************************************************
+**
+** Function bta_mse_mn_close
+**
+** Description Process the connection close event.
+**
+** Parameters ccb_idx - Index to the MN control block
+** p_data - Pointer to the MN event data
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_mse_mn_close(UINT8 ccb_idx, tBTA_MSE_DATA *p_data)
+{
+ tBTA_MSE_MN_CB *p_cb = BTA_MSE_GET_MN_CB_PTR(ccb_idx);
+
+
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT1("bta_mse_mn_close ccb idx=%d ",ccb_idx);
+#endif
+
+ bta_mse_mn_remove_all_inst_ids(ccb_idx);
+
+ /* finished if not waiting on a call-in function */
+ if (!p_cb->sdp_pending && !p_cb->cout_active)
+ bta_mse_mn_sm_execute(ccb_idx, BTA_MSE_MN_CLOSE_CMPL_EVT, p_data);
+}
+/*******************************************************************************
+**
+** Function bta_mse_mn_send_notif
+**
+** Description Process send notification request
+**
+** Parameters ccb_idx - Index to the MN control block
+** p_data - Pointer to the MN event data
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_mse_mn_send_notif(UINT8 ccb_idx, tBTA_MSE_DATA *p_data)
+{
+ tBTA_MSE_MN_CB *p_cb = BTA_MSE_GET_MN_CB_PTR(ccb_idx);
+ tBTA_MSE_MN_API_SEND_NOTIF *p_evt = &p_data->mn_send_notif;
+ UINT8 *p_buffer;
+ UINT16 buffer_len;
+ tBTA_MA_STATUS status = BTA_MA_STATUS_FAIL;
+
+
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT1("bta_mse_mn_send_notif ccb_idx=%d ",ccb_idx);
+#endif
+
+ if ( (p_cb->req_pending == TRUE) &&
+ (p_cb->obx_oper == BTA_MSE_MN_OP_PUT_EVT_RPT))
+ {
+ /* only one pending request per Obex connection is allowed */
+ bta_mse_mn_send_notif_evt(p_evt->mas_instance_id,
+ BTA_MA_STATUS_NO_RESOURCE,
+ p_cb->bd_addr);
+ return;
+ }
+
+ memset(&(p_cb->msg_notif), 0, sizeof(tBTA_MSE_MN_MSG_NOTIF));
+
+ if ((p_buffer = (UINT8 *)GKI_getbuf(BTA_MSE_MN_MAX_MSG_EVT_OBECT_SIZE)) != NULL)
+ {
+ /* Build the Message Event Object */
+ buffer_len = BTA_MSE_MN_MAX_MSG_EVT_OBECT_SIZE;
+ status = bta_mse_build_map_event_rpt_obj( p_evt->notif_type,
+ p_evt->handle,
+ p_evt->p_folder,
+ p_evt->p_old_folder,
+ p_evt->msg_type,
+ &buffer_len,
+ p_buffer);
+ if (status == BTA_MA_STATUS_OK)
+ {
+ p_cb->msg_notif.p_buffer = p_buffer;
+ p_cb->msg_notif.buffer_len = buffer_len;
+ p_cb->msg_notif.bytes_sent = 0;
+ p_cb->msg_notif.mas_instance_id = p_evt->mas_instance_id;
+ status = bta_mse_mn_cont_send_notif(ccb_idx, TRUE);
+ }
+ }
+
+ if ( status != BTA_MA_STATUS_OK)
+ {
+ bta_mse_mn_send_notif_evt(p_evt->mas_instance_id,
+ BTA_MA_STATUS_NO_RESOURCE,
+ p_cb->bd_addr);
+ bta_mse_mn_clean_send_notif(ccb_idx);
+ }
+
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT1("status=%d ",status );
+#endif
+}
+/*******************************************************************************
+**
+** Function bta_mse_mn_put_rsp
+**
+** Description Process the obx PUT response.
+**
+** Parameters ccb_idx - Index to the MN control block
+** p_data - Pointer to the MN event data
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_mse_mn_put_rsp(UINT8 ccb_idx, tBTA_MSE_DATA *p_data)
+{
+ tBTA_MSE_MN_CB *p_cb = BTA_MSE_GET_MN_CB_PTR(ccb_idx);
+ tBTA_MSE_OBX_EVT *p_evt = &p_data->obx_evt;
+ tBTA_MSE_MN_MSG_NOTIF *p_msg_notif = &p_cb->msg_notif;
+ tBTA_MA_STATUS status = BTA_MA_STATUS_FAIL;
+
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT2("bta_mse_mn_put_rsp ccb idx=%d rsp_code=%d",
+ ccb_idx, p_evt->rsp_code);
+#endif
+
+ p_cb->req_pending = FALSE;
+ /* Done with Obex packet */
+ utl_freebuf((void**)&p_evt->p_pkt);
+
+ if (p_cb->obx_oper == BTA_MSE_MN_OP_PUT_EVT_RPT)
+ {
+ /* If not finished with Put, start another read */
+ if (p_evt->rsp_code == OBX_RSP_CONTINUE)
+ bta_mse_mn_cont_send_notif(ccb_idx, FALSE);
+ else
+ {
+ /* done with obex operation */
+ if ( p_evt->rsp_code == OBX_RSP_OK ) status = BTA_MA_STATUS_OK;
+ bta_mse_mn_send_notif_evt(p_msg_notif->mas_instance_id, status,
+ p_cb->bd_addr);
+ bta_mse_mn_clean_send_notif(ccb_idx);
+ }
+ }
+}
+/*******************************************************************************
+**
+** Function bta_mse_mn_close_compl
+**
+** Description Process the close complete event.
+**
+** Parameters ccb_idx - Index to the MN control block
+** p_data - Pointer to the MN event data
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_mse_mn_close_compl(UINT8 ccb_idx, tBTA_MSE_DATA *p_data)
+{
+ tBTA_MSE_MN_CB *p_cb = BTA_MSE_GET_MN_CB_PTR(ccb_idx);
+ tBTA_MSE param;
+
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT1("bta_mse_mn_close_compl ccb idx=%d ",ccb_idx);
+#endif
+
+ /* free discovery data base */
+ utl_freebuf((void**)&p_cb->p_db);
+ p_cb->sdp_pending = FALSE;
+
+ p_cb->cout_active = FALSE;
+ bta_mse_mn_stop_timer(ccb_idx, BTA_MSE_TIMER_OP_ALL);
+ bta_mse_mn_clean_send_notif(ccb_idx);
+ /* inform role manager */
+ bta_mse_pm_conn_close(p_cb->bd_addr);
+ bdcpy(param.mn_close.bd_addr ,p_cb->bd_addr);
+ bta_mse_cb.p_cback(BTA_MSE_MN_CLOSE_EVT, &param);
+ memset(p_cb, 0 , sizeof(tBTA_MSE_MN_CB));
+}
+
+/*******************************************************************************
+**
+** Function bta_mse_mn_abort
+**
+** Description Process the abort event.
+**
+** Parameters ccb_idx - Index to the MN control block
+** p_data - Pointer to the MN event data
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_mse_mn_abort(UINT8 ccb_idx, tBTA_MSE_DATA *p_data)
+{
+ tBTA_MSE_MN_CB *p_cb = BTA_MSE_GET_MN_CB_PTR(ccb_idx);
+
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT1("bta_mse_mn_abort ccb idx=%d ",ccb_idx);
+#endif
+ /* Abort an active request */
+ if (p_cb->obx_oper != BTA_MSE_MN_OP_NONE)
+ {
+ p_cb->aborting = BTA_MSE_MN_ABORT_REQ_NOT_SENT;
+
+ /* Issue the abort request only if no request pending.
+ * some devices do not like out of sequence aborts even though
+ * the spec allows it */
+ if (!p_cb->req_pending)
+ {
+ /* Start abort response timer */
+ bta_mse_mn_start_timer(ccb_idx, BTA_MSE_TIMER_OP_ABORT);
+ OBX_AbortReq(p_cb->obx_handle, (BT_HDR *)NULL);
+ p_cb->aborting = BTA_MSE_MN_ABORT_REQ_SENT;
+ }
+ }
+}
+
+/*******************************************************************************
+**
+** Function bta_mse_mn_abort_rsp
+**
+** Description Process the abort response event.
+**
+** Parameters ccb_idx - Index to the MN control block
+** p_data - Pointer to the MN event data
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_mse_mn_abort_rsp(UINT8 ccb_idx, tBTA_MSE_DATA *p_data)
+{
+ tBTA_MSE_MN_CB *p_cb = BTA_MSE_GET_MN_CB_PTR(ccb_idx);
+ tBTA_MSE_OBX_EVT *p_evt = &p_data->obx_evt;
+ tBTA_MSE_MN_MSG_NOTIF *p_msg_notif = &p_cb->msg_notif;
+ tBTA_MA_STATUS status = BTA_MA_STATUS_FAIL;
+
+
+ bta_mse_mn_stop_timer(ccb_idx,BTA_MSE_TIMER_OP_ABORT);
+
+ /* Done with Obex packet */
+ utl_freebuf((void**)&p_evt->p_pkt);
+
+ if (p_cb->obx_oper != BTA_MSE_MN_OP_NONE)
+ {
+ if (p_cb->obx_oper == BTA_MSE_MN_OP_PUT_EVT_RPT )
+ {
+ bta_mse_mn_send_notif_evt(p_msg_notif->mas_instance_id, status,
+ p_cb->bd_addr);
+ bta_mse_mn_clean_send_notif(ccb_idx);
+ }
+ }
+}
+
+/*******************************************************************************
+**
+** Function bta_mse_mn_sdp_fail
+**
+** Description Process the SDP fail event.
+**
+** Parameters ccb_idx - Index to the MN control block
+** p_data - Pointer to the MN event data
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_mse_mn_sdp_fail(UINT8 ccb_idx, tBTA_MSE_DATA *p_data)
+{
+ tBTA_MSE_MN_CB *p_cb = BTA_MSE_GET_MN_CB_PTR(ccb_idx);
+
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT1("bta_mse_mn_sdp_fail ccb idx=%d ",ccb_idx);
+#endif
+ /* free discovery data base */
+ utl_freebuf((void**)&p_cb->p_db);
+ p_cb->sdp_pending = FALSE;
+ bta_mse_mn_sm_execute(ccb_idx, BTA_MSE_MN_OBX_CLOSE_EVT, p_data);
+}
+
+/*******************************************************************************
+**
+** Function bta_mse_mn_obx_tout
+**
+** Description Process the obx timeout event.
+**
+** Parameters ccb_idx - Index to the MN control block
+** p_data - Pointer to the MN event data
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_mse_mn_obx_tout(UINT8 ccb_idx, tBTA_MSE_DATA *p_data)
+{
+ tBTA_MSE_MN_CB *p_cb = BTA_MSE_GET_MN_CB_PTR(ccb_idx);
+
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT1("bta_mse_mn_obx_tout ccb idx=%d ",ccb_idx);
+#endif
+
+ if (p_cb->req_pending)
+ {
+ if (p_cb->obx_oper == BTA_MSE_MN_OP_PUT_EVT_RPT)
+ {
+ bta_mse_mn_send_notif_evt( p_cb->msg_notif.mas_instance_id,
+ BTA_MA_STATUS_FAIL,
+ p_cb->bd_addr);
+ bta_mse_mn_clean_send_notif(ccb_idx);
+ }
+ }
+}
+/*******************************************************************************
+**
+** Function bta_mse_mn_ignore_obx
+**
+** Description Ignore OBX event.
+**
+** Parameters ccb_idx - Index to the MN control block
+** p_data - Pointer to the MN event data
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_mse_mn_ignore_obx(UINT8 ccb_idx, tBTA_MSE_DATA *p_data)
+{
+
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT1("bta_mse_mn_ignore_obx ccb idx=%d ",ccb_idx);
+#endif
+
+ utl_freebuf((void **) &p_data->obx_evt.p_pkt);
+}
+
+
+
+/*****************************************************************************
+** MNC Callback Functions
+*****************************************************************************/
+
+/*******************************************************************************
+**
+** Function bta_mse_mn_obx_cback
+**
+** Description OBX callback function.
+**
+** Parameters handle - Handle for Obex session
+** obx_event - Obex event
+** rsp_code - Obex response code
+** param - event parameters
+** p_pkt - pointer to Obex packet
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_mse_mn_obx_cback (tOBX_HANDLE handle, tOBX_EVENT obx_event, UINT8 rsp_code,
+ tOBX_EVT_PARAM param, BT_HDR *p_pkt)
+{
+ tBTA_MSE_OBX_EVT *p_obx_msg;
+ UINT16 event = 0;
+
+
+
+ switch (obx_event)
+ {
+ case OBX_CONNECT_RSP_EVT:
+ if (rsp_code == OBX_RSP_OK)
+ {
+ event = BTA_MSE_MN_OBX_CONN_RSP_EVT;
+ }
+ else /* Obex will disconnect underneath BTA */
+ {
+ APPL_TRACE_WARNING1("MN_OBX_CBACK: Bad connect response 0x%02x", rsp_code);
+ if (p_pkt)
+ GKI_freebuf(p_pkt);
+ return;
+ }
+ break;
+ case OBX_PUT_RSP_EVT:
+ event = BTA_MSE_MN_OBX_PUT_RSP_EVT;
+ break;
+ case OBX_CLOSE_IND_EVT:
+ event = BTA_MSE_MN_OBX_CLOSE_EVT;
+ break;
+ case OBX_TIMEOUT_EVT:
+ event = BTA_MSE_MN_OBX_TOUT_EVT;
+ break;
+ case OBX_ABORT_RSP_EVT:
+ event = BTA_MSE_MN_OBX_ABORT_RSP_EVT;
+ break;
+ case OBX_PASSWORD_EVT:
+ case OBX_GET_RSP_EVT:
+ case OBX_SETPATH_RSP_EVT:
+ default:
+ /* case OBX_DISCONNECT_RSP_EVT: Handled when OBX_CLOSE_IND_EVT arrives */
+ if (p_pkt)
+ GKI_freebuf(p_pkt);
+ return;
+ }
+
+
+
+ if (event && (p_obx_msg =
+ (tBTA_MSE_OBX_EVT *) GKI_getbuf(sizeof(tBTA_MSE_OBX_EVT))) != NULL)
+ {
+#if (BTA_MSE_DEBUG == TRUE) && (BT_USE_TRACES == TRUE)
+ APPL_TRACE_DEBUG1("MN OBX Event Callback: mn_obx_event [%s]",
+ bta_mse_obx_evt_code(event));
+#endif
+ /* send event to BTA, if any */
+ p_obx_msg->hdr.event = event;
+ p_obx_msg->hdr.layer_specific = 0xFFFF; /* not used */
+ p_obx_msg->obx_event = obx_event;
+ p_obx_msg->handle = handle;
+ p_obx_msg->rsp_code = rsp_code;
+ p_obx_msg->param = param;
+ p_obx_msg->p_pkt = p_pkt;
+
+ bta_sys_sendmsg(p_obx_msg);
+ }
+}
+
+
+/*****************************************************************************
+** Local MSE Event Processing Functions
+*****************************************************************************/
+
+/*******************************************************************************
+**
+** Function bta_mse_req_app_access
+**
+** Description Sends an access request event to the application.
+**
+** Parameters ccb_idx - Index to the MN control block
+** p_data - Pointer to the MN event data
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_mse_req_app_access (UINT8 inst_idx, UINT8 sess_idx, tBTA_MSE_DATA *p_data)
+{
+ tBTA_MSE_MA_SESS_CB *p_cb = BTA_MSE_GET_SESS_CB_PTR(inst_idx, sess_idx);
+ tBTA_MSE_ACCESS *p_acc_evt;
+ char *p_devname;
+
+
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT2("bta_mse_req_app_access inst idx=%d sess idx=%d",
+ inst_idx, sess_idx);
+#endif
+
+ /* Ask application for the operation's access permission */
+ if ((p_acc_evt = (tBTA_MSE_ACCESS *)GKI_getbuf((UINT16) (sizeof(tBTA_MSE_ACCESS)+
+ (p_bta_fs_cfg->max_path_len + 1)))) != NULL)
+ {
+ memset(p_acc_evt, 0, sizeof(tBTA_MSE_ACCESS));
+ p_acc_evt->p_path = (char *) (p_acc_evt+1);
+ p_acc_evt->p_path[0]='\0';
+
+ APPL_TRACE_API1("MSE ACCESS REQ: Oper=%d", p_cb->oper);
+ switch (p_cb->oper)
+ {
+ case BTA_MSE_OPER_SETPATH:
+ BCM_STRNCPY_S(p_acc_evt->p_path, p_bta_fs_cfg->max_path_len+1,
+ p_cb->sp.p_path, p_bta_fs_cfg->max_path_len);
+ break;
+
+ case BTA_MSE_OPER_GET_MSG_LIST:
+ BCM_STRNCPY_S(p_acc_evt->p_path, p_bta_fs_cfg->max_path_len+1,
+ p_cb->ml_param.p_path, p_bta_fs_cfg->max_path_len);
+ break;
+
+ case BTA_MSE_OPER_GET_MSG:
+ memcpy(p_acc_evt->handle, p_cb->msg_param.data.handle,
+ sizeof(tBTA_MA_MSG_HANDLE));
+ break;
+ case BTA_MSE_OPER_PUSH_MSG:
+ memset(p_acc_evt->handle, 0, sizeof(tBTA_MA_MSG_HANDLE));
+ BCM_STRNCPY_S(p_acc_evt->p_path, p_bta_fs_cfg->max_path_len+1,
+ p_cb->push_msg.param.p_folder, p_bta_fs_cfg->max_path_len);
+ break;
+ case BTA_MSE_OPER_DEL_MSG:
+ memcpy(p_acc_evt->handle, p_cb->set_msg_sts.handle,
+ sizeof(tBTA_MA_MSG_HANDLE));
+ p_acc_evt->delete_sts = p_cb->set_msg_sts.sts_val;
+ break;
+ default:
+ break;
+ }
+
+ p_acc_evt->oper = p_cb->oper;
+ p_acc_evt->mas_session_id = (tBTA_MA_SESS_HANDLE) p_cb->obx_handle;
+ bdcpy(p_acc_evt->bd_addr, p_cb->bd_addr);
+ if ((p_devname = BTM_SecReadDevName(p_cb->bd_addr)) != NULL)
+ BCM_STRNCPY_S((char *)p_acc_evt->dev_name, sizeof(p_acc_evt->dev_name), p_devname, BTM_MAX_REM_BD_NAME_LEN);
+
+ bta_mse_cb.p_cback(BTA_MSE_ACCESS_EVT, (tBTA_MSE *)p_acc_evt);
+ GKI_freebuf(p_acc_evt);
+ }
+}
+
+/*****************************************************************************
+** Debug Functions
+*****************************************************************************/
+#if (BTA_MSE_DEBUG == TRUE) && (BT_USE_TRACES == TRUE)
+
+/*******************************************************************************
+**
+** Function bta_mse_obx_evt_code
+**
+** Description get the obx event string pointer
+**
+** Parameters evt_code - obex event code
+**
+** Returns char * - event string pointer
+**
+*******************************************************************************/
+static char *bta_mse_obx_evt_code(UINT16 evt_code)
+{
+ switch (evt_code)
+ {
+ case BTA_MSE_MA_OBX_CONN_EVT:
+ return "BTA_MSE_MA_OBX_CONN_EVT";
+ case BTA_MSE_MA_OBX_DISC_EVT:
+ return "BTA_MSE_MA_OBX_DISC_EVT";
+ case BTA_MSE_MA_OBX_PUT_EVT:
+ return "BTA_MSE_MA_OBX_PUT_EVT";
+ case BTA_MSE_MA_OBX_GET_EVT:
+ return "BTA_MSE_MA_OBX_GET_EVT";
+ case BTA_MSE_MA_OBX_SETPATH_EVT:
+ return "BTA_MSE_MA_OBX_SETPATH_EVT";
+ case BTA_MSE_MA_OBX_ABORT_EVT:
+ return "BTA_MSE_MA_OBX_ABORT_EVT";
+ case BTA_MSE_MA_OBX_CLOSE_EVT:
+ return "BTA_MSE_MA_OBX_CLOSE_EVT";
+ case BTA_MSE_MN_OBX_TOUT_EVT:
+ return "BTA_MSE_MN_OBX_TOUT_EVT";
+ case BTA_MSE_MN_OBX_CONN_RSP_EVT:
+ return "BTA_MSE_MN_OBX_CONN_RSP_EVT";
+ case BTA_MSE_MN_OBX_PUT_RSP_EVT:
+ return "BTA_MSE_MN_OBX_PUT_RSP_EVT";
+ case BTA_MSE_MN_OBX_CLOSE_EVT:
+ return "BTA_MSE_MN_OBX_CLOSE_EVT";
+ case BTA_MSE_MN_OBX_ABORT_RSP_EVT:
+ return"BTA_MSE_MN_OBX_ABORT_RSP_EVT";
+ default:
+ return "unknown MSE OBX event code";
+ }
+}
+#endif /* Debug Functions */
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#endif /* BTA_MSE_INCLUDED */
diff --git a/bta/ma/bta_mse_api.c b/bta/ma/bta_mse_api.c
new file mode 100644
index 0000000..5a2fd29
--- /dev/null
+++ b/bta/ma/bta_mse_api.c
@@ -0,0 +1,437 @@
+/*****************************************************************************
+**
+** Name: bta_mse_api.c
+**
+** Description: This is the implementation of the API for the Message
+** Acess Server subsystem of BTA, Broadcom Corp's Bluetooth
+** application layer for mobile phones.
+**
+** Copyright (c) 2009-2011 Broadcom Corp., All Rights Reserved.
+** Broadcom Bluetooth Core. Proprietary and confidential.
+**
+*****************************************************************************/
+
+#include "bt_target.h"
+
+#if defined(BTA_MSE_INCLUDED) && (BTA_MSE_INCLUDED == TRUE)
+
+#include <string.h>
+#include "gki.h"
+#include "bd.h"
+#include "bta_ma_def.h"
+#include "bta_mse_api.h"
+#include "bta_fs_api.h"
+#include "bta_mse_int.h"
+
+/*****************************************************************************
+** Constants
+*****************************************************************************/
+static const tBTA_SYS_REG bta_mse_reg =
+{
+ bta_mse_hdl_event,
+ BTA_MseDisable
+};
+
+/*******************************************************************************
+**
+** Function BTA_MseEnable
+**
+** Description Enable the MSE subsystems. This function must be
+** called before any other functions in the MSE API are called.
+** When the enable operation is completed the callback function
+** will be called with an BTA_MSE_ENABLE_EVT event.
+**
+** Parameters p_cback - MSE event call back function
+** app_id - Application ID
+**
+** Returns void
+**
+*******************************************************************************/
+void BTA_MseEnable(tBTA_MSE_CBACK *p_cback, UINT8 app_id)
+{
+ tBTA_MSE_API_ENABLE *p_buf;
+
+ /* register with BTA system manager */
+ GKI_sched_lock();
+ bta_sys_register(BTA_ID_MSE, &bta_mse_reg);
+ GKI_sched_unlock();
+
+ if ((p_buf = (tBTA_MSE_API_ENABLE *)GKI_getbuf(sizeof(tBTA_MSE_API_ENABLE))) != NULL)
+ {
+ p_buf->hdr.event = BTA_MSE_API_ENABLE_EVT;
+ p_buf->p_cback = p_cback;
+ p_buf->app_id = app_id;
+
+ bta_sys_sendmsg(p_buf);
+ }
+}
+
+/*******************************************************************************
+**
+** Function BTA_MseDisable
+**
+** Description Disable the MSE subsystem.
+**
+** Returns void
+**
+*******************************************************************************/
+void BTA_MseDisable(void)
+{
+ BT_HDR *p_buf;
+
+ bta_sys_deregister(BTA_ID_MSE);
+ if ((p_buf = (BT_HDR *)GKI_getbuf(sizeof(BT_HDR))) != NULL)
+ {
+ p_buf->event = BTA_MSE_API_DISABLE_EVT;
+ bta_sys_sendmsg(p_buf);
+ }
+}
+
+/*******************************************************************************
+**
+** Function BTA_MseStart
+**
+** Description Start a MA server on the MSE
+**
+**
+** Parameters mas_inst_id - MAS instance ID
+** sec_mask - Security Setting Mask
+** MSE always enables
+** (BTA_SEC_AUTHENTICATE | BTA_SEC_ENCRYPT)
+** p_service_name - Pointer to service name
+** p_root_path - Pointer to root path
+** (one level above telecom)
+** sup_msg_type - supported message type(s)
+**
+** Returns void
+**
+*******************************************************************************/
+void BTA_MseStart( tBTA_MA_INST_ID mas_inst_id,
+ tBTA_SEC sec_mask, const char *p_service_name,
+ const char *p_root_path,
+ tBTA_MA_MSG_TYPE sup_msg_type)
+{
+ tBTA_MSE_API_START *p_buf;
+
+ if ((p_buf = (tBTA_MSE_API_START *)GKI_getbuf((UINT16)(sizeof(tBTA_MSE_API_START) +
+ p_bta_fs_cfg->max_path_len + 1))) != NULL)
+ {
+ p_buf->p_root_path = (char *)(p_buf + 1);
+ p_buf->hdr.event = BTA_MSE_API_START_EVT;
+ p_buf->mas_inst_id = mas_inst_id;
+ p_buf->sec_mask = (sec_mask | BTA_SEC_AUTHENTICATE | BTA_SEC_ENCRYPT);
+ p_buf->sup_msg_type = sup_msg_type;
+
+
+ if (p_service_name)
+ {
+ BCM_STRNCPY_S(p_buf->servicename, sizeof(p_buf->servicename), p_service_name, BTA_SERVICE_NAME_LEN);
+ p_buf->servicename[BTA_SERVICE_NAME_LEN] = '\0';
+ }
+ else
+ p_buf->servicename[0]= '\0';
+
+ if (p_root_path)
+ {
+ BCM_STRNCPY_S(p_buf->p_root_path, p_bta_fs_cfg->max_path_len+1, p_root_path, p_bta_fs_cfg->max_path_len);
+ p_buf->p_root_path[p_bta_fs_cfg->max_path_len] = '\0';
+ }
+ else
+ p_buf->p_root_path[0] = '\0';
+
+ bta_sys_sendmsg(p_buf);
+ }
+}
+
+/*******************************************************************************
+**
+** Function BTA_MseStop
+**
+** Description Stop a MA server on the MSE
+**
+** Parameters mas_instance_id - MAS Instance ID
+**
+** Returns void
+**
+*******************************************************************************/
+void BTA_MseStop (tBTA_MA_INST_ID mas_instance_id)
+{
+ tBTA_MSE_API_STOP *p_buf;
+
+ if ((p_buf = (tBTA_MSE_API_STOP *)GKI_getbuf((UINT16)(sizeof(tBTA_MSE_API_STOP)))) != NULL)
+ {
+ p_buf->hdr.event = BTA_MSE_API_STOP_EVT;
+ p_buf->mas_inst_id = mas_instance_id;
+ bta_sys_sendmsg(p_buf);
+ }
+}
+
+/*******************************************************************************
+**
+** Function BTA_MseClose
+**
+** Description Close all MAS sessions on the specified MAS Instance ID
+**
+** Parameters mas_instance_id - MAS Inatance ID
+**
+** Returns void
+**
+*******************************************************************************/
+void BTA_MseClose(tBTA_MA_INST_ID mas_instance_id)
+{
+
+ tBTA_MSE_API_CLOSE *p_buf;
+
+ if ((p_buf = (tBTA_MSE_API_CLOSE *)GKI_getbuf((UINT16)(sizeof(tBTA_MSE_API_CLOSE)))) != NULL)
+ {
+ p_buf->hdr.event = BTA_MSE_API_CLOSE_EVT;
+ p_buf->mas_instance_id = mas_instance_id;
+ bta_sys_sendmsg(p_buf);
+ }
+}
+
+/*******************************************************************************
+**
+** Function BTA_MseMaClose
+**
+** Description Close a MAS sessions on the specified BD address
+**
+** Parameters bd_addr - remote BD's address
+** mas_instance_id - MAS Inatance ID
+**
+** Returns void
+**
+*******************************************************************************/
+void BTA_MseMaClose(BD_ADDR bd_addr, tBTA_MA_INST_ID mas_instance_id)
+{
+ tBTA_MSE_API_MA_CLOSE *p_buf;
+
+ if ((p_buf = (tBTA_MSE_API_MA_CLOSE *)GKI_getbuf((UINT16)(sizeof(tBTA_MSE_API_MA_CLOSE)))) != NULL)
+ {
+ memset(p_buf, 0, sizeof(tBTA_MSE_API_MA_CLOSE));
+
+ p_buf->hdr.event = BTA_MSE_API_MA_CLOSE_EVT;
+ bdcpy(p_buf->bd_addr, bd_addr);
+ p_buf->mas_instance_id = mas_instance_id;
+ bta_sys_sendmsg(p_buf);
+ }
+}
+/*******************************************************************************
+**
+** Function BTA_MseMnClose
+**
+** Description Close a MN session
+**
+** Parameters bd_addr - remote BD's address
+**
+** Returns void
+**
+*******************************************************************************/
+void BTA_MseMnClose(BD_ADDR bd_addr)
+{
+ tBTA_MSE_API_MN_CLOSE *p_buf;
+
+ if ((p_buf = (tBTA_MSE_API_MN_CLOSE *)GKI_getbuf((UINT16)(sizeof(tBTA_MSE_API_MN_CLOSE)))) != NULL)
+ {
+ p_buf->hdr.event = BTA_MSE_API_MN_CLOSE_EVT;
+ bdcpy(p_buf->bd_addr, bd_addr);
+ bta_sys_sendmsg(p_buf);
+ }
+}
+
+/*******************************************************************************
+**
+** Function BTA_MseAccessRsp
+**
+** Description Send a response for the access request
+**
+** Parameters mas_session_id - MAS session ID
+** oper - MAS operation type
+** access - Access is allowed or not
+** p_path - pointer to a path if if the operation
+** involves accessing a folder
+** Returns void
+**
+*******************************************************************************/
+void BTA_MseAccessRsp(tBTA_MA_SESS_HANDLE mas_session_id, tBTA_MSE_OPER oper,
+ tBTA_MA_ACCESS_TYPE access, char *p_path)
+{
+ tBTA_MSE_API_ACCESSRSP *p_acc_rsp;
+ UINT16 path_len;
+
+ /* If directory is specified set the length */
+ path_len = (p_path && *p_path != '\0') ? (UINT16)(strlen(p_path) + 1): 1;
+
+ if ((p_acc_rsp = (tBTA_MSE_API_ACCESSRSP *)GKI_getbuf((UINT16)(sizeof(tBTA_MSE_API_ACCESSRSP)
+ + path_len))) != NULL)
+ {
+ p_acc_rsp->mas_session_id = mas_session_id;
+ p_acc_rsp->rsp = access;
+ p_acc_rsp->oper = oper;
+ p_acc_rsp->p_path = (char *)(p_acc_rsp + 1);
+ if (p_path)
+ {
+ BCM_STRNCPY_S(p_acc_rsp->p_path, path_len, p_path, path_len-1);
+ p_acc_rsp->p_path[path_len-1] = '\0';
+ }
+ else
+ p_acc_rsp->p_path[0] = '\0';
+
+ p_acc_rsp->hdr.event = BTA_MSE_API_ACCESSRSP_EVT;
+ bta_sys_sendmsg(p_acc_rsp);
+ }
+}
+/*******************************************************************************
+**
+** Function BTA_MseUpdateInboxRsp
+**
+** Description Send a response for the update inbox request
+**
+**
+** Parameters mas_session_id - MAS session ID
+** update_rsp - update inbox is allowed or not
+**
+** Returns void
+**
+*******************************************************************************/
+void BTA_MseUpdateInboxRsp(tBTA_MA_SESS_HANDLE mas_session_id,
+ tBTA_MSE_UPDATE_INBOX_TYPE update_rsp)
+{
+ tBTA_MSE_API_UPDINBRSP *p_buf;
+
+ if ((p_buf = (tBTA_MSE_API_UPDINBRSP *)GKI_getbuf((UINT16)(sizeof(tBTA_MSE_API_UPDINBRSP)))) != NULL)
+ {
+ p_buf->hdr.event = BTA_MSE_API_UPD_IBX_RSP_EVT;
+ p_buf->mas_session_id = mas_session_id;
+ p_buf->rsp = update_rsp;
+ bta_sys_sendmsg(p_buf);
+ }
+}
+/*******************************************************************************
+**
+** Function BTA_MseSetNotifRegRsp
+**
+** Description Send a response for the set notification registration
+**
+**
+** Parameters mas_session_id - MAS session ID
+** set_notif_reg_rsp - indicate whether the set notification
+** registration is allowed or not
+**
+** Returns void
+**
+*******************************************************************************/
+void BTA_MseSetNotifRegRsp(tBTA_MA_SESS_HANDLE mas_session_id,
+ tBTA_MSE_SET_NOTIF_REG_TYPE set_notif_reg_rsp)
+{
+ tBTA_MSE_API_SETNOTIFREGRSP *p_buf;
+
+ if ((p_buf = (tBTA_MSE_API_SETNOTIFREGRSP *)GKI_getbuf((UINT16)(sizeof(tBTA_MSE_API_UPDINBRSP)))) != NULL)
+ {
+ p_buf->hdr.event = BTA_MSE_API_SET_NOTIF_REG_RSP_EVT;
+ p_buf->mas_session_id = mas_session_id;
+ p_buf->rsp = set_notif_reg_rsp;
+ bta_sys_sendmsg(p_buf);
+ }
+}
+/*******************************************************************************
+**
+** Function BTA_MseSendNotif
+**
+** Description Send a Message notification report to all MCEs registered with
+** the specified MAS instance ID
+**
+** Parameters mas_instance_id - MAS Instance ID
+** notif_type - message notification type
+** handle - message handle
+** p_folder - pointer to current folder
+** p_old_folder - pointer to older folder
+** msg_type - message type (E_MAIL, SMS_GSM, SMS_CDMA, MMS)
+** except_bd_addr - except to the MCE on this BD Address.
+** (Note: notification will be not sent to
+** this BD Addreess)
+**
+** Returns void
+**
+*******************************************************************************/
+void BTA_MseSendNotif(tBTA_MA_INST_ID mas_instance_id,
+ tBTA_MSE_NOTIF_TYPE notif_type,
+ tBTA_MA_MSG_HANDLE handle,
+ char * p_folder, char *p_old_folder,
+ tBTA_MA_MSG_TYPE msg_type,
+ BD_ADDR except_bd_addr)
+{
+ tBTA_MSE_MN_API_SEND_NOTIF *p_buf;
+ UINT16 folder_len, old_folder_len;
+
+ /* If directory is specified set the length */
+ folder_len = (p_folder && *p_folder != '\0') ? (UINT16)(strlen(p_folder) + 1): 0;
+ old_folder_len = (p_old_folder && *p_old_folder != '\0') ? (UINT16)(strlen(p_old_folder) + 1): 0;
+
+ if ((p_buf = (tBTA_MSE_MN_API_SEND_NOTIF *)GKI_getbuf((UINT16) ((UINT16)sizeof(tBTA_MSE_MN_API_SEND_NOTIF) +
+ folder_len +
+ old_folder_len))) != NULL)
+ {
+ p_buf->hdr.event = BTA_MSE_API_SEND_NOTIF_EVT;
+ p_buf->mas_instance_id = mas_instance_id;
+ p_buf->notif_type = notif_type;
+ memcpy(p_buf->handle, handle, sizeof(tBTA_MA_MSG_HANDLE));
+
+ if (folder_len)
+ {
+ p_buf->p_folder = (char *)(p_buf + 1);
+ BCM_STRNCPY_S(p_buf->p_folder, folder_len+1, p_folder, folder_len);
+ }
+ else
+ p_buf->p_folder = NULL;
+
+ if (old_folder_len)
+ {
+ if (folder_len)
+ p_buf->p_old_folder = p_buf->p_folder + folder_len;
+ else
+ p_buf->p_old_folder = (char *)(p_buf + 1);
+
+ BCM_STRNCPY_S(p_buf->p_old_folder, old_folder_len+1, p_old_folder, old_folder_len);
+ }
+ else
+ p_buf->p_old_folder = NULL;
+
+ p_buf->msg_type = msg_type;
+ if (except_bd_addr != NULL)
+ {
+ bdcpy(p_buf->except_bd_addr, except_bd_addr);
+ }
+ else
+ {
+ memset(p_buf->except_bd_addr, 0, sizeof(BD_ADDR));
+ }
+ bta_sys_sendmsg(p_buf);
+ }
+}
+
+/*******************************************************************************
+**
+** Function BTA_MseMnAbort
+**
+** Description Abort the current OBEX multi-packt operation in MN
+**
+** Parameters mas_instance_id - MAS Instance ID
+**
+** Returns void
+**
+*******************************************************************************/
+void BTA_MseMnAbort(tBTA_MA_INST_ID mas_instance_id)
+{
+ tBTA_MSE_MN_API_ABORT *p_buf;
+
+ if ((p_buf = (tBTA_MSE_MN_API_ABORT *)GKI_getbuf((UINT16)(sizeof(tBTA_MSE_MN_API_ABORT)))) != NULL)
+ {
+ p_buf->hdr.event = BTA_MSE_API_MN_ABORT_EVT;
+ p_buf->mas_instance_id = mas_instance_id;
+ bta_sys_sendmsg(p_buf);
+ }
+}
+
+
+#endif /* BTA_MSE_INCLUDED */
diff --git a/bta/ma/bta_mse_cfg.c b/bta/ma/bta_mse_cfg.c
new file mode 100644
index 0000000..69953d0
--- /dev/null
+++ b/bta/ma/bta_mse_cfg.c
@@ -0,0 +1,31 @@
+/*****************************************************************************
+**
+** Name: bta_mse_cfg.c
+**
+** Description: This file contains compile-time configurable constants
+** for the MSE subsystem.
+**
+** Copyright (c) 2009, Broadcom Corp., All Rights Reserved.
+** Broadcom Bluetooth Core. Proprietary and confidential.
+**
+*****************************************************************************/
+
+#include "bta_mse_api.h"
+
+#ifndef BTA_MSE_MAX_NAME_LEN
+ #define BTA_MSE_MAX_NAME_LEN 256
+#endif
+
+#ifndef BTA_MSE_OBX_RSP_TOUT
+ #define BTA_MSE_OBX_RSP_TOUT 2000
+#endif
+
+
+const tBTA_MSE_CFG bta_mse_cfg =
+{
+ BTA_MSE_OBX_RSP_TOUT,
+ BTA_MSE_MAX_NAME_LEN
+};
+
+tBTA_MSE_CFG *p_bta_mse_cfg = (tBTA_MSE_CFG *)&bta_mse_cfg;
+
diff --git a/bta/ma/bta_mse_ci.c b/bta/ma/bta_mse_ci.c
new file mode 100644
index 0000000..dfaeb7e
--- /dev/null
+++ b/bta/ma/bta_mse_ci.c
@@ -0,0 +1,251 @@
+/*****************************************************************************
+**
+** Name: bta_mse_ci.c
+**
+** Description: This is the implementaion for the Message Server Equipment
+** (MSE) subsystem call-in functions.
+**
+** Copyright (c) 2009, Broadcom Corp., All Rights Reserved.
+** Broadcom Bluetooth Core. Proprietary and confidential.
+**
+*****************************************************************************/
+#include <stdio.h>
+#include <string.h>
+#include "bta_api.h"
+#include "bta_ma_def.h"
+#include "bta_mse_api.h"
+#include "bta_mse_co.h"
+#include "bta_mse_int.h"
+#include "bta_mse_ci.h"
+
+/*******************************************************************************
+**
+** Function bta_mse_ci_get_folder_entry
+**
+** Description This function is called in response to the
+** bta_mse_co_get_folder_entry call-out function.
+**
+** Parameters mas_session_id - MAS session ID
+** status - BTA_MA_STATUS_OK if p_entry points to a valid entry.
+** BTA_MA_STATUS_EODIR if no more entries (p_entry is ignored).
+** BTA_MA_STATUS_FAIL if any errors have occurred.
+** evt - evt from the call-out function
+**
+** Returns void
+**
+*******************************************************************************/
+BTA_API extern void bta_mse_ci_get_folder_entry(tBTA_MA_SESS_HANDLE mas_session_id,
+ tBTA_MA_STATUS status,
+ UINT16 evt)
+{
+ tBTA_MSE_CI_GET_FENTRY *p_evt;
+
+ if ((p_evt = (tBTA_MSE_CI_GET_FENTRY *)GKI_getbuf(sizeof(tBTA_MSE_CI_GET_FENTRY))) != NULL)
+ {
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT2("bta_mse_ci_get_folder_entry sess_id=%d, status=%d \n",
+ mas_session_id, status);
+#endif
+ p_evt->hdr.event = evt;
+ p_evt->mas_session_id = mas_session_id;
+ p_evt->status = status;
+ bta_sys_sendmsg(p_evt);
+ }
+}
+/*******************************************************************************
+**
+** Function bta_mse_ci_get_msg_list_info
+**
+** Description This function is called in response to the
+** bta_mse_co_get_msg_list_info call-out function.
+**
+** Parameters mas_session_id - MAS session ID
+** status - BTA_MA_STATUS_OK operation is successful.
+** BTA_MA_STATUS_FAIL if any errors have occurred.
+** evt - evt from the call-out function
+**
+** Returns void
+**
+*******************************************************************************/
+BTA_API extern void bta_mse_ci_get_msg_list_info(tBTA_MA_SESS_HANDLE mas_session_id,
+ tBTA_MA_STATUS status,
+ UINT16 evt)
+{
+ tBTA_MSE_CI_GET_ML_INFO *p_evt;
+
+ if ((p_evt = (tBTA_MSE_CI_GET_ML_INFO *)GKI_getbuf(sizeof(tBTA_MSE_CI_GET_ML_INFO))) != NULL)
+ {
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT2("bta_mse_ci_get_msg_list_info sess_id=%d, status=%d \n",
+ mas_session_id, status);
+#endif
+ p_evt->hdr.event = evt;
+ p_evt->mas_session_id = mas_session_id;
+ p_evt->status = status;
+ bta_sys_sendmsg(p_evt);
+ }
+}
+
+/*******************************************************************************
+**
+** Function bta_mse_ci_get_msg_list_entry
+**
+** Description This function is called in response to the
+** bta_mse_co_get_msg_list_entry call-out function.
+**
+** Parameters mas_session_id - MAS session ID
+** status - BTA_MA_STATUS_OK if p_entry points to a valid entry.
+** BTA_MA_STATUS_EODIR if no more entries (p_entry is ignored).
+** BTA_MA_STATUS_FAIL if any errors have occurred.
+** evt - evt from the call-out function
+**
+** Returns void
+**
+*******************************************************************************/
+BTA_API extern void bta_mse_ci_get_msg_list_entry(tBTA_MA_SESS_HANDLE mas_session_id,
+ tBTA_MA_STATUS status,
+ UINT16 evt)
+{
+ tBTA_MSE_CI_GET_ML_ENTRY *p_evt;
+
+ if ((p_evt = (tBTA_MSE_CI_GET_ML_ENTRY *)GKI_getbuf(sizeof(tBTA_MSE_CI_GET_ML_ENTRY))) != NULL)
+ {
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT2("bta_mse_ci_get_msg_list_entry sess_id=%d, status=%d \n",
+ mas_session_id, status);
+#endif
+ p_evt->hdr.event = evt;
+ p_evt->mas_session_id = mas_session_id;
+ p_evt->status = status;
+ bta_sys_sendmsg(p_evt);
+ }
+}
+
+/*******************************************************************************
+**
+** Function bta_mse_ci_get_msg
+**
+** Description This function is called in response to the
+** bta_mse_co_get_msg call-out function.
+**
+** Parameters mas_session_id - MAS session ID
+** status - BTA_MA_STATUS_OK if p_msg points to a valid bmessage.
+** BTA_MA_STATUS_FAIL if any errors have occurred.
+** filled_buff_size - size of the filled buffer
+** multi_pkt_status - BTA_MA_MPKT_STATUS_MORE - need to get more packets
+** BTA_MA_MPKT_STATUS_LAST - last packet of the bMessage
+** frac_deliver_status - BTA_MA_FRAC_DELIVER_MORE - other fractions following
+** this bMessage
+** BTA_MA_FRAC_DELIVER_LAST - Last fraction
+** evt - evt from the call-out function
+**
+** Returns void
+**
+*******************************************************************************/
+BTA_API extern void bta_mse_ci_get_msg(tBTA_MA_SESS_HANDLE mas_session_id,
+ tBTA_MA_STATUS status,
+ UINT16 filled_buff_size,
+ tBTA_MA_MPKT_STATUS multi_pkt_status,
+ tBTA_MA_FRAC_DELIVER frac_deliver_status,
+ UINT16 evt)
+{
+ tBTA_MSE_CI_GET_MSG *p_evt;
+
+ if ((p_evt = (tBTA_MSE_CI_GET_MSG *)GKI_getbuf(sizeof(tBTA_MSE_CI_GET_MSG))) != NULL)
+ {
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT4("bta_mse_ci_get_msg sess_id=%d, status=%d, multi-pkt status=%d frac=%d\n",
+ mas_session_id,
+ status,
+ multi_pkt_status,
+ frac_deliver_status);
+#endif
+ p_evt->hdr.event = evt;
+ p_evt->mas_session_id = mas_session_id;
+ p_evt->status = status;
+ p_evt->filled_buff_size = filled_buff_size;
+ p_evt->multi_pkt_status = multi_pkt_status;
+ p_evt->frac_deliver_status = frac_deliver_status;
+ bta_sys_sendmsg(p_evt);
+ }
+}
+/*******************************************************************************
+**
+** Function bta_mse_ci_set_msg_delete_status
+**
+** Description This function is called in response to the
+** bta_mse_co_set_msg_delete_status call-out function.
+**
+** Parameters mas_session_id - MAS session ID
+** status - BTA_MA_STATUS_OK if operation is successful.
+** BTA_MA_STATUS_FAIL if any errors have occurred.
+** evt - evt from the call-out function
+**
+** Returns void
+**
+*******************************************************************************/
+BTA_API extern void bta_mse_ci_set_msg_delete_status(tBTA_MA_SESS_HANDLE mas_session_id,
+ tBTA_MA_STATUS status,
+ UINT16 evt)
+{
+ tBTA_MSE_CI_DEL_MSG *p_evt;
+
+ if ((p_evt = (tBTA_MSE_CI_DEL_MSG *)GKI_getbuf(sizeof(tBTA_MSE_CI_DEL_MSG))) != NULL)
+ {
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT3("bta_mse_ci_del_msg sess_id=%d, status=%d evt=%d\n",
+ mas_session_id, status, evt);
+#endif
+ p_evt->hdr.event = evt;
+ p_evt->mas_session_id = mas_session_id;
+ p_evt->status = status;
+ bta_sys_sendmsg(p_evt);
+ }
+}
+
+/*******************************************************************************
+**
+** Function bta_mse_ci_push_msg
+**
+** Description This function is called in response to the
+** bta_mse_co_push_msg call-out function.
+**
+** Parameters mas_session_id - MAS session ID
+** status - BTA_MA_STATUS_OK if the message upload is successful.
+** BTA_MA_STATUS_FAIL if any errors have occurred.
+** last_packet - last packet of a multi-packet message
+** handle - message handle for the uploaded message if
+** status is BTA_MA_OK and last_packet is TRUE
+** Returns void
+**
+*******************************************************************************/
+BTA_API extern void bta_mse_ci_push_msg(tBTA_MA_SESS_HANDLE mas_session_id,
+ tBTA_MA_STATUS status,
+ BOOLEAN last_packet,
+ tBTA_MA_MSG_HANDLE handle,
+ UINT16 evt)
+{
+ tBTA_MSE_CI_PUSH_MSG *p_evt;
+
+ if ((p_evt = (tBTA_MSE_CI_PUSH_MSG *)GKI_getbuf(sizeof(tBTA_MSE_CI_PUSH_MSG))) != NULL)
+ {
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT4("bta_mse_ci_push_msg sess_id=%d, status=%d, last_pkt=%d evt=%d\n",
+ mas_session_id,
+ status,
+ last_packet,
+ evt);
+#endif
+
+ p_evt->hdr.event = evt;
+ p_evt->mas_session_id = mas_session_id;
+ p_evt->status = status;
+ memcpy(p_evt->handle,
+ handle,
+ sizeof(tBTA_MA_MSG_HANDLE));
+ p_evt->last_packet = last_packet;
+ bta_sys_sendmsg(p_evt);
+ }
+}
+
+
diff --git a/bta/ma/bta_mse_int.h b/bta/ma/bta_mse_int.h
new file mode 100644
index 0000000..d519b71
--- /dev/null
+++ b/bta/ma/bta_mse_int.h
@@ -0,0 +1,835 @@
+/*****************************************************************************
+**
+** Name: bta_mse_int.h
+**
+** Description: This is the private file for the message access
+** equipment (MSE) subsystem.
+**
+** Copyright (c) 1998-2009, Broadcom Corp., All Rights Reserved.
+** Broadcom Bluetooth Core. Proprietary and confidential.
+**
+*****************************************************************************/
+#ifndef BTA_MSE_INT_H
+#define BTA_MSE_INT_H
+
+#include "bt_target.h"
+#include "bta_sys.h"
+#include "obx_api.h"
+#include "bta_ma_def.h"
+#include "bta_mse_api.h"
+#include "bta_mse_co.h"
+#include "bta_mse_ci.h"
+#include "bta_ma_util.h"
+
+/*****************************************************************************
+** Constants and data types
+*****************************************************************************/
+typedef tOBX_STATUS (tBTA_MA_OBX_RSP) (tOBX_HANDLE handle, UINT8 rsp_code, BT_HDR *p_pkt);
+
+#ifndef BTA_MSE_MN_DISC_SIZE
+ #define BTA_MSE_MN_DISC_SIZE 500
+#endif
+
+#define BTA_MSE_64BIT_HEX_STR_SIZE (16+1)
+#define BTA_MSE_32BIT_HEX_STR_SIZE (8+1)
+
+#define BTA_MSE_MN_MAX_MSG_EVT_OBECT_SIZE 1536 /* 1.5 k */
+/* mode field in tBTA_MSE_CO_FOLDER_ENTRY (OR'd together) */
+#define BTA_MSE_A_RDONLY GOEP_A_RDONLY
+#define BTA_MSE_A_DIR GOEP_A_DIR /* Entry is a sub directory */
+
+enum
+{
+ BTA_MSE_MA_GET_ACT_NEW_FOLDER_LIST = 0,
+ BTA_MSE_MA_GET_ACT_CON_FOLDER_LIST,
+ BTA_MSE_MA_GET_ACT_ERR_FOLDER_LIST,
+ BTA_MSE_MA_GET_ACT_NEW_MSG_LIST,
+ BTA_MSE_MA_GET_ACT_CON_MSG_LIST,
+ BTA_MSE_MA_GET_ACT_ERR_MSG_LIST,
+ BTA_MSE_MA_GET_ACT_NEW_MSG,
+ BTA_MSE_MA_GET_ACT_CON_MSG,
+ BTA_MSE_MA_GET_ACT_ERR_MSG,
+ BTA_MSE_MA_GET_ACT_ERR,
+ BTA_MSE_MA_GET_ACT_NONE,
+ BTA_MSE_MA_GET_ACT_MAX
+};
+typedef UINT8 tBTA_MSE_MA_GET_ACT;
+
+enum
+{
+ BTA_MSE_MA_GET_TYPE_FOLDER_LIST = 0,
+ BTA_MSE_MA_GET_TYPE_MSG_LIST,
+ BTA_MSE_MA_GET_TYPE_MSG,
+ BTA_MSE_MA_GET_TYPE_CON_FOLDER_LIST,
+ BTA_MSE_MA_GET_TYPE_CON_MSG_LIST,
+ BTA_MSE_MA_GET_TYPE_CON_MSG,
+ BTA_MSE_MA_GET_TYPE_NONE,
+ BTA_MSE_MA_GET_TYPE_MAX
+};
+typedef UINT8 tBTA_MSE_MA_GET_TYPE;
+
+enum
+{
+ BTA_MSE_MA_PUT_TYPE_NOTIF_REG = 0,
+ BTA_MSE_MA_PUT_TYPE_EVT_RPT,
+ BTA_MSE_MA_PUT_TYPE_NONE,
+ BTA_MSE_MA_PUT_TYPE_MAX
+};
+typedef UINT8 tBTA_MSE_MA_PUT_TYPE;
+
+enum
+{
+ BTA_MSE_MN_NOTIF_REG_STS_OFF = 0,
+ BTA_MSE_MN_NOTIF_REG_STS_ON,
+ BTA_MSE_MN_NOTIF_REG_STS_NONE,
+ BTA_MSE_MN_NOTIF_REG_STS_MAX
+};
+typedef UINT8 tBTA_MSE_MN_NOTIF_REG_STS;
+
+enum
+{
+ BTA_MSE_MN_ACT_TYPE_OPEN_CONN = 0,
+ BTA_MSE_MN_ACT_TYPE_OPEN_CONN_NONE,
+ BTA_MSE_MN_ACT_TYPE_OPEN_CONN_ERR,
+ BTA_MSE_MN_ACT_TYPE_CLOSE_CONN,
+ BTA_MSE_MN_ACT_TYPE_CLOSE_CONN_NONE,
+ BTA_MSE_MN_ACT_TYPE_CLOSE_CONN_ERR,
+ BTA_MSE_MN_ACT_TYPE_NONE,
+ BTA_MSE_MN_ACT_TYPE_MAX
+};
+typedef UINT8 tBTA_MSE_MN_ACT_TYPE;
+
+typedef tOBX_STATUS (tBTA_MSE_OBX_RSP) (tOBX_HANDLE handle, UINT8 rsp_code, BT_HDR *p_pkt);
+
+/* MSE Active MA obex operation (Valid in connected state) */
+#define BTA_MSE_MA_OP_NONE 0
+#define BTA_MSE_MA_OP_SETPATH 1
+#define BTA_MSE_MA_OP_GET_FOLDER_LIST 2
+#define BTA_MSE_MA_OP_GET_MSG_LIST 3
+#define BTA_MSE_MA_OP_GET_MSG 4
+#define BTA_MSE_MA_OP_SET_STATUS 5
+#define BTA_MSE_MA_OP_PUSH_MSG 6
+
+/* MAS Active MN obex operation (Valid in connected state) */
+#define BTA_MSE_MN_OP_NONE 0
+#define BTA_MSE_MN_OP_PUT_EVT_RPT 1
+
+
+/* MN Abort state */
+#define BTA_MSE_MN_ABORT_NONE 0x0
+#define BTA_MSE_MN_ABORT_REQ_NOT_SENT 0x1
+#define BTA_MSE_MN_ABORT_REQ_SENT 0x2
+#define BTA_MSE_MN_ABORT_RSP_RCVD 0x4
+
+
+/* Response Timer Operations */
+#define BTA_MSE_TIMER_OP_NONE 0
+#define BTA_MSE_TIMER_OP_STOP 1
+#define BTA_MSE_TIMER_OP_ABORT 2
+#define BTA_MSE_TIMER_OP_ALL 0xFF /* use to stop all timers */
+
+/* State Machine Events */
+enum
+{
+ /* these events are handled by the state machine */
+ BTA_MSE_INT_CLOSE_EVT = BTA_SYS_EVT_START(BTA_ID_MSE),
+ BTA_MSE_API_ACCESSRSP_EVT,
+ BTA_MSE_API_UPD_IBX_RSP_EVT,
+ BTA_MSE_API_SET_NOTIF_REG_RSP_EVT,
+ BTA_MSE_INT_START_EVT,
+ BTA_MSE_CI_GET_FENTRY_EVT,
+ BTA_MSE_CI_GET_ML_INFO_EVT,
+ BTA_MSE_CI_GET_ML_ENTRY_EVT,
+ BTA_MSE_CI_GET_MSG_EVT,
+ BTA_MSE_CI_PUSH_MSG_EVT,
+ BTA_MSE_CI_DEL_MSG_EVT,
+ BTA_MSE_MA_OBX_CONN_EVT, /* OBX Channel Connect Request */
+ BTA_MSE_MA_OBX_DISC_EVT, /* OBX Channel Disconnect */
+ BTA_MSE_MA_OBX_ABORT_EVT, /* OBX_operation aborted */
+ BTA_MSE_MA_OBX_CLOSE_EVT, /* OBX Channel Disconnected (Link Lost) */
+ BTA_MSE_MA_OBX_PUT_EVT, /* Write file data or delete */
+ BTA_MSE_MA_OBX_GET_EVT, /* Read file data or folder listing */
+ BTA_MSE_MA_OBX_SETPATH_EVT, /* Make or Change Directory */
+ BTA_MSE_CLOSE_CMPL_EVT, /* Finished closing channel */
+
+ /* Message Notification Client events */
+ BTA_MSE_MN_INT_OPEN_EVT,
+ BTA_MSE_MN_INT_CLOSE_EVT,
+ BTA_MSE_MN_SDP_OK_EVT,
+ BTA_MSE_MN_SDP_FAIL_EVT,
+ BTA_MSE_MN_OBX_CONN_RSP_EVT,
+ BTA_MSE_MN_OBX_PUT_RSP_EVT,
+ BTA_MSE_MN_OBX_CLOSE_EVT,
+ BTA_MSE_MN_OBX_TOUT_EVT,
+ BTA_MSE_MN_CLOSE_CMPL_EVT,
+ BTA_MSE_API_SEND_NOTIF_EVT,
+ BTA_MSE_API_MN_ABORT_EVT,
+ BTA_MSE_MN_OBX_ABORT_RSP_EVT,
+ BTA_MSE_MN_RSP_TOUT_EVT,
+
+ /* these events are handled outside the state machine */
+ BTA_MSE_MN_RSP0_TOUT_EVT, /* timeout event for MN control block index 0*/
+ BTA_MSE_MN_RSP1_TOUT_EVT,
+ BTA_MSE_MN_RSP2_TOUT_EVT,
+ BTA_MSE_MN_RSP3_TOUT_EVT,
+ BTA_MSE_MN_RSP4_TOUT_EVT,
+ BTA_MSE_MN_RSP5_TOUT_EVT,
+ BTA_MSE_MN_RSP6_TOUT_EVT, /* Bluetooth limit for upto 7 devices*/
+ BTA_MSE_API_ENABLE_EVT,
+ BTA_MSE_API_DISABLE_EVT,
+ BTA_MSE_API_START_EVT,
+ BTA_MSE_API_STOP_EVT,
+ BTA_MSE_API_CLOSE_EVT,
+ BTA_MSE_API_MA_CLOSE_EVT,
+ BTA_MSE_API_MN_CLOSE_EVT
+
+};
+typedef UINT16 tBTA_MSE_INT_EVT;
+
+#define BTA_MSE_MN_EVT_MIN BTA_MSE_MN_INT_OPEN_EVT
+#define BTA_MSE_MN_EVT_MAX BTA_MSE_MN_RSP_TOUT_EVT
+
+
+/* state machine states */
+enum
+{
+ BTA_MSE_MA_IDLE_ST = 0, /* Idle */
+ BTA_MSE_MA_LISTEN_ST, /* Listen - waiting for OBX/RFC connection */
+ BTA_MSE_MA_CONN_ST, /* Connected - MA Session is active */
+ BTA_MSE_MA_CLOSING_ST /* Closing is in progress */
+};
+typedef UINT8 tBTA_MSE_MA_STATE;
+
+/* data type for BTA_MSE_MA_CI_GET_FENTRY_EVT note:sdh */
+typedef struct
+{
+ BT_HDR hdr;
+ tBTA_MA_SESS_HANDLE mas_session_id;
+ tBTA_MA_STATUS status;
+} tBTA_MSE_CI_GET_FENTRY;
+
+/* data type for BTA_MSE_MA_CI_GET_FENTRY_EVT note:sdh */
+typedef struct
+{
+ BT_HDR hdr;
+ tBTA_MA_SESS_HANDLE mas_session_id;
+ tBTA_MA_STATUS status;
+} tBTA_MSE_CI_GET_ML_INFO;
+
+
+
+typedef struct
+{
+ BT_HDR hdr;
+ tBTA_MA_SESS_HANDLE mas_session_id;
+ tBTA_MA_STATUS status;
+} tBTA_MSE_CI_GET_ML_ENTRY;
+
+
+typedef struct
+{
+ BT_HDR hdr;
+ tBTA_MA_SESS_HANDLE mas_session_id;
+ tBTA_MA_STATUS status;
+ BOOLEAN last_packet;
+ tBTA_MA_MSG_HANDLE handle;
+} tBTA_MSE_CI_PUSH_MSG;
+
+
+typedef struct
+{
+ BT_HDR hdr;
+ tBTA_MA_SESS_HANDLE mas_session_id;
+ tBTA_MA_STATUS status;
+ UINT16 filled_buff_size;
+ tBTA_MA_MPKT_STATUS multi_pkt_status;
+ tBTA_MA_FRAC_DELIVER frac_deliver_status;
+} tBTA_MSE_CI_GET_MSG;
+
+typedef struct
+{
+ BT_HDR hdr;
+ tBTA_MA_SESS_HANDLE mas_session_id;
+ tBTA_MA_STATUS status;
+} tBTA_MSE_CI_DEL_MSG;
+
+
+
+/* data type for BTA_MSE_API_ENABLE_EVT note:sdh */
+typedef struct
+{
+ BT_HDR hdr;
+ tBTA_MSE_CBACK *p_cback; /* pointer to application callback function */
+ UINT8 app_id;
+} tBTA_MSE_API_ENABLE;
+
+
+/* data type for BTA_MSE_API_DISABLE_EVT note:sdh */
+typedef struct
+{
+ BT_HDR hdr;
+ UINT8 app_id;
+} tBTA_MSE_API_DISABLE;
+
+/* data type for BTA_MSE_API_START_EVT note:sdh */
+typedef struct
+{
+ BT_HDR hdr;
+ tBTA_MA_INST_ID mas_inst_id;
+ char servicename[BTA_SERVICE_NAME_LEN + 1];
+ char *p_root_path;
+ tBTA_SEC sec_mask;
+ tBTA_MA_MSG_TYPE sup_msg_type;
+} tBTA_MSE_API_START;
+
+/* data type for BTA_MSE_API_STOP_EVT note:sdh */
+typedef struct
+{
+ BT_HDR hdr;
+ tBTA_MA_INST_ID mas_inst_id;
+
+} tBTA_MSE_API_STOP;
+
+/* data type for BTA_MSE_API_CLOSE_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ tBTA_MA_INST_ID mas_instance_id;
+
+} tBTA_MSE_API_CLOSE;
+
+/* data type for BTA_MSE_API_MA_CLOSE_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ BD_ADDR bd_addr;
+ tBTA_MA_INST_ID mas_instance_id;
+
+} tBTA_MSE_API_MA_CLOSE;
+
+/* data type for BTA_MSE_INT_CLOSE_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ tBTA_MA_SESS_HANDLE mas_session_id;
+
+} tBTA_MSE_INT_CLOSE;
+
+
+/* data type for BTA_MSE_API_MN_CLOSE_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ BD_ADDR bd_addr;
+} tBTA_MSE_API_MN_CLOSE;
+
+
+typedef struct
+{
+ BT_HDR hdr;
+ tBTA_MA_SESS_HANDLE mas_session_id;
+ tBTA_MSE_OPER oper;
+ tBTA_MA_ACCESS_TYPE rsp;
+ char *p_path;
+} tBTA_MSE_API_ACCESSRSP;
+
+typedef struct
+{
+ BT_HDR hdr;
+ tBTA_MA_SESS_HANDLE mas_session_id;
+ tBTA_MSE_UPDATE_INBOX_TYPE rsp;
+ char *p_path;
+} tBTA_MSE_API_UPDINBRSP;
+
+typedef struct
+{
+ BT_HDR hdr;
+ tBTA_MA_SESS_HANDLE mas_session_id;
+ tBTA_MSE_SET_NOTIF_REG_TYPE rsp;
+} tBTA_MSE_API_SETNOTIFREGRSP;
+
+/* data type for all obex events
+ hdr.event contains the MAS event
+*/
+typedef struct
+{
+ BT_HDR hdr;
+ tOBX_HANDLE handle;
+ tOBX_EVT_PARAM param;
+ BT_HDR *p_pkt;
+ tOBX_EVENT obx_event;
+ UINT8 rsp_code;
+} tBTA_MSE_OBX_EVT;
+
+/* OBX Response Packet Structure - Holds current response packet info */
+typedef struct
+{
+ BT_HDR *p_pkt; /* (Get/Put) Holds the current OBX header for Put or Get */
+ UINT8 *p_start; /* (Get/Put) Start of the Body of the packet */
+ UINT16 offset; /* (Get/Put) Contains the current offset into the Body (p_start) */
+ UINT16 bytes_left; /* (Get/Put) Holds bytes available left in Obx packet */
+ BOOLEAN final_pkt; /* (Put) Holds the final bit of the Put packet */
+} tBTA_MSE_OBX_PKT;
+
+/* data type for BTA_MSE_MN_INT_OPEN_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ UINT8 ccb_idx;
+ BD_ADDR bd_addr;
+ tBTA_SEC sec_mask;
+}tBTA_MSE_MN_INT_OPEN;
+
+/* data type for BTA_MSE_MN_INT_OPEN_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ UINT8 ccb_idx;
+}tBTA_MSE_MN_INT_CLOSE;
+
+/* data type for BTA_MSE_MN_SDP_OK_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ UINT8 ccb_idx;
+ UINT8 scn;
+}tBTA_MSE_MN_SDP_OK;
+
+
+/* data type for BTA_MSE_MN_SDP_FAIL_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ UINT8 ccb_idx;
+}tBTA_MSE_MN_SDP_FAIL;
+
+
+/* data type for BTA_MSE_MN_API_SEND_NOTIF_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ tBTA_MA_INST_ID mas_instance_id;
+ tBTA_MSE_NOTIF_TYPE notif_type;
+ tBTA_MA_MSG_HANDLE handle;
+ char *p_folder;
+ char *p_old_folder;
+ tBTA_MA_MSG_TYPE msg_type;
+ BD_ADDR except_bd_addr;
+} tBTA_MSE_MN_API_SEND_NOTIF;
+
+/* data type for BTA_MSE_API_MN_ABORT_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ tBTA_MA_INST_ID mas_instance_id;
+}tBTA_MSE_MN_API_ABORT;
+
+
+/* union of all state machine event data types */
+typedef union
+{
+ BT_HDR hdr;
+ tBTA_MSE_API_ENABLE api_enable; /* data for BTA_MSE_API_ENABLE_EVT */
+ tBTA_MSE_API_DISABLE api_disable;
+ tBTA_MSE_API_START api_start;
+ tBTA_MSE_API_STOP api_stop;
+ tBTA_MSE_API_CLOSE api_close;
+ tBTA_MSE_INT_CLOSE int_close;
+ tBTA_MSE_API_MA_CLOSE api_ma_close;
+ tBTA_MSE_API_MN_CLOSE api_mn_close;
+ tBTA_MSE_API_ACCESSRSP api_access_rsp;
+ tBTA_MSE_API_UPDINBRSP api_upd_ibx_rsp;
+ tBTA_MSE_API_SETNOTIFREGRSP api_set_notif_reg_rsp;
+ tBTA_MSE_OBX_EVT obx_evt;
+ tBTA_MSE_CI_GET_FENTRY ci_get_fentry;
+ tBTA_MSE_CI_GET_ML_INFO ci_get_ml_info;
+ tBTA_MSE_CI_GET_ML_ENTRY ci_get_ml_entry;
+ tBTA_MSE_CI_GET_MSG ci_get_msg;
+ tBTA_MSE_CI_PUSH_MSG ci_push_msg;
+ tBTA_MSE_CI_DEL_MSG ci_del_msg;
+ tBTA_MSE_MN_INT_OPEN mn_int_open;
+ tBTA_MSE_MN_INT_CLOSE mn_int_close;
+ tBTA_MSE_MN_SDP_OK mn_sdp_ok;
+ tBTA_MSE_MN_SDP_FAIL mn_sdp_fail;
+ tBTA_MSE_MN_API_SEND_NOTIF mn_send_notif;
+ tBTA_MSE_MN_API_ABORT mn_abort;
+
+} tBTA_MSE_DATA;
+
+typedef struct
+{
+ char *p_path;
+ char *p_name;
+ tBTA_MA_DIR_NAV flags;
+} tBTA_MSE_OPER_SETPATH;
+
+/* Directory Listing bufer pointer */
+typedef struct
+{
+ tBTA_MSE_CO_FOLDER_ENTRY *p_entry; /* Holds current directory entry */
+ BOOLEAN is_root; /* TRUE if path is root directory */
+} tBTA_MSE_DIRLIST;
+
+typedef struct
+{
+ UINT16 max_list_cnt;
+ UINT16 start_offset;
+ UINT16 list_cnt;
+} tBTA_MSE_OPER_FLIST_PARAM;
+
+/* Message Listing buffer pointers */
+typedef struct
+{
+ tBTA_MSE_CO_MSG_LIST_ENTRY *p_entry;
+ tBTA_MSE_CO_MSG_LIST_INFO *p_info;
+ BOOLEAN pending_ml_frag;
+ char *p_xml_buf;
+ UINT16 offset;
+ UINT16 remaing_size;
+} tBTA_MSE_MSGLIST;
+
+typedef struct
+{
+ tBTA_MA_MSG_LIST_FILTER_PARAM filter;
+ char *p_name;
+ char *p_path;
+ BOOLEAN w4info;
+} tBTA_MSE_OPER_MLIST_PARAM;
+
+
+typedef struct
+{
+ BOOLEAN notif_status_rcv;
+ tBTA_MA_NOTIF_STATUS notif_status;
+} tBTA_NOTIF_REG;
+
+typedef struct
+{
+ tBTA_MA_GET_MSG_PARAM data;
+ char *p_msg_handle;
+ UINT8 *p_frac_delivery;
+ UINT16 byte_get_cnt;
+ UINT16 filled_buff_size;
+ BOOLEAN add_frac_del_hdr;
+ tBTA_MA_FRAC_DELIVER frac_deliver_status;
+} tBTA_MSE_OPER_MSG_PARAM;
+
+typedef struct
+{
+ tBTA_MA_PUSH_MSG_PARAM param;
+ UINT16 push_byte_cnt;
+ BOOLEAN rcv_folder_name;
+ BOOLEAN rcv_charset;
+ BOOLEAN rcv_transparent;
+ BOOLEAN rcv_retry;
+ BOOLEAN first_req_pkt;
+} tBTA_MSE_OPER_PUSH_MSG;
+
+typedef struct
+{
+ char *p_msg_handle;
+ BOOLEAN rcv_msg_handle;
+ BOOLEAN rcv_sts_ind;
+ BOOLEAN rcv_sts_val;
+ tBTA_MA_MSG_HANDLE handle;
+ tBTA_MA_STS_INDCTR sts_ind;
+ tBTA_MA_STS_VALUE sts_val;
+} tBTA_MSE_OPER_SET_MSG_STS;
+
+
+/* MAS control block */
+typedef struct
+{
+ tBTA_NOTIF_REG notif_reg_req;
+ tBTA_MSE_OPER_PUSH_MSG push_msg;
+ tBTA_MSE_OPER_SET_MSG_STS set_msg_sts;
+ tBTA_MSE_OPER_SETPATH sp;
+ tBTA_MSE_OPER_FLIST_PARAM fl_param;
+ tBTA_MSE_DIRLIST dir;
+ tBTA_MSE_OPER_MLIST_PARAM ml_param;
+ tBTA_MSE_MSGLIST ml; /* point to the Message-Listing object buffer */
+ tBTA_MSE_OPER_MSG_PARAM msg_param;
+ tBTA_MSE_OBX_PKT obx;
+ char *p_workdir; /* Current working folder */
+ tOBX_HANDLE obx_handle; /* OBEX handle,used as MAS session ID as well */
+ UINT16 peer_mtu;
+ BOOLEAN cout_active; /* TRUE when waiting for a call-in function */
+ BOOLEAN aborting;
+ BD_ADDR bd_addr; /* Device currently connected to */
+ tBTA_MSE_OPER oper;
+ tBTA_MSE_MA_STATE state; /* state machine state */
+
+} tBTA_MSE_MA_SESS_CB;
+
+typedef struct
+{
+ tBTA_MSE_MA_SESS_CB sess_cb[BTA_MSE_NUM_SESS];
+ UINT32 sdp_handle; /* SDP record handle */
+ char *p_rootpath;
+ tOBX_HANDLE obx_handle; /* OBEX handle ID */
+ BOOLEAN stopping;
+ BOOLEAN in_use;
+ tBTA_SEC sec_mask;
+ tBTA_MA_MSG_TYPE sup_msg_type;
+ char servicename[BTA_SERVICE_NAME_LEN + 1];
+ UINT8 scn; /* SCN of the MA server */
+ tBTA_MA_INST_ID mas_inst_id; /* MAS instance id */
+}tBTA_MSE_MA_CB;
+
+/* state machine states */
+enum
+{
+ BTA_MSE_MN_IDLE_ST = 0, /* Idle */
+ BTA_MSE_MN_W4_CONN_ST, /* wait for connection state */
+ BTA_MSE_MN_CONN_ST, /* Connected - MAS Session is active */
+ BTA_MSE_MN_CLOSING_ST /* Closing is in progress */
+};
+typedef UINT8 tBTA_MSE_MN_STATE;
+
+/* notification registration status */
+typedef struct
+{
+ BOOLEAN status;
+ tBTA_MA_INST_ID mas_inst_id; /* only valid when status == TRUE*/
+} tBTA_MSE_MN_REG_STATUS;
+
+/* Message notification report */
+typedef struct
+{
+ UINT16 buffer_len;
+ UINT16 bytes_sent;
+ BOOLEAN final_pkt;
+ UINT8 pkt_cnt;
+ tBTA_MA_INST_ID mas_instance_id;
+ UINT8 *p_buffer;
+}tBTA_MSE_MN_MSG_NOTIF;
+
+typedef struct
+{
+ tBTA_MSE_MN_REG_STATUS notif_reg[BTA_MSE_NUM_INST];
+ tBTA_MSE_OBX_PKT obx; /* Holds the current OBX packet information */
+ tBTA_MSE_MN_MSG_NOTIF msg_notif;
+ TIMER_LIST_ENT rsp_timer; /* response timer */
+ tSDP_DISCOVERY_DB *p_db; /* pointer to discovery database */
+ tSDP_DISC_CMPL_CB *sdp_cback;
+ tOBX_HANDLE obx_handle;
+ UINT16 sdp_service;
+ UINT16 peer_mtu;
+ BOOLEAN in_use;
+ BOOLEAN req_pending; /* TRUE when waiting for an obex response */
+ BOOLEAN cout_active; /* TRUE if call-out is currently active */
+ BOOLEAN sdp_pending;
+ BD_ADDR bd_addr; /* Peer device MNS server address */
+ tBTA_MSE_MN_STATE state; /* state machine state */
+ tBTA_SEC sec_mask;
+ UINT8 timer_oper; /* current active response timer action (abort or close) */
+ UINT8 obx_oper; /* current active OBX operation PUT or GET operations */
+ UINT8 aborting;
+}tBTA_MSE_MN_CB;
+
+typedef struct
+{
+ BOOLEAN in_use;
+ BD_ADDR bd_addr;
+ BOOLEAN opened;
+ BOOLEAN busy;
+}tBTA_MSE_PM_CB;
+
+
+typedef struct
+{
+ tBTA_MSE_MA_CB scb[BTA_MSE_NUM_INST]; /* MA Server Control Blocks */
+ tBTA_MSE_MN_CB ccb[BTA_MSE_NUM_MN]; /* MN Client Control Blocks */
+ tBTA_MSE_PM_CB pcb[BTA_MSE_NUM_MN];
+ tBTA_MSE_CBACK *p_cback; /* pointer to application event callback function */
+ BOOLEAN enable;
+ BOOLEAN disabling;
+ UINT8 app_id;
+}tBTA_MSE_CB;
+
+/******************************************************************************
+** Configuration Definitions
+*******************************************************************************/
+/* Configuration structure */
+typedef struct
+{
+ INT32 abort_tout; /* Timeout in milliseconds to wait for abort OBEX response (client only) */
+ INT32 stop_tout; /* Timeout in milliseconds to wait for close OBEX response (client only) */
+
+} tBTA_MSE_MA_CFG;
+
+/*****************************************************************************
+** Global data
+*****************************************************************************/
+
+/* MAS control block */
+#if BTA_DYNAMIC_MEMORY == FALSE
+extern tBTA_MSE_CB bta_mse_cb;
+#else
+extern tBTA_MSE_CB *bta_mse_cb_ptr;
+ #define bta_mse_cb (*bta_mse_cb_ptr)
+#endif
+
+#define BTA_MSE_GET_INST_CB_PTR(inst_idx) &(bta_mse_cb.scb[(inst_idx)])
+#define BTA_MSE_GET_SESS_CB_PTR(inst_idx, sess_idx ) &(bta_mse_cb.scb[(inst_idx)].sess_cb[(sess_idx)])
+#define BTA_MSE_GET_MN_CB_PTR(ccb_idx) &(bta_mse_cb.ccb[(ccb_idx)])
+#define BTA_MSE_GET_PM_CB_PTR(pcb_idx) &(bta_mse_cb.pcb[(pcb_idx)])
+/* MAS configuration constants */
+extern tBTA_MSE_MA_CFG * p_bta_ms_cfg;
+
+/*****************************************************************************
+** Function prototypes
+*****************************************************************************/
+/* MSE event handler for MA and MN */
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+ extern BOOLEAN bta_mse_hdl_event(BT_HDR *p_msg);
+
+/* State machine drivers */
+ extern void bta_mse_ma_sm_execute(UINT8 inst_idx, UINT8 sess_idx, UINT16 event, tBTA_MSE_DATA *p_data);
+ extern void bta_mse_mn_sm_execute(UINT8 ccb_idx, UINT16 event, tBTA_MSE_DATA *p_data);
+
+ extern void bta_mse_ma_sdp_register (tBTA_MSE_MA_CB *p_scb, char *p_service_name, tBTA_MA_INST_ID inst_id, tBTA_MA_MSG_TYPE msg_type);
+
+/* Obx callback functions */
+ extern void bta_mse_ma_obx_cback (tOBX_HANDLE handle, tOBX_EVENT event,
+ tOBX_EVT_PARAM param, BT_HDR *p_pkt);
+
+ extern void bta_mse_mn_obx_cback (tOBX_HANDLE handle, tOBX_EVENT obx_event, UINT8 rsp_code,
+ tOBX_EVT_PARAM param, BT_HDR *p_pkt);
+
+/* action functions for MA */
+ extern void bta_mse_ma_int_close(UINT8 inst_idx, UINT8 sess_idx, tBTA_MSE_DATA *p_data);
+ extern void bta_mse_ma_api_accessrsp(UINT8 inst_idx, UINT8 sess_idx, tBTA_MSE_DATA *p_data);
+ extern void bta_mse_ma_api_upd_ibx_rsp(UINT8 inst_idx, UINT8 sess_idx, tBTA_MSE_DATA *p_data);
+ extern void bta_mse_ma_api_set_notif_reg_rsp(UINT8 inst_idx, UINT8 sess_idx, tBTA_MSE_DATA *p_data);
+
+ extern void bta_mse_ma_ci_get_folder_entry(UINT8 inst_idx, UINT8 sess_idx, tBTA_MSE_DATA *p_data);
+ extern void bta_mse_ma_ci_get_ml_info(UINT8 inst_idx, UINT8 sess_idx, tBTA_MSE_DATA *p_data);
+ extern void bta_mse_ma_ci_get_ml_entry(UINT8 inst_idx, UINT8 sess_idx, tBTA_MSE_DATA *p_data);
+ extern void bta_mse_ma_ci_get_msg(UINT8 inst_idx, UINT8 sess_idx, tBTA_MSE_DATA *p_data);
+ extern void bta_mse_ma_ci_push_msg(UINT8 inst_idx, UINT8 sess_idx, tBTA_MSE_DATA *p_data);
+ extern void bta_mse_ma_ci_del_msg(UINT8 inst_idx, UINT8 sess_idx, tBTA_MSE_DATA *p_data);
+
+ extern void bta_mse_ma_obx_disc(UINT8 inst_idx, UINT8 sess_idx, tBTA_MSE_DATA *p_data);
+ extern void bta_mse_ma_obx_connect(UINT8 inst_idx, UINT8 sess_idx, tBTA_MSE_DATA *p_data);
+ extern void bta_mse_ma_obx_close(UINT8 inst_idx, UINT8 sess_idx, tBTA_MSE_DATA *p_data);
+ extern void bta_mse_ma_obx_abort(UINT8 inst_idx, UINT8 sess_idx, tBTA_MSE_DATA *p_data);
+ extern void bta_mse_ma_obx_put(UINT8 inst_idx, UINT8 sess_idx, tBTA_MSE_DATA *p_data);
+ extern void bta_mse_ma_obx_get(UINT8 inst_idx, UINT8 sess_idx, tBTA_MSE_DATA *p_data);
+ extern void bta_mse_ma_obx_setpath(UINT8 inst_idx, UINT8 sess_idx, tBTA_MSE_DATA *p_data);
+ extern void bta_mse_ma_conn_err_rsp(UINT8 inst_idx, UINT8 sess_idx, tBTA_MSE_DATA *p_data);
+ extern void bta_mse_ma_close_complete(UINT8 inst_idx, UINT8 sess_idx, tBTA_MSE_DATA *p_data);
+
+/* action function for MN */
+ extern void bta_mse_mn_init_sdp(UINT8 ccb_idx, tBTA_MSE_DATA *p_data);
+ extern void bta_mse_mn_start_client(UINT8 ccb_idx, tBTA_MSE_DATA *p_data);
+ extern void bta_mse_mn_stop_client(UINT8 ccb_idx, tBTA_MSE_DATA *p_data);
+ extern void bta_mse_mn_obx_conn_rsp(UINT8 ccb_idx, tBTA_MSE_DATA *p_data);
+ extern void bta_mse_mn_close(UINT8 ccb_idx, tBTA_MSE_DATA *p_data);
+ extern void bta_mse_mn_send_notif(UINT8 ccb_idx, tBTA_MSE_DATA *p_data);
+ extern void bta_mse_mn_rsp_timeout(UINT8 ccb_idx, tBTA_MSE_DATA *p_data);
+ extern void bta_mse_mn_put_rsp(UINT8 ccb_idx, tBTA_MSE_DATA *p_data);
+ extern void bta_mse_mn_obx_tout(UINT8 ccb_idx, tBTA_MSE_DATA *p_data);
+ extern void bta_mse_mn_close_compl(UINT8 ccb_idx, tBTA_MSE_DATA *p_data);
+ extern void bta_mse_mn_ignore_obx(UINT8 ccb_idx, tBTA_MSE_DATA *p_data);
+ extern void bta_mse_mn_sdp_fail(UINT8 ccb_idx, tBTA_MSE_DATA *p_data);
+ extern void bta_mse_mn_abort(UINT8 ccb_idx, tBTA_MSE_DATA *p_data);
+ extern void bta_mse_mn_abort_rsp(UINT8 ccb_idx, tBTA_MSE_DATA *p_data);
+
+
+/* miscellaneous functions */
+ extern void bta_mse_discard_data(UINT16 event, tBTA_MSE_DATA *p_data);
+
+/* utility functions */
+
+ extern void bta_mse_send_push_msg_in_prog_evt(UINT8 inst_idx, UINT8 sess_idx);
+ extern void bta_mse_send_get_msg_in_prog_evt(UINT8 inst_idx, UINT8 sess_idx);
+ extern void bta_mse_send_oper_cmpl_evt(UINT8 inst_idx, UINT8 sess_idx, tBTA_MA_STATUS status);
+ extern void bta_mse_pushmsg(UINT8 inst_idx, UINT8 sess_idx, BOOLEAN first_pkt);
+ extern void bta_mse_clean_set_msg_sts(UINT8 inst_idx, UINT8 sess_idx);
+ extern void bta_mse_clean_set_notif_reg(UINT8 inst_idx, UINT8 sess_idx);
+ extern void bta_mse_clean_push_msg(UINT8 inst_idx, UINT8 sess_idx);
+ extern void bta_mse_init_set_msg_sts(UINT8 inst_idx, UINT8 sess_idx, UINT8 *p_rsp_code);
+ extern void bta_mse_init_push_msg(UINT8 inst_idx, UINT8 sess_idx, UINT8 *p_rsp_code);
+ extern void bta_mse_remove_uuid(void);
+ extern void bta_mse_clean_mas_service(UINT8 inst_idx);
+ extern void bta_mse_abort_too_late(UINT8 inst_idx, UINT8 sess_idx);
+ extern void bta_mse_clean_getput(UINT8 inst_idx, UINT8 sess_idx, tBTA_MA_STATUS status);
+ extern void bta_mse_clean_msg(UINT8 inst_idx, UINT8 sess_idx);
+ extern void bta_mse_end_of_msg(UINT8 inst_idx, UINT8 sess_idx, UINT8 rsp_code);
+ extern void bta_mse_getmsg(UINT8 inst_idx, UINT8 sess_idx, BOOLEAN new_req);
+ extern tBTA_MA_STATUS bta_mse_build_msg_listing_obj(tBTA_MSE_CO_MSG_LIST_ENTRY *p_entry,
+ UINT16 *p_size, char *p_buf );
+ extern void bta_mse_clean_msg_list(UINT8 inst_idx, UINT8 sess_idx);
+ extern void bta_mse_end_of_msg_list(UINT8 inst_idx, UINT8 sess_idx, UINT8 rsp_code);
+ extern UINT8 bta_mse_add_msg_list_info(UINT8 inst_idx, UINT8 sess_idx);
+ extern UINT8 bta_mse_add_msg_list_entry(UINT8 inst_idx, UINT8 sess_idx);
+ extern void bta_mse_getmsglist(UINT8 inst_idx, UINT8 sess_idx,BOOLEAN new_req);
+ extern UINT8 * bta_mse_read_app_params(BT_HDR *p_pkt, UINT8 tag, UINT16 *param_len);
+ extern void bta_mse_clean_list(UINT8 inst_idx, UINT8 sess_idx);
+ extern void bta_mse_end_of_list(UINT8 inst_idx, UINT8 sess_idx, UINT8 rsp_code);
+ extern UINT8 bta_mse_add_list_entry(UINT8 inst_idx, UINT8 sess_idx);
+ extern void bta_mse_getfolderlist(UINT8 inst_idx, UINT8 sess_idx, BOOLEAN new_req);
+ extern UINT8 bta_mse_chdir(UINT8 inst_idx, UINT8 sess_idx, tBTA_MSE_OPER *p_oper);
+ extern BOOLEAN bta_mse_send_set_notif_reg(UINT8 status,
+ UINT8 inst_idx, UINT8 sess_idx);
+ extern void bta_mse_proc_notif_reg_status(UINT8 status,
+ UINT8 inst_idx, UINT8 sess_idx);
+ extern void bta_mse_discard_data(UINT16 event, tBTA_MSE_DATA *p_data);
+ extern BOOLEAN bta_mse_find_bd_addr_match_sess_cb_idx(BD_ADDR bd_addr, UINT8 inst_idx, UINT8 *p_idx);
+ extern BOOLEAN bta_mse_find_mas_inst_id_match_cb_idx(tBTA_MA_INST_ID mas_inst_id, UINT8 *p_idx);
+ extern BOOLEAN bta_mse_find_handle_match_mas_inst_cb_idx(tOBX_HANDLE obx_handle, UINT8 *p_idx);
+ extern BOOLEAN bta_mse_find_mas_sess_cb_idx(tOBX_HANDLE obx_handle, UINT8 *p_mas_inst_idx, UINT8 *p_mas_sess_idx);
+ extern BOOLEAN bta_mse_find_ma_cb_indexes(tBTA_MSE_DATA *p_msg, UINT8 *p_inst_idx, UINT8 *p_sess_idx);
+ extern void bta_mse_ma_cleanup(tBTA_MSE_DATA *p_msg);
+ extern BOOLEAN bta_mse_is_a_duplicate_id(tBTA_MA_INST_ID mas_inst_id);
+ extern BOOLEAN bta_mse_find_avail_mas_inst_cb_idx(UINT8 *p_idx);
+ extern BOOLEAN bta_mse_find_avail_mas_sess_cb_idx(tBTA_MSE_MA_CB *p_scb, UINT8 *p_idx);
+ extern BOOLEAN bta_mse_find_sess_id_match_ma_cb_indexes(tBTA_MA_SESS_HANDLE mas_session_id,
+ UINT8 *p_inst_idx, UINT8 *p_sess_idx);
+ extern BOOLEAN bta_mse_find_avail_mn_cb_idx(UINT8 *p_idx);
+ extern BOOLEAN bta_mse_find_bd_addr_match_mn_cb_index(BD_ADDR p_bd_addr, UINT8 *p_idx);
+ extern BOOLEAN bta_mse_find_sess_id_match_mn_cb_index(tBTA_MA_SESS_HANDLE mas_session_id,
+ UINT8 *p_idx);
+ extern BOOLEAN bta_mse_find_mn_cb_index(tBTA_MSE_DATA *p_msg, UINT8 *p_ccb_idx);
+ extern void bta_mse_mn_cleanup(tBTA_MSE_DATA *p_msg);
+ extern tBTA_MA_STATUS bta_mse_build_map_event_rpt_obj(tBTA_MSE_NOTIF_TYPE notif_type,
+ tBTA_MA_MSG_HANDLE handle,
+ char * p_folder,
+ char * p_old_folder,
+ tBTA_MA_MSG_TYPE msg_typ,
+ UINT16 * p_len,
+ UINT8 * p_buffer);
+ extern void bta_mse_mn_start_timer(UINT8 ccb_idx, UINT8 timer_id);
+ extern void bta_mse_mn_stop_timer(UINT8 ccb_idx, UINT8 timer_id);
+ extern BOOLEAN bta_mse_mn_add_inst_id(UINT8 ccb_idx, tBTA_MA_INST_ID mas_inst_id);
+ extern BOOLEAN bta_mse_mn_remove_inst_id(UINT8 ccb_idx, tBTA_MA_INST_ID mas_inst_id);
+ extern void bta_mse_mn_remove_all_inst_ids(UINT8 ccb_idx);
+ extern UINT8 bta_mse_mn_find_num_of_act_inst_id(UINT8 ccb_idx);
+ extern BOOLEAN bta_mse_mn_is_inst_id_exist(UINT8 ccb_idx, tBTA_MA_INST_ID mas_inst_id );
+ extern BOOLEAN bta_mse_mn_is_ok_to_close_mn(BD_ADDR bd_addr, tBTA_MA_INST_ID mas_inst_id );
+ extern BOOLEAN bta_mse_mn_get_first_inst_id(UINT8 ccb_idx, tBTA_MA_INST_ID *p_mas_inst_id);
+ extern tBTA_MA_STATUS bta_mse_mn_cont_send_notif(UINT8 ccb_idx, BOOLEAN first_pkt);
+ extern void bta_mse_mn_send_notif_evt(tBTA_MA_INST_ID mas_instance_id, tBTA_MA_STATUS status,
+ BD_ADDR bd_addr );
+ extern void bta_mse_mn_clean_send_notif(UINT8 ccb_idx);
+ extern void bta_mse_ma_fl_read_app_params(UINT8 inst_idx, UINT8 sess_idx, BT_HDR *p_pkt);
+ extern void bta_mse_ma_ml_read_app_params(UINT8 inst_idx, UINT8 sess_idx, BT_HDR *p_pkt);
+ extern BOOLEAN bta_mse_ma_msg_read_app_params(UINT8 inst_idx, UINT8 sess_idx, BT_HDR *p_pkt);
+ extern BOOLEAN bta_mse_get_msglist_path(UINT8 inst_idx, UINT8 sess_idx);
+
+ extern BOOLEAN bta_mse_find_pm_cb_index(BD_ADDR p_bd_addr, UINT8 *p_idx);
+ extern BOOLEAN bta_mse_find_avail_pm_cb_idx(UINT8 *p_idx);
+ extern void bta_mse_pm_conn_open(BD_ADDR bd_addr);
+ extern void bta_mse_pm_conn_close(BD_ADDR bd_addr);
+ extern void bta_mse_set_ma_oper(UINT8 inst_idx, UINT8 sess_idx, tBTA_MSE_OPER oper);
+ extern void bta_mse_set_mn_oper(UINT8 ccb_idx, UINT8 oper);
+#ifdef __cplusplus
+}
+#endif
+#endif /* BTA_MSE_INT_H */
diff --git a/bta/ma/bta_mse_main.c b/bta/ma/bta_mse_main.c
new file mode 100644
index 0000000..feddd09
--- /dev/null
+++ b/bta/ma/bta_mse_main.c
@@ -0,0 +1,1367 @@
+/*****************************************************************************
+**
+** Name: bta_mse_main.c
+**
+** Description: This file contains the Message Access Server main functions
+** and state machine.
+**
+** Copyright (c) 1998-2011, Broadcom Corp., All Rights Reserved.
+** Broadcom Bluetooth Core. Proprietary and confidential.
+**
+*****************************************************************************/
+
+#include "bt_target.h"
+
+#if defined(BTA_MSE_INCLUDED) && (BTA_MSE_INCLUDED == TRUE)
+
+#include <string.h>
+
+#include "bta_fs_api.h"
+#include "bta_mse_int.h"
+#include "gki.h"
+#include "utl.h"
+#include "obx_api.h"
+
+/*****************************************************************************
+** Message Access Server State Table
+*****************************************************************************/
+/*****************************************************************************
+** Constants and types
+*****************************************************************************/
+/* state machine action enumeration list for MAS */
+enum
+{
+ BTA_MSE_MA_INT_CLOSE,
+ BTA_MSE_MA_API_ACCESSRSP,
+ BTA_MSE_MA_API_UPD_IBX_RSP,
+ BTA_MSE_MA_API_SET_NOTIF_REG_RSP,
+ BTA_MSE_MA_CI_GET_FENTRY,
+ BTA_MSE_MA_CI_GET_ML_INFO,
+ BTA_MSE_MA_CI_GET_ML_ENTRY,
+ BTA_MSE_MA_CI_GET_MSG,
+ BTA_MSE_MA_CI_PUSH_MSG,
+ BTA_MSE_MA_CI_DEL_MSG,
+ BTA_MSE_MA_OBX_CONNECT,
+ BTA_MSE_MA_OBX_DISC,
+ BTA_MSE_MA_OBX_CLOSE,
+ BTA_MSE_MA_OBX_ABORT,
+ BTA_MSE_MA_OBX_PUT,
+ BTA_MSE_MA_OBX_GET,
+ BTA_MSE_MA_OBX_SETPATH,
+ BTA_MSE_MA_CONN_ERR_RSP,
+ BTA_MSE_MA_CLOSE_COMPLETE,
+ BTA_MSE_MA_IGNORE
+};
+
+/* type for action functions */
+typedef void (*tBTA_MSE_MA_ACTION)(UINT8 inst_idx, UINT8 sess_idx, tBTA_MSE_DATA *p_data);
+
+/* action function list for MAS */
+const tBTA_MSE_MA_ACTION bta_mse_ma_action[] =
+{
+ bta_mse_ma_int_close,
+ bta_mse_ma_api_accessrsp,
+ bta_mse_ma_api_upd_ibx_rsp,
+ bta_mse_ma_api_set_notif_reg_rsp,
+ bta_mse_ma_ci_get_folder_entry,
+ bta_mse_ma_ci_get_ml_info,
+ bta_mse_ma_ci_get_ml_entry,
+ bta_mse_ma_ci_get_msg,
+ bta_mse_ma_ci_push_msg,
+ bta_mse_ma_ci_del_msg,
+ bta_mse_ma_obx_connect,
+ bta_mse_ma_obx_disc,
+ bta_mse_ma_obx_close,
+ bta_mse_ma_obx_abort,
+ bta_mse_ma_obx_put,
+ bta_mse_ma_obx_get,
+ bta_mse_ma_obx_setpath,
+ bta_mse_ma_conn_err_rsp,
+ bta_mse_ma_close_complete,
+};
+
+
+/* state table information */
+#define BTA_MSE_MA_ACTIONS 1 /* number of actions */
+#define BTA_MSE_MA_NEXT_STATE 1 /* position of next state */
+#define BTA_MSE_MA_NUM_COLS 2 /* number of columns in state tables */
+
+
+/* state table for MAS idle state */
+static const UINT8 bta_mse_ma_st_idle[][BTA_MSE_MA_NUM_COLS] =
+{
+/* Event Action 1 Next state */
+/* BTA_MSE_INT_CLOSE_EVT */ {BTA_MSE_MA_IGNORE, BTA_MSE_MA_IDLE_ST},
+/* BTA_MSE_API_ACCESSRSP_EVT */ {BTA_MSE_MA_IGNORE, BTA_MSE_MA_IDLE_ST},
+/* BTA_MSE_API_UPD_IBX_RSP_EVT*/ {BTA_MSE_MA_IGNORE, BTA_MSE_MA_IDLE_ST},
+/* BTA_MSE_API_SET_NOTIF_REG_RSP_EVT*/ {BTA_MSE_MA_IGNORE, BTA_MSE_MA_IDLE_ST},
+/* BTA_MSE_INT_START_EVT */ {BTA_MSE_MA_IGNORE, BTA_MSE_MA_IDLE_ST},
+
+/* BTA_MSE_CI_GET_FENTRY_EVT */ {BTA_MSE_MA_IGNORE, BTA_MSE_MA_IDLE_ST},
+/* BTA_MSE_CI_GET_ML_INFO_EVT */ {BTA_MSE_MA_IGNORE, BTA_MSE_MA_IDLE_ST},
+/* BTA_MSE_CI_GET_ML_ENTRY_EVT*/ {BTA_MSE_MA_IGNORE, BTA_MSE_MA_IDLE_ST},
+/* BTA_MSE_CI_GET_MSG_EVT */ {BTA_MSE_MA_IGNORE, BTA_MSE_MA_IDLE_ST},
+/* BTA_MSE_CI_PUSH_MSG_EVT */ {BTA_MSE_MA_IGNORE, BTA_MSE_MA_IDLE_ST},
+/* BTA_MSE_CI_DEL_MSG_EVT */ {BTA_MSE_MA_IGNORE, BTA_MSE_MA_IDLE_ST},
+
+/* BTA_MSE_MA_OBX_CONN_EVT */ {BTA_MSE_MA_IGNORE, BTA_MSE_MA_IDLE_ST},
+/* BTA_MSE_MA_OBX_DISC_EVT */ {BTA_MSE_MA_IGNORE, BTA_MSE_MA_IDLE_ST},
+/* BTA_MSE_MA_OBX_ABORT_EVT */ {BTA_MSE_MA_IGNORE, BTA_MSE_MA_IDLE_ST},
+/* BTA_MSE_MA_OBX_CLOSE_EVT */ {BTA_MSE_MA_IGNORE, BTA_MSE_MA_IDLE_ST},
+/* BTA_MSE_MA_OBX_PUT_EVT */ {BTA_MSE_MA_IGNORE, BTA_MSE_MA_IDLE_ST},
+/* BTA_MSE_MA_OBX_GET_EVT */ {BTA_MSE_MA_IGNORE, BTA_MSE_MA_IDLE_ST},
+/* BTA_MSE_MA_OBX_SETPATH_EVT*/ {BTA_MSE_MA_IGNORE, BTA_MSE_MA_IDLE_ST},
+/* BTA_MSE_CLOSE_CMPL_EVT */ {BTA_MSE_MA_IGNORE, BTA_MSE_MA_IDLE_ST},
+};
+
+/* state table for obex/rfcomm connection state */
+static const UINT8 bta_mse_ma_st_listen[][BTA_MSE_MA_NUM_COLS] =
+{
+/* Event Action 1 Next state */
+/* BTA_MSE_INT_CLOSE_EVT */ {BTA_MSE_MA_IGNORE, BTA_MSE_MA_LISTEN_ST},
+/* BTA_MSE_API_ACCESSRSP_EVT */ {BTA_MSE_MA_IGNORE, BTA_MSE_MA_LISTEN_ST},
+/* BTA_MSE_API_UPD_IBX_RSP_EVT*/ {BTA_MSE_MA_IGNORE, BTA_MSE_MA_LISTEN_ST},
+/* BTA_MSE_API_SET_NOTIF_REG_RSP_EVT*/{BTA_MSE_MA_IGNORE, BTA_MSE_MA_LISTEN_ST},
+/* BTA_MSE_MA_INT_START_EVT */ {BTA_MSE_MA_IGNORE, BTA_MSE_MA_LISTEN_ST},
+/* BTA_MSE_CI_GET_FENTRY_EVT */ {BTA_MSE_MA_IGNORE, BTA_MSE_MA_LISTEN_ST},
+/* BTA_MSE_CI_GET_ML_INFO_EVT */ {BTA_MSE_MA_IGNORE, BTA_MSE_MA_LISTEN_ST},
+/* BTA_MSE_CI_GET_ML_ENTRY_EVT*/ {BTA_MSE_MA_IGNORE, BTA_MSE_MA_LISTEN_ST},
+/* BTA_MSE_CI_GET_MSG_EVT */ {BTA_MSE_MA_IGNORE, BTA_MSE_MA_LISTEN_ST},
+/* BTA_MSE_CI_PUSH_MSG_EVT */ {BTA_MSE_MA_IGNORE, BTA_MSE_MA_LISTEN_ST},
+/* BTA_MSE_CI_DEL_MSG_EVT */ {BTA_MSE_MA_IGNORE, BTA_MSE_MA_LISTEN_ST},
+/* BTA_MSE_MA_OBX_CONN_EVT */ {BTA_MSE_MA_OBX_CONNECT, BTA_MSE_MA_CONN_ST},
+/* BTA_MSE_MA_OBX_DISC_EVT */ {BTA_MSE_MA_IGNORE, BTA_MSE_MA_LISTEN_ST},
+/* BTA_MSE_MA_OBX_ABORT_EVT */ {BTA_MSE_MA_IGNORE, BTA_MSE_MA_LISTEN_ST},
+/* BTA_MSE_MA_OBX_CLOSE_EVT */ {BTA_MSE_MA_IGNORE, BTA_MSE_MA_LISTEN_ST},
+/* BTA_MSE_MA_OBX_PUT_EVT */ {BTA_MSE_MA_IGNORE, BTA_MSE_MA_LISTEN_ST},
+/* BTA_MSE_MA_OBX_GET_EVT */ {BTA_MSE_MA_IGNORE, BTA_MSE_MA_LISTEN_ST},
+/* BTA_MSE_MA_OBX_SETPATH_EVT*/ {BTA_MSE_MA_IGNORE, BTA_MSE_MA_LISTEN_ST},
+/* BTA_MSE_CLOSE_CMPL_EVT */ {BTA_MSE_MA_IGNORE, BTA_MSE_MA_LISTEN_ST},
+};
+
+/* state table for open state */
+static const UINT8 bta_mse_ma_st_connected[][BTA_MSE_MA_NUM_COLS] =
+{
+/* Event Action 1 Next state */
+/* BTA_MSE_INT_CLOSE_EVT */ {BTA_MSE_MA_INT_CLOSE, BTA_MSE_MA_CLOSING_ST},
+/* BTA_MSE_API_ACCESSRSP_EVT */ {BTA_MSE_MA_API_ACCESSRSP, BTA_MSE_MA_CONN_ST},
+/* BTA_MSE_API_UPD_IBX_RSP_EVT*/ {BTA_MSE_MA_API_UPD_IBX_RSP, BTA_MSE_MA_CONN_ST},
+/* BTA_MSE_API_SET_NOTIF_REG_RSP_EVT*/{BTA_MSE_MA_API_SET_NOTIF_REG_RSP,BTA_MSE_MA_CONN_ST},
+/* BTA_MSE_MA_INT_START_EVT */ {BTA_MSE_MA_IGNORE, BTA_MSE_MA_CONN_ST},
+/* BTA_MSE_CI_GET_FENTRY_EVT */ {BTA_MSE_MA_CI_GET_FENTRY, BTA_MSE_MA_CONN_ST},
+/* BTA_MSE_CI_GET_ML_INFO_EVT */ {BTA_MSE_MA_CI_GET_ML_INFO, BTA_MSE_MA_CONN_ST},
+/* BTA_MSE_CI_GET_ML_ENTRY_EVT*/ {BTA_MSE_MA_CI_GET_ML_ENTRY, BTA_MSE_MA_CONN_ST},
+/* BTA_MSE_CI_GET_MSG_EVT */ {BTA_MSE_MA_CI_GET_MSG, BTA_MSE_MA_CONN_ST},
+/* BTA_MSE_CI_PUSH_MSG_EVT */ {BTA_MSE_MA_CI_PUSH_MSG, BTA_MSE_MA_CONN_ST},
+/* BTA_MSE_CI_DEL_MSG_EVT */ {BTA_MSE_MA_CI_DEL_MSG, BTA_MSE_MA_CONN_ST},
+/* BTA_MSE_MA_OBX_CONN_EVT */ {BTA_MSE_MA_CONN_ERR_RSP, BTA_MSE_MA_CONN_ST},
+/* BTA_MSE_MA_OBX_DISC_EVT */ {BTA_MSE_MA_OBX_DISC, BTA_MSE_MA_CLOSING_ST},
+/* BTA_MSE_MA_OBX_ABORT_EVT */ {BTA_MSE_MA_OBX_ABORT, BTA_MSE_MA_CONN_ST},
+/* BTA_MSE_MA_OBX_CLOSE_EVT */ {BTA_MSE_MA_OBX_CLOSE, BTA_MSE_MA_CLOSING_ST},
+/* BTA_MSE_MA_OBX_PUT_EVT */ {BTA_MSE_MA_OBX_PUT, BTA_MSE_MA_CONN_ST},
+/* BTA_MSE_MA_OBX_GET_EVT */ {BTA_MSE_MA_OBX_GET, BTA_MSE_MA_CONN_ST},
+/* BTA_MSE_MA_OBX_SETPATH_EVT*/ {BTA_MSE_MA_OBX_SETPATH, BTA_MSE_MA_CONN_ST},
+/* BTA_MSE_CLOSE_CMPL_EVT */ {BTA_MSE_MA_IGNORE, BTA_MSE_MA_CONN_ST},
+};
+
+/* state table for closing state */
+static const UINT8 bta_mse_ma_st_closing[][BTA_MSE_MA_NUM_COLS] =
+{
+/* Event Action 1 Next state */
+/* BTA_MSE_INT_CLOSE_EVT */ {BTA_MSE_MA_INT_CLOSE, BTA_MSE_MA_CLOSING_ST},
+/* BTA_MSE_API_ACCESSRSP_EVT */ {BTA_MSE_MA_IGNORE, BTA_MSE_MA_CLOSING_ST},
+/* BTA_MSE_API_UPD_IBX_RSP_EVT*/ {BTA_MSE_MA_IGNORE, BTA_MSE_MA_CLOSING_ST},
+/* BTA_MSE_API_SET_NOTIF_REG_RSP_EVT*/{BTA_MSE_MA_IGNORE, BTA_MSE_MA_CLOSING_ST},
+/* BTA_MSE_MA_INT_START_EVT */ {BTA_MSE_MA_IGNORE, BTA_MSE_MA_CLOSING_ST},
+/* BTA_MSE_CI_GET_FENTRY_EVT */ {BTA_MSE_MA_CLOSE_COMPLETE, BTA_MSE_MA_CLOSING_ST},
+/* BTA_MSE_CI_GET_ML_INFO_EVT*/ {BTA_MSE_MA_CLOSE_COMPLETE, BTA_MSE_MA_CLOSING_ST},
+/* BTA_MSE_CI_GET_ML_ENTRY_EVT*/ {BTA_MSE_MA_CLOSE_COMPLETE, BTA_MSE_MA_CLOSING_ST},
+/* BTA_MSE_CI_GET_MSG_EVT */ {BTA_MSE_MA_CLOSE_COMPLETE, BTA_MSE_MA_CLOSING_ST},
+/* BTA_MSE_CI_PUSH_MSG_EVT */ {BTA_MSE_MA_CLOSE_COMPLETE, BTA_MSE_MA_CLOSING_ST},
+/* BTA_MSE_CI_DEL_MSG_EVT */ {BTA_MSE_MA_CLOSE_COMPLETE, BTA_MSE_MA_CLOSING_ST},
+/* BTA_MSE_MA_OBX_CONN_EVT */ {BTA_MSE_MA_CONN_ERR_RSP, BTA_MSE_MA_CLOSING_ST},
+/* BTA_MSE_MA_OBX_DISC_EVT */ {BTA_MSE_MA_IGNORE, BTA_MSE_MA_CLOSING_ST},
+/* BTA_MSE_MA_OBX_ABORT_EVT */ {BTA_MSE_MA_OBX_ABORT, BTA_MSE_MA_CLOSING_ST},
+/* BTA_MSE_MA_OBX_CLOSE_EVT */ {BTA_MSE_MA_OBX_CLOSE, BTA_MSE_MA_CLOSING_ST},
+/* BTA_MSE_MA_OBX_PUT_EVT */ {BTA_MSE_MA_IGNORE, BTA_MSE_MA_CLOSING_ST},
+/* BTA_MSE_MA_OBX_GET_EVT */ {BTA_MSE_MA_IGNORE, BTA_MSE_MA_CLOSING_ST},
+/* BTA_MSE_MA_OBX_SETPATH_EVT*/ {BTA_MSE_MA_IGNORE, BTA_MSE_MA_CLOSING_ST},
+/* BTA_MSE_CLOSE_CMPL_EVT */ {BTA_MSE_MA_CLOSE_COMPLETE, BTA_MSE_MA_LISTEN_ST},
+};
+
+/* type for state table MAS */
+typedef const UINT8 (*tBTA_MSE_MA_ST_TBL)[BTA_MSE_MA_NUM_COLS];
+
+/* MAS state table */
+const tBTA_MSE_MA_ST_TBL bta_mse_ma_st_tbl[] =
+{
+ bta_mse_ma_st_idle,
+ bta_mse_ma_st_listen,
+ bta_mse_ma_st_connected,
+ bta_mse_ma_st_closing
+};
+
+/*****************************************************************************
+** Message Notification Client State Table
+*****************************************************************************/
+/*****************************************************************************
+** Constants and types
+*****************************************************************************/
+/* state machine action enumeration list for MNC */
+/* The order of this enumeration must be the same as bta_mse_mn_act_tbl[] */
+enum
+{
+ BTA_MSE_MN_INIT_SDP,
+ BTA_MSE_MN_START_CLIENT,
+ BTA_MSE_MN_STOP_CLIENT,
+ BTA_MSE_MN_OBX_CONN_RSP,
+ BTA_MSE_MN_CLOSE,
+ BTA_MSE_MN_SEND_NOTIF,
+ BTA_MSE_MN_RSP_TIMEOUT,
+ BTA_MSE_MN_PUT_RSP,
+ BTA_MSE_MN_OBX_TOUT,
+ BTA_MSE_MN_CLOSE_COMPL,
+ BTA_MSE_MN_ABORT,
+ BTA_MSE_MN_ABORT_RSP,
+ BTA_MSE_MN_SDP_FAIL,
+ BTA_MSE_MN_IGNORE_OBX,
+ BTA_MSE_MN_IGNORE
+};
+
+typedef void (*tBTA_MSE_MN_ACTION)(UINT8 ccb_idx, tBTA_MSE_DATA *p_data);
+
+static const tBTA_MSE_MN_ACTION bta_mse_mn_action[] =
+{
+ bta_mse_mn_init_sdp,
+ bta_mse_mn_start_client,
+ bta_mse_mn_stop_client,
+ bta_mse_mn_obx_conn_rsp,
+ bta_mse_mn_close,
+ bta_mse_mn_send_notif,
+ bta_mse_mn_rsp_timeout,
+ bta_mse_mn_put_rsp,
+ bta_mse_mn_obx_tout,
+ bta_mse_mn_close_compl,
+ bta_mse_mn_abort,
+ bta_mse_mn_abort_rsp,
+ bta_mse_mn_sdp_fail,
+ bta_mse_mn_ignore_obx
+};
+
+
+/* state table information */
+#define BTA_MSE_MN_ACTIONS 1 /* number of actions */
+#define BTA_MSE_MN_ACTION_COL 0 /* position of action */
+#define BTA_MSE_MN_NEXT_STATE 1 /* position of next state */
+#define BTA_MSE_MN_NUM_COLS 2 /* number of columns in state tables */
+
+/* state table for idle state */
+static const UINT8 bta_mse_mn_st_idle[][BTA_MSE_MN_NUM_COLS] =
+{
+/* Event Action 1 Next state */
+/* BTA_MSE_MN_INT_OPEN_EVT */ {BTA_MSE_MN_INIT_SDP, BTA_MSE_MN_W4_CONN_ST},
+/* BTA_MSE_MN_INT_CLOSE_EVT */ {BTA_MSE_MN_IGNORE, BTA_MSE_MN_IDLE_ST},
+/* BTA_MSE_MN_SDP_OK_EVT */ {BTA_MSE_MN_IGNORE, BTA_MSE_MN_IDLE_ST},
+/* BTA_MSE_MN_SDP_FAIL_EVT */ {BTA_MSE_MN_IGNORE, BTA_MSE_MN_IDLE_ST},
+/* BTA_MSE_MN_OBX_CONN_RSP_EVT */ {BTA_MSE_MN_IGNORE_OBX, BTA_MSE_MN_IDLE_ST},
+/* BTA_MSE_MN_OBX_PUT_RSP_EVT */ {BTA_MSE_MN_IGNORE_OBX, BTA_MSE_MN_IDLE_ST},
+/* BTA_MSE_MN_OBX_CLOSE_EVT */ {BTA_MSE_MN_IGNORE_OBX, BTA_MSE_MN_IDLE_ST},
+/* BTA_MSE_MN_OBX_TOUT_EVT */ {BTA_MSE_MN_IGNORE_OBX, BTA_MSE_MN_IDLE_ST},
+/* BTA_MSE_MN_CLOSE_CMPL_EVT */ {BTA_MSE_MN_IGNORE, BTA_MSE_MN_IDLE_ST},
+/* BTA_MSE_API_SEND_NOTIF_EVT */ {BTA_MSE_MN_IGNORE, BTA_MSE_MN_IDLE_ST},
+/* BTA_MSE_API_MN_ABORT_EVT */ {BTA_MSE_MN_IGNORE, BTA_MSE_MN_IDLE_ST},
+/* BTA_MSE_MN_OBX_ABORT_RSP_EVT */ {BTA_MSE_MN_IGNORE, BTA_MSE_MN_IDLE_ST},
+/* BTA_MSE_MN_RSP_TOUT_EVT */ {BTA_MSE_MN_IGNORE, BTA_MSE_MN_IDLE_ST}
+};
+
+
+/* state table for wait for authentication state */
+static const UINT8 bta_mse_mn_st_w4_conn[][BTA_MSE_MN_NUM_COLS] =
+{
+/* Event Action 1 Next state */
+/* BTA_MSE_MN_INT_OPEN_EVT */ {BTA_MSE_MN_IGNORE, BTA_MSE_MN_W4_CONN_ST},
+/* BTA_MSE_MN_INT_CLOSE_EVT */ {BTA_MSE_MN_STOP_CLIENT, BTA_MSE_MN_CLOSING_ST},
+/* BTA_MSE_MN_SDP_OK_EVT */ {BTA_MSE_MN_START_CLIENT, BTA_MSE_MN_W4_CONN_ST},
+/* BTA_MSE_MN_SDP_FAIL_EVT */ {BTA_MSE_MN_SDP_FAIL, BTA_MSE_MN_W4_CONN_ST},
+/* BTA_MSE_MN_OBX_CONN_RSP_EVT */ {BTA_MSE_MN_OBX_CONN_RSP, BTA_MSE_MN_CONN_ST},
+/* BTA_MSE_MN_OBX_PUT_RSP_EVT */ {BTA_MSE_MN_IGNORE, BTA_MSE_MN_W4_CONN_ST},
+/* BTA_MSE_MN_OBX_CLOSE_EVT */ {BTA_MSE_MN_CLOSE, BTA_MSE_MN_CLOSING_ST},
+/* BTA_MSE_MN_OBX_TOUT_EVT */ {BTA_MSE_MN_IGNORE, BTA_MSE_MN_W4_CONN_ST},
+/* BTA_MSE_MN_CLOSE_CMPL_EVT */ {BTA_MSE_MN_IGNORE, BTA_MSE_MN_W4_CONN_ST},
+/* BTA_MSE_API_SEND_NOTIF_EVT */ {BTA_MSE_MN_IGNORE, BTA_MSE_MN_W4_CONN_ST},
+/* BTA_MSE_API_MN_ABORT_EVT */ {BTA_MSE_MN_IGNORE, BTA_MSE_MN_W4_CONN_ST},
+/* BTA_MSE_MN_OBX_ABORT_RSP_EVT */ {BTA_MSE_MN_IGNORE, BTA_MSE_MN_W4_CONN_ST},
+/* BTA_MSE_MN_RSP_TOUT_EVT */ {BTA_MSE_MN_IGNORE, BTA_MSE_MN_W4_CONN_ST}
+};
+
+/* state table for connected state */
+static const UINT8 bta_mse_mn_st_connected[][BTA_MSE_MN_NUM_COLS] =
+{
+/* Event Action 1 Next state */
+/* BTA_MSE_MN_INT_OPEN_EVT */ {BTA_MSE_MN_IGNORE, BTA_MSE_MN_CONN_ST},
+/* BTA_MSE_MN_INT_CLOSE_EVT */ {BTA_MSE_MN_STOP_CLIENT, BTA_MSE_MN_CLOSING_ST},
+/* BTA_MSE_MN_SDP_OK_EVT */ {BTA_MSE_MN_IGNORE, BTA_MSE_MN_CONN_ST},
+/* BTA_MSE_MN_SDP_FAIL_EVT */ {BTA_MSE_MN_IGNORE, BTA_MSE_MN_CONN_ST},
+/* BTA_MSE_MN_OBX_CONN_RSP_EVT */ {BTA_MSE_MN_IGNORE, BTA_MSE_MN_CONN_ST},
+/* BTA_MSE_MN_OBX_PUT_RSP_EVT */ {BTA_MSE_MN_PUT_RSP, BTA_MSE_MN_CONN_ST},
+/* BTA_MSE_MN_OBX_CLOSE_EVT */ {BTA_MSE_MN_CLOSE, BTA_MSE_MN_CLOSING_ST},
+/* BTA_MSE_MN_OBX_TOUT_EVT */ {BTA_MSE_MN_OBX_TOUT, BTA_MSE_MN_CONN_ST},
+/* BTA_MSE_MN_CLOSE_CMPL_EVT */ {BTA_MSE_MN_IGNORE, BTA_MSE_MN_CONN_ST},
+/* BTA_MSE_API_SEND_NOTIF_EVT */ {BTA_MSE_MN_SEND_NOTIF, BTA_MSE_MN_CONN_ST},
+/* BTA_MSE_API_MN_ABORT_EVT */ {BTA_MSE_MN_ABORT, BTA_MSE_MN_CONN_ST},
+/* BTA_MSE_MN_OBX_ABORT_RSP_EVT */ {BTA_MSE_MN_ABORT_RSP, BTA_MSE_MN_CONN_ST},
+/* BTA_MSE_MN_RSP_TOUT_EVT */ {BTA_MSE_MN_RSP_TIMEOUT, BTA_MSE_MN_CLOSING_ST}
+};
+
+/* state table for closing state */
+static const UINT8 bta_mse_mn_st_closing[][BTA_MSE_MN_NUM_COLS] =
+{
+/* Event Action 1 Next state */
+/* BTA_MSE_MN_INT_OPEN_EVT */ {BTA_MSE_MN_IGNORE, BTA_MSE_MN_CLOSING_ST},
+/* BTA_MSE_MN_INT_CLOSE_EVT */ {BTA_MSE_MN_IGNORE, BTA_MSE_MN_CLOSING_ST},
+/* BTA_MSE_MN_SDP_OK_EVT */ {BTA_MSE_MN_CLOSE_COMPL, BTA_MSE_MN_IDLE_ST},
+/* BTA_MSE_MN_SDP_FAIL_EVT */ {BTA_MSE_MN_CLOSE_COMPL, BTA_MSE_MN_IDLE_ST},
+/* BTA_MSE_MN_OBX_CONN_RSP_EVT */ {BTA_MSE_MN_IGNORE, BTA_MSE_MN_CLOSING_ST},
+/* BTA_MSE_MN_OBX_PUT_RSP_EVT */ {BTA_MSE_MN_IGNORE_OBX, BTA_MSE_MN_CLOSING_ST},
+/* BTA_MSE_MN_OBX_CLOSE_EVT */ {BTA_MSE_MN_CLOSE, BTA_MSE_MN_CLOSING_ST},
+/* BTA_MSE_MN_OBX_TOUT_EVT */ {BTA_MSE_MN_IGNORE, BTA_MSE_MN_CLOSING_ST},
+/* BTA_MSE_MN_CLOSE_CMPL_EVT */ {BTA_MSE_MN_CLOSE_COMPL, BTA_MSE_MN_IDLE_ST},
+/* BTA_MSE_API_SEND_NOTIF_EVT */ {BTA_MSE_MN_IGNORE, BTA_MSE_MN_CLOSING_ST},
+/* BTA_MSE_API_MN_ABORT_EVT */ {BTA_MSE_MN_IGNORE, BTA_MSE_MN_CLOSING_ST},
+/* BTA_MSE_MN_OBX_ABORT_RSP_EVT */ {BTA_MSE_MN_IGNORE, BTA_MSE_MN_CLOSING_ST},
+/* BTA_MSE_MN_RSP_TOUT_EVT */ {BTA_MSE_MN_RSP_TIMEOUT, BTA_MSE_MN_CLOSING_ST}
+};
+
+/* type for state table */
+typedef const UINT8 (*tBTA_MSE_MN_ST_TBL)[BTA_MSE_MN_NUM_COLS];
+
+/* state table */
+const tBTA_MSE_MN_ST_TBL bta_mse_mn_st_tbl[] =
+{
+ bta_mse_mn_st_idle,
+ bta_mse_mn_st_w4_conn,
+ bta_mse_mn_st_connected,
+ bta_mse_mn_st_closing
+};
+/*****************************************************************************
+** Global data
+*****************************************************************************/
+
+/* MSE control block */
+#if BTA_DYNAMIC_MEMORY == FALSE
+tBTA_MSE_CB bta_mse_cb;
+#endif
+
+#if (BTA_MSE_DEBUG == TRUE) && (BT_USE_TRACES == TRUE)
+
+static char *bta_mse_evt_code(tBTA_MSE_INT_EVT evt_code);
+static char *bta_mse_ma_state_code(tBTA_MSE_MA_STATE state_code);
+static char *bta_mse_mn_state_code(tBTA_MSE_MN_STATE state_code);
+#endif
+
+/*******************************************************************************
+**
+** Function bta_mse_ma_sm_execute
+**
+** Description State machine event handling function for MA
+**
+** Parameters inst_idx - Index to the MA instance control block
+** sess_idx - Index to the MA session control block
+** event - MA event
+** p_data - Pointer to the event data
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_mse_ma_sm_execute(UINT8 inst_idx, UINT8 sess_idx, UINT16 event, tBTA_MSE_DATA *p_data)
+{
+ tBTA_MSE_MA_ST_TBL state_table;
+ UINT8 action;
+ int i;
+ tBTA_MSE_MA_SESS_CB *p_cb = &(bta_mse_cb.scb[inst_idx].sess_cb[sess_idx]);
+
+#if (BTA_MSE_DEBUG == TRUE) && (BT_USE_TRACES == TRUE)
+ tBTA_MSE_MA_STATE in_state = p_cb->state;
+ UINT16 cur_evt = event;
+ APPL_TRACE_EVENT3("MSE MA Event Handler: State 0x%02x [%s], Event [%s]", in_state,
+ bta_mse_ma_state_code(in_state),
+ bta_mse_evt_code(cur_evt));
+#endif
+
+ /* look up the state table for the current state */
+ state_table = bta_mse_ma_st_tbl[p_cb->state];
+
+ event &= 0x00FF;
+
+ /* set next state */
+ p_cb->state = state_table[event][BTA_MSE_MA_NEXT_STATE];
+
+ /* execute action functions */
+ for (i = 0; i < BTA_MSE_MA_ACTIONS; i++)
+ {
+ if ((action = state_table[event][i]) != BTA_MSE_MA_IGNORE)
+ {
+ (*bta_mse_ma_action[action])(inst_idx, sess_idx, p_data);
+ }
+ else
+ {
+ /* discard mas data */
+ bta_mse_discard_data(p_data->hdr.event, p_data);
+ break;
+ }
+ }
+#if (BTA_MSE_DEBUG == TRUE) && (BT_USE_TRACES == TRUE)
+ if (in_state != p_cb->state)
+ {
+ APPL_TRACE_EVENT3("MSE MA State Change: [%s] -> [%s] after Event [%s]",
+ bta_mse_ma_state_code(in_state),
+ bta_mse_ma_state_code(p_cb->state),
+ bta_mse_evt_code(cur_evt));
+ }
+#endif
+
+}
+
+/*******************************************************************************
+**
+** Function bta_mse_mn_sm_execute
+**
+** Description State machine event handling function for MNC
+**
+** Parameters mn_cb_idx - Index to the MN control block
+** event - MN event
+** p_data - Pointer to the event data
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_mse_mn_sm_execute(UINT8 mn_cb_idx, UINT16 event, tBTA_MSE_DATA *p_data)
+{
+ tBTA_MSE_MN_CB *p_cb = &(bta_mse_cb.ccb[mn_cb_idx]);
+ tBTA_MSE_MN_ST_TBL state_table;
+ UINT8 action;
+ int i;
+
+
+
+#if (BTA_MSE_DEBUG == TRUE) && (BT_USE_TRACES == TRUE)
+ tBTA_MSE_MN_STATE in_state = p_cb->state;
+ UINT16 cur_evt = event;
+ APPL_TRACE_EVENT3("MSE MN Event Handler: State 0x%02x [%s], Event [%s]", in_state,
+ bta_mse_mn_state_code(in_state),
+ bta_mse_evt_code(cur_evt));
+#endif
+
+ /* look up the state table for the current state */
+ state_table = bta_mse_mn_st_tbl[p_cb->state];
+ event -= BTA_MSE_MN_EVT_MIN;
+
+ /* set next state */
+ p_cb->state = state_table[event][BTA_MSE_MN_NEXT_STATE];
+
+ /* execute action functions */
+ for (i = 0; i < BTA_MSE_MN_ACTIONS; i++)
+ {
+ if ((action = state_table[event][i]) != BTA_MSE_MN_IGNORE)
+ {
+ (*bta_mse_mn_action[action])(mn_cb_idx, p_data);
+ }
+ else
+ {
+ /* discard mas data */
+ bta_mse_discard_data(p_data->hdr.event, p_data);
+ break;
+ }
+ }
+
+
+#if (BTA_MSE_DEBUG == TRUE) && (BT_USE_TRACES == TRUE)
+ if (in_state != p_cb->state)
+ {
+ APPL_TRACE_EVENT3("MSE MN State Change: [%s] -> [%s] after Event [%s]",
+ bta_mse_mn_state_code(in_state),
+ bta_mse_mn_state_code(p_cb->state),
+ bta_mse_evt_code(cur_evt));
+ }
+#endif
+}
+/*******************************************************************************
+**
+** Function bta_mse_ma_api_enable
+**
+** Description Process API enable request to enable MCE subsystem
+**
+** Parameters p_cb - Pointer to MSE control block
+** p_data - Pointer to MSE event data
+**
+** Returns void
+**
+*******************************************************************************/
+static void bta_mse_ma_api_enable(tBTA_MSE_CB *p_cb, tBTA_MSE_DATA *p_data)
+{
+ tBTA_MSE evt_data;
+
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT0("bta_mse_ma_api_enable" );
+#endif
+ /* If already enabled then reject this request */
+ if (p_cb->enable)
+ {
+ APPL_TRACE_ERROR0("MSE is already enabled");
+ evt_data.enable.app_id = p_data->api_enable.app_id;
+ evt_data.enable.status = BTA_MA_STATUS_FAIL;
+ p_data->api_enable.p_cback(BTA_MSE_ENABLE_EVT, (tBTA_MSE *) &evt_data);
+ return;
+ }
+
+ /* Done with checking. now perform the enable oepration*/
+ /* initialize control block */
+ memset(p_cb, 0, sizeof(tBTA_MSE_CB));
+
+ p_cb->p_cback = p_data->api_enable.p_cback;
+ p_cb->app_id = p_data->api_enable.app_id;
+ p_cb->enable = TRUE;
+
+ evt_data.enable.app_id = p_cb->app_id;
+ evt_data.enable.status = BTA_MA_STATUS_OK;
+ p_cb->p_cback(BTA_MSE_ENABLE_EVT, (tBTA_MSE *) &evt_data);
+}
+/*******************************************************************************
+**
+** Function bta_mse_ma_api_disable
+**
+** Description Process API disable request
+**
+** Parameters p_cb - Pointer to MSE control block
+** p_data - Pointer to MSE event data
+**
+** Returns void
+**
+*******************************************************************************/
+static void bta_mse_ma_api_disable(tBTA_MSE_CB *p_cb, tBTA_MSE_DATA *p_data)
+{
+ tBTA_MSE evt_data;
+ tBTA_MA_STATUS status = BTA_MA_STATUS_OK;
+ UINT8 app_id = p_data->api_disable.app_id;
+ UINT8 i,j, num_act_mas=0, num_act_sess=0;
+ tBTA_MSE_MA_CB *p_scb;
+ tBTA_MSE_MA_SESS_CB *p_sess_cb;
+ BOOLEAN send_disable_evt =FALSE;
+ tBTA_MSE_MN_CB *p_ccb;
+
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT0("bta_mse_ma_api_disable" );
+#endif
+
+ if (p_cb->enable)
+ {
+ /* close all MN connections */
+ for (i=0; i < BTA_MSE_NUM_MN; i ++)
+ {
+ p_ccb = BTA_MSE_GET_MN_CB_PTR(i);
+ if (p_ccb->in_use &&
+ (p_ccb->state != BTA_MSE_MN_IDLE_ST))
+ {
+ bta_mse_mn_remove_all_inst_ids(i);
+ bta_mse_mn_sm_execute(i,BTA_MSE_MN_INT_CLOSE_EVT, NULL);
+ }
+ }
+
+ for (i=0; i < BTA_MSE_NUM_INST ; i ++)
+ {
+ p_scb = BTA_MSE_GET_INST_CB_PTR(i);
+ if (p_scb->in_use )
+ {
+ num_act_mas++;
+ p_cb->disabling = TRUE;
+ p_scb->stopping = TRUE;
+ num_act_sess =0;
+ for (j=0; j<BTA_MSE_NUM_SESS; j++ )
+ {
+ p_sess_cb = BTA_MSE_GET_SESS_CB_PTR(i, j);
+ if (p_sess_cb->state != BTA_MSE_MA_LISTEN_ST)
+ {
+ bta_mse_ma_sm_execute(i, j, BTA_MSE_INT_CLOSE_EVT, p_data);
+ num_act_sess++;
+ }
+ }
+
+ if (!num_act_sess)
+ {
+ evt_data.stop.status = BTA_MA_STATUS_OK;
+ evt_data.stop.mas_instance_id = p_scb->mas_inst_id;
+ p_cb->p_cback(BTA_MSE_STOP_EVT, (tBTA_MSE *) &evt_data);
+ bta_mse_clean_mas_service(i);
+ num_act_mas--;
+ }
+ }
+ }
+
+ if (!num_act_mas)
+ {
+ send_disable_evt = TRUE;
+ p_cb->enable = FALSE;
+ }
+ }
+ else
+ {
+ send_disable_evt = TRUE;
+ status = BTA_MA_STATUS_FAIL;
+ }
+
+
+ if (send_disable_evt)
+ {
+ evt_data.enable.app_id = app_id;
+ evt_data.enable.status = status;
+ p_cb->p_cback(BTA_MSE_DISABLE_EVT, (tBTA_MSE *) &evt_data);
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT0("MSE Disabled location-1");
+#endif
+ }
+
+}
+/*******************************************************************************
+**
+** Function bta_mse_ma_api_start
+**
+** Description Process API MA server start request
+**
+** Parameters p_cb - Pointer to MSE control block
+** p_data - Pointer to MSE event data
+**
+** Returns void
+**
+*******************************************************************************/
+static void bta_mse_ma_api_start(tBTA_MSE_CB *p_cb, tBTA_MSE_DATA *p_data)
+{
+ UINT8 i = 0;
+ tBTA_MSE evt_data; /* event call back */
+ tBTA_MSE_MA_CB *p_scb = NULL; /* MA instance control block*/
+ tOBX_StartParams start_msg;
+ tBTA_MSE_API_START *p_api = &p_data->api_start;
+ tOBX_TARGET target;
+ tOBX_STATUS status;
+ tBTA_UTL_COD cod;
+ UINT8 mas_instance_idx;
+ UINT16 root_folder_len;
+ tBTA_MA_STATUS ma_status = BTA_MA_STATUS_OK;
+
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT0("bta_mse_ma_api_start" );
+#endif
+ if (!p_cb->enable || ((p_cb->enable) && bta_mse_is_a_duplicate_id(p_api->mas_inst_id)) )
+ {
+ ma_status = BTA_MA_STATUS_DUPLICATE_ID;
+ }
+
+ if ((ma_status == BTA_MA_STATUS_OK) && bta_mse_find_avail_mas_inst_cb_idx(&mas_instance_idx))
+ {
+ APPL_TRACE_EVENT1("bta_mse_ma_api_start inst_idx=%d",mas_instance_idx );
+
+ /* initialize the MA Instance control block */
+ p_scb = &(p_cb->scb[mas_instance_idx]);
+ memset(p_scb, 0, sizeof(tBTA_MSE_MA_CB));
+
+ p_scb->in_use = TRUE;
+ BCM_STRNCPY_S(p_scb->servicename, sizeof(p_scb->servicename), p_api->servicename, BTA_SERVICE_NAME_LEN);
+ p_scb->mas_inst_id = p_api->mas_inst_id;
+ p_scb->sec_mask = p_api->sec_mask;
+ p_scb->sup_msg_type = p_api->sup_msg_type;
+
+ /* If directory is specified set the length */
+ root_folder_len = p_bta_fs_cfg->max_path_len + 1;
+
+ /* Allocate an aligned memory buffer to hold the root path in the */
+ /* MAS instance cb as well as the session cbs */
+ /* Add 1 byte for '\0' */
+ if ((p_scb->p_rootpath = (char *)GKI_getbuf((UINT16)(root_folder_len+1))) != NULL)
+ {
+ memcpy(target.target, BTA_MAS_MESSAGE_ACCESS_TARGET_UUID, BTA_MAS_UUID_LENGTH);
+ target.len = BTA_MAS_UUID_LENGTH;
+ p_scb->scn = BTM_AllocateSCN();
+ BCM_STRNCPY_S(p_scb->p_rootpath, root_folder_len+1, p_api->p_root_path, root_folder_len);
+ p_scb->p_rootpath[root_folder_len] = '\0';
+
+ /* Register MAP security requirements with BTM */
+ BTM_SetSecurityLevel(FALSE, p_api->servicename, BTM_SEC_SERVICE_MAP,
+ p_api->sec_mask, BT_PSM_RFCOMM,
+ BTM_SEC_PROTO_RFCOMM, (UINT32)p_scb->scn);
+
+ /* Start up the MSE service */
+ memset(&start_msg, 0, sizeof(tOBX_StartParams));
+ start_msg.p_target = &target;
+ /* Make the MTU fit into one RFC frame */
+ start_msg.mtu = OBX_MAX_MTU;
+ start_msg.scn = p_scb->scn;
+ start_msg.authenticate = FALSE; /* OBX authentication is disabled */
+ start_msg.auth_option = (UINT8) NULL;
+ start_msg.p_cback = bta_mse_ma_obx_cback;
+ start_msg.realm_len =(UINT8) NULL;
+ start_msg.p_realm = (UINT8) NULL;
+ start_msg.realm_charset = (tOBX_CHARSET) NULL;
+ start_msg.max_sessions = BTA_MSE_NUM_SESS;
+
+ if ((status = OBX_StartServer (&start_msg, &p_scb->obx_handle)) == OBX_SUCCESS)
+ {
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT1("Obx start for MAS server: obx_hdl=%d", p_scb->obx_handle);
+#endif
+ /* initialze all session states */
+ for (i=0; i<BTA_MSE_NUM_SESS; i++ )
+ {
+ p_scb->sess_cb[i].state = BTA_MSE_MA_LISTEN_ST;
+ }
+
+ if (ma_status == BTA_MA_STATUS_OK)
+ {
+ /* Set the File Transfer service class bit */
+ cod.service = BTM_COD_SERVICE_OBJ_TRANSFER;
+ utl_set_device_class(&cod, BTA_UTL_SET_COD_SERVICE_CLASS);
+
+ /* Set up the SDP record for pbs service */
+ bta_mse_ma_sdp_register(p_scb, p_api->servicename, p_scb->mas_inst_id, p_scb->sup_msg_type );
+ }
+ else
+ {
+ /* release resources */
+ OBX_StopServer(p_scb->obx_handle);
+ for (i=0; i < BTA_MSE_NUM_SESS; i++ )
+ {
+ utl_freebuf((void**)&p_scb->sess_cb[i].p_workdir );
+ }
+ }
+ }
+ else
+ {
+ /* release resources */
+ utl_freebuf((void**)&p_scb->p_rootpath);
+ APPL_TRACE_ERROR1("OBX_StartServer returns error (%d)", status);
+ ma_status = BTA_MA_STATUS_NO_RESOURCE;
+ }
+ }
+ else /* Cannot allocate resources to run Server */
+ {
+ APPL_TRACE_ERROR0("Not enough Resources to run MSE Server");
+ ma_status = BTA_MA_STATUS_NO_RESOURCE;
+ }
+
+ if (ma_status != BTA_MA_STATUS_OK)
+ {
+ /* clearn up the contrl block*/
+ memset(p_scb, 0, sizeof(tBTA_MSE_MA_CB));
+ }
+ }
+
+ evt_data.start.mas_instance_id = p_api->mas_inst_id;
+ evt_data.start.status = ma_status;
+ p_cb->p_cback(BTA_MSE_START_EVT, (tBTA_MSE *) &evt_data);
+
+}
+/*******************************************************************************
+**
+** Function bta_mse_ma_api_stop
+**
+** Description Process API MA server stop request
+**
+** Parameters p_cb - Pointer to MSE control block
+** p_data - Pointer to MSE event data
+**
+** Returns void
+**
+*******************************************************************************/
+static void bta_mse_ma_api_stop(tBTA_MSE_CB *p_cb, tBTA_MSE_DATA *p_data)
+{
+ tBTA_MSE_API_STOP *p_stop = &p_data->api_stop;
+ BOOLEAN send_stop_evt = FALSE;
+ tBTA_MA_STATUS status = BTA_MA_STATUS_OK;
+ tBTA_MSE_MA_CB *p_scb;
+ tBTA_MSE_MA_SESS_CB *p_sess_cb;
+ tBTA_MSE_MN_CB *p_ccb;
+ UINT8 i, inst_idx;
+ UINT8 num_act_sess=0;
+ tBTA_MSE evt_data;
+
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT0("bta_mse_ma_api_stop" );
+#endif
+
+
+ if (bta_mse_find_mas_inst_id_match_cb_idx(p_stop->mas_inst_id, &inst_idx))
+ {
+ p_scb = BTA_MSE_GET_INST_CB_PTR(inst_idx);
+ p_scb->stopping = TRUE;
+
+ for (i=0; i < BTA_MSE_NUM_MN; i ++)
+ {
+ p_ccb = BTA_MSE_GET_MN_CB_PTR(i);
+ if (p_ccb->in_use &&
+ (p_ccb->state != BTA_MSE_MN_IDLE_ST) &&
+ bta_mse_mn_is_ok_to_close_mn(p_ccb->bd_addr,p_scb->mas_inst_id))
+ {
+ /* close the MN connection if mas_inst_id is the last active inst_id */
+ bta_mse_mn_remove_inst_id(i, p_scb->mas_inst_id);
+ bta_mse_mn_sm_execute(i,BTA_MSE_MN_INT_CLOSE_EVT, NULL);
+ }
+ }
+ /* close all active session */
+ for (i=0; i < BTA_MSE_NUM_SESS; i ++)
+ {
+ p_sess_cb = &(p_scb->sess_cb[i]);
+ if (p_sess_cb->state != BTA_MSE_MA_LISTEN_ST)
+ {
+ APPL_TRACE_EVENT2("Send API CLOSE to SM for STOP sess ind=%d state=%d",i,p_sess_cb->state);
+ bta_mse_ma_sm_execute(inst_idx, i, BTA_MSE_INT_CLOSE_EVT, p_data);
+ num_act_sess++;
+ }
+ }
+
+ if (!num_act_sess)
+ {
+ bta_mse_clean_mas_service(inst_idx);
+ send_stop_evt = TRUE;
+ }
+ }
+ else
+ {
+ send_stop_evt = TRUE;
+ status = BTA_MA_STATUS_FAIL;
+ }
+
+ if (send_stop_evt)
+ {
+ evt_data.stop.status = status;
+ evt_data.stop.mas_instance_id = p_stop->mas_inst_id;
+ p_cb->p_cback(BTA_MSE_STOP_EVT, (tBTA_MSE *) &evt_data);
+ }
+}
+
+/*******************************************************************************
+**
+** Function bta_mse_ma_api_close
+**
+** Description Process API close request. It will close all MA
+** sesions on the specified MAS instance ID
+**
+** Parameters p_cb - Pointer to MSE control block
+** p_data - Pointer to MSE event data
+**
+** Returns void
+**
+*******************************************************************************/
+static void bta_mse_ma_api_close(tBTA_MSE_CB *p_cb, tBTA_MSE_DATA *p_data)
+{
+ tBTA_MSE_API_CLOSE *p_close = &p_data->api_close;
+ BOOLEAN send_close_evt = FALSE;
+ tBTA_MA_STATUS status = BTA_MA_STATUS_OK;
+ tBTA_MSE_MA_CB *p_scb;
+ tBTA_MSE_MA_SESS_CB *p_sess_cb;
+ UINT8 i, inst_idx;
+ UINT8 num_act_sess=0;
+ tBTA_MSE evt_data;
+
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT0("bta_mse_ma_api_close" );
+#endif
+ if (bta_mse_find_mas_inst_id_match_cb_idx(p_close->mas_instance_id, &inst_idx))
+ {
+ p_scb = BTA_MSE_GET_INST_CB_PTR(inst_idx);
+ /* close all active sessions for the specified MA Server */
+ for (i=0; i < BTA_MSE_NUM_SESS; i ++)
+ {
+ p_sess_cb = &(p_scb->sess_cb[i]);
+ if (p_sess_cb->state != BTA_MSE_MA_LISTEN_ST)
+ {
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT4("Disconnect inst_id=%d, sess_id=%d, inst_idx=%d, sess_idx=%d",
+ p_close->mas_instance_id,
+ p_sess_cb->obx_handle,
+ inst_idx,
+ i);
+#endif
+
+ bta_mse_ma_sm_execute(inst_idx, i, BTA_MSE_INT_CLOSE_EVT, p_data);
+ num_act_sess++;
+ }
+ }
+
+ if (!num_act_sess)
+ {
+ send_close_evt = TRUE;
+ }
+ }
+ else
+ {
+ send_close_evt = TRUE;
+ status = BTA_MA_STATUS_FAIL;
+ }
+
+ if (send_close_evt)
+ {
+ evt_data.ma_close.status = status;
+ evt_data.ma_close.mas_session_id = 0;
+ evt_data.ma_close.mas_instance_id = p_close->mas_instance_id ;
+ p_cb->p_cback(BTA_MSE_MA_CLOSE_EVT, (tBTA_MSE *) &evt_data);
+ }
+}
+
+/*******************************************************************************
+**
+** Function bta_mse_ma_api_ma_close
+**
+** Description Process API MA close request. It will close the
+** specified MA session.
+**
+** Parameters p_cb - Pointer to MSE control block
+** p_data - Pointer to MSE event data
+**
+**
+** Returns void
+**
+*******************************************************************************/
+static void bta_mse_ma_api_ma_close(tBTA_MSE_CB *p_cb, tBTA_MSE_DATA *p_data)
+{
+ tBTA_MSE_API_MA_CLOSE *p_ma_close = &p_data->api_ma_close;
+ UINT8 inst_idx, sess_idx;
+ tBTA_MSE evt_data;
+
+
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT0("bta_mse_ma_api_ma_close" );
+#endif
+
+ if (bta_mse_find_mas_inst_id_match_cb_idx (p_ma_close->mas_instance_id, &inst_idx)&&
+ bta_mse_find_bd_addr_match_sess_cb_idx(p_ma_close->bd_addr,inst_idx,&sess_idx))
+ {
+ bta_mse_ma_sm_execute(inst_idx, sess_idx, BTA_MSE_INT_CLOSE_EVT, p_data);
+ }
+ else
+ {
+ evt_data.ma_close.mas_session_id = 0xFF;
+ evt_data.ma_close.mas_instance_id = p_ma_close->mas_instance_id;
+ evt_data.ma_close.status = BTA_MA_STATUS_FAIL ;
+ p_cb->p_cback(BTA_MSE_MA_CLOSE_EVT, (tBTA_MSE *) &evt_data);
+ }
+}
+
+
+/*******************************************************************************
+**
+** Function bta_mse_mn_api_close
+**
+** Description Process API MN close request.
+**
+** Parameters p_cb - Pointer to MSE control block
+** p_data - Pointer to MSE event data
+**
+** Returns void
+**
+*******************************************************************************/
+static void bta_mse_mn_api_close(tBTA_MSE_CB *p_cb, tBTA_MSE_DATA *p_data)
+{
+ tBTA_MSE_API_MN_CLOSE *p_mn_close = &p_data->api_mn_close;
+ UINT8 ccb_idx;
+ tBTA_MSE evt_data;
+
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT0("bta_mse_mn_api_close" );
+#endif
+
+ if (bta_mse_find_bd_addr_match_mn_cb_index(p_mn_close->bd_addr, &ccb_idx))
+ {
+ bta_mse_mn_sm_execute(ccb_idx, BTA_MSE_MN_INT_CLOSE_EVT, p_data);
+ }
+ else
+ {
+ evt_data.mn_close.bd_addr[0] = '\0';
+ evt_data.mn_close.dev_name[0] = '\0';
+ p_cb->p_cback(BTA_MSE_MN_CLOSE_EVT, (tBTA_MSE *) &evt_data);
+ }
+}
+
+/*******************************************************************************
+**
+** Function bta_mse_mn_api_send_notif
+**
+** Description Process API send message notification report to all MCEs
+** registered with the specified MAS instance ID
+**
+** Parameters p_cb - Pointer to MSE control block
+** p_data - Pointer to MSE event data
+**
+** Returns void
+**
+*******************************************************************************/
+static void bta_mse_mn_api_send_notif(tBTA_MSE_CB *p_cb, tBTA_MSE_DATA *p_data)
+{
+ tBTA_MSE_MN_API_SEND_NOTIF *p_mn_send_notif = &p_data->mn_send_notif;
+ UINT8 i;
+ tBTA_MSE evt_data;
+ tBTA_MSE_MN_CB *p_ccb;
+ UINT8 active_sess_cnt;
+
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT0("bta_mse_mn_api_send_notif" );
+#endif
+
+ active_sess_cnt =0 ;
+ for (i=0; i < BTA_MSE_NUM_MN; i ++)
+ {
+ p_ccb = BTA_MSE_GET_MN_CB_PTR(i);
+
+ if (p_ccb->in_use &&
+ (p_ccb->state == BTA_MSE_MN_CONN_ST) &&
+ (memcmp(p_ccb->bd_addr, p_mn_send_notif->except_bd_addr, BD_ADDR_LEN) != 0 ) &&
+ bta_mse_mn_is_inst_id_exist(i,p_mn_send_notif->mas_instance_id))
+ {
+ bta_mse_mn_sm_execute(i, BTA_MSE_API_SEND_NOTIF_EVT, p_data);
+ active_sess_cnt++;
+ }
+ }
+
+ if (!active_sess_cnt)
+ {
+ evt_data.send_notif.mas_instance_id = p_mn_send_notif->mas_instance_id;
+ evt_data.send_notif.status = BTA_MA_STATUS_FAIL;
+ memset(evt_data.send_notif.bd_addr,0, sizeof(evt_data.send_notif.bd_addr));
+ p_cb->p_cback(BTA_MSE_SEND_NOTIF_EVT, (tBTA_MSE *) &evt_data);
+ }
+
+}
+
+
+/*******************************************************************************
+**
+** Function bta_mse_mn_api_abort
+**
+** Description Abort the current OBEX multi-packet oepration
+**
+** Parameters p_cb - Pointer to MSE control block
+** p_data - Pointer to MSE event data
+**
+** Returns void
+**
+*******************************************************************************/
+static void bta_mse_mn_api_abort(tBTA_MSE_CB *p_cb, tBTA_MSE_DATA *p_data)
+{
+ tBTA_MSE_MN_API_ABORT *p_mn_abort = &p_data->mn_abort;
+ UINT8 i;
+ tBTA_MSE_MN_CB *p_ccb;
+
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT0("bta_mse_mn_api_abort" );
+#endif
+
+ for (i=0; i < BTA_MSE_NUM_MN; i ++)
+ {
+ p_ccb = BTA_MSE_GET_MN_CB_PTR(i);
+ if (p_ccb->in_use &&
+ (p_ccb->state == BTA_MSE_MN_CONN_ST) &&
+ bta_mse_mn_is_inst_id_exist(i,p_mn_abort->mas_instance_id))
+ {
+ bta_mse_mn_sm_execute(i, BTA_MSE_API_MN_ABORT_EVT, p_data);
+ }
+ }
+
+}
+
+/*******************************************************************************
+**
+** Function bta_mse_mn_rsp_tout
+**
+** Description Process MN response timer timeout event
+**
+** Parameters p_cb - Pointer to MSE control block
+** p_data - Pointer to MSE event data
+**
+** Returns void
+**
+*******************************************************************************/
+static void bta_mse_mn_rsp_tout(tBTA_MSE_CB *p_cb, tBTA_MSE_DATA *p_data)
+{
+ UINT8 ccb_idx;
+
+ ccb_idx = (UINT8)(p_data->hdr.event - BTA_MSE_MN_RSP0_TOUT_EVT);
+
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT1("bta_mse_mn_rsp_tout ccd_idx=%d",ccb_idx);
+#endif
+ bta_mse_mn_sm_execute(ccb_idx, BTA_MSE_MN_RSP_TOUT_EVT, p_data);
+}
+/*******************************************************************************
+**
+** Function bta_mse_hdl_event
+**
+** Description MSE main event handling function.
+**
+** Parameters p_msg - Pointer to MSE event data
+**
+** Returns void
+**
+*******************************************************************************/
+BOOLEAN bta_mse_hdl_event(BT_HDR *p_msg){
+ UINT8 inst_idx, sess_idx, ccb_idx;
+ BOOLEAN success = TRUE;
+
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT1("MSE Event Handler: Event [%s]",
+ bta_mse_evt_code(p_msg->event));
+#endif
+
+ switch (p_msg->event)
+ {
+ case BTA_MSE_API_ENABLE_EVT:
+ bta_mse_ma_api_enable(&bta_mse_cb, (tBTA_MSE_DATA *) p_msg);
+ break;
+
+ case BTA_MSE_API_START_EVT:
+ bta_mse_ma_api_start(&bta_mse_cb, (tBTA_MSE_DATA *) p_msg);
+ break;
+
+ case BTA_MSE_API_STOP_EVT:
+ bta_mse_ma_api_stop(&bta_mse_cb, (tBTA_MSE_DATA *) p_msg);
+ break;
+
+ case BTA_MSE_API_DISABLE_EVT:
+ bta_mse_ma_api_disable(&bta_mse_cb, (tBTA_MSE_DATA *) p_msg);
+ break;
+
+ case BTA_MSE_API_CLOSE_EVT:
+ bta_mse_ma_api_close(&bta_mse_cb, (tBTA_MSE_DATA *) p_msg);
+ break;
+
+ case BTA_MSE_API_MA_CLOSE_EVT:
+ bta_mse_ma_api_ma_close(&bta_mse_cb, (tBTA_MSE_DATA *) p_msg);
+ break;
+
+ case BTA_MSE_API_MN_CLOSE_EVT:
+ bta_mse_mn_api_close(&bta_mse_cb, (tBTA_MSE_DATA *) p_msg);
+ break;
+
+ case BTA_MSE_API_SEND_NOTIF_EVT:
+ bta_mse_mn_api_send_notif(&bta_mse_cb, (tBTA_MSE_DATA *) p_msg);
+ break;
+
+ case BTA_MSE_API_MN_ABORT_EVT:
+ bta_mse_mn_api_abort(&bta_mse_cb, (tBTA_MSE_DATA *) p_msg);
+ break;
+
+ case BTA_MSE_MN_RSP0_TOUT_EVT:
+ case BTA_MSE_MN_RSP1_TOUT_EVT:
+ case BTA_MSE_MN_RSP2_TOUT_EVT:
+ case BTA_MSE_MN_RSP3_TOUT_EVT:
+ case BTA_MSE_MN_RSP4_TOUT_EVT:
+ case BTA_MSE_MN_RSP5_TOUT_EVT:
+ case BTA_MSE_MN_RSP6_TOUT_EVT:
+ bta_mse_mn_rsp_tout(&bta_mse_cb, (tBTA_MSE_DATA *) p_msg);
+ break;
+
+ default:
+
+ if (p_msg->event < BTA_MSE_MN_EVT_MIN)
+ {
+ if (bta_mse_find_ma_cb_indexes((tBTA_MSE_DATA *) p_msg, &inst_idx, &sess_idx))
+ {
+ bta_mse_ma_sm_execute( inst_idx ,
+ sess_idx ,
+ p_msg->event, (tBTA_MSE_DATA *) p_msg);
+ }
+ else
+ {
+ APPL_TRACE_ERROR1("unable to find inst_idx and sess_idx: event=%s",
+ bta_mse_evt_code(p_msg->event));
+ success = FALSE;
+ bta_mse_ma_cleanup ((tBTA_MSE_DATA *) p_msg);
+ }
+ }
+ else
+ {
+ if (bta_mse_find_mn_cb_index((tBTA_MSE_DATA *) p_msg, &ccb_idx))
+ {
+ bta_mse_mn_sm_execute( ccb_idx,
+ p_msg->event ,
+ (tBTA_MSE_DATA *) p_msg);
+ }
+ else
+ {
+ APPL_TRACE_ERROR1("unable to find ccb_idx: event=%s",
+ bta_mse_evt_code(p_msg->event));
+ success = FALSE;
+ bta_mse_mn_cleanup ((tBTA_MSE_DATA *) p_msg);
+ }
+ }
+ break;
+ }
+
+ return(success);
+}
+
+
+/*****************************************************************************
+** Debug Functions
+*****************************************************************************/
+#if (BTA_MSE_DEBUG == TRUE) && (BT_USE_TRACES == TRUE)
+/*******************************************************************************
+**
+** Function bta_mse_ma_evt_code
+**
+** Description Maps MA event code to the corresponding event string
+**
+** Parameters evt_code - MA event code
+**
+** Returns string pointer for the associated event name
+**
+*******************************************************************************/
+static char *bta_mse_evt_code(tBTA_MSE_INT_EVT evt_code){
+ switch (evt_code)
+ {
+ case BTA_MSE_API_CLOSE_EVT:
+ return "BTA_MSE_API_CLOSE_EVT";
+ case BTA_MSE_API_MA_CLOSE_EVT:
+ return "BTA_MSE_API_MA_CLOSE_EVT";
+ case BTA_MSE_API_MN_CLOSE_EVT:
+ return "BTA_MSE_API_MN_CLOSE_EVT";
+ case BTA_MSE_INT_CLOSE_EVT:
+ return "BTA_MSE_INT_CLOSE_EVT";
+ case BTA_MSE_API_ACCESSRSP_EVT:
+ return "BTA_MSE_API_ACCESSRSP_EVT";
+ case BTA_MSE_API_UPD_IBX_RSP_EVT:
+ return "BTA_MSE_API_UPD_IBX_RSP_EVT";
+ case BTA_MSE_API_SET_NOTIF_REG_RSP_EVT:
+ return "BTA_MSE_API_SET_NOTIF_REG_RSP_EVT";
+ case BTA_MSE_INT_START_EVT:
+ return "BTA_MSE_INT_START_EVT";
+ case BTA_MSE_CI_GET_FENTRY_EVT:
+ return "BTA_MSE_CI_GET_FENTRY_EVT";
+ case BTA_MSE_CI_GET_ML_INFO_EVT:
+ return "BTA_MSE_CI_GET_ML_INFO_EVT";
+ case BTA_MSE_CI_GET_ML_ENTRY_EVT:
+ return "BTA_MSE_CI_GET_ML_ENTRY_EVT";
+ case BTA_MSE_CI_GET_MSG_EVT:
+ return "BTA_MSE_CI_GET_MSG_EVT";
+ case BTA_MSE_CI_PUSH_MSG_EVT:
+ return "BTA_MSE_CI_PUSH_MSG_EVT";
+ case BTA_MSE_CI_DEL_MSG_EVT:
+ return "BTA_MSE_CI_DEL_MSG_EVT";
+ case BTA_MSE_MA_OBX_CONN_EVT:
+ return "BTA_MSE_MA_OBX_CONN_EVT";
+ case BTA_MSE_MA_OBX_DISC_EVT:
+ return "BTA_MSE_MA_OBX_DISC_EVT";
+ case BTA_MSE_MA_OBX_ABORT_EVT:
+ return "BTA_MSE_MA_OBX_ABORT_EVT";
+ case BTA_MSE_MA_OBX_CLOSE_EVT:
+ return "BTA_MSE_MA_OBX_CLOSE_EVT";
+ case BTA_MSE_MA_OBX_PUT_EVT:
+ return "BTA_MSE_MA_OBX_PUT_EVT";
+ case BTA_MSE_MA_OBX_GET_EVT:
+ return "BTA_MSE_MA_OBX_GET_EVT";
+ case BTA_MSE_MA_OBX_SETPATH_EVT:
+ return "BTA_MSE_MA_OBX_SETPATH_EVT";
+ case BTA_MSE_CLOSE_CMPL_EVT:
+ return "BTA_MSE_CLOSE_CMPL_EVT";
+ case BTA_MSE_MN_INT_OPEN_EVT:
+ return "BTA_MSE_MN_INT_OPEN_EVT";
+ case BTA_MSE_MN_INT_CLOSE_EVT:
+ return "BTA_MSE_MN_INT_CLOSE_EVT";
+ case BTA_MSE_MN_SDP_OK_EVT:
+ return "BTA_MSE_MN_SDP_OK_EVT";
+ case BTA_MSE_MN_SDP_FAIL_EVT:
+ return "BTA_MSE_MN_SDP_FAIL_EVT";
+ case BTA_MSE_MN_OBX_CONN_RSP_EVT:
+ return "BTA_MSE_MN_OBX_CONN_RSP_EVT";
+ case BTA_MSE_MN_OBX_PUT_RSP_EVT:
+ return "BTA_MSE_MN_OBX_PUT_RSP_EVT";
+ case BTA_MSE_MN_OBX_CLOSE_EVT:
+ return "BTA_MSE_MN_OBX_CLOSE_EVT";
+ case BTA_MSE_MN_OBX_TOUT_EVT:
+ return "BTA_MSE_MN_OBX_TOUT_EVT";
+ case BTA_MSE_MN_CLOSE_CMPL_EVT:
+ return "BTA_MSE_MN_CLOSE_CMPL_EVT";
+ case BTA_MSE_API_SEND_NOTIF_EVT:
+ return "BTA_MSE_API_SEND_NOTIF_EVT";
+ case BTA_MSE_API_MN_ABORT_EVT:
+ return "BTA_MSE_API_MN_ABORT_EVT";
+ case BTA_MSE_MN_OBX_ABORT_RSP_EVT:
+ return "BTA_MSE_MN_OBX_ABORT_RSP_EVT";
+ case BTA_MSE_API_ENABLE_EVT:
+ return "BTA_MSE_API_ENABLE_EVT";
+ case BTA_MSE_API_START_EVT:
+ return "BTA_MSE_API_START_EVT";
+ case BTA_MSE_API_STOP_EVT:
+ return "BTA_MSE_API_STOP_EVT";
+ default:
+ return "Unknown MSE event code";
+ }
+}
+
+/*******************************************************************************
+**
+** Function bta_mse_ma_state_code
+**
+** Description Maps MA state code to the corresponding state string
+**
+** Parameters state_code - MA state code
+**
+** Returns string pointer for the associated state name
+**
+*******************************************************************************/
+static char *bta_mse_ma_state_code(tBTA_MSE_MA_STATE state_code){
+ switch (state_code)
+ {
+ case BTA_MSE_MA_IDLE_ST:
+ return "BTA_MSE_MA_IDLE_ST";
+ case BTA_MSE_MA_LISTEN_ST:
+ return "BTA_MSE_MA_LISTEN_ST";
+ case BTA_MSE_MA_CONN_ST:
+ return "BTA_MSE_MA_CONN_ST";
+ case BTA_MSE_MA_CLOSING_ST:
+ return "BTA_MSE_MA_CLOSING_ST";
+ default:
+ return "Unknown MA state code";
+ }
+}
+
+
+/*******************************************************************************
+**
+** Function bta_mse_mn_state_code
+**
+** Description Maps MN state code to the corresponding state string
+**
+** Parameters state_code - MN state code
+**
+** Returns string pointer for the associated state name
+**
+*******************************************************************************/
+static char *bta_mse_mn_state_code(tBTA_MSE_MN_STATE state_code){
+ switch (state_code)
+ {
+ case BTA_MSE_MN_IDLE_ST:
+ return "BTA_MSE_MN_IDLE_ST";
+ case BTA_MSE_MN_W4_CONN_ST:
+ return "BTA_MSE_MN_W4_CONN_ST";
+ case BTA_MSE_MN_CONN_ST:
+ return "BTA_MSE_MN_CONN_ST";
+ case BTA_MSE_MN_CLOSING_ST:
+ return "BTA_MSE_MN_CLOSING_ST";
+ default:
+ return "Unknown MN state code";
+ }
+}
+
+#endif /* Debug Functions */
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#endif /* BTA_MSE_INCLUDED */
diff --git a/bta/ma/bta_mse_sdp.c b/bta/ma/bta_mse_sdp.c
new file mode 100644
index 0000000..a56e07f
--- /dev/null
+++ b/bta/ma/bta_mse_sdp.c
@@ -0,0 +1,63 @@
+/*****************************************************************************
+**
+** Name: bta_mse_sdp.c
+**
+** File: Implements the SDP functions used by Message Access Server
+**
+** Copyright (c) 1998-2009, Broadcom Corp., All Rights Reserved.
+** Broadcom Bluetooth Core. Proprietary and confidential.
+**
+*****************************************************************************/
+
+#include <string.h>
+
+#include "sdp_api.h"
+#include "bta_mse_int.h"
+#include "goep_util.h"
+
+/*****************************************************************************
+**
+** Function: bta_mas_sdp_register
+**
+** Purpose: Register the Message Access service with SDP
+**
+** Parameters: p_cb - Pointer to MA instance control block
+** p_service_name - MA server name
+** inst_id - MAS instance ID
+** msg_type - Supported message type(s)
+**
+**
+** Returns: void
+**
+*****************************************************************************/
+void bta_mse_ma_sdp_register (tBTA_MSE_MA_CB *p_cb, char *p_service_name,
+ tBTA_MA_INST_ID inst_id,
+ tBTA_MA_MSG_TYPE msg_type)
+{
+ UINT16 mas_service = UUID_SERVCLASS_MESSAGE_ACCESS;
+ tGOEP_ERRORS goep_status;
+
+ goep_status = GOEP_Register(p_service_name, &p_cb->sdp_handle, p_cb->scn,
+ 1, &mas_service, UUID_SERVCLASS_MAP_PROFILE,
+ BTA_MAS_DEFAULT_VERSION);
+ if (goep_status == GOEP_SUCCESS)
+ {
+ /* add instance ID */
+ SDP_AddAttribute(p_cb->sdp_handle, ATTR_ID_MAS_INSTANCE_ID, UINT_DESC_TYPE,
+ (UINT32)1, (UINT8*)&inst_id);
+
+ /* add supported message type */
+ SDP_AddAttribute(p_cb->sdp_handle, ATTR_ID_SUPPORTED_MSG_TYPE, UINT_DESC_TYPE,
+ (UINT32)1, (UINT8*)&msg_type);
+
+ bta_sys_add_uuid(mas_service); /* UUID_SERVCLASS_MESSAGE_ACCESS */
+ APPL_TRACE_DEBUG1("MAS: SDP Registered (handle 0x%08x)", p_cb->sdp_handle);
+ }
+ else
+ {
+ if (p_cb->sdp_handle) SDP_DeleteRecord(p_cb->sdp_handle);
+ APPL_TRACE_ERROR0("bta_mse_ma_sdp_register FAILED");
+ }
+
+ return;
+}
diff --git a/bta/ma/bta_mse_utils.c b/bta/ma/bta_mse_utils.c
new file mode 100644
index 0000000..2b14b7a
--- /dev/null
+++ b/bta/ma/bta_mse_utils.c
@@ -0,0 +1,3867 @@
+/*********************************************a********************************
+**
+** Name: bta_mse_utils.c
+**
+** Description: This file implements utility functions for the
+** file transfer server.
+**
+** Copyright (c) 2003-2011, Broadcom Corp., All Rights Reserved.
+** Broadcom Bluetooth Core. Proprietary and confidential.
+**
+*****************************************************************************/
+
+#include "bt_target.h"
+
+#if defined(BTA_MSE_INCLUDED) && (BTA_MSE_INCLUDED == TRUE)
+
+#include <stdio.h>
+#include <string.h>
+#include "gki.h"
+#include "utl.h"
+#include "bd.h"
+#include "bta_fs_api.h"
+#include "bta_mse_int.h"
+#include "bta_fs_co.h"
+#include "bta_mse_co.h"
+
+#include "bta_ma_util.h"
+
+
+/*******************************************************************************
+* Macros for MSE
+*******************************************************************************/
+#define BTA_MSE_XML_EOL "\n"
+#define BTA_MSE_FOLDER_LISTING_START ( "<?xml version=\"1.0\"?>\n" \
+ "<!DOCTYPE folder-listing SYSTEM \"obex-folder-listing.dtd\">\n" \
+ "<folder-listing version=\"1.0\">\n" )
+
+#define BTA_MSE_FOLDER_LISTING_END ( "</folder-listing>" )
+#define BTA_MSE_PARENT_FOLDER (" <parent-folder/>\n")
+
+#define BTA_MSE_FILE_ELEM "file"
+#define BTA_MSE_FOLDER_ELEM "folder"
+#define BTA_MSE_NAME_ATTR "name"
+#define BTA_MSE_SIZE_ATTR "size"
+#define BTA_MSE_TYPE_ATTR "type"
+#define BTA_MSE_MODIFIED_ATTR "modified"
+#define BTA_MSE_CREATED_ATTR "created"
+#define BTA_MSE_ACCESSED_ATTR "accessed"
+#define BTA_MSE_USER_PERM_ATTR "user-perm"
+
+#define BTA_MSE_MSG_LISTING_START ( "<MAP-msg-listing version=\"1.0\">\n" )
+#define BTA_MSE_MSG_LISTING_END ( "</MAP-msg-listing>" )
+
+
+// btla-specific ++
+#define BTA_MSE_ENABLE_FS_CO FALSE
+// btla-specific --
+
+/*******************************************************************************
+**
+** Function bta_mse_send_push_msg_in_prog_evt
+**
+** Description send the push message in progress event
+**
+** Parameters inst_idx - Index to the MA instance control block
+** sess_idx - Index to the MA session control block
+**
+** Returns void
+**
+*******************************************************************************/
+
+void bta_mse_send_push_msg_in_prog_evt(UINT8 inst_idx, UINT8 sess_idx)
+{
+ tBTA_MSE_MA_SESS_CB *p_cb = BTA_MSE_GET_SESS_CB_PTR(inst_idx, sess_idx);
+ tBTA_MSE_OPER_PUSH_MSG *p_push_msg = &p_cb->push_msg;
+ tBTA_MSE cback_evt_data;
+ tBTA_MSE *p_data = &cback_evt_data;
+
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT2("bta_mse_send_push_msg_in_prog_evt inst_idx=%d sess_idx=%d",
+ inst_idx,sess_idx);
+#endif
+
+ p_data->push_msg_in_prog.mas_session_id = p_cb->obx_handle;
+ p_data->push_msg_in_prog.bytes = p_cb->obx.offset;
+ p_data->push_msg_in_prog.obj_size = p_push_msg->push_byte_cnt;
+ bta_mse_cb.p_cback(BTA_MSE_PUSH_MSG_IN_PROG_EVT, (tBTA_MSE *) p_data);
+}
+/*******************************************************************************
+**
+** Function bta_mse_send_get_msg_in_prog_evt
+**
+** Description Sends the get message in progress event
+**
+** Parameters inst_idx - Index to the MA instance control block
+** sess_idx - Index to the MA session control block
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_mse_send_get_msg_in_prog_evt(UINT8 inst_idx, UINT8 sess_idx)
+{
+ tBTA_MSE_MA_SESS_CB *p_cb = BTA_MSE_GET_SESS_CB_PTR(inst_idx, sess_idx);
+ tBTA_MSE_OPER_MSG_PARAM *p_param = &p_cb->msg_param;
+ tBTA_MSE cback_evt_data;
+ tBTA_MSE *p_data = &cback_evt_data;
+
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT2("bta_mse_send_get_msg_in_prog_evt inst_idx=%d sess_idx=%d",
+ inst_idx,sess_idx);
+#endif
+
+ p_data->get_msg_in_prog.mas_session_id = (tBTA_MA_SESS_HANDLE) p_cb->obx_handle;
+ p_data->get_msg_in_prog.bytes = p_param->filled_buff_size;
+ p_data->get_msg_in_prog.obj_size = p_param->byte_get_cnt;
+ bta_mse_cb.p_cback(BTA_MSE_GET_MSG_IN_PROG_EVT, (tBTA_MSE *) p_data);
+}
+/*******************************************************************************
+**
+** Function bta_mse_send_oper_cmpl_evt
+**
+** Description Sends the operartion complete event based on the specified status
+**
+** Parameters inst_idx - Index to the MA instance control block
+** sess_idx - Index to the MA session control block
+** status - MA status code
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_mse_send_oper_cmpl_evt(UINT8 inst_idx, UINT8 sess_idx, tBTA_MA_STATUS status)
+{
+ tBTA_MSE_MA_SESS_CB *p_cb = BTA_MSE_GET_SESS_CB_PTR(inst_idx, sess_idx);
+ tBTA_MSE_OPER_MSG_PARAM *p_param = &p_cb->msg_param;
+ tBTA_MSE_OPER_PUSH_MSG *p_push_msg = &p_cb->push_msg;
+ tBTA_MSE cback_evt_data;
+ tBTA_MSE *p_data = &cback_evt_data;
+
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT3("bta_mse_send_oper_cmpl_evt inst_idx=%d sess_idx=%d status=%d",
+ inst_idx, sess_idx, status);
+#endif
+
+ p_data->oper_cmpl.mas_session_id = p_cb->obx_handle;
+ p_data->oper_cmpl.operation = p_cb->oper;
+ p_data->oper_cmpl.status = status;
+ switch (p_cb->oper)
+ {
+ case BTA_MSE_OPER_GET_MSG:
+ p_data->oper_cmpl.obj_size = p_param->byte_get_cnt;
+ break;
+ case BTA_MSE_OPER_PUSH_MSG:
+ p_data->oper_cmpl.obj_size = p_push_msg->push_byte_cnt;
+ break;
+ default:
+ p_data->oper_cmpl.obj_size = 0;
+ break;
+ }
+ bta_mse_cb.p_cback(BTA_MSE_OPER_CMPL_EVT, (tBTA_MSE *) p_data);
+}
+
+/*******************************************************************************
+**
+** Function bta_mse_pushmsg
+**
+** Description Process the push message request
+**
+** Parameters inst_idx - Index to the MA instance control block
+** sess_idx - Index to the MA session control block
+** first_pkt - first packet of the push message request
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_mse_pushmsg(UINT8 inst_idx, UINT8 sess_idx, BOOLEAN first_pkt)
+{
+ tBTA_MSE_MA_SESS_CB *p_cb = BTA_MSE_GET_SESS_CB_PTR(inst_idx, sess_idx);
+ tBTA_MSE_OPER_PUSH_MSG *p_push_msg = &p_cb->push_msg;
+ tBTA_MSE_OBX_PKT *p_obx = &p_cb->obx;
+ tBTA_MA_MPKT_STATUS mpkt_status;
+
+ p_push_msg->push_byte_cnt += p_obx->offset;
+ p_cb->cout_active = TRUE;
+ mpkt_status = BTA_MA_MPKT_STATUS_LAST;
+ if (!p_obx->final_pkt) mpkt_status = BTA_MA_MPKT_STATUS_MORE;
+
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT5("bta_mse_pushmsg i_idx=%d s_idx=%d first=%d final=%d cnt=%d",
+ inst_idx, sess_idx, first_pkt, p_obx->final_pkt,
+ p_push_msg->push_byte_cnt);
+#endif
+
+
+ bta_mse_co_push_msg((tBTA_MA_SESS_HANDLE) p_cb->obx_handle, &p_push_msg->param,
+ p_obx->offset, p_obx->p_start, first_pkt,
+ mpkt_status, BTA_MSE_CI_PUSH_MSG_EVT, bta_mse_cb.app_id);
+}
+
+/*******************************************************************************
+**
+** Function bta_mse_clean_set_msg_sts
+**
+** Description Cleans up the set message status resources and cotrol block
+**
+** Parameters inst_idx - Index to the MA instance control block
+** sess_idx - Index to the MA session control block
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_mse_clean_set_msg_sts(UINT8 inst_idx, UINT8 sess_idx)
+{
+ tBTA_MSE_MA_SESS_CB *p_cb = BTA_MSE_GET_SESS_CB_PTR(inst_idx, sess_idx);
+ tBTA_MSE_OPER_SET_MSG_STS *p_set_msg_sts = &p_cb->set_msg_sts;
+
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT0("bta_mse_clean_set_msg_sts");
+#endif
+
+ utl_freebuf((void**)&(p_set_msg_sts->p_msg_handle));
+ bta_mse_set_ma_oper(inst_idx, sess_idx, BTA_MSE_OPER_NONE);
+
+}
+
+/*******************************************************************************
+**
+** Function bta_mse_clean_set_notif_reg
+**
+** Description Cleans up the set notification registration resources and cotrol block
+**
+** Parameters inst_idx - Index to the MA instance control block
+** sess_idx - Index to the MA session control block
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_mse_clean_set_notif_reg(UINT8 inst_idx, UINT8 sess_idx)
+{
+ tBTA_MSE_MA_SESS_CB *p_cb = BTA_MSE_GET_SESS_CB_PTR(inst_idx, sess_idx);
+
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT0("bta_mse_clean_set_notif_reg");
+#endif
+
+ p_cb->notif_reg_req.notif_status_rcv = FALSE;
+ bta_mse_set_ma_oper(inst_idx, sess_idx, BTA_MSE_OPER_NONE);
+}
+
+/*******************************************************************************
+**
+** Function bta_mse_clean_push_msg
+**
+** Description Cleans up the push message resources and cotrol block
+**
+** Parameters inst_idx - Index to the MA instance control block
+** sess_idx - Index to the MA session control block
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_mse_clean_push_msg(UINT8 inst_idx, UINT8 sess_idx)
+{
+ tBTA_MSE_MA_SESS_CB *p_cb = BTA_MSE_GET_SESS_CB_PTR(inst_idx, sess_idx);
+ tBTA_MSE_OPER_PUSH_MSG *p_push_msg = &p_cb->push_msg;
+
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT0("bta_mse_clean_push_msg");
+#endif
+
+ utl_freebuf((void**)&(p_push_msg->param.p_folder));
+ bta_mse_set_ma_oper(inst_idx, sess_idx, BTA_MSE_OPER_NONE);
+
+}
+
+/*******************************************************************************
+**
+** Function bta_mse_init_set_msg_sts
+**
+** Description Initializes the set message status resources and cotrol block
+**
+** Parameters inst_idx - Index to the MA instance control block
+** sess_idx - Index to the MA session control block
+** p_rsp_code - (output) pointer to the obex response code
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_mse_init_set_msg_sts(UINT8 inst_idx, UINT8 sess_idx, UINT8 *p_rsp_code)
+{
+ tBTA_MSE_MA_SESS_CB *p_cb = BTA_MSE_GET_SESS_CB_PTR(inst_idx, sess_idx);
+ tBTA_MSE_OPER_SET_MSG_STS *p_set_msg_sts = &p_cb->set_msg_sts;
+
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT0("bta_mse_init_set_msg_sts");
+#endif
+ *p_rsp_code = OBX_RSP_OK;
+
+
+
+ p_set_msg_sts->rcv_msg_handle = FALSE;
+ p_set_msg_sts->rcv_sts_ind = FALSE;
+ p_set_msg_sts->rcv_sts_val = FALSE;
+
+ if (!p_set_msg_sts->p_msg_handle)
+ {
+ if ((p_set_msg_sts->p_msg_handle = (char *)GKI_getbuf((UINT16)(BTA_MSE_64BIT_HEX_STR_SIZE))) == NULL )
+ {
+ *p_rsp_code = OBX_RSP_INTRNL_SRVR_ERR;
+ }
+ }
+}
+
+/*******************************************************************************
+**
+** Function bta_mse_init_push_msg
+**
+** Description initializes the push message resources and control block
+**
+** Parameters inst_idx - Index to the MA instance control block
+** sess_idx - Index to the MA session control block
+** p_rsp_code - (output) pointer to the obex response code
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_mse_init_push_msg(UINT8 inst_idx, UINT8 sess_idx, UINT8 *p_rsp_code)
+{
+ tBTA_MSE_MA_SESS_CB *p_cb = BTA_MSE_GET_SESS_CB_PTR(inst_idx, sess_idx);
+ tBTA_MSE_OPER_PUSH_MSG *p_push_msg = &p_cb->push_msg;
+
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT0("bta_mse_init_push_msg");
+#endif
+ *p_rsp_code = OBX_RSP_OK;
+
+
+ p_push_msg->push_byte_cnt = 0;
+ p_push_msg->first_req_pkt = TRUE;
+ p_push_msg->rcv_charset = FALSE;
+ p_push_msg->rcv_folder_name = FALSE;
+ p_push_msg->rcv_retry = FALSE;
+ p_push_msg->rcv_transparent = FALSE;
+ p_push_msg->param.transparent = BTA_MA_TRANSP_OFF;
+ p_push_msg->param.retry = BTA_MA_RETRY_OFF;
+
+ if (!p_push_msg->param.p_folder)
+ {
+ if ((p_push_msg->param.p_folder = (char *)GKI_getbuf((UINT16)(p_bta_mse_cfg->max_name_len + 1))) == NULL )
+ {
+ *p_rsp_code = OBX_RSP_INTRNL_SRVR_ERR;
+ }
+ }
+}
+
+
+/*******************************************************************************
+**
+** Function bta_mse_remove_uuid
+**
+** Description Remove UUID and clear service
+**
+** Parameters none
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_mse_remove_uuid(void)
+{
+ bta_sys_remove_uuid(UUID_SERVCLASS_MESSAGE_ACCESS);
+ BTM_SecClrService(BTM_SEC_SERVICE_MAP);
+}
+
+/*******************************************************************************
+**
+** Function bta_mse_clean_mas_service
+**
+** Description Cleans up the MAS service resources and control block
+**
+** Parameters inst_idx - Index to the MA instance control block
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_mse_clean_mas_service(UINT8 inst_idx)
+{
+ tBTA_MSE_MA_CB *p_scb = BTA_MSE_GET_INST_CB_PTR(inst_idx);
+ tBTA_MSE_MA_SESS_CB *p_cb;
+ int i, num_act_mas =0;
+
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT0("bta_mse_clean_mas_service");
+#endif
+ OBX_StopServer(p_scb->obx_handle);
+ BTM_FreeSCN(p_scb->scn);
+ if (p_scb->sdp_handle) SDP_DeleteRecord(p_scb->sdp_handle);
+
+ utl_freebuf((void**)&p_scb->p_rootpath);
+ for (i=0; i < BTA_MSE_NUM_SESS; i++ )
+ {
+ p_cb = BTA_MSE_GET_SESS_CB_PTR(inst_idx, i);
+ utl_freebuf((void**)&p_cb->p_workdir);
+ }
+ p_scb->in_use = FALSE;
+
+ /* check all other MAS instances */
+ for (i=0; i < BTA_MSE_NUM_INST ; i ++)
+ {
+ p_scb = BTA_MSE_GET_INST_CB_PTR(i);
+ if (p_scb->in_use) num_act_mas++;
+ }
+
+ if (!num_act_mas) bta_mse_remove_uuid();
+}
+
+
+/*******************************************************************************
+**
+** Function bta_mse_abort_too_late
+**
+** Description It is too late to abort the operation
+**
+** Parameters inst_idx - Index to the MA instance control block
+** sess_idx - Index to the MA session control block
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_mse_abort_too_late(UINT8 inst_idx, UINT8 sess_idx)
+{
+ tBTA_MSE_MA_SESS_CB *p_cb = BTA_MSE_GET_SESS_CB_PTR(inst_idx, sess_idx);
+
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT1("bta_mse_abort_too_late oper=%d ",p_cb->oper );
+#endif
+ OBX_AbortRsp(p_cb->obx_handle, OBX_RSP_FORBIDDEN, (BT_HDR *)NULL);
+ p_cb->aborting = FALSE;
+}
+
+/*******************************************************************************
+**
+** Function bta_mse_clean_getput
+**
+** Description Cleans up get and put resources and control blocks
+**
+** Parameters inst_idx - Index to the MA instance control block
+** sess_idx - Index to the MA session control block
+** status - operation status
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_mse_clean_getput(UINT8 inst_idx, UINT8 sess_idx, tBTA_MA_STATUS status)
+{
+ tBTA_MSE_MA_SESS_CB *p_cb = BTA_MSE_GET_SESS_CB_PTR(inst_idx, sess_idx);
+
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT2("bta_mse_clean_getput oper=%d status=%d",p_cb->oper, status );
+#endif
+ if (status == BTA_MA_STATUS_ABORTED)
+ {
+ OBX_AbortRsp(p_cb->obx_handle, OBX_RSP_OK, (BT_HDR *)NULL);
+ p_cb->aborting = FALSE;
+ }
+ switch (p_cb->oper)
+ {
+ case BTA_MSE_OPER_UPDATE_INBOX:
+ bta_mse_set_ma_oper(inst_idx,sess_idx, BTA_MSE_OPER_NONE);
+ break;
+ case BTA_MSE_OPER_GET_FOLDER_LIST:
+ bta_mse_clean_list(inst_idx,sess_idx);
+ break;
+ case BTA_MSE_OPER_GET_MSG_LIST:
+ bta_mse_clean_msg_list(inst_idx,sess_idx);
+ break;
+ case BTA_MSE_OPER_GET_MSG:
+ bta_mse_send_oper_cmpl_evt(inst_idx,sess_idx, status);
+ bta_mse_clean_msg(inst_idx,sess_idx);
+ break;
+ case BTA_MSE_OPER_PUSH_MSG:
+ bta_mse_send_oper_cmpl_evt(inst_idx,sess_idx, status);
+ bta_mse_clean_push_msg(inst_idx,sess_idx);
+ break;
+ case BTA_MSE_OPER_DEL_MSG:
+ case BTA_MSE_OPER_SET_MSG_STATUS:
+ bta_mse_clean_set_msg_sts(inst_idx,sess_idx);
+ break;
+
+ default:
+ break;
+ }
+
+ utl_freebuf((void**)&p_cb->obx.p_pkt);
+ p_cb->obx.bytes_left = 0;
+
+}
+
+
+/*******************************************************************************
+**
+** Function bta_mse_clean_msg
+**
+** Description Cleans up the get message resources and control block
+**
+** Parameters inst_idx - Index to the MA instance control block
+** sess_idx - Index to the MA session control block
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_mse_clean_msg(UINT8 inst_idx, UINT8 sess_idx)
+{
+ tBTA_MSE_MA_SESS_CB *p_cb = BTA_MSE_GET_SESS_CB_PTR(inst_idx, sess_idx);
+ /* Clean up control block */
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT0("bta_mse_clean_msg");
+#endif
+ utl_freebuf((void **)&p_cb->msg_param.p_msg_handle);
+ bta_mse_set_ma_oper(inst_idx, sess_idx, BTA_MSE_OPER_NONE);
+
+}
+
+/*******************************************************************************
+**
+** Function bta_mse_end_of_msg
+**
+** Description Complete the end body of the get message response, and
+** sends out the OBX get response
+**
+** Parameters inst_idx - Index to the MA instance control block
+** sess_idx - Index to the MA session control block
+** rsp_code - Obex response code
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_mse_end_of_msg(UINT8 inst_idx, UINT8 sess_idx, UINT8 rsp_code)
+{
+ tBTA_MSE_MA_SESS_CB *p_cb = BTA_MSE_GET_SESS_CB_PTR(inst_idx, sess_idx);
+ tBTA_MSE_OBX_PKT *p_obx = &p_cb->obx;
+ tBTA_MSE_OPER_MSG_PARAM *p_param = &p_cb->msg_param;
+
+
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT0("bta_mse_end_of_msg");
+#endif
+ /* Add the end of folder listing string if successful operation */
+ if (rsp_code == OBX_RSP_OK || rsp_code == OBX_RSP_CONTINUE)
+ {
+ /* If get message has completed, update the fraction delivery status */
+
+ if (p_param->add_frac_del_hdr)
+ {
+ *(p_param->p_frac_delivery) = p_param->frac_deliver_status;
+ p_param->add_frac_del_hdr = FALSE;
+ }
+
+ p_obx->offset += p_param->filled_buff_size;
+
+ if (rsp_code == OBX_RSP_OK)
+ {
+ OBX_AddBodyEnd(p_obx->p_pkt, p_obx->p_start, p_obx->offset, TRUE);
+ }
+ else /* More data to be sent */
+ OBX_AddBodyEnd(p_obx->p_pkt, p_obx->p_start, p_obx->offset, FALSE);
+
+ OBX_GetRsp(p_cb->obx_handle, rsp_code, (BT_HDR *)p_obx->p_pkt);
+ p_obx->p_pkt = NULL; /* Do not deallocate buffer; OBX will */
+
+ if (rsp_code == OBX_RSP_CONTINUE)
+ {
+ bta_mse_send_get_msg_in_prog_evt(inst_idx, sess_idx);
+ }
+ else
+ {
+ bta_mse_clean_getput(inst_idx, sess_idx, BTA_MA_STATUS_OK);
+ }
+ }
+ else /* An error occurred */
+ {
+ OBX_GetRsp(p_cb->obx_handle, rsp_code, (BT_HDR *)NULL);
+ bta_mse_clean_getput(inst_idx, sess_idx, BTA_MA_STATUS_FAIL);
+ }
+}
+
+/*******************************************************************************
+**
+** Function bta_mse_getmsg
+**
+** Description Processes the get message request
+**
+** Parameters inst_idx - Index to the MA instance control block
+** sess_idx - Index to the MA session control block
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_mse_getmsg(UINT8 inst_idx, UINT8 sess_idx, BOOLEAN new_req)
+{
+ tBTA_MSE_MA_SESS_CB *p_cb = BTA_MSE_GET_SESS_CB_PTR(inst_idx, sess_idx);
+ tBTA_MSE_OBX_PKT *p_obx = &p_cb->obx;
+ tBTA_MSE_OPER_MSG_PARAM *p_param = &p_cb->msg_param;
+ UINT8 rsp_code = OBX_RSP_OK;
+ UINT8 *p, *p_start;
+ UINT16 len = 0;
+ BOOLEAN first_get=FALSE;
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT0("bta_mse_getmsg");
+#endif
+
+ p_obx->p_pkt = (BT_HDR *)OBX_HdrInit(p_cb->obx_handle,
+ /* p_cb->peer_mtu */ OBX_LRG_DATA_POOL_SIZE);
+ if (p_obx->p_pkt)
+ {
+ /* Is this a new request or continuation? */
+ if (new_req)
+ {
+ first_get = TRUE;
+ if (p_param->add_frac_del_hdr)
+ {
+ /* Add Fraction Deliver Header */
+ p_start = OBX_AddByteStrStart(p_obx->p_pkt, &len);
+ p = p_start;
+ *p++ = BTA_MA_APH_FRAC_DELVR;
+ *p++ = 1;
+ p_param->p_frac_delivery = p;
+ /* use Last as default and it can be changed to More if application indicates more */
+ UINT8_TO_BE_STREAM(p, BTA_MA_FRAC_DELIVER_LAST);
+ OBX_AddByteStrHdr(p_obx->p_pkt, OBX_HI_APP_PARMS, NULL, (UINT16)(p - p_start));
+ }
+ }
+
+ /* Add the start of the Body Header */
+ p_obx->offset = 0;
+ p_obx->bytes_left = 0;
+ p_obx->p_start = OBX_AddBodyStart(p_obx->p_pkt, &p_obx->bytes_left);
+ p_cb->cout_active = TRUE;
+ bta_mse_co_get_msg((tBTA_MA_SESS_HANDLE) p_cb->obx_handle,
+ &p_param->data,
+ first_get,
+ p_obx->bytes_left,
+ p_obx->p_start,
+ BTA_MSE_CI_GET_MSG_EVT,
+ bta_mse_cb.app_id);
+
+ /* List is not complete, so don't send the response yet */
+ rsp_code = OBX_RSP_PART_CONTENT;
+ }
+ else
+ rsp_code = OBX_RSP_INTRNL_SRVR_ERR;
+
+ /* Response goes out if complete or error occurred */
+ if (rsp_code != OBX_RSP_PART_CONTENT)
+ bta_mse_end_of_msg(inst_idx, sess_idx,rsp_code);
+}
+
+/*******************************************************************************
+**
+** Function bta_mse_clean_msg_list
+**
+** Description Cleans up the get message list resources and control block
+**
+** Parameters inst_idx - Index to the MA instance control block
+** sess_idx - Index to the MA session control block
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_mse_clean_msg_list(UINT8 inst_idx, UINT8 sess_idx)
+{
+ tBTA_MSE_MA_SESS_CB *p_cb = BTA_MSE_GET_SESS_CB_PTR(inst_idx, sess_idx);
+ tBTA_MSE_MSGLIST *p_ml = &p_cb->ml;
+ /* Clean up control block */
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT0("bta_mse_clean_msg_list");
+#endif
+ bta_mse_set_ma_oper(inst_idx, sess_idx, BTA_MSE_OPER_NONE);
+ p_ml->remaing_size =0;
+ p_ml->offset =0;
+ p_ml->pending_ml_frag = FALSE;
+
+ utl_freebuf((void**)&p_ml->p_entry);
+ utl_freebuf((void**)&p_ml->p_info);
+ utl_freebuf((void**)&p_ml->p_xml_buf);
+ utl_freebuf((void**)&p_cb->ml_param.p_name);
+ utl_freebuf((void**)&p_cb->ml_param.p_path);
+}
+
+/*******************************************************************************
+**
+** Function bta_mse_end_of_msg_list
+**
+** Description Complete the end body of the get message listing response, and
+** sends out the OBX get response
+**
+** Parameters inst_idx - Index to the MA instance control block
+** sess_idx - Index to the MA session control block
+** rsp_code - Obex response code
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_mse_end_of_msg_list(UINT8 inst_idx, UINT8 sess_idx, UINT8 rsp_code)
+{
+ tBTA_MSE_MA_SESS_CB *p_cb = BTA_MSE_GET_SESS_CB_PTR(inst_idx, sess_idx);
+ tBTA_MSE_OBX_PKT *p_obx = &p_cb->obx;
+ tBTA_MSE_OPER_MLIST_PARAM *p_ml_param = &p_cb->ml_param;
+ UINT16 len;
+
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT0("bta_mse_end_of_msg_list");
+#endif
+ /* Add the end of folder listing string if successful operation */
+ if (rsp_code == OBX_RSP_OK || rsp_code == OBX_RSP_CONTINUE)
+ {
+ /* If listing has completed, check the max list count */
+ if (rsp_code == OBX_RSP_OK)
+ {
+ if (p_ml_param->filter.max_list_cnt)
+ {
+ len = strlen(BTA_MSE_MSG_LISTING_END);
+ memcpy(&p_obx->p_start[p_obx->offset], BTA_MSE_MSG_LISTING_END, len);
+ p_obx->offset += len;
+
+ OBX_AddBodyEnd(p_obx->p_pkt, p_obx->p_start, p_obx->offset, TRUE);
+ }
+
+ /* Clean up control block */
+ bta_mse_clean_msg_list(inst_idx, sess_idx);
+ }
+ else /* More listing data to be sent */
+ OBX_AddBodyEnd(p_obx->p_pkt, p_obx->p_start, p_obx->offset, FALSE);
+
+ OBX_GetRsp(p_cb->obx_handle, rsp_code, (BT_HDR *)p_obx->p_pkt);
+ p_obx->p_pkt = NULL; /* Do not deallocate buffer; OBX will */
+ }
+ else /* An error occurred */
+ {
+ OBX_GetRsp(p_cb->obx_handle, rsp_code, (BT_HDR *)NULL);
+ bta_mse_clean_msg_list(inst_idx, sess_idx);
+ }
+}
+
+/*******************************************************************************
+**
+** Function bta_mse_add_msg_list_info
+**
+** Description Adds applications paramter headers for new message and
+** message list size
+**
+** Parameters inst_idx - Index to the MA instance control block
+** sess_idx - Index to the MA session control block
+**
+** Returns UINT8 - OBX response code
+** OBX_RSP_PART_CONTENT if not finished yet.
+**
+*******************************************************************************/
+UINT8 bta_mse_add_msg_list_info(UINT8 inst_idx, UINT8 sess_idx)
+{
+ tBTA_MSE_MA_SESS_CB *p_cb = BTA_MSE_GET_SESS_CB_PTR(inst_idx, sess_idx);
+ tBTA_MSE_OBX_PKT *p_obx = &p_cb->obx;
+ tBTA_MSE_MSGLIST *p_ml = &p_cb->ml;
+ tBTA_MSE_CO_MSG_LIST_INFO *p_info = p_ml->p_info;
+ tBTA_MSE_CO_MSG_LIST_ENTRY *p_entry = p_ml->p_entry;
+ tBTA_MA_MSG_LIST_FILTER_PARAM *p_filter = &p_cb->ml_param.filter;
+ UINT8 rsp_code = OBX_RSP_PART_CONTENT;
+ UINT8 *p, *p_start;
+ UINT16 len = 0;
+
+
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT2("bta_mse_add_msg_list_info: new msg=%d, list size=%d",
+ p_info->new_msg, p_info->msg_list_size );
+#endif
+
+ /* add app params for GetMessageListing */
+ p_start = OBX_AddByteStrStart(p_obx->p_pkt, &len);
+ p = p_start;
+
+ *p++ = BTA_MA_APH_NEW_MSG;
+ *p++ = 1;
+ UINT8_TO_BE_STREAM(p, p_info->new_msg);
+
+ *p++ = BTA_MA_APH_MSG_LST_SIZE;
+ *p++ = 2;
+ UINT16_TO_BE_STREAM(p, p_info->msg_list_size);
+
+ *p++ = BTA_MA_APH_MSE_TIME;
+ *p++ = p_info->mse_time_len;
+ memcpy(p, p_info->mse_time, p_info->mse_time_len);
+ p += p_info->mse_time_len;
+
+ if (p != p_start)
+ {
+ OBX_AddByteStrHdr(p_obx->p_pkt, OBX_HI_APP_PARMS, NULL, (UINT16)(p - p_start));
+ }
+
+ if (p_filter->max_list_cnt)
+ {
+ /* Add the start of the Body Header */
+ p_obx->offset = 0;
+ p_obx->bytes_left = 0;
+ p_obx->p_start = OBX_AddBodyStart(p_obx->p_pkt, &p_obx->bytes_left);
+
+ len = strlen(BTA_MSE_MSG_LISTING_START);
+ memcpy(&p_obx->p_start[p_obx->offset], BTA_MSE_MSG_LISTING_START, len);
+ p_obx->bytes_left -= (UINT16)(len + strlen(BTA_MSE_MSG_LISTING_END));
+ p_obx->offset += len;
+ p_cb->cout_active = TRUE;
+ bta_mse_co_get_msg_list_entry((tBTA_MA_SESS_HANDLE) p_cb->obx_handle,
+ p_cb->ml_param.p_name,
+ p_filter, TRUE,
+ p_entry,
+ BTA_MSE_CI_GET_ML_ENTRY_EVT,
+ bta_mse_cb.app_id);
+ }
+ else
+ {
+ /* done with get msg list request */
+ rsp_code = OBX_RSP_OK;
+ }
+ return(rsp_code);
+}
+
+/*******************************************************************************
+**
+** Function bta_mse_add_msg_list_entry
+**
+** Description Adds one entry of the message list to the message list object
+**
+** Parameters inst_idx - Index to the MA instance control block
+** sess_idx - Index to the MA session control block
+**
+** Returns UINT8 - OBX response code
+** OBX_RSP_PART_CONTENT if not finished yet.
+** OBX_RSP_CONTINUE [packet done]
+** Others send error response out
+**
+*******************************************************************************/
+UINT8 bta_mse_add_msg_list_entry(UINT8 inst_idx, UINT8 sess_idx)
+{
+ tBTA_MSE_MA_SESS_CB *p_cb = BTA_MSE_GET_SESS_CB_PTR(inst_idx, sess_idx);
+ tBTA_MSE_OBX_PKT *p_obx = &p_cb->obx;
+ tBTA_MSE_MSGLIST *p_ml = &p_cb->ml;
+ tBTA_MSE_CO_MSG_LIST_ENTRY *p_entry = p_ml->p_entry;
+ tBTA_MA_MSG_LIST_FILTER_PARAM *p_filter = &p_cb->ml_param.filter;
+ char *p_buf;
+ UINT16 size;
+ UINT8 rsp_code = OBX_RSP_PART_CONTENT;
+ tBTA_MA_STATUS status;
+ BOOLEAN release_xml_buf = TRUE;
+
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT0("bta_mse_add_msg_list_entry");
+#endif
+
+ if (p_ml->pending_ml_frag)
+ {
+ if (p_ml->remaing_size <= p_obx->bytes_left)
+ {
+ size = p_ml->remaing_size;
+ p_ml->pending_ml_frag = FALSE;
+ }
+ else
+ {
+ rsp_code = OBX_RSP_CONTINUE;
+ size = p_obx->bytes_left;
+ }
+
+ p_buf = p_ml->p_xml_buf + p_ml->offset;
+ memcpy (&p_obx->p_start[p_obx->offset], p_buf, size);
+ p_obx->offset += size;
+ p_obx->bytes_left -= size;
+ p_ml->remaing_size -= size;
+ p_ml->offset += size;
+
+ if ( !p_ml->pending_ml_frag )
+ {
+ utl_freebuf((void **) &p_ml->p_xml_buf);
+ }
+
+
+ if (rsp_code == OBX_RSP_PART_CONTENT)
+ {
+ /* Get the next msg list entry */
+ p_cb->cout_active = TRUE;
+ bta_mse_co_get_msg_list_entry((tBTA_MA_SESS_HANDLE) p_cb->obx_handle,
+ p_cb->ml_param.p_name,
+ p_filter, FALSE,
+ p_entry,
+ BTA_MSE_CI_GET_ML_ENTRY_EVT,
+ bta_mse_cb.app_id);
+ }
+ return rsp_code;
+ }
+
+ if ((p_buf = (char *)GKI_getbuf(GKI_MAX_BUF_SIZE)) != NULL)
+ {
+ p_buf[0] = '\0';
+ size = GKI_MAX_BUF_SIZE;
+ status = bta_mse_build_msg_listing_obj( p_entry, &size, p_buf );
+
+ if (status == BTA_MA_STATUS_OK)
+ {
+ size = strlen(p_buf);
+
+ if (size <= p_obx->bytes_left)
+ {
+ if ( size > 0)
+ {
+ memcpy (&p_obx->p_start[p_obx->offset], p_buf, size);
+ p_obx->offset += size;
+ p_obx->bytes_left -= size;
+ }
+
+ /* Get the next msg list entry */
+ p_cb->cout_active = TRUE;
+ bta_mse_co_get_msg_list_entry((tBTA_MA_SESS_HANDLE) p_cb->obx_handle,
+ p_cb->ml_param.p_name,
+ p_filter, FALSE,
+ p_entry,
+ BTA_MSE_CI_GET_ML_ENTRY_EVT,
+ bta_mse_cb.app_id);
+ }
+ else /* entry did not fit in current obx packet; try to add entry in next obx req */
+ {
+ p_ml->pending_ml_frag = TRUE;
+ p_ml->p_xml_buf= p_buf;
+ p_ml->offset =0;
+ p_ml->remaing_size = size - p_obx->bytes_left;
+ p_ml->offset += p_obx->bytes_left;
+ release_xml_buf = FALSE;
+ memcpy (&p_obx->p_start[p_obx->offset], p_buf, p_obx->bytes_left);
+ p_obx->offset += p_obx->bytes_left;
+ p_obx->bytes_left = 0;
+
+ APPL_TRACE_EVENT2("1st msg list fragment peer_mtu=%d msg_list_size=%d",
+ p_cb->peer_mtu, size);
+ APPL_TRACE_EVENT3("pending_flag=%d offset=%d remaining_size=%d",
+ p_ml->pending_ml_frag, p_ml->offset, p_ml->remaing_size);
+ APPL_TRACE_EVENT2("obx offset=%d byte_left=%d",
+ p_obx->offset, p_obx->bytes_left );
+
+ rsp_code = OBX_RSP_CONTINUE;
+
+ }
+ }
+ else
+ rsp_code = OBX_RSP_INTRNL_SRVR_ERR;
+ /* Done with temporary buffer */
+ if (release_xml_buf) utl_freebuf((void **) &p_buf);
+ }
+ else
+ rsp_code = OBX_RSP_INTRNL_SRVR_ERR;
+
+ return(rsp_code);
+}
+
+/*******************************************************************************
+**
+** Function bta_mse_getmsglist
+**
+** Description Process the retrieval of a msg listing.
+**
+** Parameters inst_idx - Index to the MA instance control block
+** sess_idx - Index to the MA session control block
+**
+** Returns None
+**
+*******************************************************************************/
+void bta_mse_getmsglist(UINT8 inst_idx, UINT8 sess_idx, BOOLEAN new_req)
+{
+ tBTA_MSE_MA_SESS_CB *p_cb = BTA_MSE_GET_SESS_CB_PTR(inst_idx, sess_idx);
+ tBTA_MSE_OBX_PKT *p_obx = &p_cb->obx;
+ tBTA_MSE_MSGLIST *p_ml = &p_cb->ml;
+ UINT8 rsp_code = OBX_RSP_OK;
+
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT0("bta_mse_getmsglist ");
+#endif
+
+ p_obx->p_pkt = (BT_HDR *)OBX_HdrInit(p_cb->obx_handle,
+ /* p_cb->peer_mtu */ OBX_LRG_DATA_POOL_SIZE);
+ if (!p_ml->p_entry)
+ {
+ /* Allocate enough space for the structure */
+ p_ml->p_entry = (tBTA_MSE_CO_MSG_LIST_ENTRY *)
+ GKI_getbuf((UINT16)(sizeof(tBTA_MSE_CO_MSG_LIST_ENTRY)));
+ }
+
+ if (p_ml->p_entry && p_obx->p_pkt)
+ {
+ /* Is this a new request or continuation? */
+ if (new_req)
+ {
+ if (!p_ml->p_info)
+ {
+ /* Allocate enough space for the structure */
+ p_ml->p_info = (tBTA_MSE_CO_MSG_LIST_INFO *)
+ GKI_getbuf((UINT16)(sizeof(tBTA_MSE_CO_MSG_LIST_INFO)));
+ }
+
+ if (p_ml->p_info)
+ {
+ p_cb->ml_param.w4info =TRUE;
+
+ p_cb->cout_active = TRUE;
+ bta_mse_co_get_msg_list_info((tBTA_MA_SESS_HANDLE) p_cb->obx_handle,
+ p_cb->ml_param.p_name,
+ &(p_cb->ml_param.filter),
+ p_ml->p_info,
+ BTA_MSE_CI_GET_ML_INFO_EVT,
+ bta_mse_cb.app_id);
+
+ /* List is not complete, so don't send the response yet */
+ rsp_code = OBX_RSP_PART_CONTENT;
+ }
+ else
+ rsp_code = OBX_RSP_INTRNL_SRVR_ERR;
+ }
+ else /* Add the entry previously retrieved */
+ {
+ /* Add the start of the Body Header */
+ p_obx->offset = 0;
+ p_obx->bytes_left = 0;
+ p_obx->p_start = OBX_AddBodyStart(p_obx->p_pkt, &p_obx->bytes_left);
+ rsp_code = bta_mse_add_msg_list_entry(inst_idx, sess_idx);
+ }
+ }
+ else
+ rsp_code = OBX_RSP_INTRNL_SRVR_ERR;
+
+ /* Response goes out if complete or error occurred */
+ if (rsp_code != OBX_RSP_PART_CONTENT)
+ bta_mse_end_of_msg_list(inst_idx, sess_idx,rsp_code);
+}
+
+/*******************************************************************************
+**
+** Function bta_mse_read_app_params
+**
+** Description Read the specified application parameter from the given OBX packet
+**
+** Parameters p_pkt - obex packet pointer
+** tag - application parameter tag
+** param_len - (output) pointer to the length of application paramter
+**
+** Returns pointer to the application parameter found
+** NULL - not found
+**
+*******************************************************************************/
+
+UINT8 * bta_mse_read_app_params(BT_HDR *p_pkt, UINT8 tag, UINT16 *param_len)
+{
+ UINT8 *p_data = NULL, *p = NULL;
+ UINT16 data_len = 0;
+ int left, len;
+
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT0("bta_mse_read_app_params");
+#endif
+
+ if (OBX_ReadByteStrHdr(p_pkt, OBX_HI_APP_PARMS, &p_data, &data_len, 0))
+ {
+ left = data_len;
+ while (left > 0)
+ {
+ len = *(p_data + 1);
+ if (*p_data == tag)
+ {
+ p_data += 2;
+ p = p_data;
+ *param_len = (UINT16) len;
+ break;
+ }
+ p_data += (len+2);
+ left -= (len+2);
+ }
+ }
+ return p;
+}
+
+/*******************************************************************************
+**
+** Function bta_mse_clean_list
+**
+** Description Cleans up the get folder list resources and control block
+**
+** Parameters inst_idx - Index to the MA instance control block
+** sess_idx - Index to the MA session control block
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_mse_clean_list(UINT8 inst_idx, UINT8 sess_idx)
+{
+
+ tBTA_MSE_MA_SESS_CB *p_cb = BTA_MSE_GET_SESS_CB_PTR(inst_idx, sess_idx);
+ tBTA_MSE_DIRLIST *p_dir = &p_cb->dir;
+ /*tBTA_MSE_CO_FOLDER_ENTRY *p_entry = p_dir->p_entry; */
+ /* Clean up control block */
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT0("bta_mse_clean_list");
+#endif
+ bta_mse_set_ma_oper(inst_idx,sess_idx, BTA_MSE_OPER_NONE);
+ utl_freebuf((void**)&(p_dir->p_entry));
+}
+
+/*******************************************************************************
+**
+** Function bta_mse_end_of_list
+**
+** Description Finishes up the end body of the get folder listing, and sends out the
+** OBX response
+**
+** Parameters inst_idx - Index to the MA instance control block
+** sess_idx - Index to the MA session control block
+** rsp_code - obex response code
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_mse_end_of_list(UINT8 inst_idx, UINT8 sess_idx, UINT8 rsp_code)
+{
+ tBTA_MSE_MA_SESS_CB *p_cb = BTA_MSE_GET_SESS_CB_PTR(inst_idx, sess_idx);
+ tBTA_MSE_OBX_PKT *p_obx = &p_cb->obx;
+ UINT16 len = 0;
+ UINT8 *p, *p_start;
+
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT0("bta_mse_end_of_list");
+#endif
+ /* Add the end of folder listing string if successful operation */
+ if (rsp_code == OBX_RSP_OK || rsp_code == OBX_RSP_CONTINUE)
+ {
+ /* If listing has completed, add on end string (http) */
+ if (rsp_code == OBX_RSP_OK)
+ {
+ if (p_cb->fl_param.max_list_cnt)
+ {
+ len = strlen(BTA_MSE_FOLDER_LISTING_END);
+ memcpy(&p_obx->p_start[p_obx->offset], BTA_MSE_FOLDER_LISTING_END, len);
+ p_obx->offset += len;
+ OBX_AddBodyEnd(p_obx->p_pkt, p_obx->p_start, p_obx->offset, TRUE);
+ }
+ else
+ {
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT1("list_cnt=%d",p_cb->fl_param.list_cnt);
+#endif
+
+ /* send the folder list size header only*/
+ p_start = OBX_AddByteStrStart(p_obx->p_pkt, &len);
+ p = p_start;
+
+ *p++ = BTA_MA_APH_FOLDER_LST_SIZE;
+ *p++ = 2;
+ UINT16_TO_BE_STREAM(p, p_cb->fl_param.list_cnt);
+ if (p != p_start)
+ {
+ OBX_AddByteStrHdr(p_obx->p_pkt, OBX_HI_APP_PARMS, NULL, (UINT16)(p - p_start));
+ }
+ }
+ /* Clean up control block */
+ bta_mse_clean_list(inst_idx, sess_idx);
+ }
+ else /* More listing data to be sent */
+ OBX_AddBodyEnd(p_obx->p_pkt, p_obx->p_start, p_obx->offset, FALSE);
+
+ OBX_GetRsp(p_cb->obx_handle, rsp_code, (BT_HDR *)p_obx->p_pkt);
+ p_obx->p_pkt = NULL; /* Do not deallocate buffer; OBX will */
+ }
+ else /* An error occurred */
+ {
+ OBX_GetRsp(p_cb->obx_handle, rsp_code, (BT_HDR *)NULL);
+ bta_mse_clean_list(inst_idx, sess_idx);
+ }
+}
+
+/*******************************************************************************
+**
+** Function bta_mse_add_list_entry
+**
+** Description Adds an subfolder entry to the folder list object
+**
+** Parameters inst_idx - Index to the MA instance control block
+** sess_idx - Index to the MA session control block
+**
+** Returns UINT8 - OBX response code
+** OBX_RSP_PART_CONTENT if not finished yet.
+** OBX_RSP_CONTINUE [packet done]
+** Others send error response out
+**
+*******************************************************************************/
+UINT8 bta_mse_add_list_entry(UINT8 inst_idx, UINT8 sess_idx)
+{
+ tBTA_MSE_MA_SESS_CB *p_cb = BTA_MSE_GET_SESS_CB_PTR(inst_idx, sess_idx);
+ tBTA_MSE_OBX_PKT *p_obx = &p_cb->obx;
+ tBTA_MSE_DIRLIST *p_dir = &p_cb->dir;
+ tBTA_MSE_CO_FOLDER_ENTRY *p_entry = p_dir->p_entry;
+ char *p_buf;
+ UINT16 size;
+ UINT8 rsp_code = OBX_RSP_PART_CONTENT;
+
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT0("bta_mse_add_list_entry");
+#endif
+ if ((p_buf = (char *)GKI_getbuf(GKI_MAX_BUF_SIZE)) != NULL)
+ {
+ p_buf[0] = '\0';
+
+ APPL_TRACE_DEBUG2("bta_mse_add_list_entry: attr:0x%02x, name:%s",
+ p_entry->mode, p_entry->p_name);
+
+ if (p_entry->mode & BTA_MA_A_DIR) /* only process Subdirectory ignore files */
+ {
+ /* ignore "." and ".." */
+ if (strcmp(p_entry->p_name, ".") && strcmp(p_entry->p_name, ".."))
+ {
+ p_cb->fl_param.list_cnt++;
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT1("list_cnt=%d",p_cb->fl_param.list_cnt);
+#endif
+ if (p_cb->fl_param.max_list_cnt)
+ {
+ if (p_cb->fl_param.list_cnt <= p_cb->fl_param.max_list_cnt)
+ {
+ if (p_cb->fl_param.list_cnt > p_cb->fl_param.start_offset )
+ {
+ sprintf(p_buf, " <" BTA_MSE_FOLDER_ELEM " "
+ BTA_MSE_NAME_ATTR "=\"%s\"/>" BTA_MSE_XML_EOL,
+ p_entry->p_name);
+ }
+ }
+ } /* if max_list_cnt==0 only count the list size - but no body should be included*/
+ }
+ }/* ignore files i.e. non-folder items */
+
+ size = strlen(p_buf);
+ if (size <= p_obx->bytes_left)
+ {
+ if ( size > 0)
+ {
+ memcpy (&p_obx->p_start[p_obx->offset], p_buf, size);
+ p_obx->offset += size;
+ p_obx->bytes_left -= size;
+ }
+
+ if ((p_cb->fl_param.list_cnt < p_cb->fl_param.max_list_cnt) ||
+ (p_cb->fl_param.max_list_cnt == 0) )
+ {
+ /* Get the next directory entry */
+ p_cb->cout_active = TRUE;
+ bta_mse_co_get_folder_entry((tBTA_MA_SESS_HANDLE) p_cb->obx_handle,
+ p_cb->p_workdir, FALSE, p_dir->p_entry,
+ BTA_MSE_CI_GET_FENTRY_EVT,
+ bta_mse_cb.app_id);
+ }
+ else
+ {
+ /* reach the max allowed */
+ rsp_code = OBX_RSP_OK;
+ }
+ }
+ else /* entry did not fit in current obx packet; try to add entry in next obx req */
+ {
+ p_cb->fl_param.list_cnt--;
+ rsp_code = OBX_RSP_CONTINUE;
+ }
+
+ /* Done with temporary buffer */
+ GKI_freebuf(p_buf);
+ }
+ else
+ rsp_code = OBX_RSP_INTRNL_SRVR_ERR;
+ return(rsp_code);
+}
+
+/*******************************************************************************
+**
+** Function bta_mse_getfolderlist
+**
+** Description Processes the retrieval of a folder listing.
+**
+** Parameters inst_idx - Index to the MA instance control block
+** sess_idx - Index to the MA session control block
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_mse_getfolderlist(UINT8 inst_idx, UINT8 sess_idx, BOOLEAN new_req)
+{
+ tBTA_MSE_MA_CB *p_scb = BTA_MSE_GET_INST_CB_PTR(inst_idx);
+ tBTA_MSE_MA_SESS_CB *p_cb = BTA_MSE_GET_SESS_CB_PTR(inst_idx, sess_idx);
+ tBTA_MSE_OBX_PKT *p_obx = &p_cb->obx;
+ tBTA_MSE_DIRLIST *p_dir = &p_cb->dir;
+ UINT16 temp_len;
+ UINT8 rsp_code = OBX_RSP_OK;
+
+#if BTA_MSE_ENABLE_FS_CO == TRUE
+ BOOLEAN is_dir;
+#endif
+
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT0("bta_mse_getfolderlist");
+#endif
+
+#if BTA_MSE_ENABLE_FS_CO == TRUE
+ /* Make sure the Name is a directory and accessible */
+ if (((bta_fs_co_access(p_cb->p_workdir, BTA_FS_ACC_EXIST,
+ &is_dir, bta_mse_cb.app_id))!= BTA_FS_CO_OK)
+ || !is_dir)
+ rsp_code = OBX_RSP_NOT_FOUND;
+#endif
+ /* Build the listing */
+ if (rsp_code == OBX_RSP_OK)
+ {
+ p_obx->p_pkt = (BT_HDR *)OBX_HdrInit(p_cb->obx_handle,
+ /* p_cb->peer_mtu */ OBX_LRG_DATA_POOL_SIZE);
+ if (!(strcmp(p_cb->p_workdir, p_scb->p_rootpath)))
+ p_dir->is_root = TRUE;
+ else
+ p_dir->is_root = FALSE;
+
+ if (!p_dir->p_entry)
+ {
+ /* Allocate enough space for the structure and the folder name */
+ if ((p_dir->p_entry = (tBTA_MSE_CO_FOLDER_ENTRY *)
+ GKI_getbuf((UINT16)(sizeof(tBTA_MSE_CO_FOLDER_ENTRY) +
+ p_bta_mse_cfg->max_name_len + 1))) != NULL)
+ p_dir->p_entry->p_name = (char *)(p_dir->p_entry + 1);
+ }
+
+ if (p_dir->p_entry && p_obx->p_pkt)
+ {
+ if (p_cb->fl_param.max_list_cnt)
+ {
+ /* Add the start of the Body Header */
+ p_obx->offset = 0;
+ p_obx->bytes_left = 0;
+ p_obx->p_start = OBX_AddBodyStart(p_obx->p_pkt, &p_obx->bytes_left);
+ }
+
+ /* Is this a new request or continuation? */
+ if (new_req)
+ {
+ APPL_TRACE_EVENT1("Folder List Directory: [%s]", p_cb->p_workdir);
+ p_cb->fl_param.list_cnt =0;
+
+ /* add body header if max_list_cnt is not 0
+ if max_list_cnt =0 then only report the actual number
+ accessible folders. Use FolderListingSize header only
+ */
+
+ if (p_cb->fl_param.max_list_cnt)
+ {
+ temp_len = strlen(BTA_MSE_FOLDER_LISTING_START);
+
+ /* Add the beginning label of http */
+ memcpy(p_obx->p_start, BTA_MSE_FOLDER_LISTING_START, temp_len);
+ p_obx->bytes_left -= (UINT16)(temp_len + strlen(BTA_MSE_FOLDER_LISTING_END));
+ p_obx->offset += temp_len;
+
+ /* Add the parent directory if not the root */
+ if (strcmp(p_cb->p_workdir, p_scb->p_rootpath))
+ {
+ APPL_TRACE_EVENT0("Add parent folder");
+
+ temp_len = strlen(BTA_MSE_PARENT_FOLDER);
+ memcpy(p_obx->p_start + p_obx->offset,
+ BTA_MSE_PARENT_FOLDER, temp_len);
+ p_obx->bytes_left -= temp_len;
+ p_obx->offset += temp_len;
+ }
+ }
+ p_cb->cout_active = TRUE;
+ bta_mse_co_get_folder_entry((tBTA_MA_SESS_HANDLE) p_cb->obx_handle,
+ p_cb->p_workdir, TRUE, p_dir->p_entry,
+ BTA_MSE_CI_GET_FENTRY_EVT,
+ bta_mse_cb.app_id);
+
+ /* List is not complete, so don't send the response yet */
+ rsp_code = OBX_RSP_PART_CONTENT;
+ }
+ else /* Add the entry previously retrieved */
+ rsp_code = bta_mse_add_list_entry(inst_idx, sess_idx);
+ }
+ else
+ rsp_code = OBX_RSP_INTRNL_SRVR_ERR;
+ }
+
+ /* Response goes out if complete or error occurred */
+ if (rsp_code != OBX_RSP_PART_CONTENT)
+ bta_mse_end_of_list(inst_idx, sess_idx,rsp_code);
+}
+
+/*******************************************************************************
+**
+** Function bta_mse_chdir
+**
+** Description Changes the current path based on received setpath paramters
+**
+** Parameters inst_idx - Index to the MA instance control block
+** sess_idx - Index to the MA session control block
+** p_oper - (output) pointer to the MSE operation code
+**
+** Returns UINT8 - OBX response code
+** output *p_oper set to BTA_MSE_OPER_SETPATH if the
+** the resulting path is a valid path
+*******************************************************************************/
+UINT8 bta_mse_chdir(UINT8 inst_idx, UINT8 sess_idx, tBTA_MSE_OPER *p_oper)
+{
+ tBTA_MSE_MA_CB *p_scb = BTA_MSE_GET_INST_CB_PTR(inst_idx);
+ tBTA_MSE_MA_SESS_CB *p_cb = BTA_MSE_GET_SESS_CB_PTR(inst_idx, sess_idx);
+ char *p_path = p_cb->sp.p_path;
+ char *p_name = p_cb->sp.p_name;
+ char *p_tmp;
+
+ char *p_workdir = p_cb->p_workdir;
+ UINT8 rsp_code = OBX_RSP_OK;
+
+#if BTA_MSE_ENABLE_FS_CO == TRUE
+ BOOLEAN is_dir;
+#endif
+
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT2("bta_mse_chdir flag=%d name=%s",p_cb->sp.flags,p_cb->sp.p_name );
+#endif
+ *p_oper = BTA_MSE_OPER_NONE;
+ switch (p_cb->sp.flags)
+ {
+ case BTA_MA_DIR_NAV_ROOT_OR_DOWN_ONE_LVL:
+ p_path = p_cb->sp.p_path;
+ p_name = p_cb->sp.p_name;
+ rsp_code = OBX_RSP_OK;
+ if (*p_name == '\0')
+ {
+ /* backup to root */
+ if (strcmp(p_workdir, p_scb->p_rootpath))
+ {
+ BCM_STRNCPY_S(p_path, p_bta_fs_cfg->max_path_len+1, p_scb->p_rootpath, p_bta_fs_cfg->max_path_len);
+ /* go back up to the root folder*/
+ *p_oper = BTA_MSE_OPER_SETPATH;
+ }
+ }
+ /* Make sure the new path is not too big */
+ /* +1 is for the separator */
+ else if ((strlen(p_workdir)+1+strlen(p_name)) <= p_bta_fs_cfg->max_path_len)
+ {
+ /* create a temporary path for creation attempt */
+ sprintf(p_path, "%s%c%s", p_workdir,
+ p_bta_fs_cfg->path_separator, p_name);
+#if BTA_MSE_ENABLE_FS_CO == TRUE
+ if (((bta_fs_co_access(p_path, BTA_FS_ACC_EXIST,
+ &is_dir, bta_mse_cb.app_id)) == BTA_FS_CO_OK) && is_dir)
+ {
+ /* go back down one level to the name folder*/
+ *p_oper = BTA_MSE_OPER_SETPATH;
+ }
+ else
+ rsp_code = OBX_RSP_NOT_FOUND;
+#else
+ *p_oper = BTA_MSE_OPER_SETPATH;
+#endif
+ }
+ else
+ {
+ rsp_code = OBX_RSP_INTRNL_SRVR_ERR;
+ }
+ break;
+ case BTA_MA_DIR_NAV_UP_ONE_LVL:
+
+ if (strcmp(p_workdir, p_scb->p_rootpath))
+ {
+ /* Find the last occurrence of separator and replace with '\0' */
+ BCM_STRNCPY_S(p_path, p_bta_fs_cfg->max_path_len+1, p_workdir, p_bta_fs_cfg->max_path_len);
+ if ((p_tmp = strrchr(p_path, (int)p_bta_fs_cfg->path_separator)) != NULL)
+ {
+ *p_tmp = '\0';
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT1("path=[%s]",p_path );
+ APPL_TRACE_EVENT1("name=[%s]", p_name );
+#endif
+ /* now check we need to go down one level if name is not empty*/
+ if (*p_name !='\0')
+ {
+ if ((strlen(p_workdir)+1+strlen(p_name)) <= p_bta_fs_cfg->max_path_len)
+ {
+ sprintf(p_path, "%s%c%s", p_path,
+ p_bta_fs_cfg->path_separator, p_name);
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT0("Up one level and then down one" );
+ APPL_TRACE_EVENT1("path=[%s]",p_path );
+#endif
+#if BTA_MSE_ENABLE_FS_CO == TRUE
+ if (((bta_fs_co_access(p_path, BTA_FS_ACC_EXIST,
+ &is_dir, bta_mse_cb.app_id)) == BTA_FS_CO_OK) && is_dir)
+ {
+ /* go up one level and then go down one level to the name folder */
+ *p_oper = BTA_MSE_OPER_SETPATH;
+ }
+ else
+ {
+ rsp_code = OBX_RSP_NOT_FOUND;
+ }
+#else
+ *p_oper = BTA_MSE_OPER_SETPATH;
+#endif
+ }
+ else
+ {
+ rsp_code = OBX_RSP_INTRNL_SRVR_ERR;
+ }
+ }
+ else
+ {
+ /* just go up one level to the parent directory */
+ *p_oper = BTA_MSE_OPER_SETPATH;
+ }
+ }
+ else
+ {
+ rsp_code = OBX_RSP_INTRNL_SRVR_ERR;
+ }
+ }
+ else
+ {
+ rsp_code = OBX_RSP_NOT_FOUND;
+ }
+ break;
+ default:
+ rsp_code = OBX_RSP_INTRNL_SRVR_ERR;
+ break;
+ }
+
+ return(rsp_code);
+}
+
+
+/*******************************************************************************
+**
+** Function bta_mse_send_set_notif_reg
+**
+** Description Send a set notification registration event to application
+** so application can decide whether the request is allowed or not
+**
+** Parameters status - (output) pointer to the MSE operation code
+** inst_idx - Index to the MA instance control block
+** sess_idx - Index to the MA session control block
+**
+** Returns TRUE - request is sent FALSE - requestr is not sent due to
+** error in the request
+*******************************************************************************/
+BOOLEAN bta_mse_send_set_notif_reg(UINT8 status,
+ UINT8 inst_idx, UINT8 sess_idx)
+{
+ tBTA_MSE_MA_SESS_CB *p_cb = BTA_MSE_GET_SESS_CB_PTR(inst_idx, sess_idx);
+ tBTA_MSE_MA_CB *p_scb = BTA_MSE_GET_INST_CB_PTR(inst_idx);
+ tBTA_MSE cback_evt_data;
+ tBTA_MA_NOTIF_STATUS notif_sts = BTA_MA_NOTIF_OFF;
+ BOOLEAN send_status = TRUE;
+ UINT8 ccb_idx;
+
+ if (status & BTA_MA_NOTIF_STS_ON) notif_sts = BTA_MA_NOTIF_ON;
+
+ if (notif_sts == BTA_MA_NOTIF_OFF)
+ {
+ if (!bta_mse_find_bd_addr_match_mn_cb_index(p_cb->bd_addr, &ccb_idx))
+ {
+ send_status = FALSE;
+ }
+ }
+
+ if (send_status)
+ {
+ cback_evt_data.set_notif_reg.mas_session_id = p_cb->obx_handle;
+ cback_evt_data.set_notif_reg.mas_instance_id = p_scb->mas_inst_id;
+ cback_evt_data.set_notif_reg.notif_status = notif_sts;
+ bdcpy(cback_evt_data.set_notif_reg.bd_addr, p_cb->bd_addr);
+ bta_mse_cb.p_cback(BTA_MSE_SET_NOTIF_REG_EVT, (tBTA_MSE *) &cback_evt_data);
+ }
+
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT1("bta_mse_send_set_notif_reg send_status=%d",send_status );
+#endif
+
+
+ return send_status;
+
+}
+
+/*******************************************************************************
+**
+** Function bta_mse_proc_notif_reg_status
+**
+** Description Process the notification registration status to determine
+** whether a MN conenction should be opened or closed
+**
+** Parameters status - (output) pointer to the MSE operation code
+** inst_idx - Index to the MA instance control block
+** sess_idx - Index to the MA session control block
+**
+** Returns None
+**
+*******************************************************************************/
+void bta_mse_proc_notif_reg_status(UINT8 status,
+ UINT8 inst_idx, UINT8 sess_idx )
+{
+ tBTA_MSE_MA_SESS_CB *p_cb = BTA_MSE_GET_SESS_CB_PTR(inst_idx, sess_idx);
+ tBTA_MSE_MA_CB *p_scb = BTA_MSE_GET_INST_CB_PTR(inst_idx);
+ tBTA_MA_NOTIF_STATUS notif_sts = BTA_MA_NOTIF_OFF;
+ tBTA_MSE_MN_CB *p_ccb;
+ UINT8 ccb_idx;
+ tBTA_MSE_MN_ACT_TYPE mn_act_type = BTA_MSE_MN_ACT_TYPE_NONE;
+ tOBX_RSP_CODE rsp_code = OBX_RSP_OK;
+
+ tBTA_MSE cback_evt_data;
+ tBTA_MSE_MN_INT_OPEN *p_open_evt;
+ tBTA_MSE_MN_INT_CLOSE *p_close_evt;
+
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT0("bta_mse_proc_notif_reg_status");
+#endif
+
+ if (status & BTA_MA_NOTIF_STS_ON) notif_sts = BTA_MA_NOTIF_ON;
+
+ switch (notif_sts)
+ {
+ case BTA_MA_NOTIF_ON:
+
+ if (!bta_mse_find_bd_addr_match_mn_cb_index(p_cb->bd_addr, &ccb_idx))
+ {
+ if (bta_mse_find_avail_mn_cb_idx(&ccb_idx))
+ mn_act_type = BTA_MSE_MN_ACT_TYPE_OPEN_CONN;
+ else
+ mn_act_type = BTA_MSE_MN_ACT_TYPE_OPEN_CONN_ERR;
+ }
+ else
+ {
+ /* it is connected already */
+ mn_act_type = BTA_MSE_MN_ACT_TYPE_OPEN_CONN_NONE;
+ }
+ break;
+
+ case BTA_MA_NOTIF_OFF:
+
+ if (!bta_mse_find_bd_addr_match_mn_cb_index(p_cb->bd_addr, &ccb_idx))
+ {
+ mn_act_type = BTA_MSE_MN_ACT_TYPE_CLOSE_CONN_ERR;
+ break;
+ }
+
+ p_ccb = BTA_MSE_GET_MN_CB_PTR(ccb_idx);
+
+ if ((p_ccb->state !=BTA_MSE_MN_W4_CONN_ST) &&
+ (p_ccb->state !=BTA_MSE_MN_CONN_ST))
+ {
+ /* MN is either idle or to be closed shortly so do nothing*/
+ mn_act_type = BTA_MSE_MN_ACT_TYPE_CLOSE_CONN_NONE;
+ }
+ else
+ {
+ if (bta_mse_mn_is_ok_to_close_mn(p_cb->bd_addr, p_scb->mas_inst_id))
+ {
+ /* This is the last active MN session using this conncection*/
+ mn_act_type = BTA_MSE_MN_ACT_TYPE_CLOSE_CONN;
+ }
+ else
+ {
+ mn_act_type = BTA_MSE_MN_ACT_TYPE_CLOSE_CONN_NONE;
+ }
+ }
+ break;
+ }
+
+ switch (mn_act_type)
+ {
+ case BTA_MSE_MN_ACT_TYPE_OPEN_CONN:
+
+ if ((p_open_evt = (tBTA_MSE_MN_INT_OPEN *) GKI_getbuf(sizeof(tBTA_MSE_MN_INT_OPEN))) != NULL)
+ {
+ bta_mse_mn_add_inst_id(ccb_idx, p_scb->mas_inst_id);
+ p_open_evt->hdr.event = BTA_MSE_MN_INT_OPEN_EVT;
+ p_open_evt->ccb_idx = ccb_idx;
+ p_open_evt->sec_mask = (BTA_SEC_AUTHENTICATE | BTA_SEC_ENCRYPT);
+ memcpy(p_open_evt->bd_addr, p_cb->bd_addr, sizeof(BD_ADDR));
+ bta_sys_sendmsg(p_open_evt);
+ }
+ else
+ {
+ rsp_code = OBX_RSP_FAILED;
+ }
+
+ break;
+
+ case BTA_MSE_MN_ACT_TYPE_CLOSE_CONN:
+
+ if ((p_close_evt = (tBTA_MSE_MN_INT_CLOSE *) GKI_getbuf(sizeof(tBTA_MSE_MN_INT_CLOSE))) != NULL)
+ {
+ bta_mse_mn_remove_inst_id(ccb_idx, p_scb->mas_inst_id);
+ p_close_evt->hdr.event = BTA_MSE_MN_INT_CLOSE_EVT;
+ p_close_evt->ccb_idx = ccb_idx;
+ bta_sys_sendmsg(p_close_evt);
+ }
+ else
+ {
+ rsp_code = OBX_RSP_FAILED;
+ }
+ break;
+
+ case BTA_MSE_MN_ACT_TYPE_OPEN_CONN_ERR:
+ rsp_code = OBX_RSP_FAILED;
+ break;
+
+ case BTA_MSE_MN_ACT_TYPE_OPEN_CONN_NONE:
+ bta_mse_mn_add_inst_id(ccb_idx, p_scb->mas_inst_id);
+ break;
+ case BTA_MSE_MN_ACT_TYPE_CLOSE_CONN_NONE:
+ bta_mse_mn_remove_inst_id(ccb_idx, p_scb->mas_inst_id);
+ break;
+ default:
+ break;
+ }
+
+ OBX_PutRsp(p_cb->obx_handle , rsp_code, NULL);
+ if (rsp_code == OBX_RSP_OK)
+ cback_evt_data.notif_reg.status = BTA_MA_STATUS_OK;
+ else
+ cback_evt_data.notif_reg.status = BTA_MA_STATUS_FAIL;
+ cback_evt_data.notif_reg.mas_session_id = p_cb->obx_handle;
+ cback_evt_data.notif_reg.mas_instance_id = p_scb->mas_inst_id;
+ cback_evt_data.notif_reg.notif_status = notif_sts;
+ bdcpy(cback_evt_data.notif_reg.bd_addr, p_cb->bd_addr);
+ bta_mse_clean_set_notif_reg(inst_idx,sess_idx);
+
+ bta_mse_cb.p_cback(BTA_MSE_NOTIF_REG_EVT, (tBTA_MSE *) &cback_evt_data);
+}
+
+/*******************************************************************************
+**
+** Function bta_mse_discard_data
+**
+** Description frees the data
+**
+** Parameters event - MSE event
+** p_data - Pointer to the MSE event data
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_mse_discard_data(UINT16 event, tBTA_MSE_DATA *p_data)
+{
+
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT0("bta_mse_discard_data");
+#endif
+
+ switch (event)
+ {
+ case BTA_MSE_MA_OBX_CONN_EVT:
+ case BTA_MSE_MA_OBX_DISC_EVT:
+ case BTA_MSE_MA_OBX_ABORT_EVT:
+ case BTA_MSE_MA_OBX_CLOSE_EVT:
+ case BTA_MSE_MA_OBX_PUT_EVT:
+ case BTA_MSE_MA_OBX_GET_EVT:
+ case BTA_MSE_MA_OBX_SETPATH_EVT:
+ utl_freebuf((void**)&p_data->obx_evt.p_pkt);
+ break;
+
+ default:
+ /*Nothing to free*/
+ break;
+ }
+}
+
+
+
+/*******************************************************************************
+**
+** Function bta_mse_find_mas_inst_id_match_cb_idx
+**
+** Description Finds the MAS instance control block index based on the specified
+** MAS instance ID
+**
+** Parameters mas_inst_id - MAS instance ID
+** p_idx - (output) pointer to the MA control block index
+**
+** Returns BOOLEAN - TRUE found
+** FALSE not found
+*******************************************************************************/
+BOOLEAN bta_mse_find_mas_inst_id_match_cb_idx(tBTA_MA_INST_ID mas_inst_id, UINT8 *p_idx)
+{
+ BOOLEAN found=FALSE;
+ UINT8 i;
+
+ for (i=0; i < BTA_MSE_NUM_INST ; i ++)
+ {
+ if (bta_mse_cb.scb[i].in_use)
+ {
+ if (bta_mse_cb.scb[i].mas_inst_id == mas_inst_id)
+ {
+ found = TRUE;
+ *p_idx = i;
+ break;
+ }
+ }
+ }
+
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT3("bta_mse_find_mas_inst_id_match_cb_idx found=%d, inst_id=%d inst_idx=%d",
+ found, mas_inst_id, i);
+#endif
+ return found;
+}
+
+
+/*******************************************************************************
+**
+** Function bta_mse_find_bd_addr_match_sess_cb_idx
+**
+** Description Finds the Session control block index based on the specified
+** MAS instance control block index and BD address
+**
+** Parameters bd_addr - BD address
+** inst_idx - MA control block index
+** p_idx - (output) pointer to the MA server control block
+** index
+**
+**
+** Returns BOOLEAN - TRUE found
+** FALSE not found
+*******************************************************************************/
+BOOLEAN bta_mse_find_bd_addr_match_sess_cb_idx(BD_ADDR bd_addr, UINT8 inst_idx,
+ UINT8 *p_idx)
+{
+ tBTA_MSE_MA_SESS_CB *p_cb;
+ BOOLEAN found=FALSE;
+ UINT8 i;
+
+ for (i=0; i < BTA_MSE_NUM_SESS ; i ++)
+ {
+ p_cb = BTA_MSE_GET_SESS_CB_PTR(inst_idx, i);
+ if ((p_cb->state == BTA_MSE_MA_CONN_ST) &&
+ !memcmp (p_cb->bd_addr, bd_addr, BD_ADDR_LEN))
+ {
+ found = TRUE;
+ *p_idx = i;
+ break;
+ }
+ }
+
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT3("bta_mse_find_bd_addr_match_sess_cb_idx found=%d, inst_idx=%d p_idx=%d",
+ found, inst_idx, i);
+#endif
+ return found;
+}
+
+
+/*******************************************************************************
+**
+** Function bta_mse_find_handle_match_mas_inst_cb_idx
+**
+** Description Finds the MAS instance control block index based on the specified Obx handle
+**
+** Parameters obx_handle - Obex session handle
+** p_idx - (output) pointer to the MA server control block index
+**
+**
+** Returns BOOLEAN - TRUE found
+** FALSE not found
+**
+*******************************************************************************/
+BOOLEAN bta_mse_find_handle_match_mas_inst_cb_idx(tOBX_HANDLE obx_handle, UINT8 *p_idx)
+{
+ BOOLEAN found=FALSE;
+ UINT8 i;
+
+ for (i=0; i < BTA_MSE_NUM_INST ; i ++)
+ {
+ if (bta_mse_cb.scb[i].in_use)
+ {
+ if (bta_mse_cb.scb[i].obx_handle == obx_handle)
+ {
+ found = TRUE;
+ *p_idx = i;
+ break;
+ }
+ }
+ }
+
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT2("bta_mse_find_handle_match_mas_inst_cb_idx found=%d idx=%d",found, i);
+#endif
+ return found;
+}
+/*******************************************************************************
+**
+** Function bta_mse_find_mas_sess_cb_idx
+**
+** Description Finds the MAS instance and session control block indexes
+** based on Obx handle
+**
+** Parameters obx_handle - Obex session handle
+** p_mas_inst_idx - (output) pointer to the MA server control
+** block index
+** p_mas_sess_idx - (output) pointer to the MA session control
+** block index
+**
+** Returns BOOLEAN - TRUE found
+** FALSE not found
+**
+*******************************************************************************/
+BOOLEAN bta_mse_find_mas_sess_cb_idx(tOBX_HANDLE obx_handle,
+ UINT8 *p_mas_inst_idx, UINT8 *p_mas_sess_idx)
+{
+ BOOLEAN found=FALSE;
+ UINT8 i, j;
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT0("bta_mse_find_mas_sess_cb_idx");
+#endif
+ for (i=0; i< BTA_MSE_NUM_INST; i++)
+ {
+ if (bta_mse_cb.scb[i].in_use)
+ {
+ for (j=0; j < BTA_MSE_NUM_SESS; j++ )
+ {
+ if ( (bta_mse_cb.scb[i].sess_cb[j].state != BTA_MSE_MA_LISTEN_ST) &&
+ (bta_mse_cb.scb[i].sess_cb[j].obx_handle == obx_handle) )
+ {
+ found = TRUE;
+ *p_mas_inst_idx = i;
+ *p_mas_sess_idx = j;
+ return found;
+ }
+ }
+ }
+ }
+
+ return found;
+}
+
+
+/*******************************************************************************
+**
+** Function bta_mse_find_ma_cb_indexes
+**
+** Description Finds the MAS instance and session control block indexes
+** based on the received internal event
+**
+** Parameters p_msg - Pointer to MSE msg data
+** p_mas_inst_idx - (output) pointer to the MA server control
+** block index
+** p_mas_sess_idx - (output) pointer to the MA session control
+** block index
+**
+** Returns BOOLEAN - TRUE found
+** FALSE not found
+**
+*******************************************************************************/
+BOOLEAN bta_mse_find_ma_cb_indexes(tBTA_MSE_DATA *p_msg,
+ UINT8 *p_inst_idx, UINT8 *p_sess_idx)
+{
+ BOOLEAN found = FALSE;
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT0("bta_mse_find_ma_cb_indexes");
+#endif
+ switch (p_msg->hdr.event)
+ {
+ case BTA_MSE_MA_OBX_CONN_EVT:
+
+ if (bta_mse_find_handle_match_mas_inst_cb_idx( p_msg->obx_evt.param.conn.handle, p_inst_idx))
+ {
+ if (bta_mse_find_avail_mas_sess_cb_idx(&(bta_mse_cb.scb[*p_inst_idx]), p_sess_idx))
+ found = TRUE;
+ }
+ break;
+
+ case BTA_MSE_API_ACCESSRSP_EVT:
+
+ if (bta_mse_find_sess_id_match_ma_cb_indexes(p_msg->api_access_rsp.mas_session_id,
+ p_inst_idx,p_sess_idx))
+ found = TRUE;
+
+ break;
+
+ case BTA_MSE_API_UPD_IBX_RSP_EVT:
+
+ if (bta_mse_find_sess_id_match_ma_cb_indexes(p_msg->api_upd_ibx_rsp.mas_session_id,
+ p_inst_idx,p_sess_idx))
+ found = TRUE;
+
+ break;
+
+ case BTA_MSE_API_SET_NOTIF_REG_RSP_EVT:
+
+ if (bta_mse_find_sess_id_match_ma_cb_indexes(p_msg->api_set_notif_reg_rsp.mas_session_id,
+ p_inst_idx,p_sess_idx))
+ found = TRUE;
+
+ break;
+
+ case BTA_MSE_INT_CLOSE_EVT:
+
+ if (bta_mse_find_sess_id_match_ma_cb_indexes(p_msg->int_close.mas_session_id,
+ p_inst_idx,p_sess_idx))
+ found = TRUE;
+
+ break;
+
+ case BTA_MSE_CI_GET_FENTRY_EVT:
+
+ if (bta_mse_find_sess_id_match_ma_cb_indexes(p_msg->ci_get_fentry.mas_session_id,
+ p_inst_idx,p_sess_idx))
+ found = TRUE;
+
+ break;
+ case BTA_MSE_CI_GET_ML_INFO_EVT:
+
+ if (bta_mse_find_sess_id_match_ma_cb_indexes(p_msg->ci_get_ml_info.mas_session_id,
+ p_inst_idx,p_sess_idx))
+ found = TRUE;
+
+ break;
+ case BTA_MSE_CI_GET_ML_ENTRY_EVT:
+
+ if (bta_mse_find_sess_id_match_ma_cb_indexes(p_msg->ci_get_ml_entry.mas_session_id,
+ p_inst_idx,p_sess_idx))
+ found = TRUE;
+
+ break;
+ case BTA_MSE_CI_GET_MSG_EVT:
+
+ if (bta_mse_find_sess_id_match_ma_cb_indexes(p_msg->ci_get_msg.mas_session_id,
+ p_inst_idx,p_sess_idx))
+ found = TRUE;
+
+ break;
+
+ case BTA_MSE_CI_PUSH_MSG_EVT:
+
+ if (bta_mse_find_sess_id_match_ma_cb_indexes(p_msg->ci_push_msg.mas_session_id,
+ p_inst_idx,p_sess_idx))
+ found = TRUE;
+
+ break;
+
+ case BTA_MSE_CI_DEL_MSG_EVT:
+
+ if (bta_mse_find_sess_id_match_ma_cb_indexes(p_msg->ci_del_msg.mas_session_id,
+ p_inst_idx,p_sess_idx))
+ found = TRUE;
+
+ break;
+
+ case BTA_MSE_MA_OBX_DISC_EVT:
+ case BTA_MSE_MA_OBX_ABORT_EVT:
+ case BTA_MSE_MA_OBX_CLOSE_EVT:
+ case BTA_MSE_MA_OBX_PUT_EVT:
+ case BTA_MSE_MA_OBX_GET_EVT:
+ case BTA_MSE_MA_OBX_SETPATH_EVT:
+
+ if (bta_mse_find_mas_sess_cb_idx( p_msg->obx_evt.handle, p_inst_idx, p_sess_idx))
+ found = TRUE;
+ break;
+ default:
+ break;
+
+ }
+
+ return found;
+}
+
+
+/*******************************************************************************
+**
+** Function bta_mse_ma_cleanup
+**
+** Description Free resources if unable to find MA control block indexes
+**
+** Parameters p_msg - Pointer to MSE msg data
+**
+** Returns none
+**
+*******************************************************************************/
+void bta_mse_ma_cleanup(tBTA_MSE_DATA *p_msg)
+{
+ tBTA_MSE_OBX_EVT *p_evt = &p_msg->obx_evt;
+ tBTA_MA_OBX_RSP *p_rsp = NULL;
+ UINT8 rsp_code = OBX_RSP_BAD_REQUEST;
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT0("bta_mse_ma_cleanup");
+#endif
+ switch (p_msg->hdr.event)
+ {
+ case BTA_MSE_MA_OBX_CONN_EVT:
+ p_rsp = OBX_ConnectRsp;
+ rsp_code = OBX_RSP_SERVICE_UNAVL;
+ break;
+ case BTA_MSE_MA_OBX_DISC_EVT:
+ p_rsp = OBX_DisconnectRsp;
+ break;
+ case BTA_MSE_MA_OBX_ABORT_EVT:
+ p_rsp = OBX_AbortRsp;
+ break;
+ case BTA_MSE_MA_OBX_PUT_EVT:
+ p_rsp = OBX_PutRsp;
+ break;
+ case BTA_MSE_MA_OBX_GET_EVT:
+ p_rsp = OBX_GetRsp;
+ break;
+ case BTA_MSE_MA_OBX_SETPATH_EVT:
+ p_rsp = OBX_SetPathRsp;
+ break;
+ default:
+ break;
+ }
+
+ if (p_rsp)
+ {
+ (*p_rsp)(p_evt->handle, rsp_code, (BT_HDR *)NULL);
+ /* Done with Obex packet */
+ utl_freebuf((void**)&p_evt->p_pkt);
+ }
+}
+
+
+
+/*******************************************************************************
+**
+** Function bta_mse_is_a_duplicate_id
+**
+** Description Determine the MAS instance ID has been used or not by other MAS instance
+**
+** Parameters mas_inst_id - MAS instance ID
+**
+** Returns BOOLEAN - TRUE the MAS isntance is a duplicate ID
+** FALSE not a duplicate ID
+*******************************************************************************/
+BOOLEAN bta_mse_is_a_duplicate_id(tBTA_MA_INST_ID mas_inst_id)
+{
+ BOOLEAN is_duplicate=FALSE;
+ UINT8 i;
+
+ for (i=0; i < BTA_MSE_NUM_INST ; i ++)
+ {
+ if (bta_mse_cb.scb[i].in_use &&
+ (bta_mse_cb.scb[i].mas_inst_id == mas_inst_id))
+ {
+ is_duplicate = TRUE;
+
+ break;
+ }
+ }
+
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT2("bta_mse_is_a_duplicate_id inst_id=%d status=%d",
+ mas_inst_id, is_duplicate);
+#endif
+
+ return is_duplicate;
+}
+
+
+/*******************************************************************************
+**
+** Function bta_mse_find_avail_mas_inst_cb_idx
+**
+** Description Finds a not in used MAS instance control block index
+**
+** Parameters p_idx - (output) pointer to the MA server control
+** block index
+**
+** Returns BOOLEAN - TRUE found
+** FALSE not found
+**
+*******************************************************************************/
+BOOLEAN bta_mse_find_avail_mas_inst_cb_idx(UINT8 *p_idx)
+{
+ BOOLEAN found=FALSE;
+ UINT8 i;
+
+
+ for (i=0; i < BTA_MSE_NUM_INST ; i ++)
+ {
+ if (!bta_mse_cb.scb[i].in_use)
+ {
+ found = TRUE;
+ *p_idx = i;
+ break;
+ }
+ }
+
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT2("bta_mse_find_avail_mas_inst_cb_idx found=%d inst_idx=%d",
+ found, i);
+#endif
+ return found;
+}
+/*******************************************************************************
+**
+** Function bta_mse_find_avail_mas_sess_cb_idx
+**
+** Description Finds a not in used MAS session control block index
+**
+** Parameters p_scb - Pointer to the MA control block
+** p_idx - (output) pointer to the MA session control
+** block index
+**
+** Returns BOOLEAN - TRUE found
+** FALSE not found
+*******************************************************************************/
+BOOLEAN bta_mse_find_avail_mas_sess_cb_idx(tBTA_MSE_MA_CB *p_scb, UINT8 *p_idx)
+{
+ BOOLEAN found=FALSE;
+ UINT8 i;
+
+ for (i=0; i < BTA_MSE_NUM_SESS ; i ++)
+ {
+ if (p_scb->sess_cb[i].state == BTA_MSE_MA_LISTEN_ST)
+ {
+ if ((p_scb->sess_cb[i].p_workdir = (char *)GKI_getbuf((UINT16)(p_bta_fs_cfg->max_path_len + 1))) != NULL)
+ {
+ found = TRUE;
+ *p_idx = i;
+ }
+ break;
+ }
+ }
+
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT2("bta_mse_find_avail_mas_sess_cb_idx found=%d idx=%d", found, i);
+#endif
+ return found;
+}
+
+/*******************************************************************************
+**
+** Function bta_mse_find_avail_mn_cb_idx
+**
+** Description Finds a not in use MN control block index
+**
+** Parameters p_idx - (output) pointer to the MN control block index
+**
+** Returns BOOLEAN - TRUE found
+** FALSE not found
+**
+*******************************************************************************/
+BOOLEAN bta_mse_find_avail_mn_cb_idx(UINT8 *p_idx)
+{
+ BOOLEAN found=FALSE;
+ UINT8 i;
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT0("bta_mse_find_avail_mn_cb_idx");
+#endif
+ for (i=0; i < BTA_MSE_NUM_MN ; i ++)
+ {
+ if (!bta_mse_cb.ccb[i].in_use)
+ {
+ found = TRUE;
+ *p_idx = i;
+ break;
+ }
+ }
+ return found;
+}
+
+
+
+/*******************************************************************************
+**
+** Function bta_mse_find_bd_addr_match_mn_cb_index
+**
+** Description Find the MN control block index based on the specified BD address
+**
+** Parameters p_bd_addr - Pointer to the BD address
+** p_idx - (output) pointer to the MN control block index
+**
+** Returns BOOLEAN - TRUE found
+** FALSE not found
+**
+*******************************************************************************/
+
+BOOLEAN bta_mse_find_bd_addr_match_mn_cb_index(BD_ADDR p_bd_addr, UINT8 *p_idx)
+{
+ BOOLEAN found=FALSE;
+ UINT8 i;
+
+ for (i=0; i < BTA_MSE_NUM_MN ; i ++)
+ {
+ if ((bta_mse_cb.ccb[i].in_use) &&
+ (!memcmp (bta_mse_cb.ccb[i].bd_addr, p_bd_addr, BD_ADDR_LEN)))
+ {
+ found = TRUE;
+ *p_idx = i;
+ break;
+ }
+ }
+
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT2("bta_mse_find_bd_addr_match_mn_cb_index found=%d index=%d", found, i);
+#endif
+ return found;
+}
+
+/*******************************************************************************
+**
+** Function bta_mse_find_bd_addr_match_mn_cb_index
+**
+** Description Find the MN control block index based on the specified obx handle
+**
+** Parameters obx_hdl - Obex session handle
+** p_idx - (output) pointer to the MN control block index
+**
+** Returns BOOLEAN - TRUE found
+** FALSE not found
+**
+*******************************************************************************/
+
+BOOLEAN bta_mse_find_obx_hdl_match_mn_cb_index(tOBX_HANDLE obx_hdl, UINT8 *p_idx)
+{
+ BOOLEAN found=FALSE;
+ UINT8 i;
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT0("bta_mse_find_obx_hdl_match_mn_cb_index");
+#endif
+ for (i=0; i < BTA_MSE_NUM_INST ; i ++)
+ {
+ if ((bta_mse_cb.ccb[i].in_use) &&
+ (bta_mse_cb.ccb[i].obx_handle == obx_hdl))
+ {
+ found = TRUE;
+ *p_idx = i;
+ break;
+ }
+ }
+
+ return found;
+}
+
+/*******************************************************************************
+**
+** Function bta_mse_find_sess_id_match_ma_cb_indexes
+**
+** Description Finds the MAS instance and session control block indexes
+** based on the specified MAS session ID
+**
+** Parameters mas_session_id - MAS instance ID
+** p_inst_idx - (output) pointer to the MA server control
+** block index
+** p_sess_idx - (output) pointer to the MA session control
+** block index
+**
+** Returns BOOLEAN - TRUE found
+** FALSE not found
+**
+*******************************************************************************/
+BOOLEAN bta_mse_find_sess_id_match_ma_cb_indexes(tBTA_MA_SESS_HANDLE mas_session_id,
+ UINT8 *p_inst_idx, UINT8 *p_sess_idx)
+{
+ BOOLEAN found=FALSE;
+ UINT8 i,j;
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT0("bta_mse_find_sess_id_match_ma_cb_indexes");
+#endif
+ for (i=0; i < BTA_MSE_NUM_INST ; i ++)
+ {
+ for (j=0; j<BTA_MSE_NUM_SESS; j++ )
+ {
+ if ((bta_mse_cb.scb[i].in_use) &&
+ (bta_mse_cb.scb[i].sess_cb[j].obx_handle == (tOBX_HANDLE) mas_session_id ))
+ {
+ found = TRUE;
+ *p_inst_idx = i;
+ *p_sess_idx = j;
+ return found;
+ }
+ }
+ }
+
+ return found;
+}
+
+/*******************************************************************************
+**
+** Function bta_mse_find_sess_id_match_mn_cb_index
+**
+** Description Finds the MN control block index
+** based on the specified MAS session ID
+**
+** Parameters mas_session_id - MAS instance ID
+** p_idx - (output) pointer to the MN control
+** block index
+**
+** Returns BOOLEAN - TRUE found
+** FALSE not found
+**
+*******************************************************************************/
+BOOLEAN bta_mse_find_sess_id_match_mn_cb_index(tBTA_MA_SESS_HANDLE mas_session_id,
+ UINT8 *p_idx)
+{
+ BOOLEAN found=FALSE;
+
+ UINT8 i,j;
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT0("bta_mse_find_sess_id_match_mn_cb_index");
+#endif
+ for (i=0; i < BTA_MSE_NUM_INST ; i ++)
+ {
+ for (j=0; j<BTA_MSE_NUM_SESS; j++ )
+ {
+ if ((bta_mse_cb.scb[i].in_use) &&
+ (bta_mse_cb.scb[i].sess_cb[j].obx_handle == (tOBX_HANDLE) mas_session_id ))
+ {
+ found = TRUE;
+ break;
+ }
+ }
+ if (found) break;
+ }
+
+ /* found session index now need to match BD address*/
+ if (found)
+ {
+ found = FALSE;
+ if ( bta_mse_find_bd_addr_match_mn_cb_index(bta_mse_cb.scb[i].sess_cb[j].bd_addr, p_idx))
+ {
+ found = TRUE;
+ }
+ }
+ return found;
+}
+
+
+/*******************************************************************************
+**
+** Function bta_mse_find_mn_cb_index
+**
+** Description Finds the MN control block index
+** based on the specified event
+**
+** Parameters p_msg - Pointer to MSE msg data
+** p_ccb_idx - (output) pointer to the MN control block index
+**
+** Returns BOOLEAN - TRUE found
+** FALSE not found
+**
+*******************************************************************************/
+BOOLEAN bta_mse_find_mn_cb_index(tBTA_MSE_DATA *p_msg, UINT8 *p_ccb_idx)
+{
+ BOOLEAN found = TRUE;
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT0("bta_mse_find_mn_cb_index");
+#endif
+ switch (p_msg->hdr.event)
+ {
+ case BTA_MSE_MN_INT_OPEN_EVT:
+ *p_ccb_idx= p_msg->mn_int_open.ccb_idx;
+ break;
+
+ case BTA_MSE_MN_INT_CLOSE_EVT:
+ *p_ccb_idx= p_msg->mn_int_close.ccb_idx;
+ break;
+
+ case BTA_MSE_MN_OBX_CONN_RSP_EVT:
+
+ if (!bta_mse_find_bd_addr_match_mn_cb_index(
+ p_msg->obx_evt.param.conn.peer_addr,
+ p_ccb_idx))
+ {
+ found = FALSE;
+ }
+ break;
+
+ case BTA_MSE_MN_OBX_TOUT_EVT:
+ case BTA_MSE_MN_OBX_CLOSE_EVT:
+ case BTA_MSE_MN_OBX_PUT_RSP_EVT:
+ if (!bta_mse_find_obx_hdl_match_mn_cb_index(
+ p_msg->obx_evt.handle,
+ p_ccb_idx))
+ {
+ found = FALSE;
+ }
+
+ break;
+
+ case BTA_MSE_MN_SDP_OK_EVT:
+
+ *p_ccb_idx = p_msg->mn_sdp_ok.ccb_idx;
+ break;
+
+ case BTA_MSE_MN_SDP_FAIL_EVT:
+
+ *p_ccb_idx = p_msg->mn_sdp_fail.ccb_idx;
+ break;
+
+ default:
+ found = FALSE;
+ break;
+ }
+
+ return found;
+}
+
+
+/*******************************************************************************
+**
+** Function bta_mse_mn_cleanup
+**
+** Description Free resources if unable to find MN control block index
+**
+** Parameters p_msg - Pointer to MSE msg data
+**
+** Returns none
+**
+*******************************************************************************/
+void bta_mse_mn_cleanup(tBTA_MSE_DATA *p_msg)
+{
+ tBTA_MSE_OBX_EVT *p_evt = &p_msg->obx_evt;
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT0("bta_mse_mn_cleanup");
+#endif
+ switch (p_msg->hdr.event)
+ {
+ case BTA_MSE_MN_OBX_CONN_RSP_EVT:
+ case BTA_MSE_MN_OBX_PUT_RSP_EVT:
+ /* Done with Obex packet */
+ utl_freebuf((void**)&p_evt->p_pkt);
+ break;
+
+ default:
+ break;
+ }
+}
+/*******************************************************************************
+**
+** Function bta_mse_build_map_event_rpt_obj
+**
+** Description Create a MAP-Event-Report object in the
+** specified buffer.
+**
+** Parameters notif_type - Notification type
+** handle (input only) - handle of the message that the "type"
+** indication refers to. Ignored when the event "type" is
+** "MemoryFull" or "MemoryAvailable".
+** p_folder - name of the folder in which the corresponding
+** message has been filed by the MSE. NULL when the event
+** "type" is "MemoryFull" or "MemoryAvailable".
+** p_old_folder - Used only in case of a message shift to
+** indicate the folder on the MSE from which the message
+** has been shifted out.
+** msg_typ - Gives the type of the message. Ignored when the
+** event "type" is "MemoryFull" or "MemoryAvailable".
+** p_len - Pointer to value containing the size of
+** the buffer (p_buffer). Receives the output size of
+** filled XML object.
+** p_buffer - Pointer to buffer to receive the XML object.
+**
+** Returns BTA_MA_STATUS_FAIL if buffer was not large enough, otherwise
+** returns BTA_MA_STATUS_OK.
+**
+*******************************************************************************/
+tBTA_MA_STATUS bta_mse_build_map_event_rpt_obj(tBTA_MSE_NOTIF_TYPE notif_type,
+ tBTA_MA_MSG_HANDLE handle,
+ char * p_folder,
+ char * p_old_folder,
+ tBTA_MA_MSG_TYPE msg_typ,
+ UINT16 * p_len,
+ UINT8 * p_buffer)
+{
+ tBTA_MA_STREAM strm;
+
+ memset(p_buffer, 0, *p_len);
+ BTA_MaInitMemStream(&strm, p_buffer, *p_len);
+
+ /* stream event attribute and event type */
+ bta_ma_stream_str(&strm, "<MAP-event-report version=\"1.0\">\n"
+ "<event type = \"");
+ bta_ma_stream_str(&strm, bta_ma_evt_typ_to_string(notif_type));
+
+ /* Some things are not used for "MemoryFull" and "MemoryAvailable" */
+ if ( (BTA_MSE_NOTIF_TYPE_MEMORY_FULL != notif_type)
+ && (BTA_MSE_NOTIF_TYPE_MEMORY_AVAILABLE != notif_type) )
+ {
+ /* stream handle label and value */
+ bta_ma_stream_str(&strm, "\" handle = \"");
+ bta_ma_stream_handle(&strm, handle);
+
+ if (p_folder && (*p_folder !='\0'))
+ {
+ /* stream folder */
+ bta_ma_stream_str(&strm, "\" folder = \"");
+ bta_ma_stream_str(&strm, p_folder);
+ }
+
+ /* stream old_folder if it is a "MessageShift" */
+ if ( (BTA_MSE_NOTIF_TYPE_MESSAGE_SHIFT == notif_type) &&
+ p_old_folder && (*p_old_folder !='\0'))
+ {
+ /* stream folder */
+ bta_ma_stream_str(&strm, "\" old_folder = \"");
+ bta_ma_stream_str(&strm, p_old_folder);
+ }
+
+ /* stream message type */
+ bta_ma_stream_str(&strm, "\" msg_type = \"");
+ bta_ma_stream_str(&strm, bta_ma_msg_typ_to_string(msg_typ));
+ }
+
+ /* we are done with this evnet */
+ bta_ma_stream_str(&strm, "\" />\n</MAP-event-report>");
+
+ /* set the output length (i.e. amount of buffer that got used) */
+ *p_len = bta_ma_stream_used_size(&strm);
+
+ /* return status based on the stream status */
+ return(bta_ma_stream_ok(&strm)
+ ? BTA_MA_STATUS_OK
+ : BTA_MA_STATUS_FAIL);
+}
+
+
+/*******************************************************************************
+**
+** Function bta_mse_build_msg_listing_obj
+**
+** Description Build the message listing object in the specified buffer
+**
+** Parameters p_entry - Pointer to the message listing entry
+** p_size - input: pointer to the available buffer size
+** output: pointer to the filled buffer size
+** p_buf - pointer to the buffer for building the msg listing
+** object
+**
+** Returns status - BTA_MA_STATUS_OK - build the object successfully
+** BTA_MA_STATUS_FAIL - failed to build the object
+**
+*******************************************************************************/
+tBTA_MA_STATUS bta_mse_build_msg_listing_obj(tBTA_MSE_CO_MSG_LIST_ENTRY *p_entry,
+ UINT16 *p_size, char *p_buf )
+{
+ tBTA_MA_STREAM strm;
+
+ memset(p_buf, 0, *p_size);
+ BTA_MaInitMemStream(&strm, (UINT8 *)p_buf, *p_size);
+
+ /* stream msg element */
+ bta_ma_stream_str(&strm, "<msg ");
+ /* stream msg attributes */
+ bta_ma_stream_str(&strm, "handle = \"");
+ bta_ma_stream_handle(&strm, p_entry->msg_handle);
+
+ if (p_entry->parameter_mask &BTA_MA_ML_MASK_SUBJECT)
+ {
+ bta_ma_stream_str(&strm, "\" subject = \"");
+ bta_ma_stream_str(&strm, p_entry->subject);
+ }
+
+ if (p_entry->parameter_mask & BTA_MA_ML_MASK_DATETIME)
+ {
+ bta_ma_stream_str(&strm, "\" datetime = \"");
+ bta_ma_stream_str(&strm, p_entry->date_time);
+ }
+
+ if (p_entry->parameter_mask & BTA_MA_ML_MASK_SENDER_NAME)
+ {
+ bta_ma_stream_str(&strm, "\" sender_name = \"");
+ bta_ma_stream_str(&strm, p_entry->sender_name);
+ }
+
+
+ if (p_entry->parameter_mask & BTA_MA_ML_MASK_SENDER_ADDRESSING)
+ {
+ bta_ma_stream_str(&strm, "\" sender_addressing = \"");
+ bta_ma_stream_str(&strm, p_entry->sender_addressing);
+ }
+
+ if (p_entry->parameter_mask & BTA_MA_ML_MASK_REPLYTO_ADDRESSING)
+ {
+ bta_ma_stream_str(&strm, "\" replyto_addressing = \"");
+ bta_ma_stream_str(&strm, p_entry->replyto_addressing);
+ }
+
+ if (p_entry->parameter_mask & BTA_MA_ML_MASK_RECIPIENT_NAME)
+ {
+ bta_ma_stream_str(&strm, "\" recipient_name = \"");
+ bta_ma_stream_str(&strm, p_entry->recipient_name);
+ }
+
+ if (p_entry->parameter_mask & BTA_MA_ML_MASK_RECIPIENT_ADDRESSING)
+ {
+ bta_ma_stream_str(&strm, "\" recipient_addressing = \"");
+ bta_ma_stream_str(&strm, p_entry->recipient_addressing);
+ }
+
+ if (p_entry->parameter_mask & BTA_MA_ML_MASK_TYPE)
+ {
+ bta_ma_stream_str(&strm, "\" type = \"");
+ if (!bta_ma_stream_str(&strm, bta_ma_msg_typ_to_string(p_entry->type)))
+ {
+ return BTA_MA_STATUS_FAIL;
+ }
+ }
+
+ if (p_entry->parameter_mask & BTA_MA_ML_MASK_SIZE)
+ {
+ bta_ma_stream_str(&strm, "\" size = \"");
+ bta_ma_stream_value(&strm, p_entry->org_msg_size);
+ }
+
+ if (p_entry->parameter_mask & BTA_MA_ML_MASK_TEXT)
+ {
+ bta_ma_stream_str(&strm, "\" text = \"");
+ bta_ma_stream_boolean_yes_no(&strm, p_entry->text);
+ }
+
+ if (p_entry->parameter_mask & BTA_MA_ML_MASK_RECEPTION_STATUS)
+ {
+ bta_ma_stream_str(&strm, "\" reception_status = \"");
+ if (!bta_ma_stream_str(&strm,
+ bta_ma_rcv_status_to_string(p_entry->reception_status)))
+ {
+ return BTA_MA_STATUS_FAIL;
+ }
+ }
+
+ if (p_entry->parameter_mask & BTA_MA_ML_MASK_ATTACHMENT_SIZE)
+ {
+ bta_ma_stream_str(&strm, "\" attachment_size = \"");
+ bta_ma_stream_value(&strm, p_entry->attachment_size);
+ }
+
+ if (p_entry->parameter_mask & BTA_MA_ML_MASK_PRIORITY)
+ {
+ bta_ma_stream_str(&strm, "\" priority = \"");
+ bta_ma_stream_boolean_yes_no(&strm, p_entry->high_priority);
+ }
+ if (p_entry->parameter_mask & BTA_MA_ML_MASK_READ)
+ {
+ bta_ma_stream_str(&strm, "\" read = \"");
+ bta_ma_stream_boolean_yes_no(&strm, p_entry->read);
+ }
+ if (p_entry->parameter_mask & BTA_MA_ML_MASK_SENT)
+ {
+ bta_ma_stream_str(&strm, "\" sent = \"");
+ bta_ma_stream_boolean_yes_no(&strm, p_entry->sent);
+ }
+ if (p_entry->parameter_mask & BTA_MA_ML_MASK_PROTECTED)
+ {
+ bta_ma_stream_str(&strm, "\" protected = \"");
+ bta_ma_stream_boolean_yes_no(&strm, p_entry->is_protected);
+ }
+
+ /* stream msg element end tag*/
+ bta_ma_stream_str(&strm, "\"/> ");
+
+ /* set the output length (i.e. amount of buffer that got used) */
+ *p_size = bta_ma_stream_used_size(&strm);
+
+ /* return status based on the stream status */
+ return(bta_ma_stream_ok(&strm)
+ ? BTA_MA_STATUS_OK
+ : BTA_MA_STATUS_FAIL);
+}
+
+/*******************************************************************************
+**
+** Function bta_mse_mn_start_timer
+**
+** Description Start a wait for obx response timer
+**
+** Parameters ccb_inx - MN control block index
+** timer_id - indicating this timer is for which operation
+**
+** Returns None
+**
+*******************************************************************************/
+void bta_mse_mn_start_timer(UINT8 ccb_idx, UINT8 timer_id)
+{
+ tBTA_MSE_MN_CB *p_cb = BTA_MSE_GET_MN_CB_PTR(ccb_idx);
+ UINT16 event_id;
+ p_cb->rsp_timer.param = (UINT32) (ccb_idx+1);
+ event_id = (UINT16) BTA_MSE_MN_RSP0_TOUT_EVT + ccb_idx;
+ bta_sys_start_timer(&p_cb->rsp_timer, event_id,
+ p_bta_mse_cfg->obx_rsp_tout);
+
+ p_cb->timer_oper = timer_id;
+}
+/*******************************************************************************
+**
+** Function bta_mse_mn_start_stop_timer
+**
+** Description Stop a wait for obx response timer
+**
+** Parameters ccb_inx - MN control block index
+** timer_id - indicating this timer is for which operation
+**
+** Returns None
+**
+*******************************************************************************/
+void bta_mse_mn_stop_timer(UINT8 ccb_idx, UINT8 timer_id)
+{
+ tBTA_MSE_MN_CB *p_cb = BTA_MSE_GET_MN_CB_PTR(ccb_idx);
+
+ if ((p_cb->timer_oper == timer_id) || (timer_id == BTA_MSE_TIMER_OP_ALL))
+ {
+ p_cb->rsp_timer.param = 0;
+ bta_sys_stop_timer(&p_cb->rsp_timer );
+ p_cb->timer_oper = BTA_MSE_TIMER_OP_NONE;
+ }
+}
+
+/*******************************************************************************
+**
+** Function bta_mse_mn_add_inst_id
+**
+** Description Add mas_inst_id to the MN notif_reg data base
+**
+** Parameters ccb_inx - MN control block index
+** mas_inst_id - MAS instance ID
+**
+** Returns BOOLEAN - TRUE OK
+** FALSE not OK
+**
+*******************************************************************************/
+BOOLEAN bta_mse_mn_add_inst_id(UINT8 ccb_idx, tBTA_MA_INST_ID mas_inst_id)
+{
+ BOOLEAN found=FALSE;
+ BOOLEAN add_status=FALSE;
+ UINT8 i;
+ tBTA_MSE_MN_CB *p_ccb = BTA_MSE_GET_MN_CB_PTR(ccb_idx);
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT2("bta_mse_mn_add_inst_id ccb_idx=%d mas_inst_id=%d",
+ ccb_idx, mas_inst_id);
+#endif
+ for (i=0; i < BTA_MSE_NUM_INST ; i ++)
+ {
+ if (p_ccb->notif_reg[i].status &&
+ (p_ccb->notif_reg[i].mas_inst_id == mas_inst_id))
+ {
+ found = TRUE;
+ add_status = TRUE;
+ break;
+ }
+ }
+
+ if (!found)
+ {
+ for (i=0; i < BTA_MSE_NUM_INST ; i ++)
+ {
+ if (!p_ccb->notif_reg[i].status)
+ {
+ /* find an available entry to add */
+ p_ccb->notif_reg[i].mas_inst_id = mas_inst_id;
+ p_ccb->notif_reg[i].status = TRUE;
+ add_status = TRUE;
+ break;
+ }
+ }
+ }
+
+
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT1("add_status=%d", add_status);
+#endif
+
+ return add_status;
+}
+
+/*******************************************************************************
+**
+** Function bta_mse_mn_remove_inst_id
+**
+** Description Remove mas_inst_id from the MN notif_reg data base
+**
+** Parameters ccb_inx - MN control block index
+** mas_inst_id - MAS instance ID
+**
+** Returns BOOLEAN - TRUE OK
+** FALSE not OK
+**
+*******************************************************************************/
+BOOLEAN bta_mse_mn_remove_inst_id(UINT8 ccb_idx, tBTA_MA_INST_ID mas_inst_id)
+{
+ BOOLEAN remove_status=FALSE;
+ UINT8 i;
+ tBTA_MSE_MN_CB *p_ccb = BTA_MSE_GET_MN_CB_PTR(ccb_idx);
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT2("bta_mse_mn_remove_inst_id ccb_idx=%d mas_inst_id=%d",
+ ccb_idx, mas_inst_id);
+#endif
+ for (i=0; i < BTA_MSE_NUM_INST ; i ++)
+ {
+ if (p_ccb->notif_reg[i].status &&
+ (p_ccb->notif_reg[i].mas_inst_id == mas_inst_id))
+ {
+ p_ccb->notif_reg[i].status = FALSE;
+ p_ccb->notif_reg[i].mas_inst_id =(tBTA_MA_INST_ID )0;
+
+ remove_status = TRUE;
+ break;
+ }
+ }
+
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT1("remove_status=%d", remove_status);
+#endif
+
+ return remove_status;
+}
+
+/*******************************************************************************
+**
+** Function bta_mse_mn_remove_all_inst_ids
+**
+** Description Remove all mas_inst_ids from the MN notif_reg data base
+**
+** Parameters ccb_inx - MN control block index
+**
+** Returns None
+**
+*******************************************************************************/
+void bta_mse_mn_remove_all_inst_ids(UINT8 ccb_idx)
+{
+ UINT8 i;
+ tBTA_MSE_MN_CB *p_ccb = BTA_MSE_GET_MN_CB_PTR(ccb_idx);
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT1("bta_mse_mn_remove_all_inst_ids ccb_idx=%d ",
+ ccb_idx);
+#endif
+ for (i=0; i < BTA_MSE_NUM_INST ; i ++)
+ {
+ if (p_ccb->notif_reg[i].status)
+ {
+ p_ccb->notif_reg[i].status = FALSE;
+ p_ccb->notif_reg[i].mas_inst_id =(tBTA_MA_INST_ID) 0;
+ }
+ }
+}
+
+/*******************************************************************************
+**
+** Function bta_mse_mn_find_num_of_act_inst_id
+**
+** Description fin the number of Mas Instance IDs with registration status on
+**
+** Parameters ccb_inx - MN control block index
+**
+** Returns UINT8 - Number of active Mas Instance ID
+**
+*******************************************************************************/
+UINT8 bta_mse_mn_find_num_of_act_inst_id(UINT8 ccb_idx)
+{
+ UINT8 i,cnt;
+ tBTA_MSE_MN_CB *p_ccb = BTA_MSE_GET_MN_CB_PTR(ccb_idx);;
+
+ cnt =0;
+ for (i=0; i < BTA_MSE_NUM_INST ; i ++)
+ {
+ if (p_ccb->notif_reg[i].status) cnt++;
+ }
+
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT2("bta_mse_mn_find_num_of_act_inst_id ccb_idx=%d cnt=%d",
+ ccb_idx, cnt);
+#endif
+
+ return cnt;
+}
+
+/*******************************************************************************
+**
+** Function bta_mse_mn_is_inst_id_exist
+**
+** Description Check whether the specified mas_inst_id is in the
+** MN notif_reg data base
+**
+** Parameters ccb_inx - MN control block index
+** mas_inst_id - MAS instance ID
+**
+** Returns BOOLEAN - TRUE found
+** FALSE not found
+**
+**
+*******************************************************************************/
+BOOLEAN bta_mse_mn_is_inst_id_exist(UINT8 ccb_idx, tBTA_MA_INST_ID mas_inst_id )
+{
+ BOOLEAN found = FALSE;
+ UINT8 i;
+ tBTA_MSE_MN_CB *p_ccb = BTA_MSE_GET_MN_CB_PTR(ccb_idx);;
+
+ for (i=0; i < BTA_MSE_NUM_INST ; i ++)
+ {
+ if (p_ccb->notif_reg[i].status &&
+ (p_ccb->notif_reg[i].mas_inst_id == mas_inst_id))
+ {
+ found = TRUE;
+ break;
+ }
+ }
+
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT3("bta_mse_mn_is_inst_id_exist ccb_idx=%d mas_inst_id=%d found=%d",
+ ccb_idx, mas_inst_id, found);
+#endif
+
+ return found;
+}
+
+/*******************************************************************************
+**
+** Function bta_mse_mn_is_ok_to_close_mn
+**
+** Description Determine is ok to close MN connection
+**
+** Parameters bd_addr - BD address
+** mas_inst_id - MAS instance ID
+**
+** Returns BOOLEAN - TRUE OK
+** FALSE not OK
+**
+*******************************************************************************/
+BOOLEAN bta_mse_mn_is_ok_to_close_mn(BD_ADDR bd_addr, tBTA_MA_INST_ID mas_inst_id )
+{
+ UINT8 ccb_idx;
+ BOOLEAN ok_status= FALSE;
+
+
+ if (bta_mse_find_bd_addr_match_mn_cb_index(bd_addr, &ccb_idx) &&
+ (bta_mse_mn_find_num_of_act_inst_id(ccb_idx) == 1) &&
+ (bta_mse_mn_is_inst_id_exist(ccb_idx, mas_inst_id)))
+ {
+ ok_status = TRUE;
+ }
+
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT2("bta_mse_mn_is_ok_to_close_mn mas_inst_id=%d ok_status=%d",
+ mas_inst_id, ok_status);
+#endif
+
+ return ok_status;
+}
+
+
+/*******************************************************************************
+**
+** Function bta_mse_mn_get_first_inst_id
+**
+** Description Get the first active mas_inst_id from the MN notif_reg data base
+**
+** Parameters ccb_inx - MN control block index
+** mas_inst_id - MAS instance ID
+**
+** Returns BOOLEAN - TRUE OK
+** FALSE not OK
+**
+*******************************************************************************/
+BOOLEAN bta_mse_mn_get_first_inst_id(UINT8 ccb_idx, tBTA_MA_INST_ID *p_mas_inst_id)
+{
+ BOOLEAN found=FALSE;
+ UINT8 i;
+ tBTA_MSE_MN_CB *p_ccb = BTA_MSE_GET_MN_CB_PTR(ccb_idx);
+
+
+ for (i=0; i < BTA_MSE_NUM_INST ; i ++)
+ {
+ if (p_ccb->notif_reg[i].status )
+ {
+ *p_mas_inst_id = p_ccb->notif_reg[i].mas_inst_id;
+
+ found = TRUE;
+ break;
+ }
+ }
+
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT3("bta_mse_mn_get_inst_id ccb_idx=%d found status =%d mas_inst_id=%d",
+ ccb_idx, found, *p_mas_inst_id);
+#endif
+
+ return found;
+}
+
+
+/*******************************************************************************
+**
+** Function bta_mse_mn_send_abort_req
+**
+** Description Send an abort request.
+**
+** Parameters ccb_inx - MN control block index
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_mse_mn_send_abort_req(UINT8 ccb_idx)
+{
+ tBTA_MSE_MN_CB *p_cb = BTA_MSE_GET_MN_CB_PTR(ccb_idx);
+
+ if (BTA_MSE_MN_ABORT_REQ_NOT_SENT == p_cb->aborting)
+ {
+ bta_mse_mn_start_timer(ccb_idx, BTA_MSE_TIMER_OP_ABORT);
+ OBX_AbortReq(p_cb->obx_handle, (BT_HDR *)NULL);
+ p_cb->aborting = BTA_MSE_MN_ABORT_REQ_SENT;
+ }
+}
+
+/*******************************************************************************
+**
+** Function bta_mse_mn_cont_send_notif
+**
+** Description Continues the send notification operation. Builds a new OBX packet
+**
+** Parameters ccb_idx - MN control block index
+** first_pkt - first obex packet indicator
+**
+** Returns tBTA_MA_STATUS : BTA_MA_STATUS_OK if msg notification sent is ok
+** otherwise BTA_MA_STATUS_FAIL
+*******************************************************************************/
+tBTA_MA_STATUS bta_mse_mn_cont_send_notif(UINT8 ccb_idx, BOOLEAN first_pkt)
+{
+ tBTA_MSE_MN_CB *p_cb = BTA_MSE_GET_MN_CB_PTR(ccb_idx);
+ tBTA_MSE_OBX_PKT *p_obx = &p_cb->obx;
+ tBTA_MSE_MN_MSG_NOTIF *p_msg_notif = &p_cb->msg_notif;
+ tOBX_TRIPLET app_param[1];
+ UINT16 body_len;
+ BOOLEAN final_pkt = FALSE;
+ tBTA_MA_STATUS status = BTA_MA_STATUS_OK;
+
+ /* Do not start another request if currently aborting */
+ if (p_cb->aborting)
+ {
+ bta_mse_mn_send_abort_req(ccb_idx);
+ return status;
+ }
+
+ if ((p_obx->p_pkt = OBX_HdrInit(p_cb->obx_handle, p_cb->peer_mtu)) != NULL)
+ {
+ if (first_pkt)
+ {
+ OBX_AddTypeHdr(p_obx->p_pkt, BTA_MA_HDR_TYPE_EVENT_RPT);
+
+ app_param[0].tag = BTA_MA_NAS_INST_ID_TAG_ID;
+ app_param[0].len = BTA_MA_NAS_INST_ID_LEN;
+ app_param[0].p_array = &(p_msg_notif->mas_instance_id);
+ OBX_AddAppParamHdr(p_obx->p_pkt, app_param, 1);
+ }
+ else
+ {
+ p_obx->offset =
+ p_obx->bytes_left = 0; /* 0 -length available */
+ p_obx->p_start = OBX_AddBodyStart(p_obx->p_pkt, &p_obx->bytes_left);
+
+ body_len = p_obx->bytes_left;
+ final_pkt = ( (p_msg_notif->buffer_len - p_msg_notif->bytes_sent) < body_len) ?
+ TRUE : FALSE ;
+ if (final_pkt) body_len = (p_msg_notif->buffer_len - p_msg_notif->bytes_sent);
+
+ memcpy(&p_obx->p_start[p_obx->offset],
+ &(p_msg_notif->p_buffer[p_msg_notif->bytes_sent]), body_len);
+ p_msg_notif->bytes_sent += body_len;
+ p_obx->offset += body_len;
+ OBX_AddBodyEnd(p_obx->p_pkt, p_obx->p_start, p_obx->offset, TRUE);
+ }
+
+ OBX_PutReq(p_cb->obx_handle, final_pkt , p_obx->p_pkt);
+ p_obx->p_pkt = NULL;
+ p_cb->req_pending = TRUE;
+ bta_mse_set_mn_oper(ccb_idx, BTA_MSE_MN_OP_PUT_EVT_RPT);
+ p_msg_notif->final_pkt = final_pkt;
+ p_msg_notif->pkt_cnt++;
+ }
+ else
+ {
+ status = BTA_MA_STATUS_FAIL;
+ }
+
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT4("bta_mse_mn_cont_send_notif ccb_idx=%d first_pkt=%d send_status=%d final=%d",
+ ccb_idx, first_pkt, status, final_pkt);
+#endif
+
+ return status;
+}
+/*******************************************************************************
+**
+** Function bta_mse_mn_send_notif_evt
+**
+** Description Issue a send notification event
+**
+** Parameters mas_instance_id - MAS instance ID
+** status - MS sttaus
+** bd_addr - BD address
+**
+**
+** Returns UINT8 OBX response code
+**
+*******************************************************************************/
+void bta_mse_mn_send_notif_evt(tBTA_MA_INST_ID mas_instance_id, tBTA_MA_STATUS status,
+ BD_ADDR bd_addr )
+{
+ tBTA_MSE param;
+
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT2("bta_mse_mn_send_notif_evt mas_instance_id=%d status=%d",
+ mas_instance_id,
+ status);
+#endif
+
+ param.send_notif.mas_instance_id = mas_instance_id;
+ param.send_notif.status = status;
+ bdcpy(param.send_notif.bd_addr, bd_addr);
+ bta_mse_cb.p_cback(BTA_MSE_SEND_NOTIF_EVT, &param);
+}
+
+/*******************************************************************************
+**
+** Function bta_mse_mn_clean_send_notif
+**
+** Description Clean up send notif resources and cotrol block
+**
+** Parameters ccb_idx - MN control block index
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_mse_mn_clean_send_notif(UINT8 ccb_idx)
+{
+ tBTA_MSE_MN_CB *p_cb = BTA_MSE_GET_MN_CB_PTR(ccb_idx);
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT0("bta_mse_mn_clean_send_notif");
+#endif
+
+ utl_freebuf((void**)&(p_cb->msg_notif.p_buffer));
+ bta_mse_set_mn_oper(ccb_idx, BTA_MSE_MN_OP_NONE);
+ p_cb->req_pending = FALSE;
+ p_cb->aborting = BTA_MSE_MN_ABORT_NONE;
+ memset(&(p_cb->msg_notif), 0, sizeof(tBTA_MSE_MN_MSG_NOTIF));
+}
+
+/*******************************************************************************
+**
+** Function bta_mse_ma_fl_read_app_params
+**
+** Description Read application parameters for the get folder list requst
+**
+** Parameters inst_idx - Index to the MA instance control block
+** sess_idx - Index to the MA session control block
+** p_pkt - Pointer to the obex packet
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_mse_ma_fl_read_app_params(UINT8 inst_idx, UINT8 sess_idx, BT_HDR *p_pkt)
+
+{
+ tBTA_MSE_MA_SESS_CB *p_cb = BTA_MSE_GET_SESS_CB_PTR(inst_idx, sess_idx);
+ UINT8 *p_param;
+ UINT16 len;
+
+ p_param = bta_mse_read_app_params(p_pkt, BTA_MA_APH_MAX_LIST_COUNT, &len);
+
+ if (p_param)
+ {
+ BE_STREAM_TO_UINT16(p_cb->fl_param.max_list_cnt, p_param);
+ }
+ else
+ p_cb->fl_param.max_list_cnt = BTA_MA_DEFAULT_MAX_LIST_CNT;
+
+ p_param = bta_mse_read_app_params(p_pkt, BTA_MA_APH_START_STOFF, &len);
+
+ if (p_param)
+ {
+ BE_STREAM_TO_UINT16(p_cb->fl_param.start_offset, p_param);
+ }
+ else
+ p_cb->fl_param.start_offset = 0;
+
+}
+
+/*******************************************************************************
+**
+** Function bta_mse_ma_ml_read_app_params
+**
+** Description Read application parameters for the get message list requst
+**
+** Parameters inst_idx - Index to the MA instance control block
+** sess_idx - Index to the MA session control block
+** p_pkt - Pointer to the obex packet
+**
+** Returns void
+**
+*******************************************************************************/
+
+void bta_mse_ma_ml_read_app_params(UINT8 inst_idx, UINT8 sess_idx, BT_HDR *p_pkt)
+
+{
+ tBTA_MSE_MA_SESS_CB *p_cb = BTA_MSE_GET_SESS_CB_PTR(inst_idx, sess_idx);
+ UINT8 *p_param;
+ UINT16 len;
+
+ memset(&(p_cb->ml_param.filter), 0x00, sizeof(tBTA_MA_MSG_LIST_FILTER_PARAM));
+
+ p_param = bta_mse_read_app_params(p_pkt, BTA_MA_APH_MAX_LIST_COUNT, &len);
+ if (p_param)
+ {
+ BE_STREAM_TO_UINT16(p_cb->ml_param.filter.max_list_cnt, p_param);
+ }
+ else
+ {
+ p_cb->ml_param.filter.max_list_cnt = BTA_MA_DEFAULT_MAX_LIST_CNT;
+ }
+
+ p_param = bta_mse_read_app_params(p_pkt, BTA_MA_APH_START_STOFF, &len);
+ if (p_param)
+ {
+ BE_STREAM_TO_UINT16(p_cb->ml_param.filter.list_start_offset, p_param);
+ }
+ else
+ {
+ p_cb->ml_param.filter.list_start_offset = 0;
+ }
+
+ p_param = bta_mse_read_app_params(p_pkt, BTA_MA_APH_SUBJ_LEN, &len);
+ if (p_param)
+ {
+ BE_STREAM_TO_UINT8(p_cb->ml_param.filter.subject_length, p_param);
+ }
+ else
+ {
+ p_cb->ml_param.filter.subject_length = 0xff;
+ }
+
+ p_param = bta_mse_read_app_params(p_pkt, BTA_MA_APH_PARAM_MASK, &len);
+ if (p_param)
+ {
+ BE_STREAM_TO_UINT32(p_cb->ml_param.filter.parameter_mask, p_param);
+ }
+ else
+ {
+ p_cb->ml_param.filter.parameter_mask = 0;
+ }
+
+ p_param = bta_mse_read_app_params(p_pkt, BTA_MA_APH_FILTER_MSG_TYPE, &len);
+ if (p_param)
+ {
+ BE_STREAM_TO_UINT8(p_cb->ml_param.filter.msg_mask, p_param);
+ }
+ else
+ {
+ p_cb->ml_param.filter.msg_mask = 0;
+ }
+
+ p_param = bta_mse_read_app_params(p_pkt, BTA_MA_APH_FILTER_PRD_BEGIN, &len);
+
+ if (p_param)
+ {
+ p_cb->ml_param.filter.period_begin[BTA_MA_LTIME_LEN]='\0';
+ if (len < BTA_MA_LTIME_LEN)
+ {
+ p_cb->ml_param.filter.period_begin[0] = '\0';
+ }
+ else
+ {
+ BCM_STRNCPY_S((char *)p_cb->ml_param.filter.period_begin, sizeof(p_cb->ml_param.filter.period_begin),
+ (const char *)p_param, BTA_MA_LTIME_LEN);
+ }
+ }
+ else
+ {
+ p_cb->ml_param.filter.period_begin[0] = '\0';
+ }
+
+ p_param = bta_mse_read_app_params(p_pkt, BTA_MA_APH_FILTER_PRD_END, &len);
+ if (p_param)
+ {
+ p_cb->ml_param.filter.period_end[BTA_MA_LTIME_LEN] = '\0';
+ if (len < BTA_MA_LTIME_LEN)
+ {
+ p_cb->ml_param.filter.period_end[0] = '\0';
+ }
+ else
+ {
+ BCM_STRNCPY_S((char *)p_cb->ml_param.filter.period_end, sizeof(p_cb->ml_param.filter.period_end),
+ (const char *)p_param, BTA_MA_LTIME_LEN);
+ }
+ }
+ else
+ {
+ p_cb->ml_param.filter.period_end[0] = '\0';
+ }
+
+ p_param = bta_mse_read_app_params(p_pkt, BTA_MA_APH_FILTER_READ_STS, &len);
+ if (p_param)
+ {
+ BE_STREAM_TO_UINT8(p_cb->ml_param.filter.read_status, p_param);
+ }
+ else
+ {
+ p_cb->ml_param.filter.read_status = 0;
+ }
+
+ p_param = bta_mse_read_app_params(p_pkt, BTA_MA_APH_FILTER_RECEIP, &len);
+ p_cb->ml_param.filter.recipient[0] = '\0';
+ if (p_param && len)
+ {
+ if (len >= BTA_MA_MAX_FILTER_TEXT_SIZE)
+ {
+ p_cb->ml_param.filter.recipient[BTA_MA_MAX_FILTER_TEXT_SIZE] = '\0';
+ len = BTA_MA_MAX_FILTER_TEXT_SIZE;
+ }
+ BCM_STRNCPY_S((char *)p_cb->ml_param.filter.recipient, sizeof(p_cb->ml_param.filter.recipient),
+ (const char *)p_param, len);
+ }
+
+ p_param = bta_mse_read_app_params(p_pkt, BTA_MA_APH_FILTER_ORIGIN, &len);
+ p_cb->ml_param.filter.originator[0] = '\0';
+ if (p_param && len)
+ {
+ if (len >= BTA_MA_MAX_FILTER_TEXT_SIZE)
+ {
+ p_cb->ml_param.filter.originator[BTA_MA_MAX_FILTER_TEXT_SIZE] = '\0';
+ len = BTA_MA_MAX_FILTER_TEXT_SIZE;
+ }
+ BCM_STRNCPY_S((char *)p_cb->ml_param.filter.originator, sizeof(p_cb->ml_param.filter.originator),
+ (const char *)p_param, len);
+ }
+
+ p_param = bta_mse_read_app_params(p_pkt, BTA_MA_APH_FILTER_PRIORITY, &len);
+ if (p_param)
+ {
+ BE_STREAM_TO_UINT8(p_cb->ml_param.filter.pri_status, p_param);
+ }
+ else
+ {
+ p_cb->ml_param.filter.pri_status = 0;
+ }
+}
+
+/*******************************************************************************
+**
+** Function bta_mse_ma_msg_read_app_params
+**
+** Description Read application parameters for the get message list requst
+**
+** Parameters inst_idx - Index to the MA instance control block
+** sess_idx - Index to the MA session control block
+** p_pkt - Pointer to the obex packet
+**
+** Returns BOOLEAN TRUE - operation is successful
+**
+*******************************************************************************/
+
+BOOLEAN bta_mse_ma_msg_read_app_params(UINT8 inst_idx, UINT8 sess_idx, BT_HDR *p_pkt)
+
+{
+ tBTA_MSE_MA_SESS_CB *p_cb = BTA_MSE_GET_SESS_CB_PTR(inst_idx, sess_idx);
+ UINT8 *p_param;
+ UINT16 len;
+
+ p_param = bta_mse_read_app_params(p_pkt, BTA_MA_APH_CHARSET, &len);
+ if (p_param)
+ {
+ BE_STREAM_TO_UINT8(p_cb->msg_param.data.charset, p_param);
+ }
+ else
+ {
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT0("Unable to decode or find charset in application parameter ");
+#endif
+ return FALSE;
+ }
+
+ p_param = bta_mse_read_app_params(p_pkt, BTA_MA_APH_ATTACH, &len);
+ if (p_param)
+ {
+ BE_STREAM_TO_UINT8(p_cb->msg_param.data.attachment, p_param);
+ }
+ else
+ {
+ p_cb->msg_param.data.attachment = FALSE;
+ }
+
+ p_param = bta_mse_read_app_params(p_pkt, BTA_MA_APH_FRAC_REQ, &len);
+ if (p_param)
+ {
+ BE_STREAM_TO_UINT8(p_cb->msg_param.data.fraction_request, p_param);
+ }
+ else
+ {
+ p_cb->msg_param.data.fraction_request = BTA_MA_FRAC_REQ_NO;
+ }
+
+
+ return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function bta_mse_get_msglist_path
+**
+** Description Get the path based on received folder name for the get
+** message list
+**
+** Parameters inst_idx - Index to the MA instance control block
+** sess_idx - Index to the MA session control block
+** p_path - (output) pointer to the folder path
+**
+** Returns BOOLEAN TRUE-get path is successful
+*******************************************************************************/
+BOOLEAN bta_mse_get_msglist_path(UINT8 inst_idx, UINT8 sess_idx)
+{
+ tBTA_MSE_MA_SESS_CB *p_cb = BTA_MSE_GET_SESS_CB_PTR(inst_idx, sess_idx);
+ char *p_name = p_cb->ml_param.p_name;
+ char *p_path = p_cb->ml_param.p_path;
+ char *p_workdir = p_cb->p_workdir;
+ BOOLEAN status = TRUE;
+#if BTA_MSE_ENABLE_FS_CO == TRUE
+ BOOLEAN is_dir;
+#endif
+
+
+ if (*p_name == '\0')
+ {
+ BCM_STRNCPY_S(p_path, p_bta_fs_cfg->max_path_len+1, p_workdir, p_bta_fs_cfg->max_path_len);
+ }
+ /* Make sure the new path is not too big */
+ /* +1 is for the separator */
+ else if ((strlen(p_workdir)+1+strlen(p_name)) <= p_bta_fs_cfg->max_path_len)
+ {
+ /* create a temporary path for creation attempt */
+ sprintf(p_path, "%s%c%s", p_workdir,
+ p_bta_fs_cfg->path_separator, p_name);
+#if BTA_MSE_ENABLE_FS_CO == TRUE
+ if (((bta_fs_co_access(p_path, BTA_FS_ACC_EXIST,
+ &is_dir, bta_mse_cb.app_id)) != BTA_FS_CO_OK) || !is_dir)
+ {
+ status = FALSE;
+ }
+#endif
+ }
+ else
+ {
+ status = FALSE;
+ }
+
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_EVENT2("bta_mse_get_msglist_path status=%d pth=%s",status, p_path );
+#endif
+
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function bta_mse_find_bd_addr_match_pm_cb_index
+**
+** Description Finds the PM control block index
+** based on the specified BD address
+**
+** Parameters app_id - app_id
+** p_bd_addr - BD address
+** p_idx - (output) pointer to the MN control
+** block index
+**
+** Returns BOOLEAN - TRUE found
+** FALSE not found
+**
+*******************************************************************************/
+BOOLEAN bta_mse_find_pm_cb_index(BD_ADDR p_bd_addr, UINT8 *p_idx)
+{
+ BOOLEAN found=FALSE;
+ UINT8 i;
+
+ for (i=0; i < BTA_MSE_NUM_MN ; i ++)
+ {
+ if ((bta_mse_cb.pcb[i].in_use) &&
+ (!memcmp (bta_mse_cb.pcb[i].bd_addr, p_bd_addr, BD_ADDR_LEN)))
+ {
+ found = TRUE;
+ *p_idx = i;
+ break;
+ }
+ }
+
+#if BTA_MSE_DEBUG == TRUE
+ if (!found) APPL_TRACE_DEBUG2("dbg bta_mse_find_pm_cb_index found=%d index=%d", found, i);
+#endif
+ return found;
+}
+
+
+/*******************************************************************************
+**
+** Function bta_mse_find_avail_pm_cb_idx
+**
+** Description Finds a not in use PM control block index
+**
+** Parameters p_idx - (output) pointer to the PM control block index
+**
+** Returns BOOLEAN - TRUE found
+** FALSE not found
+**
+*******************************************************************************/
+BOOLEAN bta_mse_find_avail_pm_cb_idx(UINT8 *p_idx)
+{
+ BOOLEAN found=FALSE;
+ UINT8 i;
+
+ for (i=0; i < BTA_MSE_NUM_MN ; i ++)
+ {
+ if (!bta_mse_cb.pcb[i].in_use)
+ {
+ found = TRUE;
+ *p_idx = i;
+ break;
+ }
+ }
+
+#if BTA_MSE_DEBUG == TRUE
+ if (!found) APPL_TRACE_DEBUG2("bta_mse_find_avail_pm_cb_idx found=%d i=%d", found, i);
+#endif
+
+ return found;
+}
+
+/*******************************************************************************
+**
+** Function bta_mse_pm_conn_open
+**
+** Description Determine whether or not bta_sys_conn_open should be called
+**
+** Parameters bd_addr - peer BD address
+**
+** Returns None
+**
+*******************************************************************************/
+void bta_mse_pm_conn_open(BD_ADDR bd_addr)
+{
+ tBTA_MSE_PM_CB *p_pcb;
+ UINT8 idx;
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_DEBUG0("bta_mse_pm_conn_open");
+#endif
+ if (!bta_mse_find_pm_cb_index(bd_addr, &idx))
+ {
+ if (bta_mse_find_avail_pm_cb_idx(&idx))
+ {
+ p_pcb = BTA_MSE_GET_PM_CB_PTR(idx);
+
+ p_pcb->in_use = TRUE;
+ p_pcb->opened = TRUE;
+ bdcpy(p_pcb->bd_addr, bd_addr);
+ bta_sys_conn_open(BTA_ID_MSE , bta_mse_cb.app_id, bd_addr);
+ }
+ }
+}
+
+/*******************************************************************************
+**
+** Function bta_mse_pm_conn_close
+**
+** Description Determine whether or not bta_sys_conn_close should be called
+**
+** Parameters bd_addr - peer BD address
+**
+** Returns None
+*******************************************************************************/
+void bta_mse_pm_conn_close(BD_ADDR bd_addr)
+{
+ tBTA_MSE_PM_CB *p_pcb;
+ UINT8 i, pm_idx, sess_idx, mn_idx;
+ BOOLEAN found_bd_addr=FALSE;
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_DEBUG0("bta_mse_pm_conn_close");
+#endif
+ if (bta_mse_find_pm_cb_index(bd_addr, &pm_idx))
+ {
+ p_pcb = BTA_MSE_GET_PM_CB_PTR(pm_idx);
+ if (p_pcb->opened)
+ {
+ for (i=0; i<BTA_MSE_NUM_INST; i++)
+ {
+ if (bta_mse_find_bd_addr_match_sess_cb_idx(bd_addr, i, &sess_idx))
+ {
+ found_bd_addr = TRUE;
+ break;
+ }
+ }
+
+ if (!found_bd_addr)
+ {
+ if ( bta_mse_find_bd_addr_match_mn_cb_index(bd_addr, &mn_idx))
+ {
+ found_bd_addr = TRUE;
+
+ }
+ }
+
+ if (!found_bd_addr)
+ {
+ memset(p_pcb, 0, sizeof(tBTA_MSE_PM_CB));
+ bta_sys_conn_close(BTA_ID_MSE , bta_mse_cb.app_id, bd_addr);
+ }
+ }
+ }
+}
+
+/*******************************************************************************
+**
+** Function bta_mse_set_ma_oper
+**
+** Description Set MA operation and power management's busy/idle status based on
+** MA operation
+**
+** Parameters inst_idx - Index to the MA instance control block
+** sess_idx - Index to the MA session control block
+** oper - MA operation
+**
+** Returns None
+*******************************************************************************/
+void bta_mse_set_ma_oper(UINT8 inst_idx, UINT8 sess_idx, tBTA_MSE_OPER oper)
+{
+ tBTA_MSE_MA_SESS_CB *p_cb = BTA_MSE_GET_SESS_CB_PTR(inst_idx, sess_idx);
+ tBTA_MSE_MA_SESS_CB *p_scb;
+ tBTA_MSE_MN_CB *p_mcb;
+ tBTA_MSE_PM_CB *p_pcb;
+ UINT8 i, j, pm_idx, mn_idx;
+ BOOLEAN still_busy = FALSE;
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_DEBUG2("bta_mse_set_ma_oper old=%d new=%d", p_cb->oper, oper);
+#endif
+
+ if (p_cb->oper != oper)
+ {
+ p_cb->oper = oper;
+ if (bta_mse_find_pm_cb_index(p_cb->bd_addr, &pm_idx))
+ {
+ p_pcb = BTA_MSE_GET_PM_CB_PTR(pm_idx);
+
+ if (oper != BTA_MSE_OPER_NONE )
+ {
+ if (!p_pcb->busy)
+ {
+ p_pcb->busy = TRUE;
+ bta_sys_busy(BTA_ID_MSE, bta_mse_cb.app_id, p_cb->bd_addr);
+ }
+ }
+ else
+ {
+ if (p_pcb->busy)
+ {
+ for (i=0; i<BTA_MSE_NUM_INST; i++)
+ {
+ if (bta_mse_find_bd_addr_match_sess_cb_idx( p_cb->bd_addr, i, &j) &&
+ (i != inst_idx) && (j != sess_idx))
+ {
+ p_scb = BTA_MSE_GET_SESS_CB_PTR(i, j);
+ if (p_scb->oper != BTA_MSE_OPER_NONE )
+ {
+ still_busy = TRUE;
+ break;
+ }
+ }
+ }
+
+ if ((!still_busy) &&
+ bta_mse_find_bd_addr_match_mn_cb_index( p_cb->bd_addr, &mn_idx))
+ {
+ p_mcb = BTA_MSE_GET_MN_CB_PTR(mn_idx);
+ if (p_mcb->obx_oper != BTA_MSE_MN_OP_NONE )
+ {
+ still_busy = TRUE;
+ }
+ }
+
+ if (!still_busy)
+ {
+ p_pcb->busy = FALSE;
+ bta_sys_idle(BTA_ID_MSE, bta_mse_cb.app_id, p_cb->bd_addr);
+ }
+ }
+ }
+ }
+ }
+}
+
+
+/*******************************************************************************
+**
+** Function bta_mse_set_mn_oper
+**
+** Description Set MN operation and power management's busy/idle status based on
+** MN operation
+**
+** Parameters ccb_idx - MN control block index
+** oper - MN operation
+**
+** Returns None
+*******************************************************************************/
+void bta_mse_set_mn_oper(UINT8 ccb_idx, UINT8 oper)
+{
+ tBTA_MSE_MN_CB *p_cb = BTA_MSE_GET_MN_CB_PTR(ccb_idx);
+ tBTA_MSE_MA_SESS_CB *p_scb;
+ tBTA_MSE_MN_CB *p_mcb;
+ tBTA_MSE_PM_CB *p_pcb;
+ UINT8 i, j, pm_idx, mn_idx;
+ BOOLEAN still_busy = FALSE;
+
+#if BTA_MSE_DEBUG == TRUE
+ APPL_TRACE_DEBUG2("dbg bta_mse_set_mn_oper old=%d new=%d", p_cb->obx_oper, oper);
+#endif
+ if (p_cb->obx_oper != oper)
+ {
+ p_cb->obx_oper = oper;
+ if (bta_mse_find_pm_cb_index(p_cb->bd_addr, &pm_idx))
+ {
+ p_pcb = BTA_MSE_GET_PM_CB_PTR(pm_idx);
+
+ if (oper != BTA_MSE_MN_OP_NONE )
+ {
+ if (!p_pcb->busy)
+ {
+ p_pcb->busy = TRUE;
+ bta_sys_busy(BTA_ID_MSE, bta_mse_cb.app_id, p_cb->bd_addr);
+ }
+ }
+ else
+ {
+ if (p_pcb->busy)
+ {
+ for (i=0; i<BTA_MSE_NUM_INST; i++)
+ {
+ if (bta_mse_find_bd_addr_match_sess_cb_idx( p_cb->bd_addr, i, &j))
+ {
+ p_scb = BTA_MSE_GET_SESS_CB_PTR(i, j);
+ if (p_scb->oper != BTA_MSE_OPER_NONE )
+ {
+ still_busy = TRUE;
+ break;
+ }
+ }
+ }
+
+ if ((!still_busy) &&
+ bta_mse_find_bd_addr_match_mn_cb_index(p_cb->bd_addr, &mn_idx) &&
+ (mn_idx != ccb_idx))
+ {
+ p_mcb = BTA_MSE_GET_MN_CB_PTR(mn_idx);
+ if (p_mcb->obx_oper != BTA_MSE_MN_OP_NONE )
+ {
+ still_busy = TRUE;
+ }
+ }
+
+ if (!still_busy)
+ {
+ p_pcb->busy = FALSE;
+ bta_sys_idle(BTA_ID_MSE, bta_mse_cb.app_id, p_cb->bd_addr);
+ }
+ }
+ }
+ }
+ }
+
+}
+
+#endif /* BTA_MSE_INCLUDED */