1 /*
2  * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <stdint.h>
8 #include <string.h>
9 
10 #include "btc_ble_mesh_ble.h"
11 #include "adv.h"
12 #include "scan.h"
13 #include "mesh_bearer_adapt.h"
14 #include "esp_ble_mesh_ble_api.h"
15 
16 #if CONFIG_BLE_MESH_BLE_COEX_SUPPORT
17 
btc_ble_mesh_ble_copy_req_data(btc_msg_t * msg,void * p_dst,void * p_src)18 static void btc_ble_mesh_ble_copy_req_data(btc_msg_t *msg, void *p_dst, void *p_src)
19 {
20 #if CONFIG_BLE_MESH_SUPPORT_BLE_SCAN
21     esp_ble_mesh_ble_cb_param_t *p_dst_data = (esp_ble_mesh_ble_cb_param_t *)p_dst;
22     esp_ble_mesh_ble_cb_param_t *p_src_data = (esp_ble_mesh_ble_cb_param_t *)p_src;
23 
24     if (!msg || !p_src_data || !p_dst_data) {
25         BT_ERR("%s, Invalid parameter", __func__);
26         return;
27     }
28 
29     switch (msg->act) {
30     case ESP_BLE_MESH_SCAN_BLE_ADVERTISING_PKT_EVT:
31         if (p_src_data->scan_ble_adv_pkt.data && p_src_data->scan_ble_adv_pkt.length) {
32             p_dst_data->scan_ble_adv_pkt.length = p_src_data->scan_ble_adv_pkt.length;
33             p_dst_data->scan_ble_adv_pkt.data = bt_mesh_calloc(p_src_data->scan_ble_adv_pkt.length);
34             if (p_dst_data->scan_ble_adv_pkt.data) {
35                 memcpy(p_dst_data->scan_ble_adv_pkt.data, p_src_data->scan_ble_adv_pkt.data,
36                        p_src_data->scan_ble_adv_pkt.length);
37             } else {
38                 BT_ERR("%s, Out of memory, act %d", __func__, msg->act);
39             }
40         }
41         break;
42     default:
43         break;
44     }
45 #endif /* CONFIG_BLE_MESH_SUPPORT_BLE_SCAN */
46 }
47 
btc_ble_mesh_ble_free_req_data(btc_msg_t * msg)48 static void btc_ble_mesh_ble_free_req_data(btc_msg_t *msg)
49 {
50 #if CONFIG_BLE_MESH_SUPPORT_BLE_SCAN
51     esp_ble_mesh_ble_cb_param_t *arg = NULL;
52 
53     if (!msg) {
54         BT_ERR("%s, Invalid parameter", __func__);
55         return;
56     }
57 
58     arg = (esp_ble_mesh_ble_cb_param_t *)msg->arg;
59 
60     switch (msg->act) {
61     case ESP_BLE_MESH_SCAN_BLE_ADVERTISING_PKT_EVT:
62         if (arg->scan_ble_adv_pkt.data) {
63             bt_mesh_free(arg->scan_ble_adv_pkt.data);
64         }
65         break;
66     default:
67         break;
68     }
69 #endif /* CONFIG_BLE_MESH_SUPPORT_BLE_SCAN */
70 }
71 
btc_ble_mesh_ble_callback(esp_ble_mesh_ble_cb_param_t * cb_params,uint8_t act)72 static void btc_ble_mesh_ble_callback(esp_ble_mesh_ble_cb_param_t *cb_params, uint8_t act)
73 {
74     btc_msg_t msg = {0};
75 
76     /* If corresponding callback is not registered, event will not be posted. */
77     if (!btc_profile_cb_get(BTC_PID_BLE_MESH_BLE_COEX)) {
78         return;
79     }
80 
81     msg.sig = BTC_SIG_API_CB;
82     msg.pid = BTC_PID_BLE_MESH_BLE_COEX;
83     msg.act = act;
84 
85     btc_transfer_context(&msg, cb_params, cb_params == NULL ? 0 : sizeof(esp_ble_mesh_ble_cb_param_t),
86                          btc_ble_mesh_ble_copy_req_data, btc_ble_mesh_ble_free_req_data);
87 }
88 
89 #if CONFIG_BLE_MESH_SUPPORT_BLE_SCAN
bt_mesh_ble_scan_cb_evt_to_btc(const bt_mesh_addr_t * addr,uint8_t adv_type,uint8_t data[],uint16_t length,int8_t rssi)90 void bt_mesh_ble_scan_cb_evt_to_btc(const bt_mesh_addr_t *addr,
91                                     uint8_t adv_type, uint8_t data[],
92                                     uint16_t length, int8_t rssi)
93 {
94     esp_ble_mesh_ble_cb_param_t param = {0};
95 
96     if (addr == NULL) {
97         BT_ERR("%s, Invalid parameter", __func__);
98         return;
99     }
100 
101     memcpy(param.scan_ble_adv_pkt.addr, addr->val, sizeof(addr->val));
102     param.scan_ble_adv_pkt.addr_type = addr->type;
103     if (data && length) {
104         param.scan_ble_adv_pkt.data = data;
105         param.scan_ble_adv_pkt.length = length;
106     }
107     param.scan_ble_adv_pkt.adv_type = adv_type;
108     param.scan_ble_adv_pkt.rssi = rssi;
109 
110     btc_ble_mesh_ble_callback(&param, ESP_BLE_MESH_SCAN_BLE_ADVERTISING_PKT_EVT);
111 }
112 #endif /* CONFIG_BLE_MESH_SUPPORT_BLE_SCAN */
113 
btc_ble_mesh_ble_call_handler(btc_msg_t * msg)114 void btc_ble_mesh_ble_call_handler(btc_msg_t *msg)
115 {
116     esp_ble_mesh_ble_cb_param_t param = {0};
117     btc_ble_mesh_ble_args_t *arg = NULL;
118 
119     if (!msg) {
120         BT_ERR("%s, Invalid parameter", __func__);
121         return;
122     }
123 
124     arg = (btc_ble_mesh_ble_args_t *)msg->arg;
125 
126     switch (msg->act) {
127 #if CONFIG_BLE_MESH_SUPPORT_BLE_ADV
128     case BTC_BLE_MESH_ACT_START_BLE_ADV: {
129         struct bt_mesh_ble_adv_param *set = (struct bt_mesh_ble_adv_param *)&arg->start_ble_adv.param;
130         struct bt_mesh_ble_adv_data *data = NULL;
131         if (arg->start_ble_adv.data.adv_data_len || arg->start_ble_adv.data.scan_rsp_data_len) {
132             data = (struct bt_mesh_ble_adv_data *)&arg->start_ble_adv.data;
133         }
134 
135         param.start_ble_advertising_comp.err_code =
136             bt_mesh_start_ble_advertising(set, data, &param.start_ble_advertising_comp.index);
137 
138         btc_ble_mesh_ble_callback(&param, ESP_BLE_MESH_START_BLE_ADVERTISING_COMP_EVT);
139         break;
140     }
141     case BTC_BLE_MESH_ACT_STOP_BLE_ADV:
142         param.stop_ble_advertising_comp.index = arg->stop_ble_adv.index;
143         param.stop_ble_advertising_comp.err_code =
144             bt_mesh_stop_ble_advertising(arg->stop_ble_adv.index);
145 
146         btc_ble_mesh_ble_callback(&param, ESP_BLE_MESH_STOP_BLE_ADVERTISING_COMP_EVT);
147         break;
148 #endif /* CONFIG_BLE_MESH_SUPPORT_BLE_ADV */
149 #if CONFIG_BLE_MESH_SUPPORT_BLE_SCAN
150     case BTC_BLE_MESH_ACT_START_BLE_SCAN:
151         param.start_ble_scan_comp.err_code =
152             bt_mesh_start_ble_scan((struct bt_mesh_ble_scan_param *)&arg->start_ble_scan.param);
153         btc_ble_mesh_ble_callback(&param, ESP_BLE_MESH_START_BLE_SCANNING_COMP_EVT);
154         break;
155     case BTC_BLE_MESH_ACT_STOP_BLE_SCAN:
156         param.stop_ble_scan_comp.err_code = bt_mesh_stop_ble_scan();
157         btc_ble_mesh_ble_callback(&param, ESP_BLE_MESH_STOP_BLE_SCANNING_COMP_EVT);
158         break;
159 #endif /* CONFIG_BLE_MESH_SUPPORT_BLE_SCAN */
160     default:
161         return;
162     }
163 }
164 
btc_ble_mesh_ble_cb_to_app(esp_ble_mesh_ble_cb_event_t event,esp_ble_mesh_ble_cb_param_t * param)165 static inline void btc_ble_mesh_ble_cb_to_app(esp_ble_mesh_ble_cb_event_t event,
166                                               esp_ble_mesh_ble_cb_param_t *param)
167 {
168     esp_ble_mesh_ble_cb_t btc_ble_mesh_cb =
169         (esp_ble_mesh_ble_cb_t)btc_profile_cb_get(BTC_PID_BLE_MESH_BLE_COEX);
170     if (btc_ble_mesh_cb) {
171         btc_ble_mesh_cb(event, param);
172     }
173 }
174 
btc_ble_mesh_ble_cb_handler(btc_msg_t * msg)175 void btc_ble_mesh_ble_cb_handler(btc_msg_t *msg)
176 {
177     esp_ble_mesh_ble_cb_param_t *param = NULL;
178 
179     if (!msg) {
180         BT_ERR("%s, Invalid parameter", __func__);
181         return;
182     }
183 
184     param = (esp_ble_mesh_ble_cb_param_t *)msg->arg;
185 
186     if (msg->act < ESP_BLE_MESH_BLE_EVT_MAX) {
187         btc_ble_mesh_ble_cb_to_app(msg->act, param);
188     } else {
189         BT_ERR("%s, Unknown act %d", __func__, msg->act);
190     }
191 
192     btc_ble_mesh_ble_free_req_data(msg);
193 }
194 
195 #endif /* CONFIG_BLE_MESH_BLE_COEX_SUPPORT */
196