1 /*
2 * Copyright (c) 2006-2018, 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 <wlan_dev.h>
14 #include <wlan_prot.h>
15
16 #define DBG_ENABLE
17 #ifdef RT_WLAN_PROT_DEBUG
18 #define DBG_LEVEL DBG_LOG
19 #else
20 #define DBG_LEVEL DBG_INFO
21 #endif
22 #define DBG_SECTION_NAME "WLAN.prot"
23 #define DBG_COLOR
24 #include <rtdbg.h>
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_t event;
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, 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 for (event = RT_WLAN_DEV_EVT_INIT_DONE; event < RT_WLAN_DEV_EVT_MAX; event ++)
208 {
209 if (rt_wlan_dev_register_event_handler(wlan, event, rt_wlan_prot_event_handle, RT_NULL) != RT_EOK)
210 {
211 LOG_E("prot register event filed:%d", event);
212 }
213 }
214
215 return RT_EOK;
216 }
217
rt_wlan_prot_detach_dev(struct rt_wlan_device * wlan)218 rt_err_t rt_wlan_prot_detach_dev(struct rt_wlan_device *wlan)
219 {
220 struct rt_wlan_prot *prot = wlan->prot;
221 rt_wlan_dev_event_t event;
222
223 if (prot == RT_NULL)
224 return RT_EOK;
225
226 for (event = RT_WLAN_DEV_EVT_INIT_DONE; event < RT_WLAN_DEV_EVT_MAX; event ++)
227 {
228 rt_wlan_dev_unregister_event_handler(wlan, event, rt_wlan_prot_event_handle);
229 }
230
231 /* detach prot */
232 prot->ops->dev_unreg_callback(prot, wlan);
233 wlan->prot = RT_NULL;
234
235 return RT_EOK;
236 }
237
rt_wlan_prot_regisetr(struct rt_wlan_prot * prot)238 rt_err_t rt_wlan_prot_regisetr(struct rt_wlan_prot *prot)
239 {
240 int i;
241 rt_uint32_t id;
242 static rt_uint8_t num;
243
244 /* Parameter checking */
245 if ((prot == RT_NULL) ||
246 (prot->ops->prot_recv == RT_NULL) ||
247 (prot->ops->dev_reg_callback == RT_NULL))
248 {
249 LOG_E("F:%s L:%d Parameter Wrongful", __FUNCTION__, __LINE__);
250 return -RT_EINVAL;
251 }
252
253 /* save prot */
254 for (i = 0; i < RT_WLAN_PROT_MAX; i++)
255 {
256 if (_prot[i] == RT_NULL)
257 {
258 id = (RT_LWAN_ID_PREFIX << 16) | num;
259 prot->id = id;
260 _prot[i] = prot;
261 num ++;
262 break;
263 }
264 else if (rt_strcmp(_prot[i]->name, prot->name) == 0)
265 {
266 break;
267 }
268 }
269
270 /* is full */
271 if (i >= RT_WLAN_PROT_MAX)
272 {
273 LOG_E("F:%s L:%d Space full", __FUNCTION__, __LINE__);
274 return -RT_ERROR;
275 }
276
277 return RT_EOK;
278 }
279
rt_wlan_prot_event_register(struct rt_wlan_prot * prot,rt_wlan_prot_event_t event,rt_wlan_prot_event_handler handler)280 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)
281 {
282 int i;
283
284 if ((prot == RT_NULL) || (handler == RT_NULL))
285 {
286 return -RT_EINVAL;
287 }
288
289 for (i = 0; i < RT_WLAN_PROT_MAX; i++)
290 {
291 if (prot_event_tab[event][i].handler == RT_NULL)
292 {
293 prot_event_tab[event][i].handler = handler;
294 prot_event_tab[event][i].prot = prot;
295 return RT_EOK;
296 }
297 }
298
299 return -RT_ERROR;
300 }
301
rt_wlan_prot_event_unregister(struct rt_wlan_prot * prot,rt_wlan_prot_event_t event)302 rt_err_t rt_wlan_prot_event_unregister(struct rt_wlan_prot *prot, rt_wlan_prot_event_t event)
303 {
304 int i;
305
306 if (prot == RT_NULL)
307 {
308 return -RT_EINVAL;
309 }
310
311 for (i = 0; i < RT_WLAN_PROT_MAX; i++)
312 {
313 if ((prot_event_tab[event][i].handler != RT_NULL) &&
314 (prot_event_tab[event][i].prot == prot))
315 {
316 rt_memset(&prot_event_tab[event][i], 0, sizeof(struct rt_wlan_prot_event_des));
317 return RT_EOK;
318 }
319 }
320
321 return -RT_ERROR;
322 }
323
rt_wlan_prot_transfer_dev(struct rt_wlan_device * wlan,void * buff,int len)324 rt_err_t rt_wlan_prot_transfer_dev(struct rt_wlan_device *wlan, void *buff, int len)
325 {
326 if (wlan->ops->wlan_send != RT_NULL)
327 {
328 return wlan->ops->wlan_send(wlan, buff, len);
329 }
330 return -RT_ERROR;
331 }
332
rt_wlan_dev_transfer_prot(struct rt_wlan_device * wlan,void * buff,int len)333 rt_err_t rt_wlan_dev_transfer_prot(struct rt_wlan_device *wlan, void *buff, int len)
334 {
335 struct rt_wlan_prot *prot = wlan->prot;
336
337 if (prot != RT_NULL)
338 {
339 return prot->ops->prot_recv(wlan, buff, len);
340 }
341 return -RT_ERROR;
342 }
343
344 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)345 int rt_wlan_prot_ready(struct rt_wlan_device *wlan, struct rt_wlan_buff *buff)
346 {
347 return rt_wlan_prot_ready_event(wlan, buff);
348 }
349
rt_wlan_prot_dump(void)350 void rt_wlan_prot_dump(void)
351 {
352 int i;
353
354 rt_kprintf(" name id \n");
355 rt_kprintf("-------- --------\n");
356 for (i = 0; i < RT_WLAN_PROT_MAX; i++)
357 {
358 if (_prot[i] != RT_NULL)
359 {
360 rt_kprintf("%-8.8s ", _prot[i]->name);
361 rt_kprintf("%08x\n", _prot[i]->id);
362 }
363 }
364 }
365