1 /*
2 * Copyright (c) 2006-2023, RT-Thread Development Team
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date Author Notes
8 * 2018-08-14 tyx the first version
9 */
10
11 #include <rthw.h>
12 #include <rtthread.h>
13 #include <dev_wlan.h>
14 #include <dev_wlan_prot.h>
15
16 #define DBG_TAG "WLAN.prot"
17 #ifdef RT_WLAN_PROT_DEBUG
18 #define DBG_LVL DBG_LOG
19 #else
20 #define DBG_LVL DBG_INFO
21 #endif /* RT_WLAN_PROT_DEBUG */
22 #include <rtdbg.h>
23
24 #ifdef RT_WLAN_PROT_ENABLE
25
26 #if RT_WLAN_PROT_NAME_LEN < 4
27 #error "The name is too short"
28 #endif
29
30 struct rt_wlan_prot_event_des
31 {
32 rt_wlan_prot_event_handler handler;
33 struct rt_wlan_prot *prot;
34 };
35
36 static struct rt_wlan_prot *_prot[RT_WLAN_PROT_MAX];
37
38 static struct rt_wlan_prot_event_des prot_event_tab[RT_WLAN_PROT_EVT_MAX][RT_WLAN_PROT_MAX];
39
rt_wlan_prot_event_handle(struct rt_wlan_device * wlan,rt_wlan_dev_event_t event,struct rt_wlan_buff * buff,void * parameter)40 static void rt_wlan_prot_event_handle(struct rt_wlan_device *wlan, rt_wlan_dev_event_t event, struct rt_wlan_buff *buff, void *parameter)
41 {
42 int i;
43 struct rt_wlan_prot *wlan_prot;
44 struct rt_wlan_prot *prot;
45 rt_wlan_prot_event_handler handler;
46 rt_wlan_prot_event_t prot_event;
47
48 LOG_D("F:%s L:%d event:%d", __FUNCTION__, __LINE__, event);
49
50 wlan_prot = wlan->prot;
51 handler = RT_NULL;
52 prot = RT_NULL;
53 switch (event)
54 {
55 case RT_WLAN_DEV_EVT_INIT_DONE:
56 {
57 LOG_D("L%d event: INIT_DONE", __LINE__);
58 prot_event = RT_WLAN_PROT_EVT_INIT_DONE;
59 break;
60 }
61 case RT_WLAN_DEV_EVT_CONNECT:
62 {
63 LOG_D("L%d event: CONNECT", __LINE__);
64 prot_event = RT_WLAN_PROT_EVT_CONNECT;
65 break;
66 }
67 case RT_WLAN_DEV_EVT_DISCONNECT:
68 {
69 LOG_D("L%d event: DISCONNECT", __LINE__);
70 prot_event = RT_WLAN_PROT_EVT_DISCONNECT;
71 break;
72 }
73 case RT_WLAN_DEV_EVT_AP_START:
74 {
75 LOG_D("L%d event: AP_START", __LINE__);
76 prot_event = RT_WLAN_PROT_EVT_AP_START;
77 break;
78 }
79 case RT_WLAN_DEV_EVT_AP_STOP:
80 {
81 LOG_D("L%d event: AP_STOP", __LINE__);
82 prot_event = RT_WLAN_PROT_EVT_AP_STOP;
83 break;
84 }
85 case RT_WLAN_DEV_EVT_AP_ASSOCIATED:
86 {
87 LOG_D("L%d event: AP_ASSOCIATED", __LINE__);
88 prot_event = RT_WLAN_PROT_EVT_AP_ASSOCIATED;
89 break;
90 }
91 case RT_WLAN_DEV_EVT_AP_DISASSOCIATED:
92 {
93 LOG_D("L%d event: AP_DISASSOCIATED", __LINE__);
94 prot_event = RT_WLAN_PROT_EVT_AP_DISASSOCIATED;
95 break;
96 }
97 default:
98 {
99 return;
100 }
101 }
102 for (i = 0; i < RT_WLAN_PROT_MAX; i++)
103 {
104 if ((prot_event_tab[prot_event][i].handler != RT_NULL) &&
105 (prot_event_tab[prot_event][i].prot->id == wlan_prot->id))
106 {
107 handler = prot_event_tab[prot_event][i].handler;
108 prot = prot_event_tab[prot_event][i].prot;
109 break;
110 }
111 }
112
113 if (handler != RT_NULL)
114 {
115 handler(prot, wlan, prot_event);
116 }
117 }
118
rt_wlan_prot_find_by_name(const char * name)119 static struct rt_wlan_device *rt_wlan_prot_find_by_name(const char *name)
120 {
121 rt_device_t device;
122
123 if (name == RT_NULL)
124 {
125 LOG_E("F:%s L:%d Parameter Wrongful", __FUNCTION__, __LINE__);
126 return RT_NULL;
127 }
128 device = rt_device_find(name);
129 if (device == RT_NULL)
130 {
131 LOG_E("F:%s L:%d not find wlan dev!! name:%s", __FUNCTION__, __LINE__, name);
132 return RT_NULL;
133 }
134 return (struct rt_wlan_device *)device;
135 }
136
rt_wlan_prot_attach(const char * dev_name,const char * prot_name)137 rt_err_t rt_wlan_prot_attach(const char *dev_name, const char *prot_name)
138 {
139 struct rt_wlan_device *wlan;
140
141 wlan = rt_wlan_prot_find_by_name(dev_name);
142 if (wlan == RT_NULL)
143 {
144 return -RT_ERROR;
145 }
146 return rt_wlan_prot_attach_dev(wlan, prot_name);
147 }
148
rt_wlan_prot_detach(const char * name)149 rt_err_t rt_wlan_prot_detach(const char *name)
150 {
151 struct rt_wlan_device *wlan;
152
153 wlan = rt_wlan_prot_find_by_name(name);
154 if (wlan == RT_NULL)
155 {
156 return -RT_ERROR;
157 }
158 return rt_wlan_prot_detach_dev(wlan);
159 }
160
rt_wlan_prot_attach_dev(struct rt_wlan_device * wlan,const char * prot_name)161 rt_err_t rt_wlan_prot_attach_dev(struct rt_wlan_device *wlan, const char *prot_name)
162 {
163 int i = 0;
164 struct rt_wlan_prot *prot = wlan->prot;
165 rt_wlan_dev_event_handler handler = rt_wlan_prot_event_handle;
166
167 if (wlan == RT_NULL)
168 {
169 LOG_E("F:%s L:%d wlan is null", __FUNCTION__, __LINE__);
170 return -RT_ERROR;
171 }
172
173 if (prot != RT_NULL &&
174 (rt_strcmp(prot->name, prot_name) == 0))
175 {
176 LOG_D("prot is register");
177 return RT_EOK;
178 }
179
180 /* if prot not NULL */
181 if (prot != RT_NULL)
182 rt_wlan_prot_detach_dev(wlan);
183
184 #ifdef RT_WLAN_PROT_LWIP_PBUF_FORCE
185 if (rt_strcmp(RT_WLAN_PROT_LWIP_NAME, prot_name) != 0)
186 {
187 return -RT_ERROR;
188 }
189 #endif
190 /* find prot */
191 for (i = 0; i < RT_WLAN_PROT_MAX; i++)
192 {
193 if ((_prot[i] != RT_NULL) && (rt_strcmp(_prot[i]->name, prot_name) == 0))
194 {
195 /* attach prot */
196 wlan->prot = _prot[i]->ops->dev_reg_callback(_prot[i], wlan);
197 break;
198 }
199 }
200
201 if (i >= RT_WLAN_PROT_MAX)
202 {
203 LOG_E("F:%s L:%d not find wlan protocol", __FUNCTION__, __LINE__);
204 return -RT_ERROR;
205 }
206
207 rt_wlan_dev_register_event_handler(wlan, RT_WLAN_DEV_EVT_CONNECT, handler, RT_NULL);
208 rt_wlan_dev_register_event_handler(wlan, RT_WLAN_DEV_EVT_DISCONNECT, handler, RT_NULL);
209 rt_wlan_dev_register_event_handler(wlan, RT_WLAN_DEV_EVT_AP_START, handler, RT_NULL);
210 rt_wlan_dev_register_event_handler(wlan, RT_WLAN_DEV_EVT_AP_STOP, handler, RT_NULL);
211 rt_wlan_dev_register_event_handler(wlan, RT_WLAN_DEV_EVT_AP_ASSOCIATED, handler, RT_NULL);
212 rt_wlan_dev_register_event_handler(wlan, RT_WLAN_DEV_EVT_AP_DISASSOCIATED, handler, RT_NULL);
213
214 return RT_EOK;
215 }
216
rt_wlan_prot_detach_dev(struct rt_wlan_device * wlan)217 rt_err_t rt_wlan_prot_detach_dev(struct rt_wlan_device *wlan)
218 {
219 struct rt_wlan_prot *prot = wlan->prot;
220 rt_wlan_dev_event_t event;
221
222 if (prot == RT_NULL)
223 return RT_EOK;
224
225 for (event = RT_WLAN_DEV_EVT_INIT_DONE; event < RT_WLAN_DEV_EVT_MAX; event ++)
226 {
227 rt_wlan_dev_unregister_event_handler(wlan, event, rt_wlan_prot_event_handle);
228 }
229
230 /* detach prot */
231 prot->ops->dev_unreg_callback(prot, wlan);
232 wlan->prot = RT_NULL;
233
234 return RT_EOK;
235 }
236
rt_wlan_prot_regisetr(struct rt_wlan_prot * prot)237 rt_err_t rt_wlan_prot_regisetr(struct rt_wlan_prot *prot)
238 {
239 int i;
240 rt_uint32_t id;
241 static rt_uint8_t num;
242
243 /* Parameter checking */
244 if ((prot == RT_NULL) ||
245 (prot->ops->prot_recv == RT_NULL) ||
246 (prot->ops->dev_reg_callback == RT_NULL))
247 {
248 LOG_E("F:%s L:%d Parameter Wrongful", __FUNCTION__, __LINE__);
249 return -RT_EINVAL;
250 }
251
252 /* save prot */
253 for (i = 0; i < RT_WLAN_PROT_MAX; i++)
254 {
255 if (_prot[i] == RT_NULL)
256 {
257 id = (RT_LWAN_ID_PREFIX << 16) | num;
258 prot->id = id;
259 _prot[i] = prot;
260 num ++;
261 break;
262 }
263 else if (rt_strcmp(_prot[i]->name, prot->name) == 0)
264 {
265 break;
266 }
267 }
268
269 /* is full */
270 if (i >= RT_WLAN_PROT_MAX)
271 {
272 LOG_E("F:%s L:%d Space full", __FUNCTION__, __LINE__);
273 return -RT_ERROR;
274 }
275
276 return RT_EOK;
277 }
278
rt_wlan_prot_event_register(struct rt_wlan_prot * prot,rt_wlan_prot_event_t event,rt_wlan_prot_event_handler handler)279 rt_err_t rt_wlan_prot_event_register(struct rt_wlan_prot *prot, rt_wlan_prot_event_t event, rt_wlan_prot_event_handler handler)
280 {
281 int i;
282
283 if ((prot == RT_NULL) || (handler == RT_NULL))
284 {
285 return -RT_EINVAL;
286 }
287
288 for (i = 0; i < RT_WLAN_PROT_MAX; i++)
289 {
290 if (prot_event_tab[event][i].handler == RT_NULL)
291 {
292 prot_event_tab[event][i].handler = handler;
293 prot_event_tab[event][i].prot = prot;
294 return RT_EOK;
295 }
296 }
297
298 return -RT_ERROR;
299 }
300
rt_wlan_prot_event_unregister(struct rt_wlan_prot * prot,rt_wlan_prot_event_t event)301 rt_err_t rt_wlan_prot_event_unregister(struct rt_wlan_prot *prot, rt_wlan_prot_event_t event)
302 {
303 int i;
304
305 if (prot == RT_NULL)
306 {
307 return -RT_EINVAL;
308 }
309
310 for (i = 0; i < RT_WLAN_PROT_MAX; i++)
311 {
312 if ((prot_event_tab[event][i].handler != RT_NULL) &&
313 (prot_event_tab[event][i].prot == prot))
314 {
315 rt_memset(&prot_event_tab[event][i], 0, sizeof(struct rt_wlan_prot_event_des));
316 return RT_EOK;
317 }
318 }
319
320 return -RT_ERROR;
321 }
322
rt_wlan_prot_transfer_dev(struct rt_wlan_device * wlan,void * buff,int len)323 rt_err_t rt_wlan_prot_transfer_dev(struct rt_wlan_device *wlan, void *buff, int len)
324 {
325 if (wlan->ops->wlan_send != RT_NULL)
326 {
327 return wlan->ops->wlan_send(wlan, buff, len);
328 }
329 return -RT_ERROR;
330 }
331
rt_wlan_dev_transfer_prot(struct rt_wlan_device * wlan,void * buff,int len)332 rt_err_t rt_wlan_dev_transfer_prot(struct rt_wlan_device *wlan, void *buff, int len)
333 {
334 struct rt_wlan_prot *prot = wlan->prot;
335
336 if (prot != RT_NULL)
337 {
338 return prot->ops->prot_recv(wlan, buff, len);
339 }
340 return -RT_ERROR;
341 }
342
343 extern int rt_wlan_prot_ready_event(struct rt_wlan_device *wlan, struct rt_wlan_buff *buff);
rt_wlan_prot_ready(struct rt_wlan_device * wlan,struct rt_wlan_buff * buff)344 int rt_wlan_prot_ready(struct rt_wlan_device *wlan, struct rt_wlan_buff *buff)
345 {
346 return rt_wlan_prot_ready_event(wlan, buff);
347 }
348
rt_wlan_prot_dump(void)349 void rt_wlan_prot_dump(void)
350 {
351 int i;
352
353 rt_kprintf(" name id \n");
354 rt_kprintf("-------- --------\n");
355 for (i = 0; i < RT_WLAN_PROT_MAX; i++)
356 {
357 if (_prot[i] != RT_NULL)
358 {
359 rt_kprintf("%-8.8s ", _prot[i]->name);
360 rt_kprintf("%08x\n", _prot[i]->id);
361 }
362 }
363 }
364 #endif
365