summaryrefslogtreecommitdiffstats
path: root/stack/goep/goep_util.c
diff options
context:
space:
mode:
Diffstat (limited to 'stack/goep/goep_util.c')
-rw-r--r--stack/goep/goep_util.c504
1 files changed, 504 insertions, 0 deletions
diff --git a/stack/goep/goep_util.c b/stack/goep/goep_util.c
new file mode 100644
index 0000000..099177a
--- /dev/null
+++ b/stack/goep/goep_util.c
@@ -0,0 +1,504 @@
+/*****************************************************************************
+**
+** Name: goep_util.c
+**
+** File: Implements the Utility API of the GOEP Profile
+**
+** Copyright (c) 2000-2011, Broadcom Corp., All Rights Reserved.
+** Broadcom Bluetooth Core. Proprietary and confidential.
+**
+*****************************************************************************/
+
+#include <string.h>
+
+#include "btm_api.h"
+#include "btu.h" /* BTU_HCI_RCV_MBOX */
+#include "goep_util.h"
+#include "goep_fs.h"
+#include "goep_int.h"
+#include "rfcdefs.h" /* BT_PSM_RFCOMM */
+#include "wcassert.h" /* WC_ASSERT() */
+#include "l2c_api.h" /* WC_ASSERT() */
+
+#if GOEP_DYNAMIC_MEMORY == FALSE
+tGOEP_CB goep_cb;
+#endif
+
+/*******************************************************************************
+**
+** Function GOEP_Init
+**
+** Description GOEP initialization
+**
+** Returns nothing
+**
+*******************************************************************************/
+void GOEP_Init(void)
+{
+ memset(&goep_cb, 0, sizeof(tGOEP_CB));
+
+#if defined(GOEP_INITIAL_TRACE_LEVEL)
+ goep_cb.trace_level = GOEP_INITIAL_TRACE_LEVEL;
+#else
+ goep_cb.trace_level = BT_TRACE_LEVEL_NONE; /* No traces */
+#endif
+
+}
+
+
+
+/*****************************************************************************
+**
+** Function: GOEP_SetSecurityLevel()
+**
+** Purpose: Register security & encryption level for GOEP server.
+** This is not to be used for the GOEP command server.
+**
+**
+** Parameters:
+** char *pName service name; Typically GOEP_DEFAULT_SERVICE_NAME
+** Not used if BTM_SEC_SERVICE_NAME_LEN is 0.
+** UINT8 level Security level; The mandatory GOEP security level
+** GOEP_DEFAULT_SECURITY, is or'd in.
+**
+**
+** Returns: (BOOLEAN) TRUE if OK
+** FALSE if a bad parameter
+**
+*****************************************************************************/
+BOOLEAN GOEP_SetSecurityLevel (BOOLEAN bOrig, char *pName, UINT32 service,
+ UINT8 level, UINT8 scn)
+{
+#if BTM_SEC_SERVICE_NAME_LEN > 0
+ char sec_name[BTM_SEC_SERVICE_NAME_LEN+1];
+#endif
+
+ /* Guarantee that there is a name */
+ if (!pName)
+ {
+ pName = "";
+ }
+
+#if BTM_SEC_SERVICE_NAME_LEN > 0
+ GOEP_TRACE_EVENT4("GOEP: Set Security Mode; name '%s'; service %d; level 0x%02x; scn %d",
+ pName, service, level, scn);
+
+ /* Guarantee that name is not too long */
+ if (strlen (pName) >= BTM_SEC_SERVICE_NAME_LEN)
+ {
+ BCM_STRNCPY_S(sec_name, sizeof(sec_name), pName, BTM_SEC_SERVICE_NAME_LEN);
+ sec_name[BTM_SEC_SERVICE_NAME_LEN] = '\0';
+ pName = sec_name;
+ }
+#else
+ GOEP_TRACE_EVENT3("GOEP: Set Security Mode: service id %d; level 0x%02x; scn %d",
+ service, level, scn);
+#endif
+
+ /* Register with Security Manager for the specific security level */
+ if (!BTM_SetSecurityLevel (bOrig, pName, (UINT8)service, level, BT_PSM_RFCOMM,
+ BTM_SEC_PROTO_RFCOMM, scn))
+ {
+ GOEP_TRACE_WARNING1("GOEP: Security Registration failed for %s", pName);
+ return (FALSE);
+ }
+
+ return (TRUE);
+}
+
+/*****************************************************************************
+**
+** Function: GOEP_SetTraceLevel
+**
+** Purpose: This function changes the trace level
+**
+** Returns: Nothing
+*****************************************************************************/
+void GOEP_SetTraceLevel(UINT8 level)
+{
+ goep_cb.trace_level = level;
+}
+
+/*******************************************************************************
+**
+** Function GOEP_FreeBuf
+**
+** Description free memory for specified packet
+**
+** Returns void
+**
+*******************************************************************************/
+void GOEP_FreeBuf (void **p_buf)
+{
+ if (p_buf && *p_buf)
+ {
+ GKI_freebuf(*p_buf);
+ *p_buf = NULL;
+ }
+}
+
+/*******************************************************************************
+**
+** Function GOEP_SendMsg
+**
+** Description send a message to BTU task
+**
+** Returns void
+**
+*******************************************************************************/
+void GOEP_SendMsg (void *p_msg)
+
+{
+ if(p_msg)
+ {
+ GKI_send_msg(BTU_TASK, BTU_HCI_RCV_MBOX, p_msg);
+ }
+}
+
+/*****************************************************************************
+**
+** Function: GOEP_Register()
+**
+** Purpose: Register an OBEX profile with SDP
+**
+** Parameters:
+**
+** char *p_name service name; optional (may be NULL)
+** UINT32 *phSDP handle to the created record; cannot be NULL
+** UINT8 scn scn desired for the service; must be > 0
+** UINT16 version version of the service; optional (may be 0)
+**
+** Returns: (tGOEP_ERRORS) GOEP_SUCCESS if ok; GOEP_ERROR on error
+**
+** Notes:
+**
+**
+** Preconditions:
+** - phSDP must be set (to return the SDP record handle)
+** - scn must be set
+**
+** Postconditions:
+** -
+**
+*****************************************************************************/
+tGOEP_ERRORS GOEP_Register (char *p_name,
+ UINT32 *phSDP,
+ UINT8 scn,
+ UINT8 num_srv_class,
+ UINT16 *p_service_class,
+ UINT16 profile_id,
+ UINT16 version)
+{
+ tGOEP_ERRORS status = GOEP_ERROR;
+ tSDP_PROTOCOL_ELEM protoList [GOEP_PROTOCOL_COUNT];
+ UINT16 browse;
+
+ /* GOEP_TRACE_EVENT4("GOEP: Register with SDP: name %s, scn %d, class %#x, version %d)",
+ p_name ? p_name : "NULL",
+ (UINT16)scn,
+ (UINT16)p_service_class[0],
+ version); */
+
+ /* parameter checking */
+ WC_ASSERT(phSDP);
+ WC_ASSERT(scn);
+
+ /* parameter checking */
+ if (!(phSDP && scn))
+ {
+ return (GOEP_INVALID_PARAM);
+ }
+
+ *phSDP = SDP_CreateRecord();
+ WC_ASSERT(*phSDP);
+ GOEP_TRACE_API2("GOEP: Register with SDP: scn %d, record:0x%08x", scn, *phSDP);
+
+ /* could a SDP handle be allocated? */
+ if (*phSDP == 0)
+ {
+ return (GOEP_RESOURCES);
+ }
+
+ /* add service class */
+ if (SDP_AddServiceClassIdList(*phSDP, num_srv_class, p_service_class))
+ {
+ /* add protocol list, including RFCOMM scn */
+ protoList[0].protocol_uuid = UUID_PROTOCOL_L2CAP;
+ protoList[0].num_params = 0;
+ protoList[1].protocol_uuid = UUID_PROTOCOL_RFCOMM;
+ protoList[1].num_params = 1;
+ protoList[1].params[0] = scn;
+ protoList[2].protocol_uuid = UUID_PROTOCOL_OBEX;
+ protoList[2].num_params = 0;
+
+/* coverity[uninit_use_in_call]
+FALSE-POSITIVE: coverity says
+Event uninit_use_in_call: Using uninitialized element of array "(protoList)->params" in call to function "SDP_AddProtocolList"
+Event uninit_use_in_call: Using uninitialized value "(protoList)->num_params" in call to function "SDP_AddProtocolList"
+Event uninit_use_in_call: Using uninitialized value "(protoList)->protocol_uuid" in call to function "SDP_AddProtocolList"
+SDP_AddProtocolList() uses (protoList)->params only when (protoList)->num_params is non-0
+*/
+ if (SDP_AddProtocolList(*phSDP, GOEP_PROTOCOL_COUNT, protoList))
+ {
+ /* optional: if name is not NULL, add a name entry */
+ if (p_name && p_name[0] )
+ {
+ SDP_AddAttribute(*phSDP,
+ (UINT16)ATTR_ID_SERVICE_NAME,
+ (UINT8)TEXT_STR_DESC_TYPE,
+ (UINT32)(strlen(p_name) + 1),
+ (UINT8 *)p_name);
+ } /* end of setting optional name */
+ /* Add in the Bluetooth Profile Descriptor List for IrMCSync [Sync s7.1.2] */
+ if (version)
+ {
+ SDP_AddProfileDescriptorList(*phSDP, profile_id, version);
+ } /* end of setting optional profile version */
+ status = GOEP_SUCCESS;
+ } /* end of setting mandatory protocol list */
+ } /* end of setting mandatory service class */
+
+ /* Make the service browseable */
+ browse = UUID_SERVCLASS_PUBLIC_BROWSE_GROUP;
+ if (status == GOEP_SUCCESS && SDP_AddUuidSequence (*phSDP,
+ ATTR_ID_BROWSE_GROUP_LIST,
+ 1,
+ &browse) == FALSE)
+ {
+ status = GOEP_ERROR;
+ }
+
+ if (status != GOEP_SUCCESS)
+ {
+ SDP_DeleteRecord(*phSDP);
+ GOEP_TRACE_DEBUG1("GOEP_Register status: %d", status);
+ }
+ else
+ {
+ GOEP_TRACE_EVENT1("GOEP: Register with SDP returns handle 0x%08x", *phSDP);
+ }
+
+ return (status);
+}
+
+/*****************************************************************************
+**
+** Function: GOEP_Register2()
+**
+** Purpose: Register an OBEX 1.4 profile with SDP
+**
+** Parameters:
+**
+** char *p_name service name; optional (may be NULL)
+** UINT32 *phSDP handle to the created record; cannot be NULL
+** UINT8 scn scn desired for the service; must be > 0
+** UINT16 psm psm desired for the service; must be an legal L2CAP dynamic PSM
+** UINT16 version version of the service; optional (may be 0)
+**
+** Returns: (tGOEP_ERRORS) GOEP_SUCCESS if ok; GOEP_ERROR on error
+**
+** Notes:
+**
+**
+** Preconditions:
+** - phSDP must be set (to return the SDP record handle)
+** - psm must be set
+**
+** Postconditions:
+** -
+**
+*****************************************************************************/
+tGOEP_ERRORS GOEP_Register2 (char *p_name,
+ UINT32 *phSDP,
+ UINT16 psm,
+ UINT8 num_srv_class,
+ UINT16 *p_service_class,
+ UINT16 profile_id,
+ UINT16 version)
+{
+ tGOEP_ERRORS status = GOEP_ERROR;
+ tSDP_PROTOCOL_ELEM protoList [GOEP_PROTOCOL_COUNT];
+ UINT16 browse;
+ UINT16 num_elem;
+ UINT8 *p, array[3];
+
+ /* GOEP_TRACE_EVENT4("GOEP: Register2 with SDP: name %s, psm 0x%x, class %#x, version %d)",
+ p_name ? p_name : "NULL",
+ (UINT16)psm,
+ (UINT16)p_service_class[0],
+ version); */
+
+ /* parameter checking */
+ WC_ASSERT(phSDP);
+
+ /* parameter checking */
+ if (!(phSDP && L2C_IS_VALID_PSM(psm)))
+ {
+ return (GOEP_INVALID_PARAM);
+ }
+
+ *phSDP = SDP_CreateRecord();
+ WC_ASSERT(*phSDP);
+ GOEP_TRACE_API2("GOEP: Register with SDP(2): psm 0x%x, record:0x%08x", psm, *phSDP);
+
+ /* could a SDP handle be allocated? */
+ if (*phSDP == 0)
+ {
+ return (GOEP_RESOURCES);
+ }
+
+ /* add service class */
+ if (SDP_AddServiceClassIdList(*phSDP, num_srv_class, p_service_class))
+ {
+ /* add protocol list, including RFCOMM scn */
+ num_elem=0;
+ protoList[num_elem].protocol_uuid = UUID_PROTOCOL_L2CAP;
+ protoList[num_elem].num_params = 0;
+ num_elem++;
+ protoList[num_elem].protocol_uuid = UUID_PROTOCOL_OBEX;
+ protoList[num_elem].num_params = 0;
+ num_elem++;
+/* coverity[uninit_use_in_call]
+FALSE-POSITIVE: coverity says
+Event uninit_use_in_call: Using uninitialized element of array "(protoList)->params" in call to function "SDP_AddProtocolList"
+Event uninit_use_in_call: Using uninitialized value "(protoList)->num_params" in call to function "SDP_AddProtocolList"
+Event uninit_use_in_call: Using uninitialized value "(protoList)->protocol_uuid" in call to function "SDP_AddProtocolList"
+SDP_AddProtocolList() uses (protoList)->params only when (protoList)->num_params is non-0
+*/
+ if (SDP_AddProtocolList(*phSDP, num_elem, protoList))
+ {
+ p = array;
+ UINT16_TO_BE_STREAM (p, psm);
+ SDP_AddAttribute (*phSDP, ATTR_ID_OBX_OVR_L2CAP_PSM, UINT_DESC_TYPE, 2, array);
+
+ /* optional: if name is not NULL, add a name entry */
+ if (p_name && p_name[0] )
+ {
+ SDP_AddAttribute(*phSDP,
+ (UINT16)ATTR_ID_SERVICE_NAME,
+ (UINT8)TEXT_STR_DESC_TYPE,
+ (UINT32)(strlen(p_name) + 1),
+ (UINT8 *)p_name);
+ } /* end of setting optional name */
+ /* Add in the Bluetooth Profile Descriptor List for IrMCSync [Sync s7.1.2] */
+ if (version)
+ {
+ SDP_AddProfileDescriptorList(*phSDP, profile_id, version);
+ } /* end of setting optional profile version */
+ status = GOEP_SUCCESS;
+ } /* end of setting mandatory protocol list */
+ } /* end of setting mandatory service class */
+
+ /* Make the service browseable */
+ browse = UUID_SERVCLASS_PUBLIC_BROWSE_GROUP;
+ if (status == GOEP_SUCCESS && SDP_AddUuidSequence (*phSDP,
+ ATTR_ID_BROWSE_GROUP_LIST,
+ 1,
+ &browse) == FALSE)
+ {
+ status = GOEP_ERROR;
+ }
+
+ if (status != GOEP_SUCCESS)
+ {
+ SDP_DeleteRecord(*phSDP);
+ GOEP_TRACE_DEBUG1("GOEP_Register status: %d", status);
+ }
+ else
+ {
+ GOEP_TRACE_EVENT1("GOEP: Register with SDP returns handle 0x%08x", *phSDP);
+ }
+
+
+ return (status);
+}
+
+/*****************************************************************************
+**
+** Function: GOEP_AddProtoLists()
+**
+** Purpose: Add the AdditionalProtocolDescriptorLists attribute
+** to a SDP record
+**
+** Parameters:
+**
+** UINT32 sdp_hdl the SDP record handle
+** UINT8 scn scn desired for the service; must be > 0
+**
+** Returns: (tGOEP_ERRORS) GOEP_SUCCESS if ok; GOEP_ERROR on error
+**
+** Notes:
+**
+**
+** Preconditions:
+** - sdp_hdl must be set (to the SDP record handle from GOEP_Register())
+** - scn must be set
+**
+** Postconditions:
+** -
+**
+*****************************************************************************/
+#if (BPP_INCLUDED == TRUE)
+tGOEP_ERRORS GOEP_AddProtoLists ( UINT32 sdp_hdl, UINT8 scn)
+{
+ tGOEP_ERRORS status = GOEP_ERROR;
+ tSDP_PROTO_LIST_ELEM proto_list_elem;
+ tSDP_PROTOCOL_ELEM *p_proto_list;
+
+ /*
+ GOEP_TRACE_EVENT4("GOEP: Register with SDP: name %s, scn %d, class %#x, version %d)",
+ p_name ? p_name : "NULL",
+ (UINT16)scn,
+ (UINT16)p_service_class[0],
+ version);
+ */
+
+ /* parameter checking */
+ WC_ASSERT(sdp_hdl);
+ WC_ASSERT(scn);
+
+ /* parameter checking */
+ if (!(sdp_hdl && scn))
+ {
+ return (GOEP_INVALID_PARAM);
+ }
+
+ proto_list_elem.num_elems = 0;
+ p_proto_list = &proto_list_elem.list_elem[proto_list_elem.num_elems++];
+ p_proto_list->num_params = 0;
+ p_proto_list->protocol_uuid = UUID_PROTOCOL_L2CAP;
+ p_proto_list = &proto_list_elem.list_elem[proto_list_elem.num_elems++];
+ p_proto_list->num_params = 1;
+ p_proto_list->params[0] = scn;
+ p_proto_list->protocol_uuid = UUID_PROTOCOL_RFCOMM;
+ p_proto_list = &proto_list_elem.list_elem[proto_list_elem.num_elems++];
+ p_proto_list->num_params = 0;
+ p_proto_list->protocol_uuid = UUID_PROTOCOL_OBEX;
+
+ /* add protocol list, including RFCOMM scn */
+ if(SDP_AddAdditionProtoLists( sdp_hdl, 1, &proto_list_elem))
+ status = GOEP_SUCCESS;
+
+ GOEP_TRACE_DEBUG1("GOEP_AddProtoLists status: %s", GOEP_ErrorName(status));
+
+ return (status);
+}
+#endif
+
+/*****************************************************************************
+**
+** Function: goep_dummy
+**
+** Purpose: This is to work around a GCC build linking problem
+**
+** Returns: none
+**
+*****************************************************************************/
+#if (RPC_INCLUDED == TRUE && RPC_TRACE_ONLY == TRUE && GOEP_FS_INCLUDED == TRUE)
+static void goep_dummy(void)
+{
+ GOEP_OpenRsp(0, 0, 0, 0);
+}
+#endif /* RPC stuff */
+
+