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(¶m, 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, ¶m.start_ble_advertising_comp.index);
137
138 btc_ble_mesh_ble_callback(¶m, 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(¶m, 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(¶m, 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(¶m, 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