summaryrefslogtreecommitdiffstats
path: root/stack/dun/dun_api.c
diff options
context:
space:
mode:
Diffstat (limited to 'stack/dun/dun_api.c')
-rw-r--r--stack/dun/dun_api.c592
1 files changed, 592 insertions, 0 deletions
diff --git a/stack/dun/dun_api.c b/stack/dun/dun_api.c
new file mode 100644
index 0000000..ce7380e
--- /dev/null
+++ b/stack/dun/dun_api.c
@@ -0,0 +1,592 @@
+/*****************************************************************************/
+/* */
+/* Name: dun_api.c */
+/* */
+/* Description: This file contains the DUN API routines */
+/* */
+/* */
+/* Copyright (c) 1999-2009, Broadcom Corp., All Rights Reserved. */
+/* Broadcom Bluetooth Core. Proprietary and confidential. */
+/*****************************************************************************/
+
+#include <string.h>
+#include "bt_target.h"
+#include "btm_api.h"
+#include "port_api.h"
+#include "dun_api.h"
+#include "dun_int.h"
+#include "rfcdefs.h"
+
+/*****************************************************************************
+** Constants
+*****************************************************************************/
+
+/* Number of attributes in DUN and Fax SDP records. */
+#define DUN_NUM_ATTR_DUN 4
+#define DUN_NUM_ATTR_FAX 7
+
+/* Number of protocol elements in protocol element list. */
+#define DUN_NUM_PROTO_ELEMS 2
+
+
+/* Global DUN/FAX control block structure
+*/
+#if DUN_DYNAMIC_MEMORY == FALSE
+tDUN_CB dun_cb;
+#endif
+
+/******************************************************************************
+**
+** Function dun_sdp_cback
+**
+** Description This is the SDP callback function used by DUN_FindService.
+** 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 various parameters
+** from the record. When it is finished it calls the
+** application callback function.
+**
+** Returns Nothing.
+**
+******************************************************************************/
+static void dun_sdp_cback(UINT16 status)
+{
+ tSDP_DISC_REC *p_rec = NULL;
+ tSDP_DISC_ATTR *p_attr;
+ tSDP_PROTOCOL_ELEM pe;
+ UINT8 scn = 0;
+ UINT16 name_len = 0;
+ char *p_name = "";
+ UINT16 options = 0;
+ BOOLEAN found = FALSE;
+
+ DUN_TRACE_API1("dun_sdp_cback status: %d", status);
+
+ if (status == SDP_SUCCESS)
+ {
+ /* loop through all records we found */
+ do
+ {
+ /* get next record; if none found, we're done */
+ if ((p_rec = SDP_FindServiceInDb(dun_cb.find_cb.p_db,
+ dun_cb.find_cb.service_uuid, p_rec)) == NULL)
+ {
+ break;
+ }
+
+ /* get scn from proto desc list; if not found, go to next record */
+ if (SDP_FindProtocolListElemInRec(p_rec, UUID_PROTOCOL_RFCOMM, &pe))
+ {
+ scn = (UINT8) pe.params[0];
+ }
+ else
+ {
+ continue;
+ }
+
+ /* get service name */
+ if ((p_attr = SDP_FindAttributeInRec(p_rec,
+ ATTR_ID_SERVICE_NAME)) != NULL)
+ {
+ p_name = (char *) p_attr->attr_value.v.array;
+ name_len = SDP_DISC_ATTR_LEN(p_attr->attr_len_type);
+ }
+
+ /* get audio support */
+ if ((p_attr = SDP_FindAttributeInRec(p_rec,
+ ATTR_ID_AUDIO_FEEDBACK_SUPPORT)) != NULL)
+ {
+ options |= (p_attr->attr_value.v.u8) ? DUN_OPTIONS_AUDIO : 0;
+ }
+
+ /* get fax options */
+ if(dun_cb.find_cb.service_uuid == UUID_SERVCLASS_FAX)
+ {
+ if ((p_attr = SDP_FindAttributeInRec(p_rec,
+ ATTR_ID_FAX_CLASS_1_SUPPORT)) != NULL)
+ {
+ options |= (p_attr->attr_value.v.u8) ? DUN_OPTIONS_CLASS1 : 0;
+ }
+
+ if ((p_attr = SDP_FindAttributeInRec(p_rec,
+ ATTR_ID_FAX_CLASS_2_0_SUPPORT)) != NULL)
+ {
+ options |= (p_attr->attr_value.v.u8) ? DUN_OPTIONS_CLASS20 : 0;
+ }
+
+ if ((p_attr = SDP_FindAttributeInRec(p_rec,
+ ATTR_ID_FAX_CLASS_2_SUPPORT)) != NULL)
+ {
+ options |= (p_attr->attr_value.v.u8) ? DUN_OPTIONS_CLASS2 : 0;
+ }
+ }
+
+ /* we've got everything, we're done */
+ found = TRUE;
+ break;
+
+ } while (TRUE);
+ }
+
+ /* return info from sdp record in app callback function */
+ if (dun_cb.find_cb.p_cback != NULL)
+ {
+ (*dun_cb.find_cb.p_cback)(found, scn, p_name, name_len, options);
+ }
+
+ return;
+}
+
+/******************************************************************************
+**
+** Function DUN_Listen
+**
+** Description This function opens a DUN or Fax connection in server mode.
+** It configures the security settings for the connection and
+** opens an RFCOMM connection in server mode. It returns
+** the handle for the RFCOMM connection.
+**
+** Input Parameters:
+** service_uuid: Indicates DUN or Fax.
+**
+** p_service_name: A null-terminated character string
+** containing the service name. This is used for security.
+**
+** scn: The server channel number for the RFCOMM
+** connection.
+**
+** mtu: The MTU, or maximum data frame size, for the
+** RFCOMM connection.
+**
+** security_mask: Security configuration. See the BTM API.
+**
+** p_cback: RFCOMM port callback function. See the
+** RFCOMM API.
+**
+** Output Parameters:
+** p_handle: The handle for the RFCOMM connection.
+** This value is used in subsequent calls to the RFCOMM API.
+**
+** Returns DUN_SUCCESS if function execution succeeded,
+** DUN_FAIL if function execution failed.
+**
+******************************************************************************/
+UINT8 DUN_Listen(UINT16 service_uuid, char *p_service_name, UINT8 scn, UINT16 mtu,
+ UINT8 security_mask, UINT16 *p_handle, tPORT_CALLBACK *p_cback)
+{
+ BD_ADDR bd_addr = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
+ UINT8 status = DUN_SUCCESS;
+ UINT8 service_id;
+
+ DUN_TRACE_API1("DUN_Listen uuid: %x", service_uuid);
+
+ switch (service_uuid)
+ {
+ case UUID_SERVCLASS_DIALUP_NETWORKING:
+ service_id = BTM_SEC_SERVICE_DUN;
+ break;
+
+ case UUID_SERVCLASS_FAX:
+ service_id = BTM_SEC_SERVICE_FAX;
+ break;
+
+ case UUID_SERVCLASS_SERIAL_PORT:
+ default:
+ service_id = BTM_SEC_SERVICE_SERIAL_PORT;
+ break;
+ }
+
+ /* set up security */
+ if (BTM_SetSecurityLevel(FALSE, (char *) p_service_name, service_id,
+ security_mask, BT_PSM_RFCOMM, BTM_SEC_PROTO_RFCOMM, scn) == FALSE)
+ {
+ status = DUN_FAIL;
+ }
+
+ /* open rfcomm server connection */
+ if (status == DUN_SUCCESS)
+ {
+ if (RFCOMM_CreateConnection(service_uuid, scn, TRUE, mtu, bd_addr,
+ p_handle, p_cback) != PORT_SUCCESS)
+ {
+ status = DUN_FAIL;
+ }
+ }
+
+ return status;
+}
+
+/******************************************************************************
+**
+** Function DUN_Connect
+**
+** Description This function opens a DUN or Fax client connection.
+** It configures the security settings for the connection
+** and opens an RFCOMM connection in server mode.
+** It returns the handle for the RFCOMM connection.
+**
+** Input Parameters:
+** service_uuid: Indicates DUN or Fax.
+**
+** bd_addr: BD address of the peer device.
+**
+** scn: The server channel number for the RFCOMM
+** connection.
+**
+** mtu: The MTU, or maximum data frame size, for the
+** RFCOMM connection.
+**
+** security_mask: Security configuration. See the BTM API.
+**
+** p_cback: RFCOMM port callback function. See the
+** RFCOMM API.
+**
+** Output Parameters:
+** p_handle: The handle for the RFCOMM connection.
+** This value is used in subsequent calls to the RFCOMM API.
+**
+** Returns DUN_SUCCESS if function execution succeeded,
+** DUN_FAIL if function execution failed.
+**
+******************************************************************************/
+UINT8 DUN_Connect(UINT16 service_uuid, BD_ADDR bd_addr, UINT8 scn, UINT16 mtu,
+ UINT8 security_mask, UINT16 *p_handle, tPORT_CALLBACK *p_cback)
+{
+ char name[] = ""; /* don't bother using a name for security */
+ UINT8 status = DUN_SUCCESS;
+ UINT8 service_id;
+
+ DUN_TRACE_API1("DUN_Connect uuid: %x", service_uuid);
+
+ switch (service_uuid)
+ {
+ case UUID_SERVCLASS_DIALUP_NETWORKING:
+ service_id = BTM_SEC_SERVICE_DUN;
+ break;
+
+ case UUID_SERVCLASS_FAX:
+ service_id = BTM_SEC_SERVICE_FAX;
+ break;
+
+ case UUID_SERVCLASS_SERIAL_PORT:
+ default:
+ service_id = BTM_SEC_SERVICE_SERIAL_PORT;
+ break;
+ }
+
+ /* set up security */
+ if(BTM_SetSecurityLevel(TRUE, name, service_id, security_mask,
+ BT_PSM_RFCOMM, BTM_SEC_PROTO_RFCOMM, scn) == FALSE)
+ {
+ status = DUN_FAIL;
+ }
+
+ /* open rfcomm client connection */
+ if (status == DUN_SUCCESS)
+ {
+ if (RFCOMM_CreateConnection(service_uuid, scn, FALSE, mtu, bd_addr,
+ p_handle, p_cback) != PORT_SUCCESS)
+ {
+ status = DUN_FAIL;
+ }
+ }
+
+ return status;
+}
+
+
+/******************************************************************************
+**
+** Function DUN_Close
+**
+** Description This function closes a DUN or Fax client connection
+** previously opened with DUN_Connect().
+**
+** Input Parameters:
+** handle: The handle for the RFCOMM connection
+** previously returned by DUN_Connect().
+**
+** Output Parameters:
+** None.
+**
+** Returns DUN_SUCCESS if function execution succeeded,
+** DUN_FAIL if function execution failed.
+**
+******************************************************************************/
+UINT8 DUN_Close(UINT16 handle)
+{
+ UINT8 status = DUN_SUCCESS;
+
+ DUN_TRACE_API0("DUN_close");
+
+ if (RFCOMM_RemoveConnection(handle) != PORT_SUCCESS)
+ {
+ status = DUN_FAIL;
+ }
+
+ return status;
+}
+
+
+/******************************************************************************
+**
+** Function DUN_Shutdown
+**
+** Description This function closes a DUN or Fax server connection
+** previously opened with DUN_Listen(). It is called if
+** the application wishes to close the DUN or Fax server
+** connection at any time.
+**
+** Input Parameters:
+** service_uuid: Indicates DUN or Fax.
+**
+** handle: The handle for the RFCOMM connection
+** previously returned by DUN_Connect().
+**
+** Output Parameters:
+** None.
+**
+** Returns DUN_SUCCESS if function execution succeeded,
+** DUN_FAIL if function execution failed.
+**
+******************************************************************************/
+UINT8 DUN_Shutdown(UINT16 handle)
+{
+ UINT8 status = DUN_SUCCESS;
+
+ DUN_TRACE_API0("DUN_Shutdown");
+
+ /* close rfcomm connection */
+ if (RFCOMM_RemoveServer(handle) != PORT_SUCCESS)
+ {
+ status = DUN_FAIL;
+ }
+
+ return status;
+}
+
+/******************************************************************************
+**
+** Function DUN_AddRecord
+**
+** Description This function is called by a server application to add
+** DUN or Fax information to an SDP record. Prior to
+** calling this function the application must call
+** SDP_CreateRecord() to create an SDP record.
+**
+** Input Parameters:
+** service_uuid: Indicates DUN or Fax.
+**
+** p_service_name: Pointer to a null-terminated character
+** string containing the service name.
+**
+** scn: The server channel number of the RFCOMM
+** connection.
+**
+** options: Profile support options.
+**
+** sdp_handle: SDP handle returned by SDP_CreateRecord().
+**
+** Output Parameters:
+** None.
+**
+** Returns DUN_SUCCESS if function execution succeeded,
+** DUN_FAIL if function execution failed.
+**
+******************************************************************************/
+UINT8 DUN_AddRecord(UINT16 service_uuid, char *p_service_name, UINT8 scn,
+ UINT16 options, UINT32 sdp_handle)
+{
+ tSDP_PROTOCOL_ELEM proto_elem_list[DUN_NUM_PROTO_ELEMS];
+ UINT8 audio;
+ UINT8 class1;
+ UINT8 class20;
+ UINT8 class2;
+ UINT16 browse_list[1];
+ BOOLEAN result = TRUE;
+
+ DUN_TRACE_API1("DUN_AddRecord uuid: %x", service_uuid);
+
+ memset((void*) proto_elem_list, 0 , DUN_NUM_PROTO_ELEMS*sizeof(tSDP_PROTOCOL_ELEM));
+
+ /* add the protocol element sequence */
+ proto_elem_list[0].protocol_uuid = UUID_PROTOCOL_L2CAP;
+ proto_elem_list[0].num_params = 0;
+ proto_elem_list[1].protocol_uuid = UUID_PROTOCOL_RFCOMM;
+ proto_elem_list[1].num_params = 1;
+ proto_elem_list[1].params[0] = scn;
+ result &= SDP_AddProtocolList(sdp_handle, DUN_NUM_PROTO_ELEMS, proto_elem_list);
+
+ /* add service class id list */
+ result &= SDP_AddServiceClassIdList(sdp_handle, 1, &service_uuid);
+
+ /* add service name */
+ if (p_service_name != NULL)
+ {
+ result &= SDP_AddAttribute(sdp_handle, ATTR_ID_SERVICE_NAME, TEXT_STR_DESC_TYPE,
+ (UINT32)(strlen(p_service_name)+1), (UINT8 *) p_service_name);
+ }
+
+ /* add audio feedback support */
+ if((service_uuid == UUID_SERVCLASS_FAX) ||
+ (service_uuid == UUID_SERVCLASS_DIALUP_NETWORKING))
+ {
+ audio = (options & DUN_OPTIONS_AUDIO) ? TRUE : FALSE;
+ result &= SDP_AddAttribute(sdp_handle, ATTR_ID_AUDIO_FEEDBACK_SUPPORT,
+ BOOLEAN_DESC_TYPE, 1, &audio);
+ }
+
+ /* add fax service class support */
+ if(service_uuid == UUID_SERVCLASS_FAX)
+ {
+ class1 = (options & DUN_OPTIONS_CLASS1) ? TRUE : FALSE;
+ result &= SDP_AddAttribute(sdp_handle, ATTR_ID_FAX_CLASS_1_SUPPORT,
+ BOOLEAN_DESC_TYPE, 1, &class1);
+
+ class20 = (options & DUN_OPTIONS_CLASS20) ? TRUE : FALSE;
+ result &= SDP_AddAttribute(sdp_handle, ATTR_ID_FAX_CLASS_2_0_SUPPORT,
+ BOOLEAN_DESC_TYPE, 1, &class20);
+
+ class2 = (options & DUN_OPTIONS_CLASS2) ? TRUE : FALSE;
+ result &= SDP_AddAttribute(sdp_handle, ATTR_ID_FAX_CLASS_2_SUPPORT,
+ BOOLEAN_DESC_TYPE, 1, &class2);
+ }
+
+ /* add browse group list */
+ browse_list[0] = UUID_SERVCLASS_PUBLIC_BROWSE_GROUP;
+ result &= SDP_AddUuidSequence(sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1, browse_list);
+
+ /* add profile descriptor list */
+ if (service_uuid != UUID_SERVCLASS_SERIAL_PORT) /* BQB fix: BTA DG uses this for SPP */
+ result &= SDP_AddProfileDescriptorList(sdp_handle, service_uuid, 0x0100);
+
+ return (result ? DUN_SUCCESS : DUN_FAIL);
+}
+
+/******************************************************************************
+**
+** Function DUN_FindService
+**
+** Description This function is called by a client application to
+** perform service discovery and retrieve DUN or Fax SDP
+** record information from a server. Information is
+** returned for the first service record found on the
+** server that matches the service UUID. The callback
+** function will be executed when service discovery is
+** complete. There can only be one outstanding call to
+** DUN_FindService() at a time; the application must wait
+** for the callback before it makes another call to
+** the function.
+**
+** Input Parameters:
+** service_uuid: Indicates DUN or Fax.
+**
+** bd_addr: BD address of the peer device.
+**
+** p_db: Pointer to the discovery database.
+**
+** db_len: Length, in bytes, of the discovery database.
+**
+** p_cback: Pointer to the DUN_FindService()
+** callback function.
+**
+** Output Parameters:
+** None.
+**
+** Returns DUN_SUCCESS if function execution succeeded,
+** DUN_FAIL if function execution failed.
+**
+******************************************************************************/
+UINT8 DUN_FindService(UINT16 service_uuid, BD_ADDR bd_addr,
+ tSDP_DISCOVERY_DB *p_db, UINT32 db_len, tDUN_FIND_CBACK *p_cback)
+{
+ tSDP_UUID uuid_list;
+ UINT16 num_attr;
+ BOOLEAN result = TRUE;
+ UINT16 dun_attr_list[] = {ATTR_ID_SERVICE_CLASS_ID_LIST,
+ ATTR_ID_PROTOCOL_DESC_LIST,
+ ATTR_ID_SERVICE_NAME,
+ ATTR_ID_AUDIO_FEEDBACK_SUPPORT,
+ ATTR_ID_FAX_CLASS_1_SUPPORT,
+ ATTR_ID_FAX_CLASS_2_0_SUPPORT,
+ ATTR_ID_FAX_CLASS_2_SUPPORT};
+
+ DUN_TRACE_API1("DUN_FindService uuid: %x", service_uuid);
+
+ /* set up discovery database */
+ uuid_list.len = LEN_UUID_16;
+ uuid_list.uu.uuid16 = service_uuid;
+
+ num_attr = (service_uuid == UUID_SERVCLASS_FAX) ?
+ DUN_NUM_ATTR_FAX : DUN_NUM_ATTR_DUN;
+
+ result = SDP_InitDiscoveryDb(p_db, db_len, 1, &uuid_list, num_attr,
+ (UINT16 *) dun_attr_list);
+
+ if (result == TRUE)
+ {
+ /* store service_uuid and discovery db pointer */
+ dun_cb.find_cb.p_db = p_db;
+ dun_cb.find_cb.service_uuid = service_uuid;
+ dun_cb.find_cb.p_cback = p_cback;
+
+ /* perform service search */
+ result = SDP_ServiceSearchAttributeRequest(bd_addr, p_db, dun_sdp_cback);
+ }
+
+ return (result ? DUN_SUCCESS : DUN_FAIL);
+}
+
+/*******************************************************************************
+**
+** Function DUN_Init
+**
+** Description This function is called to initialize the control block
+** for this layer. It must be called before accessing any
+** other API functions for this layer. It is typically called
+** once during the start up of the stack.
+**
+** Returns void
+**
+*******************************************************************************/
+void DUN_Init (void)
+{
+ /* All fields are cleared; nonzero fields are reinitialized in appropriate function */
+ memset(&dun_cb, 0, sizeof(tDUN_CB));
+
+#if defined(DUN_INITIAL_TRACE_LEVEL)
+ dun_cb.trace_level = DUN_INITIAL_TRACE_LEVEL;
+#else
+ dun_cb.trace_level = BT_TRACE_LEVEL_NONE; /* No traces */
+#endif
+}
+
+/******************************************************************************
+**
+** Function DUN_SetTraceLevel
+**
+** Description Sets the trace level for DUN. If 0xff is passed, the
+** current trace level is returned.
+**
+** Input Parameters:
+** new_level: The level to set the DUN tracing to:
+** 0xff-returns the current setting.
+** 0-turns off tracing.
+** >= 1-Errors.
+** >= 2-Warnings.
+** >= 3-APIs.
+** >= 4-Events.
+** >= 5-Debug.
+**
+** Returns The new trace level or current trace level if
+** the input parameter is 0xff.
+**
+******************************************************************************/
+UINT8 DUN_SetTraceLevel (UINT8 new_level)
+{
+ if (new_level != 0xFF)
+ dun_cb.trace_level = new_level;
+
+ return (dun_cb.trace_level);
+}