1 /*
2 * Copyright (c) 2021 Chipsea Technologies (Shenzhen) Corp., Ltd. All rights reserved.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "ble_ip_config.h" // SW configuration
17
18 #if (BLE_APP_SMARTCONFIG)
19
20 /*
21 * INCLUDE FILES
22 ****************************************************************************************
23 */
24 #include "app_present.h"
25 #include "app_present_task.h"
26 #include "app_smartconfig.h"
27 #include "smartconfig_task.h"
28 #include "bt_common.h"
29 #include "hal_prf_types.h"
30 #include "hal_profile_utils.h"
31 #include "arch.h"
32 #include "hal_profile.h"
33 #include "string.h"
34 #include "ble_common_utils.h"
35
36 /*
37 * LOCAL VARIABLE DEFINITIONS
38 ****************************************************************************************
39 */
40 #define BLE_SMARTCONFIG_TEST (0)
41 static struct app_smartconfig_env_tag app_smartconfig_env;
42
43 static app_smartconfig_recv_ap_info_cb recv_ap_info_callback = NULL;
44 static app_smartconfig_recv_state_info_cb recv_state_info_callback = NULL;
45
46 struct ble_smartconfig_wifi_state {
47 char state[DATA_BUF_SIZE];
48 uint8_t len;
49 };
50
51 static struct ble_smartconfig_wifi_state wifi_state;
52
53 #if BLE_SMARTCONFIG_TEST
54 static struct ble_smartconfig smartconfig_result;
55
56 #define APP_RSP ("successful")
57 #define APP_RSP_LEN (sizeof(APP_RSP))
58
app_smartconfig_ap_info_received(uint8_t * data,uint32_t length)59 int app_smartconfig_ap_info_received(uint8_t* data, uint32_t length)
60 {
61 int i = 0;
62 uint8_t index = 0;
63 dbg("%s recv ap info %d\r\n", __func__, length);
64 for (i = 0; i < length; i++) {
65 if((i%8 == 0))
66 dbg(" ");
67 dbg("%02x ", data[i]);
68 if((i+1)%16 == 0)
69 dbg("\n");
70 }
71 dbg("\n");
72
73 for (i = 0; i < length; i++) {
74 if (data[i] == '\n') {
75 memcpy(&smartconfig_result.ssid[0], &data[0], i);
76 index = i + 1;
77 break;
78 }
79 }
80
81 for (i = index; i < length; i++) {
82 memcpy(&smartconfig_result.pwd[0], &data[index], length - index);
83 }
84
85 dbg("ssid %s\r\n", smartconfig_result.ssid);
86 dbg("pwd %s\r\n", smartconfig_result.pwd);
87 memcpy(&wifi_state.state[0], APP_RSP, APP_RSP_LEN);
88 wifi_state.len = APP_RSP_LEN;
89 return NO_ERROR;
90 }
91 #endif
92
app_smartconfig_time_info_received(uint8_t * data,uint32_t length)93 int app_smartconfig_time_info_received(uint8_t* data, uint32_t length)
94 {
95 if (recv_state_info_callback) {
96 recv_state_info_callback(data, length);
97 }
98 return NO_ERROR;
99 }
100
app_smartconfig_init(void)101 void app_smartconfig_init(void)
102 {
103 dbg("%s\n", __func__);
104 memset(&app_smartconfig_env, 0, sizeof(app_smartconfig_env));
105 memset(&wifi_state, 0, sizeof(wifi_state));
106 //recv_ap_info_callback = NULL;
107 //recv_state_info_callback = NULL;
108 }
109
app_smartconfig_add_smartconfig(void)110 void app_smartconfig_add_smartconfig(void)
111 {
112 struct gapm_profile_task_add_cmd *req = KE_MSG_ALLOC_DYN(GAPM_PROFILE_TASK_ADD_CMD,
113 TASK_GAPM, TASK_APP,
114 gapm_profile_task_add_cmd, 0);
115
116 // Fill message
117 req->operation = GAPM_PROFILE_TASK_ADD;
118 #if 0
119 req->sec_lvl = PERM(SVC_AUTH, ENABLE);
120 #else
121 req->sec_lvl = PERM(SVC_AUTH, NO_AUTH);
122 #endif
123 req->prf_task_id = TASK_ID_SMARTCONFIG;
124 req->app_task = TASK_APP;
125 req->start_hdl = 0;
126
127 // Send the message
128 ke_msg_send(req);
129 }
130
app_smartconfig_enable_prf(uint8_t conidx)131 void app_smartconfig_enable_prf(uint8_t conidx)
132 {
133 app_smartconfig_env.conidx = conidx;
134 }
135
app_smartconfig_disconnected(void)136 void app_smartconfig_disconnected(void)
137 {
138 dbg("%s\n", __func__);
139 app_smartconfig_env.conidx = INVALID_CONNECTION_INDEX;
140 app_smartconfig_env.wifi_state_ntf_en = false;
141 app_smartconfig_env.time_state_ntf_en = false;
142 recv_ap_info_callback = NULL;
143 recv_state_info_callback = NULL;
144 }
145
app_smartconfig_register_ap_info_cb(app_smartconfig_recv_ap_info_cb callback)146 void app_smartconfig_register_ap_info_cb(app_smartconfig_recv_ap_info_cb callback)
147 {
148 recv_ap_info_callback = callback;
149 }
150
app_smartconfig_register_state_info_cb(app_smartconfig_recv_state_info_cb callback)151 void app_smartconfig_register_state_info_cb(app_smartconfig_recv_state_info_cb callback)
152 {
153 recv_state_info_callback = callback;
154 }
155
app_smartconfig_send_wifi_state_notification(uint8_t * data,uint32_t length)156 void app_smartconfig_send_wifi_state_notification(uint8_t* data, uint32_t length)
157 {
158 dbg("%s %d\r\n", __func__, length);
159 struct ble_smartconfig_send_data_req * req = KE_MSG_ALLOC_DYN(SMARTCONFIG_SEND_WIFI_STATE_NOTIFICATION,
160 prf_get_task_from_id(TASK_ID_SMARTCONFIG),
161 TASK_APP,
162 ble_smartconfig_send_data_req,
163 length);
164 req->conidx = app_smartconfig_env.conidx;
165 req->length = length;
166 memcpy(req->value, data, length);
167
168 ke_msg_send(req);
169 }
170
app_smartconfig_send_wifi_state_indication(uint8_t * data,uint32_t length)171 void app_smartconfig_send_wifi_state_indication(uint8_t* data, uint32_t length)
172 {
173
174 struct ble_smartconfig_send_data_req * req = KE_MSG_ALLOC_DYN(SMARTCONFIG_SEND_WIFI_STATE_INDICATION,
175 prf_get_task_from_id(TASK_ID_SMARTCONFIG),
176 TASK_APP,
177 ble_smartconfig_send_data_req,
178 length);
179 req->conidx = app_smartconfig_env.conidx;
180 req->length = length;
181 memcpy(req->value, data, length);
182
183 ke_msg_send(req);
184 }
185
app_smartconfig_send_time_state_notification(uint8_t * data,uint32_t length)186 void app_smartconfig_send_time_state_notification(uint8_t* data, uint32_t length)
187 {
188 struct ble_smartconfig_send_data_req * req = KE_MSG_ALLOC_DYN(SMARTCONFIG_SEND_TIME_STATE_NOTIFICATION,
189 prf_get_task_from_id(TASK_ID_SMARTCONFIG),
190 TASK_APP,
191 ble_smartconfig_send_data_req,
192 length);
193 req->conidx = app_smartconfig_env.conidx;
194 req->length = length;
195 memcpy(req->value, data, length);
196
197 ke_msg_send(req);
198 }
199
app_smartconfig_send_time_state_indication(uint8_t * data,uint32_t length)200 void app_smartconfig_send_time_state_indication(uint8_t* data, uint32_t length)
201 {
202 struct ble_smartconfig_send_data_req * req = KE_MSG_ALLOC_DYN(SMARTCONFIG_SEND_TIME_STATE_INDICATION,
203 prf_get_task_from_id(TASK_ID_SMARTCONFIG),
204 TASK_APP,
205 ble_smartconfig_send_data_req,
206 length);
207 req->conidx = app_smartconfig_env.conidx;
208 req->length = length;
209 memcpy(req->value, data, length);
210
211 ke_msg_send(req);
212 }
213
214 /*
215 * MESSAGE HANDLERS
216 ****************************************************************************************
217 */
218
app_smartconfig_wifi_state_service_changed_handler(ke_msg_id_t const msgid,struct ble_smartconfig_notif_config * param,ke_task_id_t const dest_id,ke_task_id_t const src_id)219 static int app_smartconfig_wifi_state_service_changed_handler(ke_msg_id_t const msgid,
220 struct ble_smartconfig_notif_config *param,
221 ke_task_id_t const dest_id,
222 ke_task_id_t const src_id)
223 {
224 app_smartconfig_env.wifi_state_ntf_en = param->ntf_en;
225 if (wifi_state.len) {
226 app_smartconfig_send_wifi_state_notification((uint8_t *)&wifi_state.state[0], wifi_state.len);
227 }
228
229 return (KE_MSG_CONSUMED);
230 }
231
app_smartconfig_time_state_service_changed_handler(ke_msg_id_t const msgid,struct ble_smartconfig_notif_config * param,ke_task_id_t const dest_id,ke_task_id_t const src_id)232 static int app_smartconfig_time_state_service_changed_handler(ke_msg_id_t const msgid,
233 struct ble_smartconfig_notif_config *param,
234 ke_task_id_t const dest_id,
235 ke_task_id_t const src_id)
236 {
237 app_smartconfig_env.time_state_ntf_en = param->ntf_en;
238 return (KE_MSG_CONSUMED);
239 }
240
app_smartconfig_time_state_sent_handler(ke_msg_id_t const msgid,struct ble_smartconfig_data_sent_ind * param,ke_task_id_t const dest_id,ke_task_id_t const src_id)241 static int app_smartconfig_time_state_sent_handler(ke_msg_id_t const msgid,
242 struct ble_smartconfig_data_sent_ind *param,
243 ke_task_id_t const dest_id,
244 ke_task_id_t const src_id)
245 {
246 return (KE_MSG_CONSUMED);
247 }
248
app_smartconfig_ap_info_received_handler(ke_msg_id_t const msgid,struct ble_smartconfig_rx_data_ind * param,ke_task_id_t const dest_id,ke_task_id_t const src_id)249 static int app_smartconfig_ap_info_received_handler(ke_msg_id_t const msgid,
250 struct ble_smartconfig_rx_data_ind *param,
251 ke_task_id_t const dest_id,
252 ke_task_id_t const src_id)
253 {
254 #if BLE_SMARTCONFIG_TEST
255 app_smartconfig_ap_info_received(param->data, param->length);
256 #endif //(BLE_SMARTCONFIG_TEST)
257 if (recv_ap_info_callback != NULL)
258 {
259 recv_ap_info_callback(param->data, param->length);
260 }
261 return (KE_MSG_CONSUMED);
262 }
263
app_smartconfig_time_info_received_handler(ke_msg_id_t const msgid,struct ble_smartconfig_rx_data_ind * param,ke_task_id_t const dest_id,ke_task_id_t const src_id)264 static int app_smartconfig_time_info_received_handler(ke_msg_id_t const msgid,
265 struct ble_smartconfig_rx_data_ind *param,
266 ke_task_id_t const dest_id,
267 ke_task_id_t const src_id)
268 {
269 app_smartconfig_time_info_received(param->data, param->length);
270 return (KE_MSG_CONSUMED);
271 }
272
273
app_smartconfig_dflt_msg_handler(ke_msg_id_t const msgid,void const * param,ke_task_id_t const dest_id,ke_task_id_t const src_id)274 static int app_smartconfig_dflt_msg_handler(ke_msg_id_t const msgid,
275 void const *param,
276 ke_task_id_t const dest_id,
277 ke_task_id_t const src_id)
278 {
279 // Do nothing
280 return (KE_MSG_CONSUMED);
281 }
282
app_smartconfig_send_rsp(uint8_t * data,uint32_t length)283 void app_smartconfig_send_rsp(uint8_t* data, uint32_t length)
284 {
285 memset(&wifi_state, 0, sizeof(wifi_state));
286 if (app_smartconfig_env.wifi_state_ntf_en) {
287 app_smartconfig_send_wifi_state_notification(data, length);
288 } else {
289 wifi_state.len = length;
290 memcpy(&wifi_state.state[0], data, length);
291 }
292 }
293
294 /*
295 * LOCAL VARIABLE DEFINITIONS
296 ****************************************************************************************
297 */
298
299 /// Default State handlers definition
300 const struct ke_msg_handler app_smartconfig_msg_handler_list[] =
301 {
302 // Note: first message is latest message checked by kernel so default is put on top.
303 {KE_MSG_DEFAULT_HANDLER, (ke_msg_func_t)app_smartconfig_dflt_msg_handler},
304
305 {SMARTCONFIG_WIFI_STATE_SERVICE_CHANGED, (ke_msg_func_t)app_smartconfig_wifi_state_service_changed_handler},
306 {SMARTCONFIG_TIME_STATE_SERVICE_CHANGED, (ke_msg_func_t)app_smartconfig_time_state_service_changed_handler},
307 {SMARTCONFIG_TIME_STATE_SENT, (ke_msg_func_t)app_smartconfig_time_state_sent_handler},
308 {SMARTCONFIG_AP_INFO_RECEIVED, (ke_msg_func_t)app_smartconfig_ap_info_received_handler},
309 {SMARTCONFIG_TIME_INFO_RECEIVED, (ke_msg_func_t)app_smartconfig_time_info_received_handler},
310 };
311
312 const struct app_subtask_handlers app_smartconfig_handlers = APP_HANDLERS(app_smartconfig);
313
314 #endif //BLE_APP_SMARTCONFIG
315