123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291 |
- /*
- * Copyright (c) 2019 Actions Semi Co., Inc.
- *
- * SPDX-License-Identifier: Apache-2.0
- */
- /**
- * @file
- * @brief bt manager discover.
- */
- #define SYS_LOG_NO_NEWLINE
- #define SYS_LOG_DOMAIN "bt discover"
- #include <os_common_api.h>
- #include <zephyr.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include <msg_manager.h>
- #include <mem_manager.h>
- #include <bt_manager.h>
- #include "bt_manager_inner.h"
- #include <sys_event.h>
- #include <sys_manager.h>
- #include <btservice_api.h>
- #include <acts_bluetooth/host_interface.h>
- #include "bt_porting_inner.h"
- #define BT_DISCOVER_LIST_MAX 4
- struct bt_discover_list {
- bd_address_t addr;
- int8_t rssi;
- uint8_t valid:1;
- uint8_t wait_req_name:1;
- };
- struct bt_discover_info {
- uint8_t discovering:1;
- btsrv_discover_result_cb cb;
- struct bt_discover_list dev_list[BT_DISCOVER_LIST_MAX];
- } discover_info;
- static void bt_discover_check_finish(void);
- static OS_MUTEX_DEFINE(bt_discover_mutex);
- static struct bt_discover_info *p_discover = &discover_info;
- /*
- Minor Device Class field - Audio/Video Major Class
- 7 6 5 4 3 2 Minor Device Class bit no. of CoD
- 0 0 0 0 0 0 Uncategorized, code not assigned
- 0 0 0 0 0 1 Wearable Headset Device
- 0 0 0 0 1 0 Hands-free Device
- 0 0 0 0 1 1 (Reserved)
- 0 0 0 1 0 0 Microphone
- 0 0 0 1 0 1 Loudspeaker
- 0 0 0 1 1 0 Headphones
- 0 0 0 1 1 1 Portable Audio
- 0 0 1 0 0 0 Car audio
- 0 0 1 0 0 1 Set-top box
- 0 0 1 0 1 0 HiFi Audio Device
- 0 0 1 0 1 1 VCR
- 0 0 1 1 0 0 Video Camera
- 0 0 1 1 0 1 Camcorder
- 0 0 1 1 1 0 Video Monitor
- 0 0 1 1 1 1 Video Display and Loudspeaker
- 0 1 0 0 0 0 Video Conferencing
- 0 1 0 0 0 1 (Reserved)
- 0 1 0 0 1 0 Gaming/Toy
- */
- #define BT_COD_RENDERING_SERVICE_BTI (0x1 << 18)
- #define BT_COD_AUDIO_SERVICE_BTI (0x1 << 21)
- #define BT_COD_MAJOR_DC_MASK (0x1F00)
- #define BT_COD_MAJOR_DC_AUDIO (0x400)
- #define BT_COD_MAJOR_DC_WEARABLE (0x700)
- #define BT_COD_MINOR_DC_MASK (0xFC)
- static const uint8_t bt_support_mdc[] = {0x04, 0x14, 0x18, 0x1C, 0x20, 0x28};
- static bool bt_discover_transmit_check_device(int cod)
- {
- uint8_t mdc, i;
- #ifdef CONFIG_OTA_PRODUCT_SUPPORT
- if ((cod & BT_COD_MAJOR_DC_WEARABLE) != BT_COD_MAJOR_DC_WEARABLE) {
- return false;
- }
- #else
- if (!(cod & (BT_COD_AUDIO_SERVICE_BTI | BT_COD_RENDERING_SERVICE_BTI))) {
- return false;
- }
- if ((cod & BT_COD_MAJOR_DC_MASK) != BT_COD_MAJOR_DC_AUDIO) {
- return false;
- }
- #endif
- mdc = (uint8_t)(cod & BT_COD_MINOR_DC_MASK);
- for (i=0; i<sizeof(bt_support_mdc); i++) {
- if (mdc == bt_support_mdc[i]) {
- return true;
- }
- }
- return false;
- }
- static void bt_discover_add_list(struct btsrv_discover_result *result)
- {
- uint8_t i, idle_pos = 0xFF, weakest_pos = 0xFF, save_pos = 0xFF;
- int8_t weakest_rssi = 127;
- for (i=0; i<BT_DISCOVER_LIST_MAX; i++) {
- if (p_discover->dev_list[i].valid) {
- if (!memcmp(&p_discover->dev_list[i].addr, &result->addr, sizeof(result->addr))) {
- if (p_discover->dev_list[i].wait_req_name && result->len) {
- p_discover->dev_list[i].wait_req_name = 0;
- }
- if (result->rssi > p_discover->dev_list[i].rssi) {
- p_discover->dev_list[i].rssi = result->rssi;
- }
- return;
- }
- if (weakest_rssi > p_discover->dev_list[i].rssi) {
- weakest_rssi = p_discover->dev_list[i].rssi;
- weakest_pos = i;
- }
- } else {
- if (idle_pos == 0xFF) {
- idle_pos = i;
- }
- }
- }
- if (idle_pos != 0xFF) {
- save_pos = idle_pos;
- } else {
- if (result->rssi > weakest_rssi) {
- save_pos = weakest_pos;
- }
- }
- if (save_pos != 0xFF) {
- memcpy(&p_discover->dev_list[save_pos].addr, &result->addr, sizeof(result->addr));
- p_discover->dev_list[save_pos].valid = 1;
- p_discover->dev_list[save_pos].rssi = result->rssi;
- if (result->len) {
- p_discover->dev_list[save_pos].wait_req_name = 0;
- } else {
- p_discover->dev_list[save_pos].wait_req_name = 1;
- }
- }
- }
- static void bt_discover_remote_name_cb(bt_addr_t *addr, uint8_t *name)
- {
- int i;
- struct btsrv_discover_result result;
- os_mutex_lock(&bt_discover_mutex, OS_FOREVER);
- if (addr && name) {
- for (i=0; i<BT_DISCOVER_LIST_MAX; i++) {
- if (p_discover->dev_list[i].valid &&
- (!memcmp(&p_discover->dev_list[i].addr, addr, sizeof(bt_addr_t)))) {
- memset(&result, 0, sizeof(result));
- memcpy(&result.addr, addr, sizeof(bt_addr_t));
- result.len = strlen(name);
- result.name = name;
- result.rssi = p_discover->dev_list[i].rssi;
- if (p_discover->cb) {
- p_discover->cb(&result);
- }
- }
- }
- }
- bt_discover_check_finish();
- os_mutex_unlock(&bt_discover_mutex);
- }
- static void bt_discover_check_finish(void)
- {
- int i, ret;
- struct btsrv_discover_result result;
- for (i=0; i<BT_DISCOVER_LIST_MAX; i++) {
- if (p_discover->dev_list[i].valid) {
- if (p_discover->dev_list[i].wait_req_name) {
- SYS_LOG_INF("Req name %2x%2x%2x%2x%2x%2x", p_discover->dev_list[i].addr.val[5],
- p_discover->dev_list[i].addr.val[4], p_discover->dev_list[i].addr.val[3],
- p_discover->dev_list[i].addr.val[2], p_discover->dev_list[i].addr.val[1],
- p_discover->dev_list[i].addr.val[0]);
- p_discover->dev_list[i].wait_req_name = 0;
- ret = btif_br_remote_name_req(&p_discover->dev_list[i].addr, bt_discover_remote_name_cb);
- if (ret) {
- continue;
- } else {
- return;
- }
- }
- }
- }
- /* Discover all finish */
- memset(&result, 0, sizeof(result));
- p_discover->discovering = 0;
- result.discover_finish = 1;
- if (p_discover->cb) {
- p_discover->cb(&result);
- }
- p_discover->cb = NULL;
- }
- static void bt_discover_result_cb(void *result)
- {
- int cod;
- struct btsrv_discover_result *cb_result = result;
- os_mutex_lock(&bt_discover_mutex, OS_FOREVER);
- if (!p_discover->discovering) {
- goto cb_exit;
- }
- if (cb_result->discover_finish) {
- bt_discover_check_finish();
- } else {
- cod = (cb_result->cod[2]<<16) + (cb_result->cod[1]<<8) + cb_result->cod[0];
- if (!bt_discover_transmit_check_device(cod)) {
- goto cb_exit;
- }
- bt_discover_add_list(cb_result);
- if (p_discover->cb) {
- p_discover->cb(result);
- }
- }
- cb_exit:
- os_mutex_unlock(&bt_discover_mutex);
- }
- int bt_manager_br_start_discover(struct btsrv_discover_param *param)
- {
- int ret;
- struct btsrv_discover_param dis_param;
- os_mutex_lock(&bt_discover_mutex, OS_FOREVER);
- if (p_discover->discovering) {
- ret = -EBUSY;
- goto start_exit;
- }
- dis_param.length = param->length;
- dis_param.num_responses = param->num_responses;
- dis_param.cb = &bt_discover_result_cb;
- ret = btif_br_start_discover(&dis_param);
- if (ret == 0) {
- p_discover->cb = param->cb;
- p_discover->discovering = 1;
- memset(p_discover->dev_list, 0, sizeof(p_discover->dev_list));
- }
- start_exit:
- os_mutex_unlock(&bt_discover_mutex);
- return ret;
- }
- int bt_manager_br_stop_discover(void)
- {
- int ret = 0;
- os_mutex_lock(&bt_discover_mutex, OS_FOREVER);
- if (!p_discover->discovering) {
- goto stop_exit;
- }
- p_discover->discovering = 0;
- p_discover->cb = NULL;
- ret = btif_br_stop_discover();
- stop_exit:
- os_mutex_unlock(&bt_discover_mutex);
- return ret;
- }
|