diff --git a/components/bt/bluedroid/include/bt_defs.h b/components/bt/bluedroid/include/bt_defs.h index 14e2bee927..7d256695e5 100755 --- a/components/bt/bluedroid/include/bt_defs.h +++ b/components/bt/bluedroid/include/bt_defs.h @@ -77,6 +77,18 @@ typedef enum { } bt_status_t; +#define ASSERTC(cond, msg, val) if (!(cond)) { LOG_ERROR( \ + "### ASSERT : %s line %d %s (%d) ###", __FILE__, __LINE__, msg, val);} + +#define HAL_CBACK(P_CB, P_CBACK, ...)\ + if (P_CB && P_CB->P_CBACK) { \ + BTIF_TRACE_API("HAL %s->%s", #P_CB, #P_CBACK); \ + P_CB->P_CBACK(__VA_ARGS__); \ + } \ + else { \ + ASSERTC(0, "Callback is NULL", 0); \ + } + #ifndef CPU_LITTLE_ENDIAN #define CPU_LITTLE_ENDIAN #endif @@ -92,6 +104,7 @@ inline uint32_t swap_byte_32(uint32_t x) { ((x & 0x00ff0000UL) >> 8) | ((x & 0xff000000UL) >> 24)); } + #ifndef ntohs inline uint16_t ntohs(uint16_t x) { #ifdef CPU_LITTLE_ENDIAN @@ -102,6 +115,16 @@ inline uint16_t ntohs(uint16_t x) { } #endif /* #ifndef ntohs */ +#ifndef htons +inline uint16_t htons(uint16_t x) { +#ifdef CPU_LITTLE_ENDIAN + return swap_byte_16(x); +#else + return x; +#endif +} +#endif /* #ifndef htons */ + #ifndef ntohl inline uint32_t ntohl(uint32_t x) { #ifdef CPU_LITTLE_ENDIAN @@ -112,4 +135,14 @@ inline uint32_t ntohl(uint32_t x) { } #endif /* #ifndef ntohl*/ +#ifndef htonl +inline uint32_t htonl(uint32_t x) { +#ifdef CPU_LITTLE_ENDIAN + return swap_byte_32(x); +#else + return x; +#endif +} +#endif /* #ifndef htonl*/ + #endif /* _BT_DEFS_H_ */ diff --git a/components/bt/bluedroid/osi/include/thread.h b/components/bt/bluedroid/osi/include/thread.h index dcdc2b44ef..32f9fdb42c 100644 --- a/components/bt/bluedroid/osi/include/thread.h +++ b/components/bt/bluedroid/osi/include/thread.h @@ -16,10 +16,11 @@ struct task_evt { typedef struct task_evt TaskEvt_t; enum { - SIG_PRF_START_UP = 0xfc, - SIG_PRF_WORK = 0xfd, + SIG_PRF_START_UP = 0xfc, + SIG_PRF_WORK = 0xfd, SIG_BTU_START_UP = 0xfe, - SIG_BTU_WORK = 0xff + SIG_BTU_WORK = 0xff, + SIG_BTIF_WORK = 0xff }; void btu_task_post(uint32_t sig); diff --git a/components/bt/bluedroid/profiles/core/btif_core.c b/components/bt/bluedroid/profiles/core/btif_core.c new file mode 100755 index 0000000000..9d1b9a25f0 --- /dev/null +++ b/components/bt/bluedroid/profiles/core/btif_core.c @@ -0,0 +1,484 @@ +/****************************************************************************** + * + * Copyright (C) 2014 The Android Open Source Project + * Copyright (C) 2009-2012 Broadcom Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************************/ + +/************************************************************************************ + * + * Filename: btif_core.c + * + * Description: Contains core functionality related to interfacing between + * Bluetooth HAL and BTE core stack. + * + ***********************************************************************************/ + +#include +// #include +// #include +// #include +// #include +#include +#include +// #include +// #include + +#define LOG_TAG "bt_btif_core" +// #include "btcore/include/bdaddr.h" + +#include "bdaddr.h" +// #include "bt_utils.h" +#include "bta_api.h" +#include "bte.h" +#include "btif_api.h" +// #include "btif_av.h" +// #include "btif_config.h" +// #include "btif_pan.h" +// #include "btif_profile_queue.h" +// #include "btif_config.h" +// #include "btif_sock.h" +// #include "btif_storage.h" +#include "btif_util.h" +#include "btu.h" +#include "controller.h" +#include "fixed_queue.h" +#include "future.h" +#include "gki.h" +#include "osi.h" +// #include "osi/include/log.h" +#include "stack_manager.h" +#include "thread.h" +#include "btif_common.h" +#include "btif_dm.h" +#include "bt_stack_manager.h" +/************************************************************************************ +** Constants & Macros +************************************************************************************/ + +/************************************************************************************ +** Local type definitions +************************************************************************************/ + +/************************************************************************************ +** Static variables +************************************************************************************/ + +static tBTA_SERVICE_MASK btif_enabled_services = 0; + +static fixed_queue_t *btif_msg_queue = NULL; +static xTaskHandle xBtifTaskHandle = NULL; + +/************************************************************************************ +** Static functions +************************************************************************************/ + +/* sends message to btif task */ +static void btif_sendmsg(void *p_msg); +static void btif_thread_post(uint32_t sig); +/************************************************************************************ +** Externs +************************************************************************************/ +static fixed_queue_t *xBtifQueue = NULL; + +/** TODO: Move these to _common.h */ +void bte_main_boot_entry(void *); +void bte_main_disable(void); +void bte_main_shutdown(void); +void btif_dm_execute_service_request(UINT16 event, char *p_param); + +/******************************************************************************* +** +** Function btif_context_switched +** +** Description Callback used to execute transferred context callback +** +** p_msg : message to be executed in btif context +** +** Returns void +** +*******************************************************************************/ + +static void btif_context_switched(void *p_msg) +{ + + BTIF_TRACE_VERBOSE("btif_context_switched"); + + tBTIF_CONTEXT_SWITCH_CBACK *p = (tBTIF_CONTEXT_SWITCH_CBACK *) p_msg; + + /* each callback knows how to parse the data */ + if (p->p_cb) + p->p_cb(p->event, p->p_param); +} + + +/******************************************************************************* +** +** Function btif_transfer_context +** +** Description This function switches context to btif task +** +** p_cback : callback used to process message in btif context +** event : event id of message +** p_params : parameter area passed to callback (copied) +** param_len : length of parameter area +** p_copy_cback : If set this function will be invoked for deep copy +** +** Returns void +** +*******************************************************************************/ + +bt_status_t btif_transfer_context (tBTIF_CBACK *p_cback, UINT16 event, char* p_params, int param_len, tBTIF_COPY_CBACK *p_copy_cback) +{ + tBTIF_CONTEXT_SWITCH_CBACK *p_msg; + + BTIF_TRACE_VERBOSE("btif_transfer_context event %d, len %d", event, param_len); + + /* allocate and send message that will be executed in btif context */ + if ((p_msg = (tBTIF_CONTEXT_SWITCH_CBACK *) GKI_getbuf(sizeof(tBTIF_CONTEXT_SWITCH_CBACK) + param_len)) != NULL) + { + p_msg->hdr.event = BT_EVT_CONTEXT_SWITCH_EVT; /* internal event */ + p_msg->p_cb = p_cback; + + p_msg->event = event; /* callback event */ + + /* check if caller has provided a copy callback to do the deep copy */ + if (p_copy_cback) + { + p_copy_cback(event, p_msg->p_param, p_params); + } + else if (p_params) + { + memcpy(p_msg->p_param, p_params, param_len); /* callback parameter data */ + } + + btif_sendmsg(p_msg); + return BT_STATUS_SUCCESS; + } + else + { + /* let caller deal with a failed allocation */ + return BT_STATUS_NOMEM; + } +} + +int btif_is_enabled(void) +{ + return (stack_manager_is_stack_running()); +} + +void btif_init_ok(void) { + BTIF_TRACE_DEBUG("btif_task: received trigger stack init event"); + future_ready(stack_manager_get_hack_future(), FUTURE_SUCCESS); +} + +/******************************************************************************* +** +** Function btif_enable_bluetooth_evt +** +** Description Event indicating bluetooth enable is completed +** Notifies HAL user with updated adapter state +** +** Returns void +** +*******************************************************************************/ + +void btif_enable_bluetooth_evt(tBTA_STATUS status) +{ + if (status == BTA_SUCCESS) { + future_ready(stack_manager_get_hack_future(), FUTURE_SUCCESS); + } else { + future_ready(stack_manager_get_hack_future(), FUTURE_FAIL); + } +} + +/******************************************************************************* +** +** Function btif_disable_bluetooth_evt +** +** Description Event notifying BT disable is now complete. +** Terminates main stack tasks and notifies HAL +** user with updated BT state. +** +** Returns void +** +*******************************************************************************/ + +void btif_disable_bluetooth_evt(void) +{ + BTIF_TRACE_DEBUG("%s", __FUNCTION__); + + /* callback to HAL */ + future_ready(stack_manager_get_hack_future(), FUTURE_SUCCESS); +} + +/******************************************************************************* +** +** Function btif_task +** +** Description BTIF task handler managing all messages being passed +** Bluetooth HAL and BTA. +** +** Returns void +** +*******************************************************************************/ +static void bt_jni_msg_ready(fixed_queue_t *queue) { + BT_HDR *p_msg; + while (!fixed_queue_is_empty(queue)) { + p_msg = (BT_HDR *)fixed_queue_dequeue(queue); + BTIF_TRACE_VERBOSE("btif task fetched event %x", p_msg->event); + switch (p_msg->event) { + case BT_EVT_CONTEXT_SWITCH_EVT: + btif_context_switched(p_msg); + break; + default: + BTIF_TRACE_ERROR("unhandled btif event (%d)", p_msg->event & BT_EVT_MASK); break; + } + GKI_freebuf(p_msg); + } +} + +/******************************************************************************* +** +** Function btif_sendmsg +** +** Description Sends msg to BTIF task +** +** Returns void +** +*******************************************************************************/ + +void btif_sendmsg(void *p_msg) +{ + fixed_queue_enqueue(btif_msg_queue, p_msg); + btif_thread_post(SIG_BTIF_WORK); +} + +static void btif_thread_post(uint32_t sig) { + TaskEvt_t *evt = (TaskEvt_t *)osi_malloc(sizeof(TaskEvt_t)); + if (evt == NULL) + return; + + evt->sig = sig; + evt->par = 0; + + if (xQueueSend(xBtifQueue, &evt, 10/portTICK_RATE_MS) != pdTRUE) { + ets_printf("xBtifQueue failed\n"); + } +} + +/***************************************************************************** +** +** Function btif_task_thread_handler +** +** Description Process BTif Task Thread. +******************************************************************************/ +void btif_task_thread_handler(void *arg) +{ + TaskEvt_t *e; + + for (;;) { + if (pdTRUE == xQueueReceive(xBtifQueue, &e, (portTickType)portMAX_DELAY)) { + + if (e->sig == SIG_BTIF_WORK) { + fixed_queue_process(btif_msg_queue); + } + osi_free(e); + } + } +} + +/******************************************************************************* +** +** Function btif_init_bluetooth +** +** Description Creates BTIF task and prepares BT scheduler for startup +** +** Returns bt_status_t +** +*******************************************************************************/ +bt_status_t btif_init_bluetooth(void) { + bte_main_boot_entry(btif_init_ok); + + btif_msg_queue = fixed_queue_new(SIZE_MAX); + if (btif_msg_queue == NULL) { + goto error_exit; + } + xBtifQueue = xQueueCreate(60, sizeof(void *)); + xTaskCreate(btif_task_thread_handler, "BtifT", 8192, NULL, configMAX_PRIORITIES - 1, &xBtifTaskHandle); + fixed_queue_register_dequeue(btif_msg_queue, bt_jni_msg_ready); + + return BT_STATUS_SUCCESS; + +error_exit:; + btif_shutdown_bluetooth(); + + return BT_STATUS_FAIL; +} + +/******************************************************************************* +** +** Function btif_enable_bluetooth +** +** Description Inititates shutdown of Bluetooth system. +** Any active links will be dropped and device entering +** non connectable/discoverable mode +** +** Returns void +** +*******************************************************************************/ +bt_status_t btif_enable_bluetooth(void) +{ + BTIF_TRACE_DEBUG("BTIF ENABLE BLUETOOTH"); + + BTA_EnableBluetooth(bte_dm_evt); + + return BT_STATUS_SUCCESS; +} + +/******************************************************************************* +** +** Function btif_disable_bluetooth +** +** Description Inititates shutdown of Bluetooth system. +** Any active links will be dropped and device entering +** non connectable/discoverable mode +** +** Returns void +** +*******************************************************************************/ +bt_status_t btif_disable_bluetooth(void) +{ + BTIF_TRACE_DEBUG("BTIF DISABLE BLUETOOTH"); + + // btif_dm_on_disable(); + /* cleanup rfcomm & l2cap api */ + // btif_sock_cleanup(); + // btif_pan_cleanup(); + BTA_DisableBluetooth(); + + return BT_STATUS_SUCCESS; +} + +/******************************************************************************* +** +** Function btif_shutdown_bluetooth +** +** Description Finalizes BT scheduler shutdown and terminates BTIF +** task. +** +** Returns void +** +*******************************************************************************/ + +bt_status_t btif_shutdown_bluetooth(void) +{ + BTIF_TRACE_DEBUG("%s", __FUNCTION__); + + fixed_queue_unregister_dequeue(btif_msg_queue); + fixed_queue_free(btif_msg_queue, NULL); + btif_msg_queue = NULL; + + vTaskDelete(xBtifTaskHandle); + xBtifTaskHandle = NULL; + + vQueueDelete(xBtifQueue); + xBtifQueue = NULL; + + bte_main_shutdown(); + + return BT_STATUS_SUCCESS; +} + +/******************************************************************************* +** +** Function btif_get_enabled_services_mask +** +** Description Fetches currently enabled services +** +** Returns tBTA_SERVICE_MASK +** +*******************************************************************************/ + +tBTA_SERVICE_MASK btif_get_enabled_services_mask(void) +{ + return btif_enabled_services; +} + +/******************************************************************************* +** +** Function btif_enable_service +** +** Description Enables the service 'service_ID' to the service_mask. +** Upon BT enable, BTIF core shall invoke the BTA APIs to +** enable the profiles +** +** Returns bt_status_t +** +*******************************************************************************/ +bt_status_t btif_enable_service(tBTA_SERVICE_ID service_id) +{ + tBTA_SERVICE_ID *p_id = &service_id; + + /* If BT is enabled, we need to switch to BTIF context and trigger the + * enable for that profile + * + * Otherwise, we just set the flag. On BT_Enable, the DM will trigger + * enable for the profiles that have been enabled */ + + btif_enabled_services |= (1 << service_id); + + BTIF_TRACE_DEBUG("%s: current services:0x%x", __FUNCTION__, btif_enabled_services); + + if (btif_is_enabled()) { + btif_transfer_context(btif_dm_execute_service_request, + BTIF_DM_ENABLE_SERVICE, + (char*)p_id, sizeof(tBTA_SERVICE_ID), NULL); + } + + return BT_STATUS_SUCCESS; +} +/******************************************************************************* +** +** Function btif_disable_service +** +** Description Disables the service 'service_ID' to the service_mask. +** Upon BT disable, BTIF core shall invoke the BTA APIs to +** disable the profiles +** +** Returns bt_status_t +** +*******************************************************************************/ +bt_status_t btif_disable_service(tBTA_SERVICE_ID service_id) +{ + tBTA_SERVICE_ID *p_id = &service_id; + + /* If BT is enabled, we need to switch to BTIF context and trigger the + * disable for that profile so that the appropriate uuid_property_changed will + * be triggerred. Otherwise, we just need to clear the service_id in the mask + */ + + btif_enabled_services &= (tBTA_SERVICE_MASK)(~(1< +// #include +#include +#include +#include +// #include +// #include + +// #include + +// #include +#include "gki.h" +#include "btu.h" +// #include "btcore/include/bdaddr.h" +#include "bta_api.h" +#include "btif_api.h" +#include "btif_util.h" +#include "btif_dm.h" +// #include "btif_storage.h" +// #include "btif_hh.h" +// #include "btif_config.h" +// #include "btif_sdp.h" +// #include "bta_gatt_api.h" +// #include "device/include/interop.h" +// #include "include/stack_config.h" +// #include "osi/include/log.h" +#include "allocator.h" +#include "btm_int.h" +#include "bt_defs.h" +#include "future.h" +#include "stack_manager.h" + +/****************************************************************************** +** Constants & Macros +******************************************************************************/ +#define BTA_SERVICE_ID_TO_SERVICE_MASK(id) (1 << (id)) + +/************************************************************************************ +** Static variables +************************************************************************************/ +/****************************************************************************** +** Static functions +******************************************************************************/ +/****************************************************************************** +** Externs +******************************************************************************/ +extern bt_status_t btif_sdp_execute_service(BOOLEAN b_enable); + +/****************************************************************************** +** Functions +******************************************************************************/ + +static void btif_dm_data_copy(uint16_t event, char *dst, char *src) +{ + tBTA_DM_SEC *dst_dm_sec = (tBTA_DM_SEC*)dst; + tBTA_DM_SEC *src_dm_sec = (tBTA_DM_SEC*)src; + + if (!src_dm_sec) + return; + + assert(dst_dm_sec); + memcpy(dst_dm_sec, src_dm_sec, sizeof(tBTA_DM_SEC)); + + if (event == BTA_DM_BLE_KEY_EVT) { + dst_dm_sec->ble_key.p_key_value = osi_malloc(sizeof(tBTM_LE_KEY_VALUE)); + assert(src_dm_sec->ble_key.p_key_value); + assert(dst_dm_sec->ble_key.p_key_value); + memcpy(dst_dm_sec->ble_key.p_key_value, src_dm_sec->ble_key.p_key_value, sizeof(tBTM_LE_KEY_VALUE)); + } +} + +static void btif_dm_data_free(uint16_t event, tBTA_DM_SEC *dm_sec) +{ + if (event == BTA_DM_BLE_KEY_EVT) { + osi_free(dm_sec->ble_key.p_key_value); + } +} + +bt_status_t btif_in_execute_service_request(tBTA_SERVICE_ID service_id, + BOOLEAN b_enable) +{ + BTIF_TRACE_DEBUG("%s service_id: %d", __FUNCTION__, service_id); + /* Check the service_ID and invoke the profile's BT state changed API */ + switch (service_id) { + case BTA_SDP_SERVICE_ID: + btif_sdp_execute_service(b_enable); + break; + default: + BTIF_TRACE_ERROR("%s: Unknown service being enabled", __FUNCTION__); + return BT_STATUS_FAIL; + } + return BT_STATUS_SUCCESS; +} + +void btif_dm_execute_service_request(UINT16 event, char *p_param) +{ + BOOLEAN b_enable = FALSE; + if (event == BTIF_DM_ENABLE_SERVICE) { + b_enable = TRUE; + } + + btif_in_execute_service_request(*((tBTA_SERVICE_ID*)p_param), b_enable); +} + +/******************************************************************************* +** +** Function btif_dm_upstreams_cback +** +** Description Executes UPSTREAMS events in btif context +** +** Returns void +** +*******************************************************************************/ +static void btif_dm_upstreams_evt(UINT16 event, char* p_param) +{ + tBTA_DM_SEC *p_data = (tBTA_DM_SEC*)p_param; + tBTA_SERVICE_MASK service_mask; + uint32_t i; + BTIF_TRACE_EVENT("btif_dm_upstreams_cback ev: %d\n", event); + + switch (event) { + case BTA_DM_ENABLE_EVT: + /* for each of the enabled services in the mask, trigger the profile + * enable */ + service_mask = btif_get_enabled_services_mask(); + for (i=0; i <= BTA_MAX_SERVICE_ID; i++) { + if (service_mask & + (tBTA_SERVICE_MASK)(BTA_SERVICE_ID_TO_SERVICE_MASK(i))) { + btif_in_execute_service_request(i, TRUE); + } + } + btif_enable_bluetooth_evt(p_data->enable.status); + break; + case BTA_DM_DISABLE_EVT: + /* for each of the enabled services in the mask, trigger the profile + * disable */ + service_mask = btif_get_enabled_services_mask(); + for (i=0; i <= BTA_MAX_SERVICE_ID; i++) { + if (service_mask & + (tBTA_SERVICE_MASK)(BTA_SERVICE_ID_TO_SERVICE_MASK(i))) { + btif_in_execute_service_request(i, FALSE); + } + } + btif_disable_bluetooth_evt(); + break; + case BTA_DM_PIN_REQ_EVT: + case BTA_DM_AUTH_CMPL_EVT: + case BTA_DM_BOND_CANCEL_CMPL_EVT: + case BTA_DM_SP_CFM_REQ_EVT: + case BTA_DM_SP_KEY_NOTIF_EVT: + + case BTA_DM_DEV_UNPAIRED_EVT: + case BTA_DM_BUSY_LEVEL_EVT: + case BTA_DM_LINK_UP_EVT: + case BTA_DM_LINK_DOWN_EVT: + case BTA_DM_HW_ERROR_EVT: + +#if (defined(BLE_INCLUDED) && (BLE_INCLUDED == TRUE)) + case BTA_DM_BLE_KEY_EVT: + case BTA_DM_BLE_SEC_REQ_EVT: + case BTA_DM_BLE_PASSKEY_NOTIF_EVT: + case BTA_DM_BLE_PASSKEY_REQ_EVT: + case BTA_DM_BLE_NC_REQ_EVT: + case BTA_DM_BLE_OOB_REQ_EVT: + case BTA_DM_BLE_LOCAL_IR_EVT: + case BTA_DM_BLE_LOCAL_ER_EVT: + case BTA_DM_BLE_AUTH_CMPL_EVT: + case BTA_DM_LE_FEATURES_READ: + case BTA_DM_ENER_INFO_READ: +#endif + + case BTA_DM_AUTHORIZE_EVT: + case BTA_DM_SIG_STRENGTH_EVT: + case BTA_DM_SP_RMT_OOB_EVT: + case BTA_DM_SP_KEYPRESS_EVT: + case BTA_DM_ROLE_CHG_EVT: + + default: + BTIF_TRACE_WARNING( "btif_dm_cback : unhandled event (%d)", event ); + break; + } + + btif_dm_data_free(event, p_data); +} + +/******************************************************************************* +** +** Function bte_dm_evt +** +** Description Switches context from BTE to BTIF for all DM events +** +** Returns void +** +*******************************************************************************/ + +void bte_dm_evt(tBTA_DM_SEC_EVT event, tBTA_DM_SEC *p_data) +{ + /* switch context to btif task context (copy full union size for convenience) */ + bt_status_t status = btif_transfer_context(btif_dm_upstreams_evt, (uint16_t)event, + (void*)p_data, sizeof(tBTA_DM_SEC), btif_dm_data_copy); + + /* catch any failed context transfers */ + ASSERTC(status == BT_STATUS_SUCCESS, "context transfer failed", status); +} diff --git a/components/bt/bluedroid/profiles/core/btif_util.c b/components/bt/bluedroid/profiles/core/btif_util.c new file mode 100755 index 0000000000..b64e7fdeb2 --- /dev/null +++ b/components/bt/bluedroid/profiles/core/btif_util.c @@ -0,0 +1,159 @@ +/****************************************************************************** + * + * Copyright (c) 2014 The Android Open Source Project + * Copyright (C) 2009-2012 Broadcom Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************************/ + +/************************************************************************************ + * + * Filename: btif_util.c + * + * Description: Miscellaneous helper functions + * + * + ***********************************************************************************/ + +// #include +// #include +// #include +// #include +#include +#include +#include +#include + + +#define LOG_TAG "bt_btif_util" +// #include "btif_common.h" +// #include "bta_api.h" +// #include "gki.h" +// #include "btu.h" +// #include "bte.h" +// #include "btif_dm.h" +#include "btif_util.h" +// #include "bta_ag_api.h" +// #include "bta_av_api.h" +// #include "bta_hh_api.h" +// #include "bta_hf_client_api.h" +// #include "avrc_defs.h" +#include "bt_defs.h" + +/************************************************************************************ +** Constants & Macros +************************************************************************************/ +#define ISDIGIT(a) ((a>='0') && (a<='9')) +#define ISXDIGIT(a) (((a>='0') && (a<='9'))||((a>='A') && (a<='F'))||((a>='a') && (a<='f'))) + +/************************************************************************************ +** Local type definitions +************************************************************************************/ + +/************************************************************************************ +** Static variables +************************************************************************************/ + +/************************************************************************************ +** Static functions +************************************************************************************/ + +/************************************************************************************ +** Externs +************************************************************************************/ + +/************************************************************************************ +** Functions +************************************************************************************/ + +/***************************************************************************** +** Logging helper functions +*****************************************************************************/ + +UINT32 devclass2uint(DEV_CLASS dev_class) +{ + UINT32 cod = 0; + + if(dev_class != NULL) + { + /* if COD is 0, irrespective of the device type set it to Unclassified device */ + cod = (dev_class[2]) | (dev_class[1] << 8) | (dev_class[0] << 16); + } + return cod; +} +void uint2devclass(UINT32 cod, DEV_CLASS dev_class) +{ + dev_class[2] = (UINT8)cod; + dev_class[1] = (UINT8)(cod >> 8); + dev_class[0] = (UINT8)(cod >> 16); +} + +static const UINT8 sdp_base_uuid[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, + 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB}; + +void uuid16_to_uuid128(uint16_t uuid16, bt_uuid_t* uuid128) +{ + uint16_t uuid16_bo; + memset(uuid128, 0, sizeof(bt_uuid_t)); + + memcpy(uuid128->uu, sdp_base_uuid, MAX_UUID_SIZE); + uuid16_bo = ntohs(uuid16); + memcpy(uuid128->uu + 2, &uuid16_bo, sizeof(uint16_t)); +} + +void string_to_uuid(char *str, bt_uuid_t *p_uuid) +{ + uint32_t uuid0, uuid4; + uint16_t uuid1, uuid2, uuid3, uuid5; + + sscanf(str, "%08x-%04hx-%04hx-%04hx-%08x%04hx", + &uuid0, &uuid1, &uuid2, &uuid3, &uuid4, &uuid5); + + uuid0 = htonl(uuid0); + uuid1 = htons(uuid1); + uuid2 = htons(uuid2); + uuid3 = htons(uuid3); + uuid4 = htonl(uuid4); + uuid5 = htons(uuid5); + + memcpy(&(p_uuid->uu[0]), &uuid0, 4); + memcpy(&(p_uuid->uu[4]), &uuid1, 2); + memcpy(&(p_uuid->uu[6]), &uuid2, 2); + memcpy(&(p_uuid->uu[8]), &uuid3, 2); + memcpy(&(p_uuid->uu[10]), &uuid4, 4); + memcpy(&(p_uuid->uu[14]), &uuid5, 2); + + return; + +} + +void uuid_to_string_legacy(bt_uuid_t *p_uuid, char *str) +{ + uint32_t uuid0, uuid4; + uint16_t uuid1, uuid2, uuid3, uuid5; + + memcpy(&uuid0, &(p_uuid->uu[0]), 4); + memcpy(&uuid1, &(p_uuid->uu[4]), 2); + memcpy(&uuid2, &(p_uuid->uu[6]), 2); + memcpy(&uuid3, &(p_uuid->uu[8]), 2); + memcpy(&uuid4, &(p_uuid->uu[10]), 4); + memcpy(&uuid5, &(p_uuid->uu[14]), 2); + + sprintf((char *)str, "%.8x-%.4x-%.4x-%.4x-%.8x%.4x", + ntohl(uuid0), ntohs(uuid1), + ntohs(uuid2), ntohs(uuid3), + ntohl(uuid4), ntohs(uuid5)); + return; +} + diff --git a/components/bt/bluedroid/profiles/core/include/bt_stack_manager.h b/components/bt/bluedroid/profiles/core/include/bt_stack_manager.h new file mode 100644 index 0000000000..c01e6324cf --- /dev/null +++ b/components/bt/bluedroid/profiles/core/include/bt_stack_manager.h @@ -0,0 +1,31 @@ +#ifndef __BT_STACK_MANAGER_H__ +#define __BT_STACK_MANAGER_H__ + +#include "bt_defs.h" + +/** Bluetooth Adapter State */ +typedef enum { + BT_STATE_OFF, + BT_STATE_ON +} bt_state_t; + +/** Bluetooth Interface callbacks */ + +/** Bluetooth Enable/Disable Callback. */ +typedef void (*adapter_state_changed_callback)(bt_state_t state); + + +/** Bluetooth Device callback structure. */ +typedef struct { + adapter_state_changed_callback adapter_state_changed_cb; +} bt_callbacks_t; + +bt_status_t API_BTDM_InitStack(bt_callbacks_t *cb); + +bt_status_t API_BTDM_EnableStack(void); + +bt_status_t API_BTDM_DisableStack(void); + +bt_status_t API_BTDM_CleanUpStack(void); + +#endif /* __BT_STACK_MANAGER_H__ */ diff --git a/components/bt/bluedroid/profiles/core/include/btif_api.h b/components/bt/bluedroid/profiles/core/include/btif_api.h new file mode 100755 index 0000000000..753fec100d --- /dev/null +++ b/components/bt/bluedroid/profiles/core/include/btif_api.h @@ -0,0 +1,88 @@ +/****************************************************************************** + * + * Copyright (C) 2009-2012 Broadcom Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************************/ + +/******************************************************************************* + * + * Filename: btif_api.h + * + * Description: Main API header file for all BTIF functions accessed + * from main bluetooth HAL. All HAL extensions will not + * require headerfiles as they would be accessed through + * callout/callins. + * + *******************************************************************************/ + +#ifndef BTIF_API_H +#define BTIF_API_H + +#include "btif_common.h" +#include "btif_dm.h" + +/******************************************************************************* +** BTIF CORE API +********************************************************************************/ + +/******************************************************************************* +** +** Function btif_init_bluetooth +** +** Description Creates BTIF task and prepares BT scheduler for startup +** +** Returns bt_status_t +** +*******************************************************************************/ +bt_status_t btif_init_bluetooth(void); + +/******************************************************************************* +** +** Function btif_enable_bluetooth +** +** Description Performs chip power on and kickstarts OS scheduler +** +** Returns bt_status_t +** +*******************************************************************************/ +bt_status_t btif_enable_bluetooth(void); + +/******************************************************************************* +** +** Function btif_disable_bluetooth +** +** Description Inititates shutdown of Bluetooth system. +** Any active links will be dropped and device entering +** non connectable/discoverable mode +** +** Returns void +** +*******************************************************************************/ +bt_status_t btif_disable_bluetooth(void); + +/******************************************************************************* +** +** Function btif_shutdown_bluetooth +** +** Description Finalizes BT scheduler shutdown and terminates BTIF +** task. +** +** +** Returns void +** +*******************************************************************************/ +bt_status_t btif_shutdown_bluetooth(void); + +#endif /* BTIF_API_H */ diff --git a/components/bt/bluedroid/profiles/core/include/btif_common.h b/components/bt/bluedroid/profiles/core/include/btif_common.h new file mode 100755 index 0000000000..ca6168c52b --- /dev/null +++ b/components/bt/bluedroid/profiles/core/include/btif_common.h @@ -0,0 +1,122 @@ +/****************************************************************************** + * + * Copyright (c) 2014 The Android Open Source Project + * Copyright (C) 2009-2012 Broadcom Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************************/ + +#ifndef BTIF_COMMON_H +#define BTIF_COMMON_H + +#include +// #include + +#include "bt_types.h" +#include "bta_api.h" +#include "osi.h" + +// #include "osi/include/log.h" + +/******************************************************************************* +** Constants & Macros +********************************************************************************/ +#define ASSERTC(cond, msg, val) if (!(cond)) { LOG_ERROR( \ + "### ASSERT : %s line %d %s (%d) ###", __FILE__, __LINE__, msg, val);} + +/* Calculate start of event enumeration; id is top 8 bits of event */ +#define BTIF_SIG_START(id) ((id) << 8) + +/* For upstream the MSB bit is always SET */ +#define BTIF_SIG_CB_BIT (0x8000) +#define BTIF_SIG_CB_START(id) (((id) << 8) | BTIF_SIG_CB_BIT) + +/* BTIF sub-systems */ +#define BTIF_CORE 0 +#define BTIF_DM 1 +// #define BTIF_HFP 2 +// #define BTIF_AV 3 +// #define BTIF_PAN 4 +// #define BTIF_HF_CLIENT 5 + +#define HAL_CBACK(P_CB, P_CBACK, ...)\ + if (P_CB && P_CB->P_CBACK) { \ + BTIF_TRACE_API("HAL %s->%s", #P_CB, #P_CBACK); \ + P_CB->P_CBACK(__VA_ARGS__); \ + } \ + else { \ + ASSERTC(0, "Callback is NULL", 0); \ + } + +/** + * BTIF events for requests that require context switch to btif task + * on downstreams path + */ +enum +{ + BTIF_CORE_API_START = BTIF_SIG_START(BTIF_CORE), + /* add here */ + + BTIF_DM_API_START = BTIF_SIG_START(BTIF_DM), + BTIF_DM_ENABLE_SERVICE, + BTIF_DM_DISABLE_SERVICE, + /* add here */ + +}; + + +/******************************************************************************* +** Type definitions for callback functions +********************************************************************************/ + +typedef void (tBTIF_CBACK) (UINT16 event, char *p_param); +typedef void (tBTIF_COPY_CBACK) (UINT16 event, char *p_dest, char *p_src); + + +/******************************************************************************* +** Type definitions and return values +********************************************************************************/ + +/* this type handles all btif context switches between BTU and HAL */ +typedef struct +{ + BT_HDR hdr; + tBTIF_CBACK* p_cb; /* context switch callback */ + + /* parameters passed to callback */ + UINT16 event; /* message event id */ + char p_param[0]; /* parameter area needs to be last */ +} tBTIF_CONTEXT_SWITCH_CBACK; + + +/******************************************************************************* +** Functions +********************************************************************************/ + +bt_status_t btif_transfer_context (tBTIF_CBACK *p_cback, UINT16 event, char* p_params, + int param_len, tBTIF_COPY_CBACK *p_copy_cback); +tBTA_SERVICE_MASK btif_get_enabled_services_mask(void); +bt_status_t btif_enable_service(tBTA_SERVICE_ID service_id); +bt_status_t btif_disable_service(tBTA_SERVICE_ID service_id); +int btif_is_enabled(void); + +/** + * BTIF_Events + */ +void btif_enable_bluetooth_evt(tBTA_STATUS status); +void btif_disable_bluetooth_evt(void); + + + +#endif /* BTIF_COMMON_H */ diff --git a/components/bt/bluedroid/profiles/core/include/btif_dm.h b/components/bt/bluedroid/profiles/core/include/btif_dm.h new file mode 100755 index 0000000000..58f535c30b --- /dev/null +++ b/components/bt/bluedroid/profiles/core/include/btif_dm.h @@ -0,0 +1,32 @@ +/****************************************************************************** + * + * Copyright (C) 2009-2012 Broadcom Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************************/ + +#ifndef BTIF_DM_H +#define BTIF_DM_H + +#include "bta_api.h" +/************************************************************************************ +** Functions +********************************************************************************/ + +/** + * BTIF callback to switch context from bte to btif + */ +void bte_dm_evt(tBTA_DM_SEC_EVT event, tBTA_DM_SEC *p_data); + +#endif diff --git a/components/bt/bluedroid/profiles/core/include/btif_util.h b/components/bt/bluedroid/profiles/core/include/btif_util.h new file mode 100755 index 0000000000..8c5e035fc7 --- /dev/null +++ b/components/bt/bluedroid/profiles/core/include/btif_util.h @@ -0,0 +1,52 @@ +/****************************************************************************** + * + * Copyright (c) 2014 The Android Open Source Project + * Copyright (C) 2009-2012 Broadcom Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************************/ + +#ifndef BTIF_UTIL_H +#define BTIF_UTIL_H + +// #include +// #include +#include +// #include + +#include "bt_types.h" +// #include "bt_utils.h" +#include "bt_defs.h" + +/******************************************************************************* +** Constants & Macros +********************************************************************************/ +/******************************************************************************* +** Type definitions for callback functions +********************************************************************************/ + +typedef char bdstr_t[18]; + + +/******************************************************************************* +** Functions +********************************************************************************/ +UINT32 devclass2uint(DEV_CLASS dev_class); +void uint2devclass(UINT32 dev, DEV_CLASS dev_class); +void uuid16_to_uuid128(uint16_t uuid16, bt_uuid_t* uuid128); + +void uuid_to_string_legacy(bt_uuid_t *p_uuid, char *str); +void string_to_uuid(char *str, bt_uuid_t *p_uuid); + +#endif /* BTIF_UTIL_H */ diff --git a/components/bt/bluedroid/profiles/core/include/stack_manager.h b/components/bt/bluedroid/profiles/core/include/stack_manager.h new file mode 100755 index 0000000000..466cdca122 --- /dev/null +++ b/components/bt/bluedroid/profiles/core/include/stack_manager.h @@ -0,0 +1,29 @@ +/****************************************************************************** + * + * Copyright (C) 2014 Google, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************************/ + +#ifndef __STACK_MANAGER_H__ +#define __STACK_MANAGER_H__ + +#include +#include "future.h" + +bool stack_manager_is_stack_running(void); + +future_t *stack_manager_get_hack_future(void); + +#endif /* __STACK_MANAGER_H__*/ diff --git a/components/bt/bluedroid/profiles/core/stack_manager.c b/components/bt/bluedroid/profiles/core/stack_manager.c new file mode 100644 index 0000000000..c2d2d847bb --- /dev/null +++ b/components/bt/bluedroid/profiles/core/stack_manager.c @@ -0,0 +1,160 @@ +#include +#include +#include "bt_stack_manager.h" +#include "bt_defs.h" +#include "bt_trace.h" +#include "future.h" +#include "btif_common.h" +#include "btif_api.h" +#include "btif_dm.h" + +/************************************************************************************ +** Constants & Macros +************************************************************************************/ +/************************************************************************************ +** Local type definitions +************************************************************************************/ +/************************************************************************************ +** Static variables +************************************************************************************/ +static bool stack_is_initialized = false; +static bool stack_is_running = false; +static bt_callbacks_t *bt_hal_cbacks = NULL; +static future_t *hack_future = NULL; + +static bt_status_t event_init_stack(bt_callbacks_t *cb); +static bt_status_t event_start_up_stack(void); +static bt_status_t event_shut_down_stack(void); +static bt_status_t event_clean_up_stack(void); +static void event_signal_stack_initialized(void); +static void event_signal_stack_up(UNUSED_ATTR uint16_t event, UNUSED_ATTR char *p_param); +static void event_signal_stack_down(UNUSED_ATTR uint16_t event, UNUSED_ATTR char *p_param); + +static bt_status_t event_init_stack(bt_callbacks_t *cb) +{ + bt_status_t ret; + if (!stack_is_initialized) { + hack_future = future_new(); + ret = btif_init_bluetooth(); + if (future_await(hack_future) != FUTURE_SUCCESS) { + return BT_STATUS_FAIL; + } + if (ret == BT_STATUS_SUCCESS) { + bt_hal_cbacks = cb; + stack_is_initialized = true; + } + return ret; + } + else { + return BT_STATUS_DONE; + } +} + +static bt_status_t event_start_up_stack(void) +{ + if (!stack_is_initialized) { + LOG_DEBUG("%s stack not initialized yet.\n", __func__); + return BT_STATUS_NOT_READY; + } + + if (stack_is_running) { + LOG_DEBUG("%s stack already brought up.\n", __func__); + return BT_STATUS_DONE; + } + + LOG_DEBUG("%s is bringing up the stack.", __func__); + hack_future = future_new(); + + btif_enable_bluetooth(); + + if (future_await(hack_future) != FUTURE_SUCCESS) { + stack_is_running = true; // So stack shutdown actually happens + event_shut_down_stack(); + return BT_STATUS_FAIL; + } + + stack_is_running = true; + LOG_DEBUG("%s finished", __func__); + btif_transfer_context(event_signal_stack_up, 0, NULL, 0, NULL); + return BT_STATUS_SUCCESS; +} + +static bt_status_t event_shut_down_stack(void) +{ + if (!stack_is_running) { + LOG_DEBUG("%s stack is already brought down.", __func__); + return BT_STATUS_DONE; + } + + LOG_DEBUG("%s is bringing down the stack.", __func__); + hack_future = future_new(); + stack_is_running = false; + + btif_disable_bluetooth(); + + future_await(hack_future); + + LOG_DEBUG("%s finished.", __func__); + btif_transfer_context(event_signal_stack_down, 0, NULL, 0, NULL); + return BT_STATUS_SUCCESS; +} + +static bt_status_t event_clean_up_stack(void) +{ + if (!stack_is_initialized) { + LOG_DEBUG("%s found the stack already in a clean state.", __func__); + return BT_STATUS_DONE; + } + + if (stack_is_running) { + event_shut_down_stack(); + } + + LOG_DEBUG("%s is cleaning up the stack.", __func__); + + stack_is_initialized = false; + + btif_shutdown_bluetooth(); + + return BT_STATUS_SUCCESS; +} + +static void event_signal_stack_up(UNUSED_ATTR uint16_t event, UNUSED_ATTR char *p_param) +{ + HAL_CBACK(bt_hal_cbacks, adapter_state_changed_cb, BT_STATE_ON); +} + +static void event_signal_stack_down(UNUSED_ATTR uint16_t event, UNUSED_ATTR char *p_param) +{ + HAL_CBACK(bt_hal_cbacks, adapter_state_changed_cb, BT_STATE_OFF); +} + +bt_status_t API_BTDM_InitStack(bt_callbacks_t *cb) +{ + return event_init_stack(cb); +} + +bt_status_t API_BTDM_EnableStack(void) +{ + return event_start_up_stack(); +} + +bt_status_t API_BTDM_DisableStack(void) +{ + return event_shut_down_stack(); +} + +bt_status_t API_BTDM_CleanUpStack(void) +{ + return event_clean_up_stack(); +} + +bool stack_manager_is_stack_running(void) +{ + return stack_is_running; +} + +future_t *stack_manager_get_hack_future(void) +{ + return hack_future; +} diff --git a/components/bt/bluedroid/profiles/std/gap/btif_gap.c b/components/bt/bluedroid/profiles/std/gap/btif_gap.c new file mode 100644 index 0000000000..1ac7f46921 --- /dev/null +++ b/components/bt/bluedroid/profiles/std/gap/btif_gap.c @@ -0,0 +1,36 @@ +#include "bt_gap.h" +#include "bta_api.h" +#include "bt_trace.h" + +bt_status_t API_BT_GapSetScanMode(bt_scan_mode_t mode) +{ + tBTA_DM_DISC disc_mode; + tBTA_DM_CONN conn_mode; + + switch(mode) { + case BT_SCAN_MODE_NONE: + disc_mode = BTA_DM_NON_DISC; + conn_mode = BTA_DM_NON_CONN; + break; + + case BT_SCAN_MODE_CONNECTABLE: + disc_mode = BTA_DM_NON_DISC; + conn_mode = BTA_DM_CONN; + break; + + case BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE: + disc_mode = BTA_DM_GENERAL_DISC; + conn_mode = BTA_DM_CONN; + break; + + default: + BTIF_TRACE_ERROR("invalid scan mode (0x%x)", mode); + return BT_STATUS_PARM_INVALID; + } + + BTIF_TRACE_EVENT("set property scan mode : %x", mode); + + BTA_DmSetVisibility(disc_mode, conn_mode, BTA_DM_IGNORE, BTA_DM_IGNORE); + + return BT_STATUS_SUCCESS; +} diff --git a/components/bt/bluedroid/profiles/std/include/bt_gap.h b/components/bt/bluedroid/profiles/std/include/bt_gap.h new file mode 100644 index 0000000000..21b793647d --- /dev/null +++ b/components/bt/bluedroid/profiles/std/include/bt_gap.h @@ -0,0 +1,13 @@ +#ifndef __BT_GAP_H__ +#define __BT_GAP_H__ +#include "bt_defs.h" + +typedef enum { + BT_SCAN_MODE_NONE, + BT_SCAN_MODE_CONNECTABLE, + BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE +} bt_scan_mode_t; + +bt_status_t API_BT_GapSetScanMode(bt_scan_mode_t mode); + +#endif /* __BT_GAP_H__ */ diff --git a/components/bt/bluedroid/profiles/std/include/bt_sdp.h b/components/bt/bluedroid/profiles/std/include/bt_sdp.h new file mode 100755 index 0000000000..0a7a6618fa --- /dev/null +++ b/components/bt/bluedroid/profiles/std/include/bt_sdp.h @@ -0,0 +1,146 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __BT_SDP_H__ +#define __BT_SDP_H__ + +#include +// #include "bluetooth.h" +#include "bt_defs.h" + +#define SDP_OPP_SUPPORTED_FORMATS_MAX_LENGTH 15 + +/** + * These events are handled by the state machine + */ +typedef enum { + SDP_TYPE_RAW, // Used to carry raw SDP search data for unknown UUIDs + SDP_TYPE_MAP_MAS, // Message Access Profile - Server + SDP_TYPE_MAP_MNS, // Message Access Profile - Client (Notification Server) + SDP_TYPE_PBAP_PSE, // Phone Book Profile - Server + SDP_TYPE_PBAP_PCE, // Phone Book Profile - Client + SDP_TYPE_OPP_SERVER, // Object Push Profile + SDP_TYPE_SAP_SERVER // SIM Access Profile +} bluetooth_sdp_types; + +typedef struct _bluetooth_sdp_hdr { + bluetooth_sdp_types type; + bt_uuid_t uuid; + uint32_t service_name_length; + char *service_name; + int32_t rfcomm_channel_number; + int32_t l2cap_psm; + int32_t profile_version; +} bluetooth_sdp_hdr; + +/** + * Some signals need additional pointers, hence we introduce a + * generic way to handle these pointers. + */ +typedef struct _bluetooth_sdp_hdr_overlay { + bluetooth_sdp_types type; + bt_uuid_t uuid; + uint32_t service_name_length; + char *service_name; + int32_t rfcomm_channel_number; + int32_t l2cap_psm; + int32_t profile_version; + + // User pointers, only used for some signals - see bluetooth_sdp_ops_record + int user1_ptr_len; + uint8_t *user1_ptr; + int user2_ptr_len; + uint8_t *user2_ptr; +} bluetooth_sdp_hdr_overlay; + +typedef struct _bluetooth_sdp_mas_record { + bluetooth_sdp_hdr_overlay hdr; + uint32_t mas_instance_id; + uint32_t supported_features; + uint32_t supported_message_types; +} bluetooth_sdp_mas_record; + +typedef struct _bluetooth_sdp_mns_record { + bluetooth_sdp_hdr_overlay hdr; + uint32_t supported_features; +} bluetooth_sdp_mns_record; + +typedef struct _bluetooth_sdp_pse_record { + bluetooth_sdp_hdr_overlay hdr; + uint32_t supported_features; + uint32_t supported_repositories; +} bluetooth_sdp_pse_record; + +typedef struct _bluetooth_sdp_pce_record { + bluetooth_sdp_hdr_overlay hdr; +} bluetooth_sdp_pce_record; + +typedef struct _bluetooth_sdp_ops_record { + bluetooth_sdp_hdr_overlay hdr; + int supported_formats_list_len; + uint8_t supported_formats_list[SDP_OPP_SUPPORTED_FORMATS_MAX_LENGTH]; +} bluetooth_sdp_ops_record; + +typedef struct _bluetooth_sdp_sap_record { + bluetooth_sdp_hdr_overlay hdr; +} bluetooth_sdp_sap_record; + +typedef union { + bluetooth_sdp_hdr_overlay hdr; + bluetooth_sdp_mas_record mas; + bluetooth_sdp_mns_record mns; + bluetooth_sdp_pse_record pse; + bluetooth_sdp_pce_record pce; + bluetooth_sdp_ops_record ops; + bluetooth_sdp_sap_record sap; +} bluetooth_sdp_record; + + +/** Callback for SDP search */ +typedef void (*btsdp_search_callback)(bt_status_t status, bt_bdaddr_t *bd_addr, uint8_t* uuid, int num_records, bluetooth_sdp_record *records); + +typedef struct { + /** Set to sizeof(btsdp_callbacks_t) */ + size_t size; + btsdp_search_callback sdp_search_cb; +} btsdp_callbacks_t; + +/** Register BT SDP search callbacks */ +bt_status_t API_BT_SdpInit(btsdp_callbacks_t *callbacks); + +/** Unregister BT SDP */ +bt_status_t API_BT_SdpDeinit(void); + +/** Search for SDP records with specific uuid on remote device */ +bt_status_t API_BT_SdpSearch(bt_bdaddr_t *bd_addr, const uint8_t* uuid); + +/** + * Use listen in the socket interface to create rfcomm and/or l2cap PSM channels, + * (without UUID and service_name and set the BTSOCK_FLAG_NO_SDP flag in flags). + * Then use createSdpRecord to create the SDP record associated with the rfcomm/l2cap channels. + * + * Returns a handle to the SDP record, which can be parsed to remove_sdp_record. + * + * record (in) The SDP record to create + * record_handle (out)The corresponding record handle will be written to this pointer. + */ +bt_status_t API_BT_SdpCreateRecord(bluetooth_sdp_record *record, int* record_handle); + +/** Remove a SDP record created by API_BT_SdpCreateRecord */ +bt_status_t API_BT_SdpRemoveRecord(int record_handle); + + +#endif /* __BT_SDP_H__ */ diff --git a/components/bt/bluedroid/profiles/std/sdp/btif_sdp.c b/components/bt/bluedroid/profiles/std/sdp/btif_sdp.c new file mode 100755 index 0000000000..58d042c975 --- /dev/null +++ b/components/bt/bluedroid/profiles/std/sdp/btif_sdp.c @@ -0,0 +1,183 @@ +/****************************************************************************** + * + * Copyright (C) 2014 Samsung System LSI + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************************/ + +/************************************************************************************ + * + * Filename: btif_sdp.c + * Description: SDP Bluetooth Interface. + * Implements the generic message handling and search functionality. + * References btif_sdp_server.c for SDP record creation. + * + ***********************************************************************************/ + +// #include +#include "bt_sdp.h" +#include +#include + +#define LOG_TAG "BTIF_SDP" +#include "btif_common.h" +#include "btif_util.h" +// #include "btif_profile_queue.h" +#include "bta_api.h" +#include "bta_sdp_api.h" + +/***************************************************************************** +** Functions implemented in sdp_server.c +******************************************************************************/ +bt_status_t sdp_server_init(); +void sdp_server_cleanup(); +bt_status_t create_sdp_record(bluetooth_sdp_record *records, int* record_handles); +bt_status_t remove_sdp_record(int record_handle); +void on_create_record_event(int handle); +void on_remove_record_event(int handle); + +// Utility functions: +int get_sdp_records_size(bluetooth_sdp_record* in_record, int count); +void copy_sdp_records(bluetooth_sdp_record* in_records, + bluetooth_sdp_record* out_records, int count); + + +/***************************************************************************** +** Static variables +******************************************************************************/ + +static btsdp_callbacks_t *bt_sdp_callbacks = NULL; + +static void btif_sdp_search_comp_evt(UINT16 event, char *p_param) +{ + tBTA_SDP_SEARCH_COMP *evt_data = (tBTA_SDP_SEARCH_COMP*) p_param; + bt_bdaddr_t addr; + BTIF_TRACE_DEBUG("%s: event = %d", __FUNCTION__, event); + + if (event != BTA_SDP_SEARCH_COMP_EVT) + return; + + bdcpy(addr.address, evt_data->remote_addr); + + HAL_CBACK(bt_sdp_callbacks, sdp_search_cb, evt_data->status, + &addr, (uint8_t*)(evt_data->uuid.uu.uuid128), + evt_data->record_count, evt_data->records); +} + +static void sdp_search_comp_copy_cb(UINT16 event, char *p_dest, char *p_src) +{ + tBTA_SDP_SEARCH_COMP *p_dest_data = (tBTA_SDP_SEARCH_COMP *) p_dest; + tBTA_SDP_SEARCH_COMP *p_src_data = (tBTA_SDP_SEARCH_COMP *) p_src; + + if (!p_src) + return; + + if (event != BTA_SDP_SEARCH_COMP_EVT) + return; + + memcpy(p_dest_data, p_src_data, sizeof(tBTA_SDP_SEARCH_COMP)); + + copy_sdp_records(p_src_data->records, p_dest_data->records, p_src_data->record_count); +} + +static void sdp_dm_cback(tBTA_SDP_EVT event, tBTA_SDP *p_data, void *user_data) +{ + switch (event) + { + case BTA_SDP_SEARCH_COMP_EVT: + { + int size = sizeof(tBTA_SDP); + size += get_sdp_records_size(p_data->sdp_search_comp.records, + p_data->sdp_search_comp.record_count); + + /* need to deep copy the record content */ + btif_transfer_context(btif_sdp_search_comp_evt, event, + (char*)p_data, size, sdp_search_comp_copy_cb); + break; + } + case BTA_SDP_CREATE_RECORD_USER_EVT: + { + on_create_record_event((int)user_data); + break; + } + case BTA_SDP_REMOVE_RECORD_USER_EVT: + { + on_remove_record_event((int)user_data); + break; + } + default: + break; + } +} + +bt_status_t API_BT_SdpInit(btsdp_callbacks_t *callbacks) +{ + BTIF_TRACE_DEBUG("Sdp Search %s", __FUNCTION__); + + bt_sdp_callbacks = callbacks; + sdp_server_init(); + + btif_enable_service(BTA_SDP_SERVICE_ID); + + return BT_STATUS_SUCCESS; +} + +bt_status_t API_BT_SdpDeinit(void) +{ + BTIF_TRACE_DEBUG("Sdp Search %s", __FUNCTION__); + + bt_sdp_callbacks = NULL; + sdp_server_cleanup(); + btif_disable_service(BTA_SDP_SERVICE_ID); + + return BT_STATUS_SUCCESS; +} + + +bt_status_t API_BT_SdpSearch(bt_bdaddr_t *bd_addr, const uint8_t* uuid) +{ + bdstr_t bdstr; + tSDP_UUID sdp_uuid; + sdp_uuid.len = 16; + memcpy(sdp_uuid.uu.uuid128, uuid, sizeof(sdp_uuid.uu.uuid128)); + + BTA_SdpSearch(bd_addr->address, &sdp_uuid); + + return BT_STATUS_SUCCESS; +} + +/******************************************************************************* +** +** Function btif_sdp_execute_service +** +** Description Initializes/Shuts down the service +** +** Returns BT_STATUS_SUCCESS on success, BT_STATUS_FAIL otherwise +** +*******************************************************************************/ +bt_status_t btif_sdp_execute_service(BOOLEAN b_enable) +{ + BTIF_TRACE_DEBUG("%s enable:%d", __FUNCTION__, b_enable); + + if (b_enable) + { + BTA_SdpEnable(sdp_dm_cback); + } + else + { + /* This is called on BT disable so no need to extra cleanup */ + } + return BT_STATUS_SUCCESS; +} + diff --git a/components/bt/bluedroid/profiles/std/sdp/btif_sdp_server.c b/components/bt/bluedroid/profiles/std/sdp/btif_sdp_server.c new file mode 100755 index 0000000000..e87a331d05 --- /dev/null +++ b/components/bt/bluedroid/profiles/std/sdp/btif_sdp_server.c @@ -0,0 +1,783 @@ +/****************************************************************************** + * + * Copyright (C) 2014 Samsung System LSI + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************************/ + +/************************************************************************************ + * + * Filename: btif_sdp_server.c + * Description: SDP server Bluetooth Interface to create and remove SDP records. + * To be used in combination with the RFCOMM/L2CAP(LE) sockets. + * + * + ***********************************************************************************/ + +// #include +#include "bt_sdp.h" +#include +#include +// #include + +#define LOG_TAG "BTIF_SDP_SERVER" +#include "allocator.h" +#include "btif_common.h" +// #include "btif_util.h" +#include "bta_sdp_api.h" +#include "bta_sys.h" +#include "utl.h" +// #include "btif_sock_util.h" + +// static pthread_mutex_t sdp_lock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; +static pthread_mutex_t sdp_lock; + +/** + * The need for a state variable have been reduced to two states. + * The remaining state control is handled by program flow + */ +typedef enum { + SDP_RECORD_FREE = 0, + SDP_RECORD_ALLOCED, +} sdp_state_t; + +typedef struct { + sdp_state_t state; + int sdp_handle; + bluetooth_sdp_record* record_data; +} sdp_slot_t; + +#define MAX_SDP_SLOTS 128 +static sdp_slot_t sdp_slots[MAX_SDP_SLOTS]; + +/***************************************************************************** + * LOCAL Functions + *****************************************************************************/ +static int add_maps_sdp(const bluetooth_sdp_mas_record* rec); +static int add_mapc_sdp(const bluetooth_sdp_mns_record* rec); +static int add_pbaps_sdp(const bluetooth_sdp_pse_record* rec); +static int add_opps_sdp(const bluetooth_sdp_ops_record* rec); +static int add_saps_sdp(const bluetooth_sdp_sap_record* rec); +bt_status_t remove_sdp_record(int record_id); +static int free_sdp_slot(int id); + +/****************************************************************************** + * WARNING: Functions below are not called in BTU context. + * Introduced to make it possible to create SDP records from JAVA with both a + * RFCOMM channel and a L2CAP PSM. + * Overall architecture: + * 1) JAVA calls createRecord() which returns a pseudo ID which at a later + * point will be linked to a specific SDP handle. + * 2) createRecord() requests the BTU task(thread) to call a callback in SDP + * which creates the actual record, and updates the ID<->SDPHandle map + * based on the ID beeing passed to BTA as user_data. + *****************************************************************************/ + +static void init_sdp_slots() +{ + int i; + memset(sdp_slots, 0, sizeof(sdp_slot_t)*MAX_SDP_SLOTS); + /* if SDP_RECORD_FREE is zero - no need to set the value */ + if(SDP_RECORD_FREE != 0) { + for(i = 0; i < MAX_SDP_SLOTS; i++) + { + sdp_slots[i].state = SDP_RECORD_FREE; + } + } +} + +bt_status_t sdp_server_init() +{ + BTIF_TRACE_DEBUG("Sdp Server %s", __FUNCTION__); + pthread_mutex_init(&sdp_lock, NULL); + init_sdp_slots(); + return BT_STATUS_SUCCESS; +} + +void sdp_server_cleanup() +{ + BTIF_TRACE_DEBUG("Sdp Server %s", __FUNCTION__); + pthread_mutex_lock(&sdp_lock); + int i; + for(i = 0; i < MAX_SDP_SLOTS; i++) + { + /*remove_sdp_record(i); we cannot send messages to the other threads, since they might + * have been shut down already. Just do local cleanup. + */ + free_sdp_slot(i); + } + pthread_mutex_unlock(&sdp_lock); + pthread_mutex_destroy(&sdp_lock); +} + +int get_sdp_records_size(bluetooth_sdp_record* in_record, int count) { + bluetooth_sdp_record* record = in_record; + int records_size = 0; + int i; + for(i=0; ihdr.service_name_length; + if(record->hdr.service_name_length > 0){ + records_size++; /* + '\0' termination of string */ + } + records_size += record->hdr.user1_ptr_len; + records_size += record->hdr.user2_ptr_len; + } + return records_size; +} + +/* Deep copy all content of in_records into out_records. + * out_records must point to a chunk of memory large enough to contain all + * the data. Use getSdpRecordsSize() to calculate the needed size. */ +void copy_sdp_records(bluetooth_sdp_record* in_records, + bluetooth_sdp_record* out_records, int count) { + int i; + bluetooth_sdp_record* in_record; + bluetooth_sdp_record* out_record; + char* free_ptr = (char*)(&out_records[count]); /* set pointer to after the last entry */ + + for(i=0; ihdr.service_name == NULL || in_record->hdr.service_name_length == 0) { + out_record->hdr.service_name = NULL; + out_record->hdr.service_name_length = 0; + } else { + out_record->hdr.service_name = free_ptr; // Update service_name pointer + // Copy string + memcpy(free_ptr, in_record->hdr.service_name, in_record->hdr.service_name_length); + free_ptr += in_record->hdr.service_name_length; + *(free_ptr) = '\0'; // Set '\0' termination of string + free_ptr++; + } + if(in_record->hdr.user1_ptr != NULL) { + out_record->hdr.user1_ptr = (UINT8*)free_ptr; // Update pointer + memcpy(free_ptr, in_record->hdr.user1_ptr, in_record->hdr.user1_ptr_len); // Copy content + free_ptr += in_record->hdr.user1_ptr_len; + } + if(in_record->hdr.user2_ptr != NULL) { + out_record->hdr.user2_ptr = (UINT8*)free_ptr; // Update pointer + memcpy(free_ptr, in_record->hdr.user2_ptr, in_record->hdr.user2_ptr_len); // Copy content + free_ptr += in_record->hdr.user2_ptr_len; + } + } + return; +} + +/* Reserve a slot in sdp_slots, copy data and set a reference to the copy. + * The record_data will contain both the record and any data pointed to by + * the record. + * Currently this covers: + * service_name string, + * user1_ptr and + * user2_ptr. */ +static int alloc_sdp_slot(bluetooth_sdp_record* in_record) { + int i; + char* tmp_ptr = NULL; + int record_size = get_sdp_records_size(in_record, 1); + bluetooth_sdp_record* record = osi_malloc(record_size); + + copy_sdp_records(in_record, record, 1); + + /* We are optimists here, and preallocate the record. + * This is to reduce the time we hold the sdp_lock. */ + pthread_mutex_lock(&sdp_lock); + for(i = 0; i < MAX_SDP_SLOTS; i++) + { + if(sdp_slots[i].state == SDP_RECORD_FREE) { + sdp_slots[i].state = SDP_RECORD_ALLOCED; + sdp_slots[i].record_data = record; + break; + } + } + pthread_mutex_unlock(&sdp_lock); + if(i >= MAX_SDP_SLOTS) { + APPL_TRACE_ERROR("%s() failed - no more free slots!", __func__); + /* Rearly the optimist is too optimistic, and cleanup is needed...*/ + osi_free(record); + return -1; + } + return i; +} + +static int free_sdp_slot(int id) { + int handle = -1; + bluetooth_sdp_record* record = NULL; + if(id >= MAX_SDP_SLOTS) { + APPL_TRACE_ERROR("%s() failed - id %d is invalid", __func__, id); + return handle; + } + pthread_mutex_lock(&sdp_lock); + handle = sdp_slots[id].sdp_handle; + sdp_slots[id].sdp_handle = 0; + if(sdp_slots[id].state != SDP_RECORD_FREE) + { + /* safe a copy of the pointer, and free after unlock() */ + record = sdp_slots[id].record_data; + } + sdp_slots[id].state = SDP_RECORD_FREE; + pthread_mutex_unlock(&sdp_lock); + + if(record != NULL) { + osi_free(record); + } else { + // Record have already been freed + handle = -1; + } + return handle; +} + +/*** + * Use this to get a reference to a SDP slot AND change the state to + * SDP_RECORD_CREATE_INITIATED. + */ +static const sdp_slot_t* start_create_sdp(int id) { + sdp_slot_t* sdp_slot; + if(id >= MAX_SDP_SLOTS) { + APPL_TRACE_ERROR("%s() failed - id %d is invalid", __func__, id); + return NULL; + } + pthread_mutex_lock(&sdp_lock); + if(sdp_slots[id].state == SDP_RECORD_ALLOCED) { + sdp_slot = &(sdp_slots[id]); + } else { + /* The record have been removed before this event occurred - e.g. deinit */ + sdp_slot = NULL; + } + pthread_mutex_unlock(&sdp_lock); + if(sdp_slot == NULL) { + APPL_TRACE_ERROR("%s() failed - state for id %d is " + "sdp_slots[id].state = %d expected %d", __func__, + id, sdp_slots[id].state, SDP_RECORD_ALLOCED); + } + return sdp_slot; +} + +static void set_sdp_handle(int id, int handle) { + pthread_mutex_lock(&sdp_lock); + sdp_slots[id].sdp_handle = handle; + pthread_mutex_unlock(&sdp_lock); + BTIF_TRACE_DEBUG("%s() id=%d to handle=0x%08x", __FUNCTION__, id, handle); +} + +bt_status_t API_BT_SdpCreateRecord(bluetooth_sdp_record *record, int* record_handle) { + int handle; + + handle = alloc_sdp_slot(record); + BTIF_TRACE_DEBUG("%s() handle = 0x%08x", __FUNCTION__, handle); + + if(handle < 0) + return BT_STATUS_FAIL; + + BTA_SdpCreateRecordByUser((void*) handle); + + *record_handle = handle; + + return BT_STATUS_SUCCESS; +} + +bt_status_t API_BT_SdpRemoveRecord(int record_handle) { + int handle; + + /* Get the Record handle, and free the slot */ + handle = free_sdp_slot(record_handle); + BTIF_TRACE_DEBUG("Sdp Server %s id=%d to handle=0x%08x", + __FUNCTION__, record_handle, handle); + + /* Pass the actual record handle */ + if(handle > 0) { + BTA_SdpRemoveRecordByUser((void*) handle); + return BT_STATUS_SUCCESS; + } + BTIF_TRACE_DEBUG("Sdp Server %s - record already removed - or never created", __FUNCTION__); + return BT_STATUS_FAIL; +} + + +/****************************************************************************** + * CALLBACK FUNCTIONS + * Called in BTA context to create/remove SDP records. + ******************************************************************************/ + +void on_create_record_event(int id) { + /* + * 1) Fetch the record pointer, and change its state? + * 2) switch on the type to create the correct record + * 3) Update state on completion + * 4) What to do at fail? + * */ + BTIF_TRACE_DEBUG("Sdp Server %s", __FUNCTION__); + const sdp_slot_t* sdp_slot = start_create_sdp(id); + /* In the case we are shutting down, sdp_slot is NULL */ + if(sdp_slot != NULL) { + bluetooth_sdp_record* record = sdp_slot->record_data; + int handle = -1; + switch(record->hdr.type) { + case SDP_TYPE_MAP_MAS: + handle = add_maps_sdp(&record->mas); + break; + case SDP_TYPE_MAP_MNS: + handle = add_mapc_sdp(&record->mns); + break; + case SDP_TYPE_PBAP_PSE: + handle = add_pbaps_sdp(&record->pse); + break; + case SDP_TYPE_OPP_SERVER: + handle = add_opps_sdp(&record->ops); + break; + case SDP_TYPE_SAP_SERVER: + handle = add_saps_sdp(&record->sap); + break; + case SDP_TYPE_PBAP_PCE: + // break; not yet supported + default: + BTIF_TRACE_DEBUG("Record type %d is not supported",record->hdr.type); + break; + } + if(handle != -1) { + set_sdp_handle(id, handle); + } + } +} + +void on_remove_record_event(int handle) { + BTIF_TRACE_DEBUG("Sdp Server %s", __FUNCTION__); + + // User data carries the actual SDP handle, not the ID. + if(handle != -1 && handle != 0) { + BOOLEAN result; + result = SDP_DeleteRecord( handle ); + if(result == FALSE) { + BTIF_TRACE_ERROR(" Unable to remove handle 0x%08x", handle); + } + } +} + +/**** + * Below the actual functions accessing BTA context data - hence only call from BTA context! + */ + +/* Create a MAP MAS SDP record based on information stored in a bluetooth_sdp_mas_record */ +static int add_maps_sdp(const bluetooth_sdp_mas_record* rec) +{ + + tSDP_PROTOCOL_ELEM protoList [3]; + UINT16 service = UUID_SERVCLASS_MESSAGE_ACCESS; + UINT16 browse = UUID_SERVCLASS_PUBLIC_BROWSE_GROUP; + BOOLEAN status = TRUE; + UINT32 sdp_handle = 0; + UINT8 temp[4]; + UINT8* p_temp = temp; + + APPL_TRACE_DEBUG("%s(): MASID = 0x%02x, scn 0x%02x, psm = 0x%04x\n service name %s", __func__, + rec->mas_instance_id, rec->hdr.rfcomm_channel_number, + rec->hdr.l2cap_psm, rec->hdr.service_name); + + APPL_TRACE_DEBUG(" msg_types: 0x%02x, feature_bits: 0x%08x", + rec->supported_message_types, rec->supported_features); + + if ((sdp_handle = SDP_CreateRecord()) == 0) + { + APPL_TRACE_ERROR("%s() - Unable to register MAPS Service", __func__); + return sdp_handle; + } + + /* add service class */ + status &= SDP_AddServiceClassIdList(sdp_handle, 1, &service); + memset( protoList, 0 , 3*sizeof(tSDP_PROTOCOL_ELEM) ); + + /* 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] = rec->hdr.rfcomm_channel_number; + protoList[2].protocol_uuid = UUID_PROTOCOL_OBEX; + protoList[2].num_params = 0; + status &= SDP_AddProtocolList(sdp_handle, 3, protoList); + + /* Add a name entry */ + status &= SDP_AddAttribute(sdp_handle, + (UINT16)ATTR_ID_SERVICE_NAME, + (UINT8)TEXT_STR_DESC_TYPE, + (UINT32)(rec->hdr.service_name_length + 1), + (UINT8 *)rec->hdr.service_name); + + /* Add in the Bluetooth Profile Descriptor List */ + status &= SDP_AddProfileDescriptorList(sdp_handle, + UUID_SERVCLASS_MAP_PROFILE, + rec->hdr.profile_version); + + /* Add MAS instance ID */ + status &= SDP_AddAttribute(sdp_handle, ATTR_ID_MAS_INSTANCE_ID, UINT_DESC_TYPE, + (UINT32)1, (UINT8*)&rec->mas_instance_id); + + /* Add supported message types */ + status &= SDP_AddAttribute(sdp_handle, ATTR_ID_SUPPORTED_MSG_TYPE, UINT_DESC_TYPE, + (UINT32)1, (UINT8*)&rec->supported_message_types); + + /* Add supported feature */ + UINT32_TO_BE_STREAM(p_temp, rec->supported_features); + status &= SDP_AddAttribute(sdp_handle, ATTR_ID_MAP_SUPPORTED_FEATURES, + UINT_DESC_TYPE, (UINT32)4, temp); + + /* Add the L2CAP PSM if present */ + if(rec->hdr.l2cap_psm != -1) { + p_temp = temp;// The macro modifies p_temp, hence rewind. + UINT16_TO_BE_STREAM(p_temp, rec->hdr.l2cap_psm); + status &= SDP_AddAttribute(sdp_handle, ATTR_ID_GOEP_L2CAP_PSM, + UINT_DESC_TYPE, (UINT32)2, temp); + } + + /* Make the service browseable */ + status &= SDP_AddUuidSequence (sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1, &browse); + + if (!status) + { + SDP_DeleteRecord(sdp_handle); + sdp_handle = 0; + APPL_TRACE_ERROR("%s() FAILED", __func__); + } + else + { + bta_sys_add_uuid(service); /* UUID_SERVCLASS_MESSAGE_ACCESS */ + APPL_TRACE_DEBUG("%s(): SDP Registered (handle 0x%08x)", __func__, sdp_handle); + } + return sdp_handle; +} + +/* Create a MAP MNS SDP record based on information stored in a bluetooth_sdp_mns_record */ +static int add_mapc_sdp(const bluetooth_sdp_mns_record* rec) +{ + + tSDP_PROTOCOL_ELEM protoList [3]; + UINT16 service = UUID_SERVCLASS_MESSAGE_NOTIFICATION; + UINT16 browse = UUID_SERVCLASS_PUBLIC_BROWSE_GROUP; + BOOLEAN status = TRUE; + UINT32 sdp_handle = 0; + UINT8 temp[4]; + UINT8* p_temp = temp; + + APPL_TRACE_DEBUG("%s(): scn 0x%02x, psm = 0x%04x\n service name %s", __func__, + rec->hdr.rfcomm_channel_number, rec->hdr.l2cap_psm, rec->hdr.service_name); + + APPL_TRACE_DEBUG(" feature_bits: 0x%08x", rec->supported_features); + + if ((sdp_handle = SDP_CreateRecord()) == 0) + { + APPL_TRACE_ERROR("%s(): Unable to register MAP Notification Service", __func__); + return sdp_handle; + } + + /* add service class */ + status &= SDP_AddServiceClassIdList(sdp_handle, 1, &service); + memset( protoList, 0 , 3*sizeof(tSDP_PROTOCOL_ELEM) ); + + /* 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] = rec->hdr.rfcomm_channel_number; + protoList[2].protocol_uuid = UUID_PROTOCOL_OBEX; + protoList[2].num_params = 0; + status &= SDP_AddProtocolList(sdp_handle, 3, protoList); + + /* Add a name entry */ + status &= SDP_AddAttribute(sdp_handle, + (UINT16)ATTR_ID_SERVICE_NAME, + (UINT8)TEXT_STR_DESC_TYPE, + (UINT32)(rec->hdr.service_name_length + 1), + (UINT8 *)rec->hdr.service_name); + + /* Add in the Bluetooth Profile Descriptor List */ + status &= SDP_AddProfileDescriptorList(sdp_handle, + UUID_SERVCLASS_MAP_PROFILE, + rec->hdr.profile_version); + + /* Add supported feature */ + UINT32_TO_BE_STREAM(p_temp, rec->supported_features); + status &= SDP_AddAttribute(sdp_handle, ATTR_ID_MAP_SUPPORTED_FEATURES, + UINT_DESC_TYPE, (UINT32)4, temp); + + /* Add the L2CAP PSM if present */ + if(rec->hdr.l2cap_psm != -1) { + p_temp = temp;// The macro modifies p_temp, hence rewind. + UINT16_TO_BE_STREAM(p_temp, rec->hdr.l2cap_psm); + status &= SDP_AddAttribute(sdp_handle, ATTR_ID_GOEP_L2CAP_PSM, + UINT_DESC_TYPE, (UINT32)2, temp); + } + + /* Make the service browseable */ + status &= SDP_AddUuidSequence (sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1, &browse); + + if (!status) + { + SDP_DeleteRecord(sdp_handle); + sdp_handle = 0; + APPL_TRACE_ERROR("%s() FAILED", __func__); + } + else + { + bta_sys_add_uuid(service); /* UUID_SERVCLASS_MESSAGE_ACCESS */ + APPL_TRACE_DEBUG("%s(): SDP Registered (handle 0x%08x)", __func__, sdp_handle); + } + return sdp_handle; +} + +/* Create a PBAP Server SDP record based on information stored in a bluetooth_sdp_pse_record */ +static int add_pbaps_sdp(const bluetooth_sdp_pse_record* rec) +{ + + tSDP_PROTOCOL_ELEM protoList [3]; + UINT16 service = UUID_SERVCLASS_PBAP_PSE; + UINT16 browse = UUID_SERVCLASS_PUBLIC_BROWSE_GROUP; + BOOLEAN status = TRUE; + UINT32 sdp_handle = 0; + UINT8 temp[4]; + UINT8* p_temp = temp; + + APPL_TRACE_DEBUG("%s(): scn 0x%02x, psm = 0x%04x\n service name %s", __func__, + rec->hdr.rfcomm_channel_number, rec->hdr.l2cap_psm, rec->hdr.service_name); + + APPL_TRACE_DEBUG(" supported_repositories: 0x%08x, feature_bits: 0x%08x", + rec->supported_repositories, rec->supported_features); + + if ((sdp_handle = SDP_CreateRecord()) == 0) + { + APPL_TRACE_ERROR("%s(): Unable to register PBAP Server Service", __func__); + return sdp_handle; + } + + /* add service class */ + status &= SDP_AddServiceClassIdList(sdp_handle, 1, &service); + memset( protoList, 0 , 3*sizeof(tSDP_PROTOCOL_ELEM) ); + + /* 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] = rec->hdr.rfcomm_channel_number; + protoList[2].protocol_uuid = UUID_PROTOCOL_OBEX; + protoList[2].num_params = 0; + status &= SDP_AddProtocolList(sdp_handle, 3, protoList); + + /* Add a name entry */ + status &= SDP_AddAttribute(sdp_handle, + (UINT16)ATTR_ID_SERVICE_NAME, + (UINT8)TEXT_STR_DESC_TYPE, + (UINT32)(rec->hdr.service_name_length + 1), + (UINT8 *)rec->hdr.service_name); + + /* Add in the Bluetooth Profile Descriptor List */ + status &= SDP_AddProfileDescriptorList(sdp_handle, + UUID_SERVCLASS_PHONE_ACCESS, + rec->hdr.profile_version); + + /* Add supported repositories 1 byte */ + status &= SDP_AddAttribute(sdp_handle, ATTR_ID_SUPPORTED_REPOSITORIES, + UINT_DESC_TYPE, (UINT32)1, (UINT8*)&rec->supported_repositories); + + /* Add supported feature 4 bytes*/ + UINT32_TO_BE_STREAM(p_temp, rec->supported_features); + status &= SDP_AddAttribute(sdp_handle, ATTR_ID_PBAP_SUPPORTED_FEATURES, + UINT_DESC_TYPE, (UINT32)4, temp); + + /* Add the L2CAP PSM if present */ + if(rec->hdr.l2cap_psm != -1) { + p_temp = temp;// The macro modifies p_temp, hence rewind. + UINT16_TO_BE_STREAM(p_temp, rec->hdr.l2cap_psm); + status &= SDP_AddAttribute(sdp_handle, ATTR_ID_GOEP_L2CAP_PSM, + UINT_DESC_TYPE, (UINT32)2, temp); + } + + /* Make the service browseable */ + status &= SDP_AddUuidSequence (sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1, &browse); + + if (!status) + { + SDP_DeleteRecord(sdp_handle); + sdp_handle = 0; + APPL_TRACE_ERROR("%s() FAILED", __func__); + } + else + { + bta_sys_add_uuid(service); /* UUID_SERVCLASS_MESSAGE_ACCESS */ + APPL_TRACE_DEBUG("%s(): SDP Registered (handle 0x%08x)", __func__, sdp_handle); + } + return sdp_handle; +} + + +/* Create a OPP Server SDP record based on information stored in a bluetooth_sdp_ops_record */ +static int add_opps_sdp(const bluetooth_sdp_ops_record* rec) +{ + + tSDP_PROTOCOL_ELEM protoList [3]; + UINT16 service = UUID_SERVCLASS_OBEX_OBJECT_PUSH; + UINT16 browse = UUID_SERVCLASS_PUBLIC_BROWSE_GROUP; + UINT8 type_len[rec->supported_formats_list_len]; + UINT8 desc_type[rec->supported_formats_list_len]; + UINT8 *type_value[rec->supported_formats_list_len]; + BOOLEAN status = TRUE; + UINT32 sdp_handle = 0; + UINT8 temp[4]; + UINT8* p_temp = temp; + tBTA_UTL_COD cod; + int i,j; + + APPL_TRACE_DEBUG("%s(): scn 0x%02x, psm = 0x%04x\n service name %s", __func__, + rec->hdr.rfcomm_channel_number, rec->hdr.l2cap_psm, rec->hdr.service_name); + + APPL_TRACE_DEBUG(" supported formats count: %d", + rec->supported_formats_list_len); + + if ((sdp_handle = SDP_CreateRecord()) == 0) + { + APPL_TRACE_ERROR("%s(): Unable to register Object Push Server Service", __func__); + return sdp_handle; + } + + /* add service class */ + status &= SDP_AddServiceClassIdList(sdp_handle, 1, &service); + memset( protoList, 0 , 3*sizeof(tSDP_PROTOCOL_ELEM) ); + + /* 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] = rec->hdr.rfcomm_channel_number; + protoList[2].protocol_uuid = UUID_PROTOCOL_OBEX; + protoList[2].num_params = 0; + status &= SDP_AddProtocolList(sdp_handle, 3, protoList); + + /* Add a name entry */ + status &= SDP_AddAttribute(sdp_handle, + (UINT16)ATTR_ID_SERVICE_NAME, + (UINT8)TEXT_STR_DESC_TYPE, + (UINT32)(rec->hdr.service_name_length + 1), + (UINT8 *)rec->hdr.service_name); + + /* Add in the Bluetooth Profile Descriptor List */ + status &= SDP_AddProfileDescriptorList(sdp_handle, + UUID_SERVCLASS_OBEX_OBJECT_PUSH, + rec->hdr.profile_version); + + /* add sequence for supported types */ + for (i = 0, j = 0; i < rec->supported_formats_list_len; i++) + { + type_value[j] = (UINT8 *) &rec->supported_formats_list[i]; + desc_type[j] = UINT_DESC_TYPE; + type_len[j++] = 1; + } + + status &= SDP_AddSequence(sdp_handle, (UINT16) ATTR_ID_SUPPORTED_FORMATS_LIST, + (UINT8) rec->supported_formats_list_len, desc_type, type_len, type_value); + + /* Add the L2CAP PSM if present */ + if(rec->hdr.l2cap_psm != -1) { + p_temp = temp;// The macro modifies p_temp, hence rewind. + UINT16_TO_BE_STREAM(p_temp, rec->hdr.l2cap_psm); + status &= SDP_AddAttribute(sdp_handle, ATTR_ID_GOEP_L2CAP_PSM, + UINT_DESC_TYPE, (UINT32)2, temp); + } + + /* Make the service browseable */ + status &= SDP_AddUuidSequence (sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1, &browse); + + if (!status) + { + SDP_DeleteRecord(sdp_handle); + sdp_handle = 0; + APPL_TRACE_ERROR("%s() FAILED", __func__); + } + else + { + /* set class of device */ + cod.service = BTM_COD_SERVICE_OBJ_TRANSFER; + utl_set_device_class(&cod, BTA_UTL_SET_COD_SERVICE_CLASS); + + bta_sys_add_uuid(service); /* UUID_SERVCLASS_OBEX_OBJECT_PUSH */ + APPL_TRACE_DEBUG("%s(): SDP Registered (handle 0x%08x)", __func__, sdp_handle); + } + return sdp_handle; +} + +// Create a Sim Access Profile SDP record based on information stored in a bluetooth_sdp_sap_record. +static int add_saps_sdp(const bluetooth_sdp_sap_record* rec) +{ + tSDP_PROTOCOL_ELEM protoList [2]; + UINT16 services[2]; + UINT16 browse = UUID_SERVCLASS_PUBLIC_BROWSE_GROUP; + BOOLEAN status = TRUE; + UINT32 sdp_handle = 0; + + APPL_TRACE_DEBUG("%s(): scn 0x%02x, service name %s", __func__, + rec->hdr.rfcomm_channel_number, rec->hdr.service_name); + + if ((sdp_handle = SDP_CreateRecord()) == 0) + { + APPL_TRACE_ERROR("%s(): Unable to register SAPS Service", __func__); + return sdp_handle; + } + + services[0] = UUID_SERVCLASS_SAP; + services[1] = UUID_SERVCLASS_GENERIC_TELEPHONY; + + // add service class + status &= SDP_AddServiceClassIdList(sdp_handle, 2, services); + memset(protoList, 0, 2 * sizeof(tSDP_PROTOCOL_ELEM)); + + // 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] = rec->hdr.rfcomm_channel_number; + status &= SDP_AddProtocolList(sdp_handle, 2, protoList); + + // Add a name entry + status &= SDP_AddAttribute(sdp_handle, + (UINT16)ATTR_ID_SERVICE_NAME, + (UINT8)TEXT_STR_DESC_TYPE, + (UINT32)(rec->hdr.service_name_length + 1), + (UINT8 *)rec->hdr.service_name); + + // Add in the Bluetooth Profile Descriptor List + status &= SDP_AddProfileDescriptorList(sdp_handle, + UUID_SERVCLASS_SAP, + rec->hdr.profile_version); + + // Make the service browseable + status &= SDP_AddUuidSequence (sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1, &browse); + + if (!status) + { + SDP_DeleteRecord(sdp_handle); + sdp_handle = 0; + APPL_TRACE_ERROR("%s(): FAILED deleting record", __func__); + } + else + { + bta_sys_add_uuid(UUID_SERVCLASS_SAP); + APPL_TRACE_DEBUG("%s(): SDP Registered (handle 0x%08x)", __func__, sdp_handle); + } + return sdp_handle; +} + diff --git a/components/bt/bluedroid/stack/btu/btu_init.c b/components/bt/bluedroid/stack/btu/btu_init.c index cd0af18ad8..9ac18a86a8 100755 --- a/components/bt/bluedroid/stack/btu/btu_init.c +++ b/components/bt/bluedroid/stack/btu/btu_init.c @@ -44,7 +44,7 @@ #endif #endif -extern fixed_queue_t *btif_msg_queue; +// extern fixed_queue_t *btif_msg_queue; // Communication queue from bta thread to bt_workqueue. fixed_queue_t *btu_bta_msg_queue; diff --git a/components/bt/component.mk b/components/bt/component.mk index 8fc144b42d..2683703d9f 100644 --- a/components/bt/component.mk +++ b/components/bt/component.mk @@ -60,6 +60,7 @@ COMPONENT_SRCDIRS := bluedroid/bta/dm \ bluedroid/profiles/std/hid \ bluedroid/profiles/std/hid_le \ bluedroid/profiles/std/rfcomm \ + bluedroid/profiles/std/sdp \ bluedroid/profiles/std \ bluedroid/profiles \ bluedroid/stack/btm \