xref: /nrf52832-nimble/rt-thread/components/drivers/wlan/wlan_prot.c (revision 104654410c56c573564690304ae786df310c91fc)
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