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 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 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 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 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 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 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 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 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 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 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 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); 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 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