1 /* 2 * CmdInterpretWext.c 3 * 4 * Copyright(c) 1998 - 2009 Texas Instruments. All rights reserved. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * * Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * * Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * * Neither the name Texas Instruments nor the names of its 18 * contributors may be used to endorse or promote products derived 19 * from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 35 #include "tidef.h" 36 #include "WlanDrvIf.h" 37 #include "tiwlnif.h" 38 #include "osDot11.h" 39 #include "802_11Defs.h" 40 #include "paramOut.h" 41 #include "coreDefaultParams.h" 42 #include "version.h" 43 #include "osApi.h" 44 #include "CmdHndlr.h" 45 #include "CmdInterpret.h" 46 #include "CmdInterpretWext.h" 47 #include "TI_IPC_Api.h" 48 #include "WlanDrvIf.h" 49 #include <linux/wireless.h> 50 #include <linux/if_arp.h> 51 #include <asm/uaccess.h> 52 #include <net/iw_handler.h> 53 #include "privateCmd.h" 54 #include "DrvMain.h" 55 #include "CmdDispatcher.h" 56 #include "EvHandler.h" 57 #include "admCtrl.h" 58 59 60 static TI_INT32 cmdInterpret_Event(IPC_EV_DATA* pData); 61 static int cmdInterpret_setSecurityParams (TI_HANDLE hCmdInterpret); 62 static int cmdInterpret_initEvents(TI_HANDLE hCmdInterpret); 63 static int cmdInterpret_unregisterEvents(TI_HANDLE hCmdInterpret, TI_HANDLE hEvHandler); 64 65 #define CHECK_PENDING_RESULT(x,y) if (x == COMMAND_PENDING) { os_printf ("Unexpected COMMAND PENDING result (cmd = 0x%x)\n",y->paramType); break; } 66 67 static const char *ieee80211_modes[] = { 68 "?", "IEEE 802.11 B", "IEEE 802.11 A", "IEEE 802.11 BG", "IEEE 802.11 ABG" 69 }; 70 #ifdef XCC_MODULE_INCLUDED 71 typedef struct 72 { 73 74 TI_UINT8 *assocRespBuffer; 75 TI_UINT32 assocRespLen; 76 } cckm_assocInformation_t; 77 78 #define ASSOC_RESP_FIXED_DATA_LEN 6 79 #define MAX_BEACON_BODY_LENGTH 350 80 #define BEACON_HEADER_FIX_SIZE 12 81 #define CCKM_START_EVENT_SIZE 23 /* cckm-start string + timestamp + bssid + null */ 82 #endif 83 84 /* Initialize the CmdInterpreter module */ 85 TI_HANDLE cmdInterpret_Create (TI_HANDLE hOs) 86 { 87 cmdInterpret_t *pCmdInterpret; 88 89 /* Allocate memory for object */ 90 pCmdInterpret = os_memoryAlloc (hOs, sizeof(cmdInterpret_t)); 91 92 /* In case of failure -> return NULL */ 93 if (!pCmdInterpret) 94 { 95 os_printf ("cmdInterpret_init: failed to allocate memory...aborting\n"); 96 return NULL; 97 } 98 99 /* Clear all fields in cmdInterpreter module object */ 100 os_memoryZero (hOs, pCmdInterpret, sizeof (cmdInterpret_t)); 101 102 /* Save handlers */ 103 pCmdInterpret->hOs = hOs; 104 105 /* Return pointer to object */ 106 return (TI_HANDLE)pCmdInterpret; 107 } 108 109 110 /* Deinitialize the cmdInterpreter module */ 111 TI_STATUS cmdInterpret_Destroy (TI_HANDLE hCmdInterpret, TI_HANDLE hEvHandler) 112 { 113 cmdInterpret_t *pCmdInterpret = (cmdInterpret_t *)hCmdInterpret; 114 115 /* Unregister events */ 116 cmdInterpret_unregisterEvents ((TI_HANDLE)pCmdInterpret, hEvHandler); 117 118 /* Release allocated memory */ 119 os_memoryFree (pCmdInterpret->hOs, pCmdInterpret, sizeof(cmdInterpret_t)); 120 121 return TI_OK; 122 } 123 124 125 void cmdInterpret_Init (TI_HANDLE hCmdInterpret, TStadHandlesList *pStadHandles) 126 { 127 cmdInterpret_t *pCmdInterpret = (cmdInterpret_t *)hCmdInterpret; 128 129 pCmdInterpret->hCmdHndlr = pStadHandles->hCmdHndlr; 130 pCmdInterpret->hEvHandler = pStadHandles->hEvHandler; 131 pCmdInterpret->hCmdDispatch = pStadHandles->hCmdDispatch; 132 133 /* Register to driver events */ 134 cmdInterpret_initEvents (hCmdInterpret); 135 } 136 137 138 /* Handle a single command */ 139 int cmdInterpret_convertAndExecute(TI_HANDLE hCmdInterpret, TConfigCommand *cmdObj) 140 { 141 cmdInterpret_t *pCmdInterpret = (cmdInterpret_t *)hCmdInterpret; 142 paramInfo_t *pParam; 143 TI_STATUS res = TI_NOK; 144 int i,j; 145 146 union iwreq_data *wrqu = (union iwreq_data *)cmdObj->buffer1; 147 148 cmdObj->return_code = WEXT_NOT_SUPPORTED; 149 pParam = (paramInfo_t *)os_memoryAlloc(pCmdInterpret->hOs, sizeof(paramInfo_t)); 150 if (!pParam) 151 return res; 152 /* Check user request */ 153 switch (cmdObj->cmd) 154 { 155 156 /* get name == wireless protocol - used to verify the presence of Wireless Extensions*/ 157 case SIOCGIWNAME: 158 os_memoryCopy(pCmdInterpret->hOs, cmdObj->buffer1, WLAN_PROTOCOL_NAME, IFNAMSIZ); 159 res = TI_OK; 160 break; 161 162 /* Set channel / frequency */ 163 case SIOCSIWFREQ: 164 { 165 /* If there is a given channel */ 166 if (wrqu->freq.m != 0) 167 { 168 pParam->paramType = SITE_MGR_DESIRED_CHANNEL_PARAM; 169 pParam->paramLength = sizeof(TI_UINT32); 170 pParam->content.siteMgrDesiredChannel = wrqu->freq.m; 171 172 res = cmdDispatch_SetParam (pCmdInterpret->hCmdDispatch, pParam); 173 CHECK_PENDING_RESULT(res,pParam) 174 } 175 break; 176 } 177 178 /* Get channel / frequency */ 179 case SIOCGIWFREQ: 180 { 181 pParam->paramType = SITE_MGR_CURRENT_CHANNEL_PARAM; 182 pParam->paramLength = sizeof(TI_UINT32); 183 184 res = cmdDispatch_GetParam (pCmdInterpret->hCmdDispatch, pParam); 185 if(res == NO_SITE_SELECTED_YET) 186 res = TI_OK; 187 188 CHECK_PENDING_RESULT(res,pParam) 189 190 if (res == TI_OK) 191 { 192 wrqu->freq.m = pParam->content.siteMgrCurrentChannel; 193 wrqu->freq.e = 3; 194 wrqu->freq.i = 0; 195 } 196 break; 197 } 198 199 /* Set Mode (Adhoc / infrastructure) */ 200 case SIOCSIWMODE: 201 { 202 pParam->paramType = SME_DESIRED_BSS_TYPE_PARAM; 203 pParam->paramLength = sizeof(ScanBssType_e); 204 205 switch (wrqu->mode) 206 { 207 case IW_MODE_AUTO: 208 pParam->content.smeDesiredBSSType = BSS_ANY; 209 break; 210 case IW_MODE_ADHOC: 211 pParam->content.smeDesiredBSSType = BSS_INDEPENDENT; 212 break; 213 case IW_MODE_INFRA: 214 pParam->content.smeDesiredBSSType = BSS_INFRASTRUCTURE; 215 break; 216 default: 217 res = -EOPNOTSUPP; 218 goto cmd_end; 219 } 220 221 res = cmdDispatch_SetParam(pCmdInterpret->hCmdDispatch, pParam); 222 CHECK_PENDING_RESULT(res,pParam) 223 224 /* also set the site mgr desired mode */ 225 pParam->paramType = SITE_MGR_DESIRED_BSS_TYPE_PARAM; 226 res = cmdDispatch_SetParam(pCmdInterpret->hCmdDispatch, pParam); 227 CHECK_PENDING_RESULT(res,pParam) 228 229 break; 230 } 231 232 /* Get Mode (Adhoc / infrastructure) */ 233 case SIOCGIWMODE: 234 { 235 pParam->paramType = SME_DESIRED_BSS_TYPE_PARAM; 236 pParam->paramLength = sizeof(ScanBssType_e); 237 res = cmdDispatch_GetParam(pCmdInterpret->hCmdDispatch, pParam); 238 CHECK_PENDING_RESULT(res,pParam) 239 240 switch (pParam->content.smeDesiredBSSType) 241 { 242 case BSS_ANY: 243 wrqu->mode = IW_MODE_AUTO; 244 break; 245 case BSS_INDEPENDENT: 246 wrqu->mode = IW_MODE_ADHOC; 247 break; 248 case BSS_INFRASTRUCTURE: 249 wrqu->mode = IW_MODE_INFRA; 250 break; 251 default: 252 break; 253 } 254 255 break; 256 } 257 258 /* Set sensitivity (Rssi roaming threshold)*/ 259 case SIOCSIWSENS: 260 { 261 /* First get the current roaming configuration as a whole */ 262 pParam->paramType = ROAMING_MNGR_APPLICATION_CONFIGURATION; 263 pParam->paramLength = sizeof (roamingMngrConfigParams_t); 264 res = cmdDispatch_GetParam(pCmdInterpret->hCmdDispatch, pParam); 265 266 CHECK_PENDING_RESULT(res,pParam) 267 268 /* Now change the low rssi threshold supplied by the user */ 269 pParam->content.roamingConfigBuffer.roamingMngrThresholdsConfig.lowRssiThreshold = wrqu->param.value; 270 271 /* And set the parameters back to the roaming module */ 272 res = cmdDispatch_SetParam(pCmdInterpret->hCmdDispatch, pParam); 273 274 CHECK_PENDING_RESULT(res,pParam) 275 276 break; 277 } 278 279 /* Get sensitivity (Rssi threshold OR CCA?)*/ 280 case SIOCGIWSENS: 281 { 282 pParam->paramType = ROAMING_MNGR_APPLICATION_CONFIGURATION; 283 pParam->paramLength = sizeof (roamingMngrConfigParams_t); 284 res = cmdDispatch_GetParam(pCmdInterpret->hCmdDispatch, pParam); 285 286 CHECK_PENDING_RESULT(res,pParam) 287 288 if (res == TI_OK) 289 { 290 wrqu->param.value = pParam->content.roamingConfigBuffer.roamingMngrThresholdsConfig.lowRssiThreshold; 291 wrqu->param.disabled = (wrqu->param.value == 0); 292 wrqu->param.fixed = 1; 293 } 294 295 break; 296 } 297 298 /* Get a range of parameters regarding the device capabilities */ 299 case SIOCGIWRANGE: 300 { 301 struct iw_point *data = (struct iw_point *) cmdObj->buffer1; 302 struct iw_range *range = (struct iw_range *) cmdObj->buffer2; 303 int i; 304 305 /* Reset structure */ 306 data->length = sizeof(struct iw_range); 307 os_memorySet(pCmdInterpret->hOs, range, 0, sizeof(struct iw_range)); 308 309 /* Wireless Extension version info */ 310 range->we_version_compiled = WIRELESS_EXT; /* Must be WIRELESS_EXT */ 311 range->we_version_source = 19; /* Last update of source */ 312 313 /* estimated maximum TCP throughput values (bps) */ 314 range->throughput = MAX_THROUGHPUT; 315 316 /* NWID (or domain id) */ 317 range->min_nwid = 0; /* Minimal NWID we are able to set */ 318 range->max_nwid = 0; /* Maximal NWID we are able to set */ 319 320 /* Old Frequency - no need to support this*/ 321 range->old_num_channels = 0; 322 range->old_num_frequency = 0; 323 324 /* Wireless event capability bitmasks */ 325 IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWAP); 326 IW_EVENT_CAPA_SET(range->event_capa, IWEVREGISTERED); 327 IW_EVENT_CAPA_SET(range->event_capa, IWEVEXPIRED); 328 329 /* signal level threshold range */ 330 range->sensitivity = 0; 331 332 /* Rates */ 333 pParam->paramType = SITE_MGR_DESIRED_SUPPORTED_RATE_SET_PARAM; 334 res = cmdDispatch_GetParam (pCmdInterpret->hCmdDispatch, pParam ); 335 336 CHECK_PENDING_RESULT(res,pParam) 337 338 /* Number of entries in the rates list */ 339 range->num_bitrates = pParam->content.siteMgrDesiredSupportedRateSet.len; 340 for (i=0; i<pParam->content.siteMgrDesiredSupportedRateSet.len; i++) 341 { 342 range->bitrate[i] = ((pParam->content.siteMgrDesiredSupportedRateSet.ratesString[i] & 0x7F) * 500000); 343 } 344 345 /* RTS threshold */ 346 range->min_rts = TWD_RTS_THRESHOLD_MIN; /* Minimal RTS threshold */ 347 range->max_rts = TWD_RTS_THRESHOLD_DEF; /* Maximal RTS threshold */ 348 349 /* Frag threshold */ 350 range->min_frag = TWD_FRAG_THRESHOLD_MIN; /* Minimal frag threshold */ 351 range->max_frag = TWD_FRAG_THRESHOLD_DEF; /* Maximal frag threshold */ 352 353 /* Power Management duration & timeout */ 354 range->min_pmp = 0; /* Minimal PM period */ 355 range->max_pmp = 0; /* Maximal PM period */ 356 range->min_pmt = 0; /* Minimal PM timeout */ 357 range->max_pmt = 0; /* Maximal PM timeout */ 358 range->pmp_flags = IW_POWER_ON; /* How to decode max/min PM period */ 359 range->pmt_flags = IW_POWER_ON; /* How to decode max/min PM timeout */ 360 361 /* What Power Management options are supported */ 362 range->pm_capa = IW_POWER_UNICAST_R | /* Receive only unicast messages */ 363 IW_POWER_MULTICAST_R | /* Receive only multicast messages */ 364 IW_POWER_ALL_R | /* Receive all messages though PM */ 365 IW_POWER_FORCE_S | /* Force PM procedure for sending unicast */ 366 IW_POWER_PERIOD | /* Value is a period/duration of */ 367 IW_POWER_TIMEOUT; /* Value is a timeout (to go asleep) */ 368 369 /* Transmit power */ 370 range->txpower_capa = IW_TXPOW_RELATIVE | IW_TXPOW_RANGE; /* What options are supported */ 371 range->num_txpower = 5; /* Number of entries in the list */ 372 range->txpower[0] = 1; /* list of values (maximum is IW_MAX_TXPOWER = 8) */ 373 range->txpower[1] = 2; /* list of values (maximum is IW_MAX_TXPOWER = 8) */ 374 range->txpower[2] = 3; /* list of values (maximum is IW_MAX_TXPOWER = 8) */ 375 range->txpower[3] = 4; /* list of values (maximum is IW_MAX_TXPOWER = 8) */ 376 range->txpower[4] = 5; /* list of values (maximum is IW_MAX_TXPOWER = 8) */ 377 378 /* Retry limits and lifetime */ 379 range->retry_capa = 0; /* What retry options are supported */ 380 range->retry_flags = 0; /* How to decode max/min retry limit */ 381 range->r_time_flags = 0; /* How to decode max/min retry life */ 382 range->min_retry = 0; /* Minimal number of retries */ 383 range->max_retry = 0; /* Maximal number of retries */ 384 range->min_r_time = 0; /* Minimal retry lifetime */ 385 range->max_r_time = 0; /* Maximal retry lifetime */ 386 387 /* Get Supported channels */ 388 pParam->paramType = SITE_MGR_RADIO_BAND_PARAM; 389 res = cmdDispatch_GetParam( pCmdInterpret->hCmdDispatch, pParam ); 390 391 CHECK_PENDING_RESULT(res,pParam) 392 393 /* pParam->content.siteMgrRadioBand contains the current band, now get list of supported channels */ 394 pParam->paramType = REGULATORY_DOMAIN_ALL_SUPPORTED_CHANNELS; 395 res = cmdDispatch_GetParam( pCmdInterpret->hCmdDispatch, pParam ); 396 397 CHECK_PENDING_RESULT(res,pParam) 398 399 range->num_channels = pParam->content.supportedChannels.sizeOfList; /* Number of channels [0; num - 1] */ 400 range->num_frequency = pParam->content.supportedChannels.sizeOfList; /* Number of entry in the list */ 401 402 for (i=0; i<pParam->content.supportedChannels.sizeOfList; i++) 403 { 404 range->freq[i].e = 0; 405 range->freq[i].m = i; 406 range->freq[i].i = pParam->content.supportedChannels.listOfChannels[i]+1; 407 } 408 409 /* Encoder (Encryption) capabilities */ 410 range->num_encoding_sizes = 4; 411 /* 64(40) bits WEP */ 412 range->encoding_size[0] = WEP_KEY_LENGTH_40; 413 /* 128(104) bits WEP */ 414 range->encoding_size[1] = WEP_KEY_LENGTH_104; 415 /* 256 bits for WPA-PSK */ 416 range->encoding_size[2] = TKIP_KEY_LENGTH; 417 /* 128 bits for WPA2-PSK */ 418 range->encoding_size[3] = AES_KEY_LENGTH; 419 /* 4 keys are allowed */ 420 range->max_encoding_tokens = 4; 421 422 range->encoding_login_index = 0; /* token index for login token */ 423 424 /* Encryption capabilities */ 425 range->enc_capa = IW_ENC_CAPA_WPA | 426 IW_ENC_CAPA_WPA2 | 427 IW_ENC_CAPA_CIPHER_TKIP | 428 IW_ENC_CAPA_CIPHER_CCMP; /* IW_ENC_CAPA_* bit field */ 429 430 } 431 break; 432 433 /* Set desired BSSID */ 434 case SIOCSIWAP: 435 { 436 437 /* If MAC address is zeroes -> connect to "ANY" BSSID */ 438 if (MAC_NULL (wrqu->ap_addr.sa_data)) 439 { 440 /* Convert to "FF:FF:FF:FF:FF:FF" since this driver requires this value */ 441 MAC_COPY (pParam->content.siteMgrDesiredBSSID, "\xff\xff\xff\xff\xff\xff"); 442 } 443 else 444 { 445 MAC_COPY (pParam->content.siteMgrDesiredBSSID, wrqu->ap_addr.sa_data); 446 } 447 448 pParam->paramType = SITE_MGR_DESIRED_BSSID_PARAM; 449 res = cmdDispatch_SetParam ( pCmdInterpret->hCmdDispatch, pParam ); 450 CHECK_PENDING_RESULT(res,pParam) 451 452 /* also set it to the SME */ 453 pParam->paramType = SME_DESIRED_BSSID_PARAM; 454 res = cmdDispatch_SetParam ( pCmdInterpret->hCmdDispatch, pParam ); 455 CHECK_PENDING_RESULT(res,pParam) 456 457 break; 458 } 459 460 461 /* Get current BSSID */ 462 case SIOCGIWAP: 463 { 464 /* Get current AP BSSID */ 465 pParam->paramType = SITE_MGR_CURRENT_BSSID_PARAM; 466 res = cmdDispatch_GetParam ( pCmdInterpret->hCmdDispatch, pParam ); 467 468 CHECK_PENDING_RESULT(res,pParam) 469 470 /* In case we are not associated - copy zeroes into bssid */ 471 if (res == NO_SITE_SELECTED_YET) 472 { 473 MAC_COPY (wrqu->ap_addr.sa_data, "\x00\x00\x00\x00\x00\x00"); 474 cmdObj->return_code = WEXT_OK; 475 } 476 else if (res == TI_OK) 477 { 478 MAC_COPY (wrqu->ap_addr.sa_data, pParam->content.siteMgrDesiredBSSID); 479 } 480 481 break; 482 } 483 484 485 /* request MLME operation (Deauthenticate / Disassociate) */ 486 case SIOCSIWMLME: 487 { 488 struct iw_mlme *mlme = (struct iw_mlme *)cmdObj->param3; 489 490 pParam->paramType = SITE_MGR_DESIRED_SSID_PARAM; 491 492 /* In either case - we need to disconnect, so prepare "junk" SSID */ 493 for (i = 0; i < MAX_SSID_LEN; i++) 494 pParam->content.siteMgrDesiredSSID.str[i] = (i+1); 495 pParam->content.siteMgrDesiredSSID.len = MAX_SSID_LEN; 496 497 switch (mlme->cmd) 498 { 499 case IW_MLME_DEAUTH: 500 case IW_MLME_DISASSOC: 501 res = cmdDispatch_SetParam (pCmdInterpret->hCmdDispatch, pParam ); 502 CHECK_PENDING_RESULT(res,pParam) 503 /* now also set it to the SME */ 504 pParam->paramType = SME_DESIRED_SSID_ACT_PARAM; 505 res = cmdDispatch_SetParam (pCmdInterpret->hCmdDispatch, pParam ); 506 CHECK_PENDING_RESULT(res,pParam) 507 break; 508 default: 509 res = -EOPNOTSUPP; 510 goto cmd_end; 511 } 512 break; 513 } 514 515 /* trigger scanning (list cells) */ 516 case SIOCSIWSCAN: 517 { 518 if (wrqu->data.flags & IW_SCAN_THIS_ESSID) 519 { 520 struct iw_scan_req scanReq; 521 522 if(copy_from_user(&scanReq, wrqu->data.pointer, sizeof(scanReq))) 523 { 524 printk("CRITICAL: Could not copy data from user space!!!"); 525 res = -EFAULT; 526 goto cmd_end; 527 } 528 529 pParam->content.tScanDesiredSSID.len = scanReq.essid_len; 530 os_memoryCopy(pCmdInterpret->hOs, pParam->content.tScanDesiredSSID.str, scanReq.essid, scanReq.essid_len); 531 } 532 else 533 { 534 pParam->content.tScanDesiredSSID.len = 0; 535 } 536 537 pParam->paramType = SCAN_CNCN_BSSID_LIST_SCAN_PARAM; 538 pParam->paramLength = sizeof(pParam->content.tScanDesiredSSID); 539 res = cmdDispatch_SetParam (pCmdInterpret->hCmdDispatch, pParam ); 540 CHECK_PENDING_RESULT(res,pParam) 541 } 542 break; 543 544 /* get scanning results */ 545 case SIOCGIWSCAN: 546 { 547 unsigned char ies[256]; 548 unsigned char buf[30]; 549 char *event = (char *)cmdObj->buffer2; 550 struct iw_event iwe; 551 char *end_buf, *current_val; 552 int allocated_size; 553 OS_802_11_BSSID_LIST_EX *my_list; 554 OS_802_11_BSSID_EX *my_current; 555 int offset; 556 OS_802_11_VARIABLE_IEs *pRsnIes; 557 int ies_offset; 558 int i; 559 560 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) 561 struct iw_request_info info; 562 info.cmd = SIOCGIWSCAN; 563 info.flags = 0; 564 #endif 565 end_buf = (char *)(cmdObj->buffer2 + wrqu->data.length); 566 567 /* First get the amount of memory required to hold the entire BSSID list by setting the length to 0 */ 568 pParam->paramType = SCAN_CNCN_BSSID_LIST_SIZE_PARAM; 569 pParam->paramLength = 0; 570 res = cmdDispatch_GetParam (pCmdInterpret->hCmdDispatch, pParam ); 571 CHECK_PENDING_RESULT(res,pParam) 572 573 allocated_size = pParam->content.uBssidListSize; 574 575 /* Allocate required memory */ 576 my_list = os_memoryAlloc (pCmdInterpret->hOs, allocated_size); 577 if (!my_list) { 578 res = -ENOMEM; 579 goto cmd_end; 580 } 581 582 /* And retrieve the list */ 583 pParam->paramType = SCAN_CNCN_BSSID_LIST_PARAM; 584 pParam->content.pBssidList = my_list; 585 pParam->paramLength = allocated_size; 586 res = cmdDispatch_GetParam (pCmdInterpret->hCmdDispatch, pParam ); 587 CHECK_PENDING_RESULT(res,pParam) 588 589 my_current = &my_list->Bssid[0]; 590 i=0; 591 if(wrqu->data.flags) 592 { 593 for (i=0; i<wrqu->data.flags; i++) 594 my_current = (OS_802_11_BSSID_EX *) (((char *) my_current) + my_current->Length); 595 } 596 /* Now send a wireless event per BSSID with "tokens" describing it */ 597 598 for (; i<my_list->NumberOfItems; i++) 599 { 600 601 if (event + my_current->Length > end_buf) 602 { 603 break; 604 } 605 606 /* The first entry MUST be the AP BSSID */ 607 os_memorySet (pCmdInterpret->hOs, &iwe, 0, sizeof(iwe)); 608 iwe.cmd = SIOCGIWAP; 609 iwe.u.ap_addr.sa_family = ARPHRD_ETHER; 610 iwe.len = IW_EV_ADDR_LEN; 611 os_memoryCopy(pCmdInterpret->hOs, iwe.u.ap_addr.sa_data, &my_current->MacAddress, ETH_ALEN); 612 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27) 613 event = iwe_stream_add_event(event, end_buf, &iwe, IW_EV_ADDR_LEN); 614 #else 615 event = iwe_stream_add_event(&info,event, end_buf, &iwe, IW_EV_ADDR_LEN); 616 #endif 617 /* Add SSID */ 618 iwe.cmd = SIOCGIWESSID; 619 iwe.u.data.flags = 1; 620 iwe.u.data.length = min((TI_UINT8)my_current->Ssid.SsidLength, (TI_UINT8)32); 621 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27) 622 event = iwe_stream_add_point(event, end_buf, &iwe, my_current->Ssid.Ssid); 623 #else 624 event = iwe_stream_add_point(&info,event, end_buf, &iwe, my_current->Ssid.Ssid); 625 #endif 626 /* Add the protocol name (BSS support for A/B/G) */ 627 os_memorySet (pCmdInterpret->hOs, &iwe, 0, sizeof(iwe)); 628 iwe.cmd = SIOCGIWNAME; 629 os_memoryCopy(pCmdInterpret->hOs, (void*)iwe.u.name, (void*)ieee80211_modes[my_current->NetworkTypeInUse], IFNAMSIZ); 630 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27) 631 event = iwe_stream_add_event(event, end_buf, &iwe, IW_EV_CHAR_LEN); 632 #else 633 event = iwe_stream_add_event(&info,event, end_buf, &iwe, IW_EV_CHAR_LEN); 634 #endif 635 /* add mode (infrastructure or Adhoc) */ 636 os_memorySet (pCmdInterpret->hOs, &iwe, 0, sizeof(iwe)); 637 iwe.cmd = SIOCGIWMODE; 638 if (my_current->InfrastructureMode == os802_11IBSS) 639 iwe.u.mode = IW_MODE_ADHOC; 640 else if (my_current->InfrastructureMode == os802_11Infrastructure) 641 iwe.u.mode = IW_MODE_INFRA; 642 else 643 iwe.u.mode = IW_MODE_AUTO; 644 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27) 645 event = iwe_stream_add_event(event, end_buf, &iwe, IW_EV_UINT_LEN); 646 #else 647 event = iwe_stream_add_event(&info,event, end_buf, &iwe, IW_EV_UINT_LEN); 648 #endif 649 650 /* add freq */ 651 os_memorySet (pCmdInterpret->hOs, &iwe, 0, sizeof(iwe)); 652 iwe.cmd = SIOCGIWFREQ; 653 iwe.u.freq.m = my_current->Configuration.Union.channel; 654 iwe.u.freq.e = 3; /* Frequency divider */ 655 iwe.u.freq.i = 0; 656 iwe.len = IW_EV_FREQ_LEN; 657 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27) 658 event = iwe_stream_add_event(event, end_buf, &iwe, IW_EV_FREQ_LEN); 659 #else 660 event = iwe_stream_add_event(&info,event, end_buf, &iwe, IW_EV_FREQ_LEN); 661 #endif 662 /* Add quality statistics */ 663 iwe.cmd = IWEVQUAL; 664 iwe.u.qual.updated = IW_QUAL_LEVEL_UPDATED | IW_QUAL_QUAL_INVALID | IW_QUAL_NOISE_INVALID | IW_QUAL_DBM; 665 iwe.u.qual.qual = 0; 666 iwe.u.qual.level = my_current->Rssi; 667 iwe.u.qual.noise = 0; 668 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27) 669 event = iwe_stream_add_event(event, end_buf, &iwe, IW_EV_QUAL_LEN); 670 #else 671 event = iwe_stream_add_event(&info,event, end_buf, &iwe, IW_EV_QUAL_LEN); 672 #endif 673 /* Add encryption capability */ 674 iwe.cmd = SIOCGIWENCODE; 675 if ((my_current->Capabilities >> CAP_PRIVACY_SHIFT) & CAP_PRIVACY_MASK) 676 iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; 677 else 678 iwe.u.data.flags = IW_ENCODE_DISABLED; 679 iwe.u.data.length = 0; 680 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27) 681 event = iwe_stream_add_point(event, end_buf, &iwe, NULL); 682 #else 683 event = iwe_stream_add_point(&info,event, end_buf, &iwe, NULL); 684 #endif 685 686 /* add rate */ 687 os_memorySet (pCmdInterpret->hOs, &iwe, 0, sizeof(iwe)); 688 iwe.cmd = SIOCGIWRATE; 689 current_val = event + IW_EV_LCP_LEN; 690 for (j=0; j<16; j++) 691 { 692 if (my_current->SupportedRates[j]) 693 { 694 iwe.u.bitrate.value = ((my_current->SupportedRates[j] & 0x7f) * 500000); 695 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27) 696 current_val = iwe_stream_add_value(event, current_val, end_buf, &iwe,IW_EV_PARAM_LEN); 697 #else 698 current_val = iwe_stream_add_value(&info,event, current_val,end_buf, &iwe,IW_EV_PARAM_LEN); 699 #endif 700 } 701 } 702 703 event = current_val; 704 705 /* CUSTOM - Add beacon interval */ 706 os_memorySet (pCmdInterpret->hOs, &iwe, 0, sizeof(iwe)); 707 iwe.cmd = IWEVCUSTOM; 708 sprintf(buf, "Bcn int = %d ms ", my_current->Configuration.BeaconPeriod); 709 iwe.u.data.length = strlen(buf); 710 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27) 711 event = iwe_stream_add_point(event, end_buf, &iwe, buf); 712 #else 713 event = iwe_stream_add_point(&info,event, end_buf, &iwe, buf); 714 #endif 715 /* add RSN IE */ 716 os_memorySet (pCmdInterpret->hOs, &iwe, 0, sizeof(iwe)); 717 os_memorySet (pCmdInterpret->hOs, ies, 0, 256); 718 iwe.cmd = IWEVGENIE; 719 offset = sizeof(OS_802_11_FIXED_IEs); 720 ies_offset = 0; 721 722 while(offset < my_current->IELength) 723 { 724 pRsnIes = (OS_802_11_VARIABLE_IEs*)&(my_current->IEs[offset]); 725 if((pRsnIes->ElementID == RSN_IE_ID) || (pRsnIes->ElementID == WPA_IE_ID)) 726 { 727 os_memoryCopy (pCmdInterpret->hOs, ies + ies_offset, (char *)&(my_current->IEs[offset]), pRsnIes->Length + 2); 728 ies_offset += pRsnIes->Length + 2; 729 } 730 offset += pRsnIes->Length + 2; 731 } 732 if (ies_offset) 733 { 734 iwe.u.data.flags = 1; 735 iwe.u.data.length = ies_offset; 736 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27) 737 event = iwe_stream_add_point(event, end_buf, &iwe, (char *)ies); 738 #else 739 event = iwe_stream_add_point(&info, event, end_buf, &iwe, (char *)ies); 740 #endif 741 } 742 743 my_current = (OS_802_11_BSSID_EX *) (((char *) my_current) + my_current->Length); 744 } 745 746 wrqu->data.length = event - ((char *)cmdObj->buffer2); 747 if(i == my_list->NumberOfItems) 748 { 749 wrqu->data.flags = 0; 750 } 751 else 752 { 753 wrqu->data.flags = i; 754 } 755 756 os_memoryFree (pCmdInterpret->hOs, my_list, allocated_size); 757 cmdObj->return_code = WEXT_OK; 758 } 759 760 break; 761 762 /* Set ESSID */ 763 case SIOCSIWESSID: 764 { 765 char *extra = cmdObj->buffer2; 766 int length; 767 768 if (wrqu->essid.flags & SET_SSID_WITHOUT_SUPPL) 769 wrqu->essid.flags &= ~SET_SSID_WITHOUT_SUPPL; 770 else 771 cmdInterpret_setSecurityParams (hCmdInterpret); 772 773 os_memoryZero (pCmdInterpret->hOs, &pParam->content.siteMgrDesiredSSID.str, MAX_SSID_LEN); 774 775 pParam->content.siteMgrCurrentSSID.len = 0; 776 777 if (wrqu->essid.flags == 0) 778 { 779 /* Connect to ANY ESSID - use empty */ 780 os_memoryCopy(pCmdInterpret->hOs, &pParam->content.siteMgrCurrentSSID.str, "\00", 1); 781 pParam->content.siteMgrCurrentSSID.len = 0;; 782 } else 783 { 784 /* Handle ESSID length issue in WEXT (backward compatibility with old/new versions) */ 785 length = wrqu->essid.length - 1; 786 if (length > 0) 787 length--; 788 while (length < wrqu->essid.length && extra[length]) 789 length++; 790 791 os_memoryCopy(pCmdInterpret->hOs, &pParam->content.siteMgrCurrentSSID.str, cmdObj->buffer2, length); 792 pParam->content.siteMgrCurrentSSID.len = length; 793 } 794 795 pParam->paramType = SITE_MGR_DESIRED_SSID_PARAM; 796 pParam->paramLength = sizeof (TSsid); 797 res = cmdDispatch_SetParam (pCmdInterpret->hCmdDispatch, pParam ); 798 CHECK_PENDING_RESULT(res,pParam) 799 /* also set it to the SME */ 800 pParam->paramType = SME_DESIRED_SSID_ACT_PARAM; 801 res = cmdDispatch_SetParam (pCmdInterpret->hCmdDispatch, pParam ); 802 CHECK_PENDING_RESULT(res,pParam) 803 } 804 break; 805 806 /* get ESSID */ 807 case SIOCGIWESSID: 808 { 809 char *extra = (char *)cmdObj->buffer2; 810 811 pParam->paramType = SITE_MGR_CURRENT_SSID_PARAM; 812 res = cmdDispatch_GetParam ( pCmdInterpret->hCmdDispatch, pParam ); 813 if(res == NO_SITE_SELECTED_YET) 814 res = WEXT_OK; 815 816 CHECK_PENDING_RESULT(res,pParam) 817 818 wrqu->essid.flags = 1; 819 820 os_memoryCopy(pCmdInterpret->hOs, cmdObj->buffer2, &pParam->content.siteMgrCurrentSSID.str, pParam->content.siteMgrCurrentSSID.len ); 821 822 if (pParam->content.siteMgrCurrentSSID.len < MAX_SSID_LEN) 823 { 824 extra[pParam->content.siteMgrCurrentSSID.len] = 0; 825 } 826 wrqu->essid.length = pParam->content.siteMgrCurrentSSID.len; 827 } 828 829 break; 830 831 /* set node name/nickname */ 832 case SIOCSIWNICKN: 833 { 834 if (wrqu->data.length > IW_ESSID_MAX_SIZE) { 835 res = -EINVAL; 836 goto cmd_end; 837 } 838 os_memoryCopy(pCmdInterpret->hOs, pCmdInterpret->nickName, cmdObj->buffer2, wrqu->data.length); 839 pCmdInterpret->nickName[IW_ESSID_MAX_SIZE] = 0; 840 res = TI_OK; 841 } 842 843 break; 844 845 /* get node name/nickname */ 846 case SIOCGIWNICKN: 847 { 848 struct iw_point *data = (struct iw_point *) cmdObj->buffer1; 849 850 data->length = strlen(pCmdInterpret->nickName); 851 os_memoryCopy(pCmdInterpret->hOs, cmdObj->buffer2, &pCmdInterpret->nickName, data->length); 852 853 res = TI_OK; 854 } 855 break; 856 857 /* Set RTS Threshold */ 858 case SIOCSIWRTS: 859 { 860 pParam->paramType = TWD_RTS_THRESHOLD_PARAM; 861 862 if (wrqu->rts.disabled) 863 pParam->content.halCtrlRtsThreshold = TWD_RTS_THRESHOLD_DEF; 864 else 865 pParam->content.halCtrlRtsThreshold = wrqu->rts.value; 866 867 res = cmdDispatch_SetParam (pCmdInterpret->hCmdDispatch,pParam); 868 CHECK_PENDING_RESULT(res,pParam) 869 break; 870 } 871 872 /* Get RTS Threshold */ 873 case SIOCGIWRTS: 874 { 875 pParam->paramType = TWD_RTS_THRESHOLD_PARAM; 876 res = cmdDispatch_GetParam (pCmdInterpret->hCmdDispatch,pParam); 877 878 CHECK_PENDING_RESULT(res,pParam) 879 880 wrqu->rts.value = pParam->content.halCtrlRtsThreshold; 881 wrqu->rts.fixed = 1; 882 cmdObj->return_code = WEXT_OK; 883 break; 884 } 885 886 /* Set Fragmentation threshold */ 887 case SIOCSIWFRAG: 888 { 889 pParam->paramType = TWD_FRAG_THRESHOLD_PARAM; 890 pParam->content.halCtrlFragThreshold = ((wrqu->frag.value+1)>>1) << 1; /* make it always even */ 891 892 res = cmdDispatch_SetParam(pCmdInterpret->hCmdDispatch, pParam); 893 CHECK_PENDING_RESULT(res,pParam) 894 895 break; 896 } 897 898 /* Get Fragmentation threshold */ 899 case SIOCGIWFRAG: 900 { 901 pParam->paramType = TWD_FRAG_THRESHOLD_PARAM; 902 res = cmdDispatch_GetParam (pCmdInterpret->hCmdDispatch,pParam); 903 904 CHECK_PENDING_RESULT(res,pParam) 905 906 wrqu->rts.value = pParam->content.halCtrlFragThreshold; 907 wrqu->rts.fixed = 1; 908 cmdObj->return_code = WEXT_OK; 909 break; 910 } 911 912 /* Set TX power level */ 913 case SIOCSIWTXPOW: 914 if (wrqu->txpower.disabled == 1) 915 { 916 cmdObj->return_code = WEXT_INVALID_PARAMETER; 917 } 918 else 919 { 920 pParam->paramType = REGULATORY_DOMAIN_CURRENT_TX_POWER_LEVEL_PARAM; 921 pParam->content.desiredTxPower = wrqu->txpower.value; 922 res = cmdDispatch_SetParam (pCmdInterpret->hCmdDispatch,pParam); 923 CHECK_PENDING_RESULT(res,pParam) 924 } 925 break; 926 927 /* Get TX power level */ 928 case SIOCGIWTXPOW: 929 { 930 pParam->paramType = REGULATORY_DOMAIN_CURRENT_TX_POWER_IN_DBM_PARAM; 931 res = cmdDispatch_GetParam (pCmdInterpret->hCmdDispatch,pParam); 932 933 CHECK_PENDING_RESULT(res,pParam) 934 935 wrqu->txpower.flags = IW_TXPOW_RELATIVE | IW_TXPOW_RANGE; 936 wrqu->txpower.disabled = 0; 937 wrqu->txpower.fixed = 0; 938 wrqu->txpower.value = pParam->content.desiredTxPower; 939 940 break; 941 } 942 943 /* set encoding token & mode - WEP only */ 944 case SIOCSIWENCODE: 945 { 946 int index; 947 948 index = (wrqu->encoding.flags & IW_ENCODE_INDEX); 949 950 /* iwconfig gives index as 1 - N */ 951 if (index > 0) 952 index--; 953 else 954 { 955 pParam->paramType = RSN_DEFAULT_KEY_ID; 956 res = cmdDispatch_GetParam (pCmdInterpret->hCmdDispatch,pParam); 957 CHECK_PENDING_RESULT(res,pParam) 958 index = pParam->content.rsnDefaultKeyID; 959 } 960 961 pParam->paramType = RSN_ADD_KEY_PARAM; 962 /* remove key if disabled */ 963 if (wrqu->data.flags & IW_ENCODE_DISABLED) 964 { 965 pParam->paramType = RSN_REMOVE_KEY_PARAM; 966 } 967 968 pParam->content.rsnOsKey.KeyIndex = index; 969 970 if (wrqu->data.length) 971 { 972 os_memoryCopy(pCmdInterpret->hOs, &pParam->content.rsnOsKey.KeyMaterial, cmdObj->buffer2, wrqu->data.length); 973 pParam->content.rsnOsKey.KeyLength = wrqu->data.length; 974 } else 975 { 976 /* No key material is provided, just set given index as default TX key */ 977 pParam->paramType = RSN_DEFAULT_KEY_ID; 978 pParam->content.rsnDefaultKeyID = index; 979 } 980 981 res = cmdDispatch_SetParam (pCmdInterpret->hCmdDispatch, pParam); 982 CHECK_PENDING_RESULT(res,pParam) 983 984 break; 985 } 986 987 988 /* get encoding token & mode */ 989 case SIOCGIWENCODE: 990 { 991 int index, encr_mode; 992 char *extra = (char *)cmdObj->buffer2; 993 TSecurityKeys myKeyInfo; 994 995 wrqu->data.length = 0; 996 extra[0] = 0; 997 998 /* Get Index from user request */ 999 index = (wrqu->encoding.flags & IW_ENCODE_INDEX); 1000 if (index > 0) 1001 index--; 1002 else 1003 { 1004 pParam->paramType = RSN_DEFAULT_KEY_ID; 1005 res = cmdDispatch_GetParam (pCmdInterpret->hCmdDispatch,pParam); 1006 CHECK_PENDING_RESULT(res,pParam) 1007 index = pParam->content.rsnDefaultKeyID; 1008 wrqu->data.flags = (index+1); 1009 } 1010 1011 pParam->content.pRsnKey = &myKeyInfo; 1012 1013 pParam->paramType = RSN_KEY_PARAM; 1014 pParam->content.pRsnKey->keyIndex = index; 1015 res = cmdDispatch_GetParam (pCmdInterpret->hCmdDispatch,pParam); 1016 CHECK_PENDING_RESULT(res,pParam) 1017 1018 if ((pParam->content.pRsnKey) && (pParam->content.pRsnKey->encLen)) 1019 { 1020 wrqu->data.flags |= IW_ENCODE_ENABLED; 1021 wrqu->data.length = pParam->content.pRsnKey->encLen; 1022 os_memoryCopy(pCmdInterpret->hOs,extra, &pParam->content.pRsnKey->encKey,wrqu->data.length); 1023 } 1024 1025 /* Convert from driver (OID-like) authentication parameters to WEXT */ 1026 if (pCmdInterpret->wai.iw_auth_cipher_pairwise & IW_AUTH_CIPHER_CCMP) 1027 encr_mode = os802_11Encryption3Enabled; 1028 else if (pCmdInterpret->wai.iw_auth_cipher_pairwise & IW_AUTH_CIPHER_TKIP) 1029 encr_mode = os802_11Encryption2Enabled; 1030 else if (pCmdInterpret->wai.iw_auth_cipher_pairwise & (IW_AUTH_CIPHER_WEP40 | IW_AUTH_CIPHER_WEP104)) 1031 encr_mode = os802_11Encryption1Enabled; 1032 else if (pCmdInterpret->wai.iw_auth_cipher_group & IW_AUTH_CIPHER_CCMP) 1033 encr_mode = os802_11Encryption3Enabled; 1034 else if (pCmdInterpret->wai.iw_auth_cipher_group & IW_AUTH_CIPHER_TKIP) 1035 encr_mode = os802_11Encryption2Enabled; 1036 else 1037 encr_mode = os802_11EncryptionDisabled; 1038 1039 if (encr_mode == os802_11EncryptionDisabled) 1040 wrqu->data.flags |= IW_ENCODE_OPEN; 1041 else 1042 wrqu->data.flags |= IW_ENCODE_RESTRICTED; 1043 1044 cmdObj->return_code = WEXT_OK; 1045 1046 } 1047 break; 1048 1049 /* Set Authentication */ 1050 case SIOCSIWAUTH: 1051 res = TI_OK; 1052 switch (wrqu->param.flags & IW_AUTH_INDEX) 1053 { 1054 case IW_AUTH_WPA_VERSION: 1055 pCmdInterpret->wai.iw_auth_wpa_version = wrqu->param.value; 1056 break; 1057 case IW_AUTH_CIPHER_PAIRWISE: 1058 pCmdInterpret->wai.iw_auth_cipher_pairwise = wrqu->param.value; 1059 break; 1060 case IW_AUTH_CIPHER_GROUP: 1061 pCmdInterpret->wai.iw_auth_cipher_group = wrqu->param.value; 1062 break; 1063 case IW_AUTH_KEY_MGMT: 1064 pCmdInterpret->wai.iw_auth_key_mgmt = wrqu->param.value; 1065 break; 1066 case IW_AUTH_80211_AUTH_ALG: 1067 pCmdInterpret->wai.iw_auth_80211_auth_alg = wrqu->param.value; 1068 break; 1069 case IW_AUTH_WPA_ENABLED: 1070 break; 1071 case IW_AUTH_TKIP_COUNTERMEASURES: 1072 break; 1073 case IW_AUTH_DROP_UNENCRYPTED: 1074 break; 1075 case IW_AUTH_RX_UNENCRYPTED_EAPOL: 1076 break; 1077 case IW_AUTH_PRIVACY_INVOKED: 1078 break; 1079 default: 1080 res = -EOPNOTSUPP; 1081 } 1082 break; 1083 1084 /* Get Authentication */ 1085 case SIOCGIWAUTH: 1086 res = TI_OK; 1087 { 1088 switch (wrqu->param.flags & IW_AUTH_INDEX) 1089 { 1090 case IW_AUTH_WPA_VERSION: 1091 wrqu->param.value = pCmdInterpret->wai.iw_auth_wpa_version; 1092 break; 1093 case IW_AUTH_CIPHER_PAIRWISE: 1094 wrqu->param.value = pCmdInterpret->wai.iw_auth_cipher_pairwise; 1095 break; 1096 case IW_AUTH_CIPHER_GROUP: 1097 wrqu->param.value = pCmdInterpret->wai.iw_auth_cipher_group; 1098 break; 1099 case IW_AUTH_KEY_MGMT: 1100 wrqu->param.value = pCmdInterpret->wai.iw_auth_key_mgmt; 1101 break; 1102 case IW_AUTH_80211_AUTH_ALG: 1103 wrqu->param.value = pCmdInterpret->wai.iw_auth_80211_auth_alg; 1104 break; 1105 default: 1106 res = -EOPNOTSUPP; 1107 } 1108 } 1109 break; 1110 1111 /* set encoding token & mode */ 1112 case SIOCSIWENCODEEXT: 1113 { 1114 struct iw_encode_ext *ext = (struct iw_encode_ext *)cmdObj->buffer2; 1115 TI_UINT8 *addr; 1116 TI_UINT8 temp[32]; 1117 1118 addr = ext->addr.sa_data; 1119 1120 /* 1121 os_printf ("\next->address = %02x:%02x:%02x:%02x:%02x:%02x \n",addr[0],addr[1],addr[2],addr[3],addr[4],addr[5]); 1122 os_printf ("ext->alg = 0x%x\n",ext->alg); 1123 os_printf ("ext->ext_flags = 0x%x\n",ext->ext_flags); 1124 os_printf ("ext->key_len = 0x%x\n",ext->key_len); 1125 os_printf ("ext->key_idx = 0x%x\n",(wrqu->encoding.flags & IW_ENCODE_INDEX)); 1126 1127 os_printf ("key = "); 1128 for (i=0; i<ext->key_len; i++) 1129 { 1130 os_printf ("0x%02x:",ext->key[i]); 1131 } 1132 os_printf ("\n"); 1133 */ 1134 1135 MAC_COPY (pParam->content.rsnOsKey.BSSID, addr); 1136 1137 pParam->content.rsnOsKey.KeyLength = ext->key_len; 1138 1139 pParam->content.rsnOsKey.KeyIndex = wrqu->encoding.flags & IW_ENCODE_INDEX; 1140 pParam->content.rsnOsKey.KeyIndex -= 1; 1141 1142 if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) 1143 { 1144 pParam->content.rsnOsKey.KeyIndex |= TIWLAN_KEY_FLAGS_TRANSMIT; 1145 } 1146 1147 if (addr[0]!=0xFF) 1148 { 1149 pParam->content.rsnOsKey.KeyIndex |= TIWLAN_KEY_FLAGS_PAIRWISE; 1150 } 1151 1152 if (ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) 1153 { 1154 os_memoryCopy(pCmdInterpret->hOs, &pParam->content.rsnOsKey.KeyRSC, &ext->rx_seq, IW_ENCODE_SEQ_MAX_SIZE); 1155 pParam->content.rsnOsKey.KeyIndex |= TIWLAN_KEY_FLAGS_SET_KEY_RSC; 1156 } 1157 1158 /* If key is TKIP - need to switch RX and TX MIC (to match driver API) */ 1159 if (ext->alg == IW_ENCODE_ALG_TKIP) 1160 { 1161 os_memoryCopy(pCmdInterpret->hOs,(TI_UINT8*)(((TI_UINT8*)&temp)+24),(TI_UINT8*)(((TI_UINT8*)&ext->key)+16),8); 1162 os_memoryCopy(pCmdInterpret->hOs,(TI_UINT8*)(((TI_UINT8*)&temp)+16),(TI_UINT8*)(((TI_UINT8*)&ext->key)+24),8); 1163 os_memoryCopy(pCmdInterpret->hOs,&temp,&ext->key,16); 1164 os_memoryCopy(pCmdInterpret->hOs, &pParam->content.rsnOsKey.KeyMaterial, &temp, ext->key_len); 1165 } else 1166 { 1167 os_memoryCopy(pCmdInterpret->hOs, &pParam->content.rsnOsKey.KeyMaterial, &ext->key, ext->key_len); 1168 } 1169 1170 if (ext->key_len == 0) 1171 pParam->paramType = RSN_REMOVE_KEY_PARAM; 1172 else 1173 pParam->paramType = RSN_ADD_KEY_PARAM; 1174 1175 res = cmdDispatch_SetParam (pCmdInterpret->hCmdDispatch, pParam); 1176 CHECK_PENDING_RESULT(res,pParam) 1177 1178 } 1179 break; 1180 1181 /* SIOCSIWPMKSA - PMKSA cache operation */ 1182 case SIOCSIWPMKSA: 1183 { 1184 struct iw_pmksa *pmksa = (struct iw_pmksa *) cmdObj->buffer2; 1185 1186 switch (pmksa->cmd) 1187 { 1188 case IW_PMKSA_ADD: 1189 pParam->paramType = RSN_PMKID_LIST; 1190 pParam->content.rsnPMKIDList.BSSIDInfoCount = 1; 1191 pParam->content.rsnPMKIDList.Length = 2*sizeof(TI_UINT32) + MAC_ADDR_LEN + PMKID_VALUE_SIZE; 1192 MAC_COPY (pParam->content.rsnPMKIDList.osBSSIDInfo[0].BSSID, pmksa->bssid.sa_data); 1193 os_memoryCopy(pCmdInterpret->hOs, &pParam->content.rsnPMKIDList.osBSSIDInfo[0].PMKID, pmksa->pmkid, IW_PMKID_LEN); 1194 1195 res = cmdDispatch_SetParam (pCmdInterpret->hCmdDispatch, pParam); 1196 CHECK_PENDING_RESULT(res,pParam) 1197 1198 break; 1199 case IW_PMKSA_REMOVE: 1200 /* Not supported yet */ 1201 break; 1202 case IW_PMKSA_FLUSH: 1203 pParam->paramType = RSN_PMKID_LIST; 1204 /* By using info count=0, RSN knows to clear its tables */ 1205 /* It's also possible to call rsn_resetPMKIDList directly, but cmdDispatcher should be the interface */ 1206 pParam->content.rsnPMKIDList.BSSIDInfoCount = 0; 1207 res = cmdDispatch_SetParam (pCmdInterpret->hCmdDispatch, pParam); 1208 CHECK_PENDING_RESULT(res,pParam) 1209 1210 break; 1211 default: 1212 cmdObj->return_code = WEXT_NOT_SUPPORTED; 1213 break; 1214 } 1215 } 1216 1217 break; 1218 1219 case SIOCIWFIRSTPRIV: 1220 { 1221 ti_private_cmd_t *my_command = (ti_private_cmd_t *)cmdObj->param3; 1222 1223 /* 1224 os_printf ("cmd = 0x%x flags = 0x%x\n",(unsigned int)my_command->cmd,(unsigned int)my_command->flags); 1225 os_printf ("in_buffer = 0x%x (len = %d)\n",my_command->in_buffer,(unsigned int)my_command->in_buffer_len); 1226 os_printf ("out_buffer = 0x%x (len = %d)\n",my_command->out_buffer,(unsigned int)my_command->out_buffer_len); 1227 */ 1228 1229 pParam->paramType = my_command->cmd; 1230 1231 if (IS_PARAM_ASYNC(my_command->cmd)) 1232 { 1233 /* os_printf ("Detected ASYNC command - setting CB \n"); */ 1234 pParam->content.interogateCmdCBParams.hCb = (TI_HANDLE)pCmdInterpret; 1235 pParam->content.interogateCmdCBParams.fCb = (void*)cmdInterpret_ServiceCompleteCB; 1236 pParam->content.interogateCmdCBParams.pCb = my_command->out_buffer; 1237 if (my_command->out_buffer) 1238 { 1239 /* the next copy is need for PLT commands */ 1240 os_memoryCopy(pCmdInterpret->hOs, my_command->out_buffer, my_command->in_buffer, min(my_command->in_buffer_len,my_command->out_buffer_len)); 1241 } 1242 } 1243 else if ((my_command->in_buffer) && (my_command->in_buffer_len)) 1244 { 1245 /* 1246 this cmd doesnt have the structure allocated as part of the paramInfo_t structure. 1247 as a result we need to allocate the memory internally. 1248 */ 1249 if(IS_ALLOC_NEEDED_PARAM(my_command->cmd)) 1250 { 1251 *(void **)&pParam->content = os_memoryAlloc(pCmdInterpret->hOs, my_command->in_buffer_len); 1252 os_memoryCopy(pCmdInterpret->hOs, *(void **)&pParam->content, my_command->in_buffer, my_command->in_buffer_len); 1253 } 1254 else 1255 os_memoryCopy(pCmdInterpret->hOs,&pParam->content,my_command->in_buffer,my_command->in_buffer_len); 1256 } 1257 1258 if (my_command->flags & PRIVATE_CMD_SET_FLAG) 1259 { 1260 /* os_printf ("Calling setParam\n"); */ 1261 pParam->paramLength = my_command->in_buffer_len; 1262 res = cmdDispatch_SetParam (pCmdInterpret->hCmdDispatch,pParam); 1263 } 1264 else if (my_command->flags & PRIVATE_CMD_GET_FLAG) 1265 { 1266 /* os_printf ("Calling getParam\n"); */ 1267 pParam->paramLength = my_command->out_buffer_len; 1268 res = cmdDispatch_GetParam (pCmdInterpret->hCmdDispatch,pParam); 1269 if(res == EXTERNAL_GET_PARAM_DENIED) 1270 { 1271 cmdObj->return_code = WEXT_INVALID_PARAMETER; 1272 goto cmd_end; 1273 } 1274 1275 /* 1276 this is for cmd that want to check the size of memory that they need to 1277 allocate for the actual data. 1278 */ 1279 if(pParam->paramLength && (my_command->out_buffer_len == 0)) 1280 { 1281 my_command->out_buffer_len = pParam->paramLength; 1282 } 1283 } 1284 else 1285 { 1286 res = TI_NOK; 1287 } 1288 1289 if (res == TI_OK) 1290 { 1291 if(IS_PARAM_ASYNC(my_command->cmd)) 1292 { 1293 pCmdInterpret->pAsyncCmd = cmdObj; /* Save command handle for completion CB */ 1294 res = COMMAND_PENDING; 1295 } 1296 else 1297 { 1298 if ((my_command->out_buffer) && (my_command->out_buffer_len)) 1299 { 1300 if(IS_ALLOC_NEEDED_PARAM(my_command->cmd)) 1301 { 1302 os_memoryCopy(pCmdInterpret->hOs,my_command->out_buffer,*(void **)&pParam->content,my_command->out_buffer_len); 1303 } 1304 else 1305 { 1306 os_memoryCopy(pCmdInterpret->hOs,my_command->out_buffer,&pParam->content,my_command->out_buffer_len); 1307 } 1308 } 1309 } 1310 } 1311 1312 /* need to free the allocated memory */ 1313 if(IS_ALLOC_NEEDED_PARAM(my_command->cmd)) 1314 { 1315 os_memoryFree(pCmdInterpret->hOs, *(void **)&pParam->content, my_command->in_buffer_len); 1316 } 1317 } 1318 1319 break; 1320 1321 default: 1322 break; 1323 1324 } 1325 1326 if (res == TI_OK) 1327 { 1328 cmdObj->return_code = WEXT_OK; 1329 } 1330 cmd_end: 1331 os_memoryFree(pCmdInterpret->hOs, pParam, sizeof(paramInfo_t)); 1332 /* Return with return code */ 1333 return res; 1334 1335 } 1336 1337 1338 1339 /* This routine is called by the command mailbox module to signal an ASYNC command has complete */ 1340 int cmdInterpret_ServiceCompleteCB (TI_HANDLE hCmdInterpret, int status, void *buffer) 1341 { 1342 cmdInterpret_t *pCmdInterpret = (cmdInterpret_t *)hCmdInterpret; 1343 1344 if (pCmdInterpret->pAsyncCmd == NULL) 1345 { 1346 os_printf ("cmdInterpret_ServiceCompleteCB: AsyncCmd is NULL!!\n"); 1347 return TI_NOK; 1348 } 1349 1350 pCmdInterpret->pAsyncCmd->return_code = status; 1351 1352 pCmdInterpret->pAsyncCmd = NULL; 1353 1354 /* Call the Cmd module to complete command processing */ 1355 cmdHndlr_Complete (pCmdInterpret->hCmdHndlr); 1356 1357 /* Call commands handler to continue handling further commands if queued */ 1358 cmdHndlr_HandleCommands (pCmdInterpret->hCmdHndlr); 1359 1360 return TI_OK; 1361 } 1362 1363 /* Register to receive events */ 1364 static int cmdInterpret_initEvents(TI_HANDLE hCmdInterpret) 1365 { 1366 cmdInterpret_t *pCmdInterpret = (cmdInterpret_t *)(hCmdInterpret); 1367 IPC_EVENT_PARAMS evParams; 1368 int i = 0; 1369 1370 for (i=0; i<IPC_EVENT_MAX; i++) 1371 { 1372 evParams.uDeliveryType = DELIVERY_PUSH; 1373 evParams.uProcessID = 0; 1374 evParams.uEventID = 0; 1375 evParams.hUserParam = hCmdInterpret; 1376 evParams.pfEventCallback = cmdInterpret_Event; 1377 evParams.uEventType = i; 1378 EvHandlerRegisterEvent (pCmdInterpret->hEvHandler, (TI_UINT8*) &evParams, sizeof(IPC_EVENT_PARAMS)); 1379 pCmdInterpret->hEvents[i] = evParams.uEventID; 1380 } 1381 1382 return TI_OK; 1383 } 1384 1385 1386 /* Unregister events */ 1387 static int cmdInterpret_unregisterEvents(TI_HANDLE hCmdInterpret, TI_HANDLE hEvHandler) 1388 { 1389 cmdInterpret_t *pCmdInterpret = (cmdInterpret_t *)(hCmdInterpret); 1390 IPC_EVENT_PARAMS evParams; 1391 int i = 0; 1392 os_setDebugOutputToLogger(TI_FALSE); 1393 1394 for (i=0; i<IPC_EVENT_MAX; i++) 1395 { 1396 evParams.uEventType = i; 1397 evParams.uEventID = pCmdInterpret->hEvents[i]; 1398 EvHandlerUnRegisterEvent (pCmdInterpret->hEvHandler, &evParams); 1399 } 1400 1401 return TI_OK; 1402 } 1403 1404 1405 /* Handle driver events and convert to WEXT format */ 1406 static TI_INT32 cmdInterpret_Event(IPC_EV_DATA* pData) 1407 { 1408 IPC_EVENT_PARAMS * pInParam = (IPC_EVENT_PARAMS *)pData; 1409 cmdInterpret_t *pCmdInterpret = (cmdInterpret_t *)(pInParam->hUserParam); 1410 OS_802_11_ASSOCIATION_INFORMATION *assocInformation; 1411 TI_UINT8 *requestIEs; 1412 TI_UINT8 *responseIEs; 1413 union iwreq_data wrqu; 1414 char *memptr; 1415 int TotalLength, res = TI_OK; 1416 #ifdef XCC_MODULE_INCLUDED 1417 cckm_assocInformation_t cckm_assoc; 1418 unsigned char beaconIE[MAX_BEACON_BODY_LENGTH]; 1419 unsigned char Cckmstart[CCKM_START_EVENT_SIZE * 2]; 1420 int i,len,n; 1421 OS_802_11_BSSID_EX *my_current; 1422 #endif 1423 /* indicate to the OS */ 1424 os_IndicateEvent (pCmdInterpret->hOs, pData); 1425 1426 1427 switch (pData->EvParams.uEventType) 1428 { 1429 case IPC_EVENT_ASSOCIATED: 1430 { 1431 paramInfo_t *pParam; 1432 1433 pParam = (paramInfo_t *)os_memoryAlloc(pCmdInterpret->hOs, sizeof(paramInfo_t)); 1434 if (!pParam) 1435 return TI_NOK; 1436 1437 /* Get Association information */ 1438 1439 /* first check if this is ADHOC or INFRA (to avoid retrieving ASSOC INFO for ADHOC)*/ 1440 1441 pParam->paramType = CTRL_DATA_CURRENT_BSS_TYPE_PARAM; 1442 cmdDispatch_GetParam(pCmdInterpret->hCmdDispatch, pParam); 1443 if (pParam->content.ctrlDataCurrentBssType == BSS_INFRASTRUCTURE) 1444 { 1445 1446 /* First get length of data */ 1447 pParam->paramType = ASSOC_ASSOCIATION_INFORMATION_PARAM; 1448 pParam->paramLength = 0; 1449 res = cmdDispatch_GetParam(pCmdInterpret->hCmdDispatch, pParam); 1450 1451 if (res != TI_NOK) 1452 { 1453 TotalLength = sizeof(OS_802_11_ASSOCIATION_INFORMATION) + pParam->content.assocAssociationInformation.RequestIELength + 1454 pParam->content.assocAssociationInformation.ResponseIELength; 1455 1456 memptr = os_memoryAlloc (pCmdInterpret->hOs, TotalLength); 1457 1458 /* Get actual data */ 1459 1460 pParam->paramType = ASSOC_ASSOCIATION_INFORMATION_PARAM; 1461 pParam->paramLength = TotalLength; 1462 cmdDispatch_GetParam(pCmdInterpret->hCmdDispatch, pParam); 1463 1464 os_memoryCopy(pCmdInterpret->hOs, memptr, &pParam->content, TotalLength); 1465 1466 assocInformation = (OS_802_11_ASSOCIATION_INFORMATION*)memptr; 1467 requestIEs = (TI_UINT8*)memptr + sizeof(OS_802_11_ASSOCIATION_INFORMATION); 1468 1469 if (assocInformation->RequestIELength > 0) 1470 { 1471 os_memorySet (pCmdInterpret->hOs,&wrqu, 0, sizeof(wrqu)); 1472 wrqu.data.length = assocInformation->RequestIELength; 1473 wireless_send_event(NETDEV(pCmdInterpret->hOs), IWEVASSOCREQIE, &wrqu, (char *)assocInformation->OffsetRequestIEs); 1474 } 1475 1476 responseIEs = (char *)assocInformation->OffsetRequestIEs + assocInformation->RequestIELength; 1477 1478 if (assocInformation->ResponseIELength > 0) 1479 { 1480 os_memorySet (pCmdInterpret->hOs,&wrqu, 0, sizeof(wrqu)); 1481 wrqu.data.length = assocInformation->ResponseIELength; 1482 wireless_send_event(NETDEV(pCmdInterpret->hOs), IWEVASSOCRESPIE, &wrqu, (char *)responseIEs); 1483 } 1484 1485 os_memoryFree (pCmdInterpret->hOs, memptr, TotalLength); 1486 1487 } 1488 } 1489 1490 #ifdef XCC_MODULE_INCLUDED 1491 /* 1492 the driver must provide BEACON IE for calculate MIC in case of fast roaming 1493 the data is an ASCII NUL terminated string 1494 */ 1495 1496 1497 my_current = os_memoryAlloc (pCmdInterpret->hOs,MAX_BEACON_BODY_LENGTH); 1498 if (!my_current) { 1499 res = TI_NOK; 1500 goto event_end; 1501 } 1502 pParam->paramType = SITE_MGR_GET_SELECTED_BSSID_INFO_EX; 1503 pParam->content.pSiteMgrSelectedSiteInfo = my_current; 1504 pParam->paramLength = MAX_BEACON_BODY_LENGTH; 1505 cmdDispatch_GetParam(pCmdInterpret->hCmdDispatch, pParam); 1506 1507 len = pParam->content.pSiteMgrSelectedSiteInfo->IELength - BEACON_HEADER_FIX_SIZE; 1508 1509 n = sprintf(beaconIE, "BEACONIE="); 1510 for (i = 0; i < len; i++) 1511 { 1512 n += sprintf(beaconIE + n, "%02x", pParam->content.pSiteMgrSelectedSiteInfo->IEs[BEACON_HEADER_FIX_SIZE+i] & 0xff); 1513 } 1514 1515 os_memorySet (pCmdInterpret->hOs,&wrqu, 0, sizeof(wrqu)); 1516 wrqu.data.length = n; 1517 wireless_send_event(NETDEV(pCmdInterpret->hOs), IWEVCUSTOM, &wrqu, beaconIE); 1518 os_memoryFree(pCmdInterpret->hOs,my_current,MAX_BEACON_BODY_LENGTH); 1519 1520 1521 /* 1522 The driver should be sending the Association Resp IEs 1523 This informs the supplicant of the IEs used in the association exchanged which are required to proceed with CCKM. 1524 */ 1525 1526 1527 pParam->paramType = ASSOC_ASSOCIATION_RESP_PARAM; 1528 pParam->paramLength = sizeof(TAssocReqBuffer); 1529 cmdDispatch_GetParam(pCmdInterpret->hCmdDispatch, pParam); 1530 1531 cckm_assoc.assocRespLen = Param.content.assocReqBuffer.bufferSize - ASSOC_RESP_FIXED_DATA_LEN ; 1532 cckm_assoc.assocRespBuffer = os_memoryAlloc (pCmdInterpret->hOs, cckm_assoc.assocRespLen); 1533 if (!cckm_assoc.assocRespBuffer) { 1534 res = TI_NOK; 1535 goto event_end; 1536 } 1537 memcpy(cckm_assoc.assocRespBuffer,(pParam->content.assocReqBuffer.buffer)+ASSOC_RESP_FIXED_DATA_LEN,cckm_assoc.assocRespLen); 1538 wrqu.data.length = cckm_assoc.assocRespLen; 1539 wireless_send_event(NETDEV(pCmdInterpret->hOs), IWEVASSOCRESPIE, &wrqu, (TI_UINT8*)cckm_assoc.assocRespBuffer); 1540 os_memoryFree(pCmdInterpret->hOs,cckm_assoc.assocRespBuffer,cckm_assoc.assocRespLen); 1541 1542 #endif 1543 /* Send associated event (containing BSSID of AP) */ 1544 1545 os_memorySet (pCmdInterpret->hOs,&wrqu, 0, sizeof(wrqu)); 1546 pParam->paramType = SITE_MGR_CURRENT_BSSID_PARAM; 1547 cmdDispatch_GetParam ( pCmdInterpret->hCmdDispatch, pParam ); 1548 MAC_COPY (wrqu.ap_addr.sa_data, pParam->content.siteMgrDesiredBSSID); 1549 wrqu.ap_addr.sa_family = ARPHRD_ETHER; 1550 wireless_send_event(NETDEV(pCmdInterpret->hOs), SIOCGIWAP, &wrqu, NULL); 1551 #ifdef XCC_MODULE_INCLUDED 1552 event_end: 1553 #endif 1554 os_memoryFree(pCmdInterpret->hOs, pParam, sizeof(paramInfo_t)); 1555 } 1556 break; 1557 case IPC_EVENT_DISASSOCIATED: 1558 wrqu.ap_addr.sa_family = ARPHRD_ETHER; 1559 os_memorySet (pCmdInterpret->hOs,wrqu.ap_addr.sa_data, 0, ETH_ALEN); 1560 1561 wireless_send_event(NETDEV(pCmdInterpret->hOs), SIOCGIWAP, &wrqu, NULL); 1562 1563 os_memorySet (pCmdInterpret->hOs,&wrqu, 0, sizeof(wrqu)); 1564 wrqu.data.length = sizeof(IPC_EV_DATA); 1565 wireless_send_event(NETDEV(pCmdInterpret->hOs), IWEVCUSTOM, &wrqu, (TI_UINT8 *)pData); 1566 1567 break; 1568 1569 case IPC_EVENT_SCAN_COMPLETE: 1570 { 1571 TI_UINT8 *buf; 1572 wrqu.data.length = 0; 1573 wrqu.data.flags = 0; 1574 buf = pData->uBuffer; 1575 1576 if (*(TI_UINT32*)buf == SCAN_STATUS_COMPLETE) 1577 wireless_send_event(NETDEV(pCmdInterpret->hOs), SIOCGIWSCAN, &wrqu, NULL); 1578 else 1579 { 1580 if (*(TI_UINT32*)buf == SCAN_STATUS_STOPPED) // scan is stopped successfully 1581 pData->EvParams.uEventType = IPC_EVENT_SCAN_STOPPED; 1582 else if (*(TI_UINT32*)buf == SCAN_STATUS_FAILED) // scan is stopped successfully 1583 pData->EvParams.uEventType = IPC_EVENT_SCAN_FAILED; 1584 else 1585 break; 1586 1587 os_memorySet (pCmdInterpret->hOs,&wrqu, 0, sizeof(wrqu)); 1588 wrqu.data.length = sizeof(IPC_EV_DATA); 1589 wireless_send_event(NETDEV(pCmdInterpret->hOs), IWEVCUSTOM, &wrqu, (u8 *)pData); 1590 } 1591 } 1592 break; 1593 1594 case IPC_EVENT_MEDIA_SPECIFIC: 1595 { 1596 TI_UINT8 *buf; 1597 OS_802_11_AUTHENTICATION_REQUEST *request; 1598 struct iw_michaelmicfailure ev; 1599 struct iw_pmkid_cand pcand; 1600 1601 buf = pData->uBuffer; 1602 1603 if (*(TI_UINT32*)buf == os802_11StatusType_Authentication) 1604 { 1605 request = (OS_802_11_AUTHENTICATION_REQUEST *) (buf + sizeof(TI_UINT32)); 1606 if ( request->Flags == OS_802_11_REQUEST_PAIRWISE_ERROR || request->Flags == OS_802_11_REQUEST_GROUP_ERROR) 1607 { 1608 os_printf ("MIC failure detected\n"); 1609 1610 os_memorySet (pCmdInterpret->hOs,&ev, 0, sizeof(ev)); 1611 1612 ev.flags = 0 & IW_MICFAILURE_KEY_ID; 1613 1614 if (request->Flags == OS_802_11_REQUEST_GROUP_ERROR) 1615 ev.flags |= IW_MICFAILURE_GROUP; 1616 else 1617 ev.flags |= IW_MICFAILURE_PAIRWISE; 1618 1619 ev.src_addr.sa_family = ARPHRD_ETHER; 1620 MAC_COPY (ev.src_addr.sa_data, request->BSSID); 1621 os_memorySet (pCmdInterpret->hOs,&wrqu, 0, sizeof(wrqu)); 1622 wrqu.data.length = sizeof(ev); 1623 wireless_send_event(NETDEV(pCmdInterpret->hOs), IWEVMICHAELMICFAILURE, &wrqu, (char *) &ev); 1624 } 1625 1626 } else if (*(TI_UINT32*)buf == os802_11StatusType_PMKID_CandidateList) 1627 { 1628 OS_802_11_PMKID_CANDIDATELIST *pCandList = (OS_802_11_PMKID_CANDIDATELIST *) (buf + sizeof(TI_UINT32)); 1629 int i; 1630 1631 os_printf ("Preauthentication list (%d entries)!\n",pCandList->NumCandidates); 1632 1633 for (i=0; i<pCandList->NumCandidates; i++) 1634 { 1635 os_memorySet (pCmdInterpret->hOs,&pcand, 0, sizeof(pcand)); 1636 pcand.flags |= IW_PMKID_CAND_PREAUTH; 1637 1638 pcand.index = i; 1639 1640 MAC_COPY (pcand.bssid.sa_data, pCandList->CandidateList[i].BSSID); 1641 1642 os_memorySet (pCmdInterpret->hOs,&wrqu, 0, sizeof(wrqu)); 1643 1644 wrqu.data.length = sizeof(pcand); 1645 1646 wireless_send_event(NETDEV(pCmdInterpret->hOs), IWEVPMKIDCAND, 1647 &wrqu, (TI_UINT8 *)&pcand); 1648 } 1649 1650 } 1651 1652 } 1653 1654 break; 1655 #ifdef XCC_MODULE_INCLUDED 1656 case IPC_EVENT_CCKM_START: 1657 1658 n = sprintf(Cckmstart, "CCKM-Start="); 1659 for (i = 0; i < 14; i++) 1660 { 1661 n += sprintf(Cckmstart + n, "%02x", pData->uBuffer[i] & 0xff); 1662 } 1663 1664 os_memorySet (pCmdInterpret->hOs,&wrqu, 0, sizeof(wrqu)); 1665 wrqu.data.length = n; 1666 wireless_send_event(NETDEV(pCmdInterpret->hOs), IWEVCUSTOM, &wrqu, Cckmstart); 1667 1668 break; 1669 #endif 1670 1671 default: 1672 /* Other event? probably private and does not need interface-specific conversion */ 1673 /* Send as "custom" event */ 1674 { 1675 os_memorySet (pCmdInterpret->hOs,&wrqu, 0, sizeof(wrqu)); 1676 wrqu.data.length = sizeof(IPC_EV_DATA); 1677 wireless_send_event(NETDEV(pCmdInterpret->hOs), IWEVCUSTOM, &wrqu, (TI_UINT8 *)pData); 1678 } 1679 1680 break; 1681 } 1682 1683 return res; 1684 } 1685 1686 1687 /* Configure driver authentication and security by converting from WEXT interface to driver (OID-like) settings */ 1688 static int cmdInterpret_setSecurityParams (TI_HANDLE hCmdInterpret) 1689 { 1690 cmdInterpret_t *pCmdInterpret = (cmdInterpret_t *)hCmdInterpret; 1691 paramInfo_t *pParam; 1692 int auth_mode, encr_mode; 1693 1694 /* 1695 printk ("wpa_version=0x%x auth_alg=0x%x key_mgmt=0x%x " 1696 "cipher_pairwise=0x%x cipher_group=0x%x\n", 1697 pCmdInterpret->wai.iw_auth_wpa_version, pCmdInterpret->wai.iw_auth_80211_auth_alg, 1698 pCmdInterpret->wai.iw_auth_key_mgmt, pCmdInterpret->wai.iw_auth_cipher_pairwise, 1699 pCmdInterpret->wai.iw_auth_cipher_group); 1700 */ 1701 pParam = (paramInfo_t *)os_memoryAlloc(pCmdInterpret->hOs, sizeof(paramInfo_t)); 1702 if (!pParam) 1703 return TI_NOK; 1704 if (pCmdInterpret->wai.iw_auth_wpa_version & IW_AUTH_WPA_VERSION_WPA2) 1705 { 1706 if (pCmdInterpret->wai.iw_auth_key_mgmt & IW_AUTH_KEY_MGMT_802_1X) 1707 auth_mode = os802_11AuthModeWPA2; 1708 else 1709 auth_mode = os802_11AuthModeWPA2PSK; 1710 } else if (pCmdInterpret->wai.iw_auth_wpa_version & IW_AUTH_WPA_VERSION_WPA) 1711 { 1712 if (pCmdInterpret->wai.iw_auth_key_mgmt & IW_AUTH_KEY_MGMT_802_1X) 1713 auth_mode = os802_11AuthModeWPA; 1714 else if (pCmdInterpret->wai.iw_auth_key_mgmt & IW_AUTH_KEY_MGMT_PSK) 1715 auth_mode = os802_11AuthModeWPAPSK; 1716 else 1717 auth_mode = os802_11AuthModeWPANone; 1718 } else if (pCmdInterpret->wai.iw_auth_80211_auth_alg & IW_AUTH_ALG_SHARED_KEY) 1719 { 1720 if (pCmdInterpret->wai.iw_auth_80211_auth_alg & IW_AUTH_ALG_OPEN_SYSTEM) 1721 auth_mode = os802_11AuthModeAutoSwitch; 1722 else 1723 auth_mode = os802_11AuthModeShared; 1724 } else 1725 auth_mode = os802_11AuthModeOpen; 1726 1727 if (pCmdInterpret->wai.iw_auth_cipher_pairwise & IW_AUTH_CIPHER_CCMP) 1728 encr_mode = os802_11Encryption3Enabled; 1729 else if (pCmdInterpret->wai.iw_auth_cipher_pairwise & IW_AUTH_CIPHER_TKIP) 1730 encr_mode = os802_11Encryption2Enabled; 1731 else if (pCmdInterpret->wai.iw_auth_cipher_pairwise & 1732 (IW_AUTH_CIPHER_WEP40 | IW_AUTH_CIPHER_WEP104)) 1733 encr_mode = os802_11Encryption1Enabled; 1734 else if (pCmdInterpret->wai.iw_auth_cipher_group & IW_AUTH_CIPHER_CCMP) 1735 encr_mode = os802_11Encryption3Enabled; 1736 else if (pCmdInterpret->wai.iw_auth_cipher_group & IW_AUTH_CIPHER_TKIP) 1737 encr_mode = os802_11Encryption2Enabled; 1738 else 1739 encr_mode = os802_11EncryptionDisabled; 1740 1741 switch (encr_mode) 1742 { 1743 case os802_11WEPDisabled: 1744 encr_mode = TWD_CIPHER_NONE; 1745 break; 1746 case os802_11WEPEnabled: 1747 encr_mode = TWD_CIPHER_WEP; 1748 break; 1749 case os802_11Encryption2Enabled: 1750 encr_mode = TWD_CIPHER_TKIP; 1751 break; 1752 case os802_11Encryption3Enabled: 1753 encr_mode = TWD_CIPHER_AES_CCMP; 1754 break; 1755 default: 1756 break; 1757 } 1758 1759 pParam->paramType = RSN_EXT_AUTHENTICATION_MODE; 1760 pParam->content.rsnExtAuthneticationMode = auth_mode; 1761 cmdDispatch_SetParam ( pCmdInterpret->hCmdDispatch, pParam ); 1762 1763 pParam->paramType = RSN_ENCRYPTION_STATUS_PARAM; 1764 pParam->content.rsnEncryptionStatus = encr_mode; 1765 cmdDispatch_SetParam ( pCmdInterpret->hCmdDispatch, pParam ); 1766 os_memoryFree(pCmdInterpret->hOs, pParam, sizeof(paramInfo_t)); 1767 return TI_OK; 1768 } 1769 1770 1771 void *cmdInterpret_GetStat (TI_HANDLE hCmdInterpret) 1772 { 1773 cmdInterpret_t *pCmdInterpret = (cmdInterpret_t *)hCmdInterpret; 1774 1775 /* Check if driver is initialized - If not - return empty statistics */ 1776 if (hCmdInterpret) 1777 { 1778 pCmdInterpret->wstats.status = 0; 1779 pCmdInterpret->wstats.miss.beacon = 0; 1780 pCmdInterpret->wstats.discard.retries = 0; /* Tx : Max MAC retries num reached */ 1781 pCmdInterpret->wstats.discard.nwid = 0; /* Rx : Wrong nwid/essid */ 1782 pCmdInterpret->wstats.discard.code = 0; /* Rx : Unable to code/decode (WEP) */ 1783 pCmdInterpret->wstats.discard.fragment = 0; /* Rx : Can't perform MAC reassembly */ 1784 pCmdInterpret->wstats.discard.misc = 0; /* Others cases */ 1785 1786 pCmdInterpret->wstats.qual.qual = 0; 1787 pCmdInterpret->wstats.qual.level = 0; 1788 pCmdInterpret->wstats.qual.noise = 0; 1789 pCmdInterpret->wstats.qual.updated = IW_QUAL_NOISE_INVALID | IW_QUAL_QUAL_INVALID | IW_QUAL_LEVEL_INVALID; 1790 return &pCmdInterpret->wstats; 1791 } 1792 return (void *)NULL; 1793 } 1794