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