1 /* 2 * WPA Supplicant - driver interaction with TI station 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License version 2 as 6 * published by the Free Software Foundation. 7 * 8 * Alternatively, this software may be distributed under the terms of BSD 9 * license. 10 * 11 */ 12 13 /* Copyright Texas Instruments Incorporated (Oct 2005) 14 * THIS CODE/PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, 15 * EITHER EXPRESS OR IMPLIED, INCLUDED BUT NOT LIMITED TO , THE IMPLIED 16 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 17 * This program has been modified from its original operation by Texas 18 * Instruments Incorporated. These changes are covered under version 2 19 * of the GNU General Public License, dated June 1991. 20 * 21 * Copyright Google Inc (Feb 2008) 22 */ 23 /*-------------------------------------------------------------------*/ 24 #include "includes.h" 25 #include <sys/ioctl.h> 26 #include <net/route.h> 27 #include <net/if.h> 28 #include <fcntl.h> 29 #include <netpacket/packet.h> 30 #include <stddef.h> 31 #include "common.h" 32 #include "driver.h" 33 #include "eloop.h" 34 #include "wpa.h" 35 #include "wpa_supplicant.h" 36 #include "config.h" 37 #include "wpa_supplicant_i.h" 38 #include "wpa_i.h" 39 #include "l2_packet.h" 40 #include "wpa_ctrl.h" 41 /*----- STA_DK files -----*/ 42 #include "wspVer.h" 43 #include "driver_ti.h" 44 #include "scanmerge.h" 45 #include "scanMngrTypes.h" 46 #ifdef ANDROID 47 #include <cutils/properties.h> 48 #endif 49 /*-------------------------------------------------------------------*/ 50 #define TI_DRIVER_MSG_PORT 9000 51 #define RX_SELF_FILTER 0 52 #define RX_BROADCAST_FILTER 1 53 #define RX_IPV4_MULTICAST_FILTER 2 54 #define RX_IPV6_MULTICAST_FILTER 3 55 #define TI2WPA_STATUS(s) (((s) != OK) ? -1 : 0) 56 #define TI_CHECK_DRIVER(f,r) \ 57 if( !(f) ) { \ 58 wpa_printf(MSG_ERROR,"TI: Driver not initialized yet...aborting..."); \ 59 return( r ); \ 60 } 61 /*-------------------------------------------------------------------*/ 62 /* Lock file pointer - used to access pid-lock-file to prevent two instances of wpa_supplicant */ 63 #ifdef CONFIG_TI_LOCKFILE 64 static int lfp; 65 #endif 66 /*-------------------------------------------------------------------*/ 67 68 /*----------------------------------------------------------------------------- 69 Routine Name: check_and_get_build_channels 70 Routine Description: get number of allowed channels according to a build var. 71 Arguments: None 72 Return Value: Number of channels 73 -----------------------------------------------------------------------------*/ 74 static int check_and_get_build_channels( void ) 75 { 76 #ifdef ANDROID 77 char prop_status[PROPERTY_VALUE_MAX]; 78 char *prop_name = "ro.wifi.channels"; 79 int i, default_channels = NUMBER_SCAN_CHANNELS_FCC; 80 81 if( property_get(prop_name, prop_status, NULL) ) { 82 i = atoi(prop_status); 83 if( i != 0 ) 84 default_channels = i; 85 } 86 return( default_channels ); 87 #else 88 return( NUMBER_SCAN_CHANNELS_FCC ); 89 #endif 90 } 91 92 /*----------------------------------------------------------------------------- 93 Routine Name: wpa_driver_tista_event_receive 94 Routine Description: driver events callback, called from driver IPC 95 Arguments: 96 priv - pointer to private data structure 97 pData - pointer to event information 98 Return Value: 99 -----------------------------------------------------------------------------*/ 100 void wpa_driver_tista_event_receive( IPC_EV_DATA *pData ) 101 { 102 struct wpa_driver_ti_data *mySuppl; 103 struct sockaddr_in echoserver; 104 int res, msg_size; 105 106 wpa_printf(MSG_DEBUG,"wpa_driver_tista_event_receive called: %d", 107 pData->uBufferSize); 108 109 mySuppl = pData->EvParams.hUserParam; 110 msg_size = (int)(pData->uBufferSize + offsetof(IPC_EV_DATA, uBuffer)); 111 112 os_memset( &echoserver, 0, sizeof(echoserver) ); /* Clear struct */ 113 echoserver.sin_family = AF_INET; /* Internet/IP */ 114 echoserver.sin_addr.s_addr = inet_addr("127.0.0.1"); /* IP address */ 115 echoserver.sin_port = htons(TI_DRIVER_MSG_PORT); /* server port */ 116 117 res = sendto(mySuppl->driverEventsSocket, pData, msg_size, 0, (struct sockaddr *)&echoserver, sizeof(echoserver)); 118 echoserver.sin_port = htons(TI_DRIVER_MSG_PORT + 1); 119 res = sendto(mySuppl->driverEventsSocket, pData, msg_size, 0, (struct sockaddr *)&echoserver, sizeof(echoserver)); 120 } 121 122 /*----------------------------------------------------------------------------- 123 Routine Name: wpa_driver_tista_register_events 124 Routine Description: register to driver events 125 Arguments: 126 ctx - pointer to private data structure 127 Return Value: None 128 -----------------------------------------------------------------------------*/ 129 void wpa_driver_tista_register_events( void *ctx ) 130 { 131 struct wpa_driver_ti_data *myDrv = (struct wpa_driver_ti_data *)ctx; 132 IPC_EVENT_PARAMS pEvent; 133 int i; 134 135 os_memset( myDrv->hEvents, 0, sizeof(ULONG) * IPC_EVENT_MAX ); 136 for(i=IPC_EVENT_ASSOCIATED;( i < IPC_EVENT_MAX );i++) { 137 /* Register to receive driver events */ 138 pEvent.uEventType = i; 139 pEvent.uDeliveryType = DELIVERY_PUSH; 140 pEvent.hUserParam = (TI_HANDLE)myDrv; 141 pEvent.pfEventCallback = (TI_EVENT_CALLBACK)wpa_driver_tista_event_receive; 142 TI_RegisterEvent( myDrv->hDriver, &pEvent ); 143 myDrv->hEvents[i] = pEvent.uEventID; 144 } 145 } 146 147 /*----------------------------------------------------------------------------- 148 Routine Name: wpa_driver_tista_unregister_events 149 Routine Description: unregister driver events 150 Arguments: 151 ctx - pointer to private data structure 152 Return Value: None 153 -----------------------------------------------------------------------------*/ 154 void wpa_driver_tista_unregister_events( void *ctx ) 155 { 156 struct wpa_driver_ti_data *myDrv = (struct wpa_driver_ti_data *)ctx; 157 IPC_EVENT_PARAMS pEvent; 158 int idx; 159 160 for(idx=0;( idx < IPC_EVENT_MAX );idx++) { 161 if( myDrv->hEvents[idx] ) { 162 pEvent.uEventType = idx; 163 pEvent.uEventID = myDrv->hEvents[idx]; 164 TI_UnRegisterEvent( myDrv->hDriver, &pEvent ); 165 } 166 } 167 } 168 169 /*----------------------------------------------------------------------------- 170 Routine Name: wpa_driver_tista_get_bssid 171 Routine Description: get current BSSID from driver 172 Arguments: 173 priv - pointer to private data structure 174 bssid - pointer to hold bssid 175 Return Value: 0 on success, -1 on failure 176 -----------------------------------------------------------------------------*/ 177 static int wpa_driver_tista_get_bssid( void *priv, u8 *bssid ) 178 { 179 struct wpa_driver_ti_data *myDrv = (struct wpa_driver_ti_data *)priv; 180 OS_802_11_MAC_ADDRESS tiAPMacAddr; 181 TI_STATUS retValue; 182 183 wpa_printf(MSG_DEBUG, "wpa_driver_tista_get_bssid called"); 184 185 /* If driver is not initialized yet - we cannot access it so return */ 186 TI_CHECK_DRIVER( myDrv->driver_is_loaded, -1 ); 187 188 /* Get MAC address of current AP */ 189 if( TI_GetBSSID( myDrv->hDriver, &tiAPMacAddr ) != TI_RESULT_OK ) 190 return( -1 ); 191 192 /* Copy BSSID into caller pointer provided in routine parameters */ 193 os_memcpy( (void *)bssid, (void *)&tiAPMacAddr, MAC_ADDR_LEN ); 194 wpa_hexdump(MSG_DEBUG, "get_bssid:", bssid, MAC_ADDR_LEN); 195 return( 0 ); 196 } 197 198 /*----------------------------------------------------------------------------- 199 Routine Name: wpa_driver_tista_get_ssid 200 Routine Description: get current SSID 201 Arguments: 202 priv - pointer to private data structure 203 ssid - pointer to hold current bssid 204 Return Value: Length of SSID string 205 -----------------------------------------------------------------------------*/ 206 static int wpa_driver_tista_get_ssid( void *priv, u8 *ssid ) 207 { 208 struct wpa_driver_ti_data *myDrv = (struct wpa_driver_ti_data *)priv; 209 OS_802_11_SSID myssid; 210 211 wpa_printf(MSG_DEBUG,"wpa_driver_tista_get_ssid called"); 212 213 /* If driver is not initialized yet - we cannot access it so return */ 214 TI_CHECK_DRIVER( myDrv->driver_is_loaded, -1 ); 215 216 /* Get current SSID from driver */ 217 if( TI_GetCurrentSSID(myDrv->hDriver, &myssid) != TI_RESULT_OK ) 218 return( -1 ); 219 220 /* Copy to user supplied pointer */ 221 os_memcpy( (void *)ssid, (void *)&myssid.Ssid, myssid.SsidLength ); 222 223 /* Return length of SSID */ 224 return( myssid.SsidLength ); 225 } 226 227 /*----------------------------------------------------------------------------- 228 Routine Name: wpa_driver_tista_set_ssid 229 Routine Description: sets current SSID (Associates) 230 Arguments: 231 priv - pointer to private data structure 232 ssid - pointer to ssid 233 ssid_len - length of ssid 234 Return Value: 0 on success, -1 on failure 235 -----------------------------------------------------------------------------*/ 236 static int wpa_driver_tista_set_ssid( void *priv, const u8 *ssid, size_t ssid_len ) 237 { 238 struct wpa_driver_ti_data *myDrv = (struct wpa_driver_ti_data *)priv; 239 char ssidBuf[MAX_SSID_LEN]; 240 int ret; 241 242 wpa_printf(MSG_DEBUG,"wpa_driver_tista_set_ssid called: %s", ssid); 243 244 /* If driver is not initialized yet - we cannot access it so return */ 245 TI_CHECK_DRIVER( myDrv->driver_is_loaded, -1 ); 246 247 /* Copy user supplied SSID into local buffer */ 248 os_memset( ssidBuf, 0, MAX_SSID_LEN ); 249 os_memcpy( ssidBuf, ssid, ssid_len ); 250 251 /* Set local SSID buffer to driver - triggering connection process in driver */ 252 wpa_printf(MSG_DEBUG,"Associate: SSID = %s", ssidBuf); /* Dm: */ 253 #ifdef STA_DK_VER_5_0_0_94 254 ret = (int)TI_SetSSID( myDrv->hDriver, (char *)ssidBuf ); 255 #else 256 ret = (int)TI_SetSSID( myDrv->hDriver, (u8 *)ssidBuf ); 257 #endif 258 return( TI2WPA_STATUS(ret) ); 259 } 260 261 /*----------------------------------------------------------------------------- 262 Routine Name: wpa_driver_tista_set_wpa 263 Routine Description: enable/disable WPA support in driver - not implemented since not supported in driver. also obselete for wpa-suppl core 264 Arguments: 265 priv - pointer to private data structure 266 enabled - enable/disable flag 267 Return Value: 0 on success, -1 on failure 268 -----------------------------------------------------------------------------*/ 269 static int wpa_driver_tista_set_wpa(void *priv, int enabled) 270 { 271 struct wpa_driver_ti_data *myDrv = (struct wpa_driver_ti_data *)priv; 272 273 wpa_printf(MSG_DEBUG,"wpa_driver_tista_set_wpa called: %d",enabled); 274 return( 0 ); 275 } 276 277 /*----------------------------------------------------------------------------- 278 Routine Name: wpa_driver_tista_set_proto 279 Routine Description: set authentication protocol (WPA/WPA2(RSN)) 280 Arguments: 281 priv - pointer to private data structure 282 proto - authentication suite 283 Return Value: 0 on success, -1 on failure 284 -----------------------------------------------------------------------------*/ 285 static int wpa_driver_tista_set_proto( void *priv, int proto ) 286 { 287 struct wpa_driver_ti_data *myDrv = (struct wpa_driver_ti_data *)priv; 288 289 wpa_printf(MSG_DEBUG,"wpa_driver_tista_set_proto called: %d", proto); 290 myDrv->proto = proto; 291 292 return( 0 ); 293 } 294 295 /*----------------------------------------------------------------------------- 296 Routine Name: wpa_driver_tista_set_wpa_options 297 Routine Description: set wpa_options 298 Arguments: 299 priv - pointer to private data structure 300 wpa_options - WPA options (0 - disable, 3 - enable) 301 Return Value: 0 on success, -1 on failure 302 -----------------------------------------------------------------------------*/ 303 static int wpa_driver_tista_set_wpa_options( void *priv, int key_mgmt_suite ) 304 { 305 struct wpa_driver_ti_data *myDrv = (struct wpa_driver_ti_data *)priv; 306 UINT32 wpa_opt = WPA_OPTIONS_DISABLE; 307 int ret; 308 309 wpa_printf(MSG_DEBUG,"wpa_driver_tista_set_wpa_options called: %d", key_mgmt_suite); 310 /* If driver is not initialized yet - we cannot access it so return */ 311 TI_CHECK_DRIVER( myDrv->driver_is_loaded, -1 ); 312 313 myDrv->key_mgmt = key_mgmt_suite; 314 315 switch( key_mgmt_suite ) { 316 case KEY_MGMT_802_1X: /* Dm: EAP */ 317 wpa_opt = WPA_OPTIONS_ENABLE; /* wpa_auth = 1; */ 318 break; 319 320 case KEY_MGMT_PSK: /* Dm: PSK */ 321 wpa_opt = WPA_OPTIONS_ENABLE; /* wpa_auth = 2; */ 322 break; 323 324 case KEY_MGMT_802_1X_NO_WPA: /* Dm: ??? */ 325 break; 326 327 case KEY_MGMT_WPA_NONE: /* Dm: ??? */ 328 break; 329 330 case KEY_MGMT_NONE: 331 default: 332 wpa_opt = WPA_OPTIONS_DISABLE; /* wpa_auth = 255; */ 333 break; 334 } 335 336 /* Set WPA Options */ 337 ret = TI_SetWpaOptions( myDrv->hDriver, wpa_opt ); 338 return( TI2WPA_STATUS(ret) ); 339 } 340 341 /*----------------------------------------------------------------------------- 342 Routine Name: wpa_driver_tista_set_encryption 343 Routine Description: set authentication protocol (WPA/WPA2(RSN)) 344 Arguments: 345 priv - pointer to private data structure 346 proto - authentication suite 347 Return Value: 0 on success, -1 on failure 348 -----------------------------------------------------------------------------*/ 349 static int wpa_driver_tista_set_encryption( void *priv, int encryption ) 350 { 351 struct wpa_driver_ti_data *myDrv = (struct wpa_driver_ti_data *)priv; 352 int ret = -1; 353 OS_802_11_ENCRYPTION_TYPES wpa_cipher = OS_ENCRYPTION_TYPE_NONE; 354 355 wpa_printf(MSG_DEBUG,"wpa_driver_tista_set_encryption called: %d",encryption); 356 /* If driver is not initialized yet - we cannot access it so return */ 357 TI_CHECK_DRIVER( myDrv->driver_is_loaded, -1 ); 358 359 myDrv->encryption = encryption; 360 switch( encryption ) { 361 case CIPHER_WEP40: 362 case CIPHER_WEP104: 363 wpa_printf(MSG_DEBUG, "encryption: OS_ENCRYPTION_TYPE_WEP"); 364 wpa_cipher = OS_ENCRYPTION_TYPE_WEP; 365 break; 366 367 case CIPHER_TKIP: 368 wpa_printf(MSG_DEBUG, "encryption: OS_ENCRYPTION_TYPE_TKIP"); 369 wpa_cipher = OS_ENCRYPTION_TYPE_TKIP; 370 break; 371 372 case CIPHER_CCMP: 373 wpa_printf(MSG_DEBUG, "encryption: OS_ENCRYPTION_TYPE_AES"); 374 wpa_cipher = OS_ENCRYPTION_TYPE_AES; 375 break; 376 377 case CIPHER_NONE: 378 default: 379 wpa_printf(MSG_DEBUG, "encryption: OS_ENCRYPTION_TYPE_NONE"); 380 wpa_cipher = OS_ENCRYPTION_TYPE_NONE; 381 break; 382 } 383 ret = TI_SetEncryptionType( myDrv->hDriver, wpa_cipher ); 384 return( TI2WPA_STATUS(ret) ); 385 } 386 387 /*---------------------------------------------------------------------------*/ 388 void wpa_driver_tista_print_auth_mode( OS_802_11_AUTHENTICATION_MODE myAuth ) 389 { 390 char *mode_name = NULL; 391 392 switch( myAuth ) { 393 case os802_11AuthModeOpen: 394 mode_name = "os802_11AuthModeOpen"; 395 break; 396 case os802_11AuthModeShared: 397 mode_name = "os802_11AuthModeShared"; 398 break; 399 case os802_11AuthModeAutoSwitch: 400 mode_name = "os802_11AuthModeAutoSwitch"; 401 break; 402 case os802_11AuthModeWPA: 403 mode_name = "os802_11AuthModeWPA"; 404 break; 405 case os802_11AuthModeWPAPSK: 406 mode_name = "os802_11AuthModeWPAPSK"; 407 break; 408 case os802_11AuthModeWPANone: 409 mode_name = "os802_11AuthModeWPANone"; 410 break; 411 case os802_11AuthModeWPA2: 412 mode_name = "os802_11AuthModeWPA2"; 413 break; 414 case os802_11AuthModeWPA2PSK: 415 mode_name = "os802_11AuthModeWPA2PSK"; 416 break; 417 case os802_11AuthModeMax: 418 default: 419 mode_name = "Unknown"; 420 break; 421 } 422 wpa_printf(MSG_DEBUG, "Selected AuthMode: %s", mode_name); 423 } 424 425 /*----------------------------------------------------------------------------- 426 Routine Name: wpa_driver_tista_set_auth_mode 427 Routine Description: 428 Arguments: 429 priv - pointer to private data structure 430 Return Value: 0 on success, -1 on failure 431 -----------------------------------------------------------------------------*/ 432 static int wpa_driver_tista_set_auth_mode( void *priv ) 433 { 434 struct wpa_driver_ti_data *myDrv = (struct wpa_driver_ti_data *)priv; 435 OS_802_11_AUTHENTICATION_MODE myAuth = os802_11AuthModeAutoSwitch; 436 int ret; 437 438 wpa_printf(MSG_DEBUG,"wpa_driver_tista_set_auth_mode called"); 439 440 /* If driver is not initialized yet - we cannot access it so return */ 441 TI_CHECK_DRIVER( myDrv->driver_is_loaded, -1 ); 442 443 wpa_driver_tista_set_proto( priv, ((struct wpa_supplicant *)myDrv->hWpaSupplicant)->wpa->proto ); 444 wpa_printf(MSG_DEBUG, "proto: %d", myDrv->proto); /* should be set BEFORE */ 445 wpa_printf(MSG_DEBUG, "auth_alg: %d",myDrv->auth_alg); 446 447 if( (myDrv->auth_alg == AUTH_ALG_OPEN_SYSTEM) || 448 (myDrv->auth_alg == AUTH_ALG_LEAP) ) { 449 switch( myDrv->key_mgmt ) { 450 case KEY_MGMT_802_1X: 451 if( myDrv->proto & WPA_PROTO_WPA ) { 452 myAuth = os802_11AuthModeWPA; 453 } 454 else if( myDrv->proto & WPA_PROTO_RSN ) { 455 myAuth = os802_11AuthModeWPA2; 456 } 457 break; 458 case KEY_MGMT_PSK: 459 if( myDrv->proto & WPA_PROTO_WPA ) { 460 myAuth = os802_11AuthModeWPAPSK; 461 } 462 else if( myDrv->proto & WPA_PROTO_RSN ) { 463 myAuth = os802_11AuthModeWPA2PSK; 464 } 465 break; 466 case KEY_MGMT_802_1X_NO_WPA: 467 case KEY_MGMT_WPA_NONE: 468 myAuth = os802_11AuthModeWPANone; 469 break; 470 case KEY_MGMT_NONE: 471 default: 472 myAuth = os802_11AuthModeOpen; 473 break; 474 } 475 } 476 else if( myDrv->auth_alg == AUTH_ALG_SHARED_KEY ) { 477 myAuth = os802_11AuthModeShared; 478 } 479 if( myDrv->auth_alg == AUTH_ALG_LEAP ) { 480 TI_SetEAPType( myDrv->hDriver, OS_EAP_TYPE_LEAP ); 481 TI_SetEAPTypeDriver( myDrv->hDriver, OS_EAP_TYPE_LEAP ); 482 } 483 wpa_driver_tista_print_auth_mode( myAuth ); 484 ret = TI_SetAuthenticationMode( myDrv->hDriver, myAuth ); 485 return( TI2WPA_STATUS(ret) ); 486 } 487 488 /*----------------------------------------------------------------------------- 489 Routine Name: wpa_driver_tista_del_key 490 Routine Description: remove key from driver 491 Arguments: 492 priv - pointer to private data structure 493 key_idx - key index 494 addr - key address (unicast/broadcast) 495 Return Value: 0 on success, -1 on failure 496 -----------------------------------------------------------------------------*/ 497 static int wpa_driver_tista_del_key(void *priv, int key_idx, 498 const unsigned char *addr) 499 { 500 struct wpa_driver_ti_data *myDrv = (struct wpa_driver_ti_data *)priv; 501 OS_802_11_REMOVE_KEY myKey; 502 int ret; 503 504 wpa_printf(MSG_DEBUG,"wpa_driver_tista_del_key called"); 505 wpa_printf(MSG_DEBUG,"key_idx = %d, addr = " TIMACSTR, key_idx, MAC2STR(addr)); 506 507 /* If driver is not initialized yet - we cannot access it so return */ 508 TI_CHECK_DRIVER( myDrv->driver_is_loaded, -1 ); 509 510 /* copy parameters (MAC of key to remove, etc) to local structure */ 511 myKey.Length = sizeof(OS_802_11_REMOVE_KEY); 512 os_memcpy(&myKey.BSSID,addr,MAC_ADDR_LEN); 513 myKey.KeyIndex = key_idx; 514 515 /* Call Utility adapter to remove the key */ 516 ret = TI_RemoveKey( myDrv->hDriver, &myKey ); 517 return( TI2WPA_STATUS(ret) ); 518 } 519 520 /*----------------------------------------------------------------------------- 521 Routine Name: wpa_driver_tista_set_key 522 Routine Description: set key in driver 523 Arguments: 524 priv - pointer to private data structure 525 alg - type of key 526 addr - key address (unicast/broadcast) 527 key_idx - key index 528 set_tx - use key for immidiate tx 529 seq - sequence counter (for replay detection) 530 seq_len - sequence counter buffer len 531 key - key content 532 key_len - length of key (32 for TKIP, 16 for AES) 533 Return Value: 0 on success, -1 on failure 534 -----------------------------------------------------------------------------*/ 535 static int wpa_driver_tista_set_key(void *priv, wpa_alg alg, 536 const unsigned char *addr, int key_idx, int set_tx, 537 const u8 *seq, size_t seq_len, 538 const u8 *key, size_t key_len) 539 { 540 struct wpa_driver_ti_data *myDrv = (struct wpa_driver_ti_data *)priv; 541 OS_802_11_KEY myKey; 542 OS_802_11_WEP myWepKey; 543 UINT8 temp[TKIP_KEY_LENGTH]; 544 int ret = -1; 545 546 wpa_printf(MSG_DEBUG,"wpa_driver_tista_set_key called"); 547 /* If driver is not initialized yet - we cannot access it so return */ 548 TI_CHECK_DRIVER( myDrv->driver_is_loaded, -1 ); 549 550 wpa_printf(MSG_DEBUG, "add_key (addr): " MACSTR, MAC2STR(addr)); 551 wpa_printf(MSG_DEBUG, "add_key (key_idx): %d", key_idx); 552 wpa_printf(MSG_DEBUG, "add_key (alg): %d", alg); 553 wpa_printf(MSG_DEBUG, "add_key (set_tx): %d", set_tx); 554 wpa_hexdump(MSG_DEBUG, "add_key (seq):", seq, seq_len); 555 wpa_hexdump(MSG_DEBUG, "add_key (key):", key, key_len); 556 557 switch( key_len ) { 558 case TKIP_KEY_LENGTH: /* 32 */ 559 case AES_KEY_LENGTH: /* 16 */ 560 /* Set key index */ 561 myKey.KeyIndex = key_idx; 562 /* Set key length and content */ 563 myKey.KeyLength = key_len; 564 /* Set structure size */ 565 myKey.Length = sizeof(OS_802_11_KEY); 566 /* set key MAC address - FF:FF:FF:FF:FF:FF for broadcast, other for unicast */ 567 os_memcpy( &myKey.BSSID, addr, MAC_ADDR_LEN ); 568 569 if( seq_len ) { 570 /* Set key RSC */ 571 os_memcpy( &myKey.KeyRSC, seq, seq_len ); 572 myKey.KeyIndex |= TIWLAN_KEY_FLAGS_SET_KEY_RSC; 573 } 574 575 if( set_tx ) { 576 myKey.KeyIndex |= TIWLAN_KEY_FLAGS_TRANSMIT; 577 } 578 579 if( myKey.BSSID[0] != 0xFF ) { 580 myKey.KeyIndex |= TIWLAN_KEY_FLAGS_PAIRWISE; 581 } 582 583 os_memcpy( &temp, key, AES_KEY_LENGTH ); 584 if( key_len == TKIP_KEY_LENGTH ) { 585 /* need to switch RX and TX MIC set with key (to match driver API) */ 586 os_memcpy( (UINT8*)(((UINT8*)&temp)+24), (UINT8*)(((UINT8*)key)+16), 8 ); 587 os_memcpy( (UINT8*)(((UINT8*)&temp)+16), (UINT8*)(((UINT8*)key)+24), 8 ); 588 } 589 os_memcpy( &myKey.KeyMaterial, &temp, key_len ); 590 ret = TI_AddKey( myDrv->hDriver, &myKey ); 591 break; 592 593 case WEP_KEY_LENGTH_40: /* 5 */ 594 case WEP_KEY_LENGTH_104: /* 13 */ 595 if( key_len != 0 ) { 596 /* Set key index */ 597 myWepKey.KeyIndex = key_idx; 598 /* Set key length and content */ 599 myWepKey.KeyLength = key_len; 600 /* Set structure size */ 601 myWepKey.Length = sizeof(OS_802_11_WEP); 602 603 if( set_tx ) { 604 myWepKey.KeyIndex |= TIWLAN_KEY_FLAGS_TRANSMIT; 605 wpa_printf(MSG_DEBUG, "setting this key to be the index: 0x%x", myWepKey.KeyIndex); 606 } 607 608 os_memcpy( &myWepKey.KeyMaterial, key, key_len ); 609 wpa_printf(MSG_DEBUG, "Adding WEP key index: 0x%x", key_idx); 610 ret = TI_AddWEPKey( myDrv->hDriver, &myWepKey ); 611 } 612 else { 613 wpa_printf(MSG_DEBUG, "Removing WEP key index: 0x%x", key_idx); 614 ret = TI_RemoveWEPKey( myDrv->hDriver, key_idx ); 615 } 616 break; 617 618 default: 619 wpa_printf(MSG_ERROR,"Set_key: Wrong Key\n"); 620 break; 621 } 622 return( TI2WPA_STATUS(ret) ); 623 } 624 625 /*----------------------------------------------------------------------------- 626 Routine Name: wpa_driver_tista_set_countermeasures 627 Routine Description: start/stop countermeasures (drop packets due to replay attack detection) 628 Arguments: 629 priv - pointer to private data structure 630 enabled - enable/disable flag 631 Return Value: 0 on success, -1 on failure 632 -----------------------------------------------------------------------------*/ 633 static int wpa_driver_tista_set_countermeasures(void *priv, int enabled) 634 { 635 struct wpa_driver_ti_data *myDrv = (struct wpa_driver_ti_data *)priv; 636 637 wpa_printf(MSG_DEBUG,"wpa_driver_tista_set_countermeasures called: %d", enabled); 638 return( 0 ); 639 } 640 641 /*----------------------------------------------------------------------------- 642 Routine Name: wpa_driver_tista_set_drop_unencrypted 643 Routine Description: enable/disable EAPOL-only tx by driver 644 Arguments: 645 priv - pointer to private data structure 646 enabled - enable/disable flag 647 Return Value: 0 on success, -1 on failure 648 -----------------------------------------------------------------------------*/ 649 static int wpa_driver_tista_set_drop_unencrypted(void *priv, int enabled) 650 { 651 struct wpa_driver_ti_data *myDrv = (struct wpa_driver_ti_data *)priv; 652 653 wpa_printf(MSG_DEBUG,"TI: wpa_driver_tista_set_drop_unencrypted called: %d - not implemented", enabled); 654 return( 0 ); 655 } 656 657 /*----------------------------------------------------------------------------- 658 Routine Name: wpa_driver_tista_deauthenticate 659 Routine Description: send deauthentication packet 660 Arguments: 661 priv - pointer to private data structure 662 addr - address to send deauth packet to 663 reason_code - reason code supplied in deauth packet 664 Return Value: 0 on success, -1 on failure 665 -----------------------------------------------------------------------------*/ 666 static int wpa_driver_tista_deauthenticate(void *priv, const UINT8 *addr, int reason_code) 667 { 668 struct wpa_driver_ti_data *myDrv = (struct wpa_driver_ti_data *)priv; 669 int ret; 670 671 wpa_printf(MSG_DEBUG,"wpa_driver_tista_deauthenticate called"); 672 /* If driver is not initialized yet - we cannot access it so return */ 673 TI_CHECK_DRIVER( myDrv->driver_is_loaded, -1 ); 674 675 /* Block any pending disassoc event until successfully connected */ 676 if( myDrv->block_disassoc_events == NO_BLOCK ) 677 myDrv->block_disassoc_events = NO_BLOCK_DISASSOC_IN_PROGRESS; 678 679 ret = TI_Disassociate( myDrv->hDriver ); 680 return( TI2WPA_STATUS(ret) ); 681 } 682 683 /*----------------------------------------------------------------------------- 684 Routine Name: wpa_driver_tista_disassociate 685 Routine Description: disassociate from AP 686 Arguments: 687 priv - pointer to private data structure 688 addr - address to send deauth packet to 689 reason_code - reason code supplied in deauth packet 690 Return Value: 0 on success, -1 on failure 691 -----------------------------------------------------------------------------*/ 692 static int wpa_driver_tista_disassociate(void *priv, const UINT8 *addr, int reason_code) 693 { 694 struct wpa_driver_ti_data *myDrv = (struct wpa_driver_ti_data *)priv; 695 int ret; 696 697 wpa_printf(MSG_DEBUG,"TI: wpa_driver_tista_disassociate called"); 698 /* If driver is not initialized yet - we cannot access it so return */ 699 TI_CHECK_DRIVER( myDrv->driver_is_loaded, -1 ); 700 701 /* Block any pending disassoc event until successfully connected */ 702 if( myDrv->block_disassoc_events == NO_BLOCK ) 703 myDrv->block_disassoc_events = NO_BLOCK_DISASSOC_IN_PROGRESS; 704 705 ret = TI_Disassociate( myDrv->hDriver ); 706 return( TI2WPA_STATUS(ret) ); 707 } 708 709 /*----------------------------------------------------------------------------- 710 Routine Name: wpa_driver_tista_associate 711 Routine Description: associate with AP 712 Arguments: 713 priv - pointer to private data structure 714 params - struct wpa_driver_associate_params (ssid, bssid, etc) 715 Return Value: 0 on success, -1 on failure 716 -----------------------------------------------------------------------------*/ 717 static int wpa_driver_tista_associate(void *priv, struct wpa_driver_associate_params *params) 718 { 719 struct wpa_driver_ti_data *myDrv = (struct wpa_driver_ti_data *)priv; 720 OS_802_11_MAC_ADDRESS bssid = { 0xff,0xff,0xff,0xff,0xff,0xff }; 721 int wpa_opt, wpa_cipher, ret; 722 723 wpa_printf(MSG_DEBUG,"TI: wpa_driver_tista_associate called"); 724 /* If driver is not initialized yet - we cannot access it so return */ 725 TI_CHECK_DRIVER( myDrv->driver_is_loaded, -1 ); 726 727 if( myDrv->block_disassoc_events == NO_BLOCK_DISASSOC_IN_PROGRESS ) 728 myDrv->block_disassoc_events = BLOCK_DISASSOC; 729 730 if( params->bssid ) { 731 wpa_printf(MSG_DEBUG, "TI: BSSID=" MACSTR, MAC2STR(params->bssid)); 732 /* if there is bssid -> set it */ 733 if( os_memcmp( params->bssid, "\x00\x00\x00\x00\x00\x00", ETH_ALEN ) != 0 ) { 734 os_memcpy( &bssid, params->bssid, ETH_ALEN ); 735 TI_SetBSSID( myDrv->hDriver, &bssid ); 736 } 737 } 738 else { 739 /* else set it to {0xff, 0xff, 0xff, 0xff, 0xff, 0xff} */ 740 TI_SetBSSID( myDrv->hDriver, &bssid ); 741 } 742 743 /* Set driver network mode (Adhoc/Infrastructure) according to supplied parameters */ 744 if( params->mode == IEEE80211_MODE_INFRA ) { 745 wpa_printf(MSG_DEBUG,"TI: setting os802_11Infrastructure mode..."); 746 TI_SetBSSType( myDrv->hDriver, os802_11Infrastructure ); 747 } 748 else if( params->mode == IEEE80211_MODE_IBSS ) { 749 wpa_printf(MSG_DEBUG,"TI: setting os802_11IBSS mode..."); 750 TI_SetBSSType( myDrv->hDriver, os802_11IBSS ); 751 } 752 else { 753 wpa_printf(MSG_ERROR,"TI: Associate: invalid mode specified..."); 754 } 755 756 wpa_driver_tista_set_wpa_options( priv, params->key_mgmt_suite ); 757 wpa_driver_tista_set_auth_mode( priv ); 758 wpa_driver_tista_set_encryption( priv, params->pairwise_suite ); 759 760 /* And trigger connection/association process in driver by setting SSID */ 761 ret = wpa_driver_tista_set_ssid( priv, params->ssid, params->ssid_len); 762 return( ret ); 763 } 764 765 /*----------------------------------------------------------------------------- 766 Routine Name: ti_init_scan_params 767 Routine Description: int scan parameters before scan command 768 Arguments: 769 pScanParams - pointer to scan paramters structure 770 pScanPolicy - pointer to scan policy structure 771 scanType - scan type 772 noOfChan - number of allowed channels 773 Return Value: None 774 -----------------------------------------------------------------------------*/ 775 static void ti_init_scan_params( scan_Params_t *pScanParams, 776 scan_Policy_t *pScanPolicy, 777 int scan_type, 778 struct wpa_driver_ti_data *myDrv ) 779 { 780 UINT32 scanMaxDwellTime = SME_SCAN_BG_MAX_DWELL_TIME_DEF; 781 UINT32 scanMinDwellTime = SME_SCAN_BG_MIN_DWELL_TIME_DEF; 782 UINT32 chanMaxDwellTime = SME_SCAN_BG_MIN_DWELL_TIME_DEF; 783 UINT32 chanMinDwellTime = SME_SCAN_BG_MIN_DWELL_TIME_DEF / 2; 784 int scanType = scan_type; 785 int noOfChan = myDrv->scan_channels; 786 int btCoexScan = myDrv->btcoex_scan; 787 int i, j; 788 UINT8 tid = 0, probeNum = 3; 789 790 if( noOfChan > MAX_NUMBER_OF_CHANNELS_PER_SCAN ) 791 noOfChan = MAX_NUMBER_OF_CHANNELS_PER_SCAN; 792 /* init application scan default params */ 793 pScanParams->desiredSsid.len = 0; 794 pScanParams->band = RADIO_BAND_2_4_GHZ; 795 if( btCoexScan ) { /* Changing scan parameteres to coexist with BT A2DP */ 796 if( scanType == SCAN_TYPE_NORMAL_PASSIVE ) 797 scanType = SCAN_TYPE_TRIGGERED_PASSIVE; 798 else if( scanType == SCAN_TYPE_NORMAL_ACTIVE ) 799 scanType = SCAN_TYPE_TRIGGERED_ACTIVE; 800 probeNum = 1; 801 tid = 0xFF; 802 scanMaxDwellTime /= 6; 803 scanMinDwellTime /= 6; 804 chanMaxDwellTime /= 6; 805 chanMinDwellTime /= 6; 806 } 807 pScanParams->scanType = scanType; 808 pScanParams->probeReqNumber = probeNum; 809 pScanParams->Tid = tid; 810 pScanParams->probeRequestRate = DRV_RATE_MASK_2_BARKER; 811 pScanParams->numOfChannels = (UINT8)noOfChan; 812 for(i=0;( i < noOfChan );i++) { 813 for(j=0;( j < MAC_ADDR_LEN );j++) { 814 pScanParams->channelEntry[ i ].normalChannelEntry.bssId.addr[ j ] = 0xff; 815 } 816 pScanParams->channelEntry[ i ].normalChannelEntry.earlyTerminationEvent = SCAN_ET_COND_DISABLE; 817 pScanParams->channelEntry[ i ].normalChannelEntry.ETMaxNumOfAPframes = 0; 818 pScanParams->channelEntry[ i ].normalChannelEntry.maxChannelDwellTime = scanMaxDwellTime; 819 pScanParams->channelEntry[ i ].normalChannelEntry.minChannelDwellTime = scanMinDwellTime; 820 #ifdef STA_DK_VER_5_0_0_94 821 pScanParams->channelEntry[ i ].normalChannelEntry.txPowerLevel = 1; 822 #else 823 pScanParams->channelEntry[ i ].normalChannelEntry.txPowerDbm = MAX_TX_POWER; 824 #endif 825 pScanParams->channelEntry[ i ].normalChannelEntry.channel = i + 1; 826 } 827 828 /* init default scan policy */ 829 pScanPolicy->normalScanInterval = 10000; 830 pScanPolicy->deterioratingScanInterval = 5000; 831 pScanPolicy->maxTrackFailures = 3; 832 pScanPolicy->BSSListSize = 4; 833 pScanPolicy->BSSNumberToStartDiscovery = 1; 834 pScanPolicy->numOfBands = 1; 835 pScanPolicy->bandScanPolicy[ 0 ].band = RADIO_BAND_2_4_GHZ; 836 pScanPolicy->bandScanPolicy[ 0 ].rxRSSIThreshold = -80; 837 pScanPolicy->bandScanPolicy[ 0 ].numOfChannles = (UINT8)noOfChan; 838 pScanPolicy->bandScanPolicy[ 0 ].numOfChannlesForDiscovery = 3; 839 for(i=0;( i < noOfChan );i++) { 840 pScanPolicy->bandScanPolicy[ 0 ].channelList[ i ] = i + 1; 841 } 842 pScanPolicy->bandScanPolicy[ 0 ].trackingMethod.scanType = SCAN_TYPE_NO_SCAN; 843 pScanPolicy->bandScanPolicy[ 0 ].trackingMethod.method.basicMethodParams.earlyTerminationEvent = SCAN_ET_COND_DISABLE; 844 pScanPolicy->bandScanPolicy[ 0 ].trackingMethod.method.basicMethodParams.ETMaxNumberOfApFrames = 0; 845 pScanPolicy->bandScanPolicy[ 0 ].trackingMethod.method.basicMethodParams.maxChannelDwellTime = chanMaxDwellTime; 846 pScanPolicy->bandScanPolicy[ 0 ].trackingMethod.method.basicMethodParams.minChannelDwellTime = chanMinDwellTime; 847 pScanPolicy->bandScanPolicy[ 0 ].trackingMethod.method.basicMethodParams.probReqParams.bitrate = DRV_RATE_MASK_1_BARKER; 848 pScanPolicy->bandScanPolicy[ 0 ].trackingMethod.method.basicMethodParams.probReqParams.numOfProbeReqs = pScanParams->probeReqNumber; 849 #ifdef STA_DK_VER_5_0_0_94 850 pScanPolicy->bandScanPolicy[ 0 ].trackingMethod.method.basicMethodParams.probReqParams.txLevel = 1; 851 #else 852 pScanPolicy->bandScanPolicy[ 0 ].trackingMethod.method.basicMethodParams.probReqParams.txPowerDbm = MAX_TX_POWER; 853 #endif 854 pScanPolicy->bandScanPolicy[ 0 ].discoveryMethod.scanType = SCAN_TYPE_NO_SCAN; 855 pScanPolicy->bandScanPolicy[ 0 ].discoveryMethod.method.basicMethodParams.earlyTerminationEvent = SCAN_ET_COND_DISABLE; 856 pScanPolicy->bandScanPolicy[ 0 ].discoveryMethod.method.basicMethodParams.ETMaxNumberOfApFrames = 0; 857 pScanPolicy->bandScanPolicy[ 0 ].discoveryMethod.method.basicMethodParams.maxChannelDwellTime = chanMaxDwellTime; 858 pScanPolicy->bandScanPolicy[ 0 ].discoveryMethod.method.basicMethodParams.minChannelDwellTime = chanMinDwellTime; 859 pScanPolicy->bandScanPolicy[ 0 ].discoveryMethod.method.basicMethodParams.probReqParams.bitrate = DRV_RATE_MASK_2_BARKER; 860 pScanPolicy->bandScanPolicy[ 0 ].discoveryMethod.method.basicMethodParams.probReqParams.numOfProbeReqs = pScanParams->probeReqNumber; 861 #ifdef STA_DK_VER_5_0_0_94 862 pScanPolicy->bandScanPolicy[ 0 ].discoveryMethod.method.basicMethodParams.probReqParams.txLevel = 1; 863 #else 864 pScanPolicy->bandScanPolicy[ 0 ].discoveryMethod.method.basicMethodParams.probReqParams.txPowerDbm = MAX_TX_POWER; 865 #endif 866 pScanPolicy->bandScanPolicy[ 0 ].immediateScanMethod.scanType = btCoexScan ? SCAN_TYPE_TRIGGERED_ACTIVE : SCAN_TYPE_NORMAL_ACTIVE; 867 pScanPolicy->bandScanPolicy[ 0 ].immediateScanMethod.method.basicMethodParams.earlyTerminationEvent = SCAN_ET_COND_DISABLE; 868 pScanPolicy->bandScanPolicy[ 0 ].immediateScanMethod.method.basicMethodParams.ETMaxNumberOfApFrames = 0; 869 pScanPolicy->bandScanPolicy[ 0 ].immediateScanMethod.method.basicMethodParams.maxChannelDwellTime = chanMaxDwellTime; 870 pScanPolicy->bandScanPolicy[ 0 ].immediateScanMethod.method.basicMethodParams.minChannelDwellTime = chanMinDwellTime; 871 pScanPolicy->bandScanPolicy[ 0 ].immediateScanMethod.method.basicMethodParams.probReqParams.bitrate = DRV_RATE_MASK_5_5_CCK; 872 pScanPolicy->bandScanPolicy[ 0 ].immediateScanMethod.method.basicMethodParams.probReqParams.numOfProbeReqs = pScanParams->probeReqNumber; 873 #ifdef STA_DK_VER_5_0_0_94 874 pScanPolicy->bandScanPolicy[ 0 ].immediateScanMethod.method.basicMethodParams.probReqParams.txLevel = 1; 875 #else 876 pScanPolicy->bandScanPolicy[ 0 ].immediateScanMethod.method.basicMethodParams.probReqParams.txPowerDbm = MAX_TX_POWER; 877 #endif 878 } 879 880 /*----------------------------------------------------------------------------- 881 Routine Name: wpa_driver_tista_scan 882 Routine Description: request scan from driver 883 Arguments: 884 priv - pointer to private data structure 885 ssid - ssid buffer 886 ssid_len - length of ssid 887 Return Value: 0 on success, -1 on failure 888 -----------------------------------------------------------------------------*/ 889 static int wpa_driver_tista_scan( void *priv, const UINT8 *ssid, size_t ssid_len ) 890 { 891 struct wpa_driver_ti_data *myDrv = (struct wpa_driver_ti_data *)priv; 892 struct wpa_supplicant *wpa_s = (struct wpa_supplicant *)(myDrv->hWpaSupplicant); 893 struct wpa_ssid *issid; 894 scan_Params_t scanParams; 895 scan_Policy_t scanPolicy; 896 int scan_type, ret, scan_probe_flag = 0; 897 898 wpa_printf(MSG_DEBUG,"wpa_driver_tista_scan called"); 899 /* If driver is not initialized yet - we cannot access it so return */ 900 TI_CHECK_DRIVER( myDrv->driver_is_loaded, -1 ); 901 902 scan_type = myDrv->scan_type; 903 if (wpa_s->prev_scan_ssid != BROADCAST_SSID_SCAN) { 904 if (wpa_s->prev_scan_ssid->scan_ssid) { 905 scan_type = SCAN_TYPE_NORMAL_ACTIVE; 906 scan_probe_flag = 1; 907 } 908 } 909 910 ti_init_scan_params( &scanParams, &scanPolicy, scan_type, myDrv ); 911 912 myDrv->force_merge_flag = 0; /* Set merge flag */ 913 914 if ((scan_probe_flag && ssid) && 915 (ssid_len > 0 && ssid_len <= sizeof(scanParams.desiredSsid.ssidString))) { 916 os_memcpy(scanParams.desiredSsid.ssidString, ssid, ssid_len); 917 if (ssid_len < sizeof(scanParams.desiredSsid.ssidString)) 918 scanParams.desiredSsid.ssidString[ssid_len] = '\0'; 919 scanParams.desiredSsid.len = ssid_len; 920 myDrv->force_merge_flag = 1; 921 } 922 TI_SetScanPolicy( myDrv->hDriver, (UINT8 *)&scanPolicy, sizeof(scan_Policy_t) ); 923 myDrv->last_scan = scan_type; /* Remember scan type for last scan */ 924 ret = TI_StartScan( myDrv->hDriver, (scan_Params_t *)&scanParams ); 925 return( TI2WPA_STATUS(ret) ); 926 } 927 928 /*----------------------------------------------------------------------------- 929 Routine Name: wpa_driver_tista_set_auth_alg 930 Routine Description: set authentication in driver 931 Arguments: 932 priv - pointer to private data structure 933 auth_alg - Open/Shared/LEAP 934 Return Value: 0 on success, -1 on failure 935 -----------------------------------------------------------------------------*/ 936 static int wpa_driver_tista_set_auth_alg( void *priv, int auth_alg ) 937 { 938 struct wpa_driver_ti_data *myDrv = (struct wpa_driver_ti_data *)priv; 939 940 wpa_printf(MSG_DEBUG,"wpa_driver_tista_set_auth_alg called: %d", auth_alg); 941 /* If driver is not initialized yet - we cannot access it so return */ 942 TI_CHECK_DRIVER( myDrv->driver_is_loaded, -1 ); 943 myDrv->auth_alg = auth_alg; 944 return( 0 ); 945 } 946 947 /*----------------------------------------------------------------------------- 948 Routine Name: wpa_driver_tista_get_bssid_info 949 Routine Description: retrieve bssid full info 950 Arguments: 951 hDriver - pointer to driver structure 952 Return Value: pointer to BSSID structure or NULL 953 -----------------------------------------------------------------------------*/ 954 static OS_802_11_BSSID_EX *wpa_driver_tista_get_bssid_info( TI_HANDLE hDriver ) 955 { 956 OS_802_11_BSSID_LIST_EX *bssid_list; 957 OS_802_11_BSSID_EX *pBssid, *nBssid = NULL; 958 int i, number_items, res; 959 OS_802_11_MAC_ADDRESS bssid; 960 OS_802_11_SSID ssid; 961 962 if( TI_GetBSSIDList( hDriver, &bssid_list ) || !bssid_list ) 963 return( nBssid ); 964 965 if( TI_GetBSSID( hDriver, &bssid ) != TI_RESULT_OK ) 966 return( nBssid ); 967 968 if( TI_GetCurrentSSID( hDriver, &ssid ) != TI_RESULT_OK ) 969 return( nBssid ); 970 971 pBssid = &bssid_list->Bssid[0]; 972 number_items = (int)(bssid_list->NumberOfItems); 973 for(i=0;( i < number_items );i++) { 974 if( !os_memcmp((void *)&bssid, pBssid->MacAddress, MAC_ADDR_LEN) && 975 !os_memcmp(ssid.Ssid, pBssid->Ssid.Ssid, pBssid->Ssid.SsidLength) ) { 976 nBssid = (OS_802_11_BSSID_EX *)os_malloc( pBssid->Length ); 977 if( nBssid != NULL ) 978 os_memcpy( nBssid, pBssid, pBssid->Length ); 979 break; 980 } 981 pBssid = (OS_802_11_BSSID_EX *)(((char *)pBssid) + pBssid->Length); 982 } 983 os_free( bssid_list ); 984 return( nBssid ); 985 } 986 987 /*----------------------------------------------------------------------------- 988 Compare function for sorting scan results. Return >0 if @b is considered better. 989 -----------------------------------------------------------------------------*/ 990 static int wpa_driver_tista_scan_result_compare(const void *a, const void *b) 991 { 992 const struct wpa_scan_result *wa = a; 993 const struct wpa_scan_result *wb = b; 994 995 return( wb->level - wa->level ); 996 } 997 998 /*----------------------------------------------------------------------------- 999 Routine Name: wpa_driver_tista_get_scan_results 1000 Routine Description: retrieve driver scan results 1001 Arguments: 1002 priv - pointer to private data structure 1003 results - pointer to buffer 1004 max_size - maximum size of results buffer 1005 Return Value: number of SSID on success, -1 on failure 1006 -----------------------------------------------------------------------------*/ 1007 static int wpa_driver_tista_get_scan_results( void *priv, 1008 struct wpa_scan_result *results, 1009 size_t max_size ) 1010 { 1011 struct wpa_driver_ti_data *myDrv = (struct wpa_driver_ti_data *)priv; 1012 OS_802_11_BSSID_LIST_EX *bssid_list; 1013 OS_802_11_BSSID_EX *pBssid; 1014 OS_802_11_FIXED_IEs *pFixedIes; 1015 OS_802_11_VARIABLE_IEs *pVarIes; 1016 unsigned int number_items, i, index; 1017 1018 wpa_printf(MSG_DEBUG,"wpa_driver_tista_get_scan_results called"); 1019 /* If driver is not initialized yet - we cannot access it so return */ 1020 TI_CHECK_DRIVER( myDrv->driver_is_loaded, -1 ); 1021 1022 if( TI_GetBSSIDList(myDrv->hDriver, &bssid_list) || !bssid_list ) 1023 return( -1 ); 1024 1025 pBssid = &bssid_list->Bssid[0]; 1026 number_items = (int)(bssid_list->NumberOfItems); 1027 1028 wpa_printf(MSG_MSGDUMP, "Received %d bytes of scan results (%d BSSes)", 1029 number_items * sizeof(OS_802_11_BSSID_EX), number_items); 1030 1031 os_memset( results, 0, max_size * sizeof(struct wpa_scan_result) ); 1032 number_items = MIN( number_items, max_size ); 1033 1034 for(index=0; index < number_items; index++) { 1035 os_memcpy( results[index].bssid, &pBssid->MacAddress, ETH_ALEN ); 1036 os_memcpy( results[index].ssid, pBssid->Ssid.Ssid, pBssid->Ssid.SsidLength ); 1037 results[index].ssid_len = pBssid->Ssid.SsidLength; 1038 #ifdef STA_DK_VER_5_0_0_94 1039 results[index].freq = pBssid->Configuration.channel / 1000; 1040 results[index].caps = pBssid->Capabilities; 1041 #else 1042 results[index].freq = pBssid->Configuration.Union.channel / 1000; 1043 results[index].caps = pBssid->Union.Capabilities; 1044 #endif 1045 results[index].level = pBssid->Rssi; 1046 results[index].maxrate = 0; /* In units of 0.5 Mb/s */ 1047 for (i = 0; i < sizeof(pBssid->SupportedRates); i++) { 1048 if (pBssid->SupportedRates[i] > (unsigned)results[index].maxrate) { 1049 results[index].maxrate = pBssid->SupportedRates[i]; 1050 } 1051 } 1052 wpa_printf(MSG_DEBUG,"TI: Net: %s Cap: 0x%04x Priv: 0x%x NetType: 0x%x InfraMode: 0x%x IELen: %d", 1053 #ifdef STA_DK_VER_5_0_0_94 1054 pBssid->Ssid.Ssid, pBssid->Capabilities, pBssid->Privacy, pBssid->NetworkTypeInUse, 1055 #else 1056 pBssid->Ssid.Ssid, pBssid->Union.Capabilities, pBssid->Privacy, pBssid->NetworkTypeInUse, 1057 #endif 1058 pBssid->InfrastructureMode, pBssid->IELength ); 1059 1060 /* Fixed IEs from site entry - same Capabilities */ 1061 pFixedIes = (OS_802_11_FIXED_IEs *)&pBssid->IEs[0]; 1062 wpa_printf(MSG_DEBUG,"TI: Fixed IEs: Beacon: 0x%x Cap: 0x%x", pFixedIes->BeaconInterval, pFixedIes->Capabilities); 1063 for(i=sizeof(OS_802_11_FIXED_IEs); i < pBssid->IELength;) { 1064 pVarIes = (OS_802_11_VARIABLE_IEs *)&pBssid->IEs[i]; 1065 wpa_printf(MSG_DEBUG,"TI: Variable IEs: ID: 0x%x Len: %d", pVarIes->ElementID, pVarIes->Length); 1066 wpa_hexdump(MSG_DEBUG,"TI: oui:", pVarIes->data, pVarIes->Length); 1067 switch( pVarIes->ElementID ) { 1068 case GENERIC_INFO_ELEM: /* 0xdd */ 1069 if( (pVarIes->Length > 3) && (os_memcmp(pVarIes->data, WPA_OUI, 4) == 0) ) { 1070 results[index].wpa_ie_len = MIN((pVarIes->Length + 2), SSID_MAX_WPA_IE_LEN); 1071 os_memcpy( results[index].wpa_ie, pVarIes, results[index].wpa_ie_len ); 1072 } 1073 break; 1074 1075 case RSN_INFO_ELEM: /* 0x30 */ 1076 results[index].rsn_ie_len = MIN((pVarIes->Length + 2), SSID_MAX_WPA_IE_LEN); 1077 os_memcpy( results[index].rsn_ie, pVarIes, results[index].rsn_ie_len ); 1078 break; 1079 } 1080 i += (pVarIes->Length + (2 * sizeof(tiUINT8))); 1081 } 1082 pBssid = (OS_802_11_BSSID_EX *)(((u8 *)pBssid) + pBssid->Length); 1083 } 1084 /* Merge new results with previous */ 1085 number_items = scan_merge( myDrv, results, myDrv->force_merge_flag, number_items, max_size ); 1086 1087 qsort( results, number_items, sizeof(struct wpa_scan_result), 1088 wpa_driver_tista_scan_result_compare ); 1089 1090 os_free( bssid_list ); 1091 return( number_items ); 1092 } 1093 1094 /*----------------------------------------------------------------------------- 1095 Routine Name: wpa_driver_tista_get_scan_results 1096 Routine Description: retrieve driver scan results 1097 Arguments: 1098 sock - socket 1099 priv - pointer to private data structure 1100 sock_ctx - pointer to other private data 1101 Return Value: None 1102 -----------------------------------------------------------------------------*/ 1103 static void wpa_driver_tista_receive_driver_event( int sock, void *priv, void *sock_ctx ) 1104 { 1105 IPC_EV_DATA myBuf; 1106 UINT8 *buf; 1107 UINT32 *bufLong; 1108 union wpa_event_data myEventData; 1109 struct wpa_driver_ti_data *mySuppl; 1110 OS_802_11_ASSOCIATION_INFORMATION *pInfo = NULL; 1111 OS_802_11_AUTHENTICATION_REQUEST *pMediaSpecificBuf; 1112 OS_802_11_BSSID_EX *pSelectedBssidInfo = NULL; 1113 OS_802_11_NETWORK_MODE myBssType; 1114 IPC_EV_DATA *pData = &myBuf; 1115 int res; 1116 #ifndef STA_DK_VER_5_0_0_94 1117 btCoexStatus_t *btCoexStatus; 1118 #endif 1119 1120 wpa_printf(MSG_DEBUG,"wpa_driver_tista_receive_driver_event..."); 1121 1122 res = recv( sock, &myBuf, sizeof(myBuf), 0 ); 1123 if( res < 0 ) { 1124 wpa_printf(MSG_ERROR,"l2_packet_receive - recvfrom"); 1125 return; 1126 } 1127 1128 mySuppl = pData->EvParams.hUserParam; 1129 1130 switch( ((IPC_EVENT_PARAMS*)pData)->uEventType ) { 1131 case IPC_EVENT_ASSOCIATED: 1132 /* Associated event is called after successfull ASSOC_RSP packet is received */ 1133 wpa_printf(MSG_DEBUG,"wpa_supplicant - Associated"); 1134 1135 TI_GetBSSType( mySuppl->hDriver, &myBssType ); 1136 wpa_printf(MSG_DEBUG,"myBssType = %d",myBssType); 1137 1138 if( myBssType == os802_11Infrastructure ) { 1139 /* Get ASSOC_REQ and ASSOC_RSP IE */ 1140 res = TI_GetAssociationInfo( mySuppl->hDriver, &pInfo ); 1141 buf = (UINT8 *)pInfo; 1142 1143 if( buf != NULL ) { 1144 myEventData.assoc_info.req_ies = buf + pInfo->OffsetRequestIEs; 1145 myEventData.assoc_info.req_ies_len = pInfo->RequestIELength; 1146 myEventData.assoc_info.resp_ies = buf + pInfo->OffsetResponseIEs; 1147 myEventData.assoc_info.resp_ies_len = pInfo->ResponseIELength; 1148 myEventData.assoc_info.beacon_ies = NULL; 1149 myEventData.assoc_info.beacon_ies_len = 0; 1150 1151 /* Get AP Beacon IEs - especially WPA/RSN IE */ 1152 pSelectedBssidInfo = wpa_driver_tista_get_bssid_info( mySuppl->hDriver ); 1153 if( pSelectedBssidInfo ) { 1154 if( pSelectedBssidInfo->IELength && pSelectedBssidInfo->IEs ) { /* Dm: Fixed IEs */ 1155 myEventData.assoc_info.beacon_ies = (UINT8 *)pSelectedBssidInfo->IEs + sizeof(OS_802_11_FIXED_IEs); 1156 myEventData.assoc_info.beacon_ies_len = pSelectedBssidInfo->IELength - sizeof(OS_802_11_FIXED_IEs); 1157 } 1158 } 1159 wpa_printf(MSG_DEBUG,"myEventData.assoc_info.req_ies = 0x%x",(unsigned)myEventData.assoc_info.req_ies); 1160 wpa_printf(MSG_DEBUG,"myEventData.assoc_info.req_ies_len = %d",myEventData.assoc_info.req_ies_len); 1161 wpa_printf(MSG_DEBUG,"myEventData.assoc_info.resp_ies = 0x%x",(unsigned)myEventData.assoc_info.resp_ies); 1162 wpa_printf(MSG_DEBUG,"myEventData.assoc_info.resp_ies_len = %d",myEventData.assoc_info.resp_ies_len); 1163 wpa_printf(MSG_DEBUG,"myEventData.assoc_info.beacon_ies = 0x%x",(unsigned)myEventData.assoc_info.beacon_ies); 1164 wpa_printf(MSG_DEBUG,"myEventData.assoc_info.beacon_ies_len = %d",myEventData.assoc_info.beacon_ies_len); 1165 wpa_hexdump(MSG_DEBUG, "WPA: beacon_ies", myEventData.assoc_info.beacon_ies, myEventData.assoc_info.beacon_ies_len); 1166 1167 /* First we notify wpa_supplicant and give it all the above IEs */ 1168 wpa_supplicant_event( mySuppl->hWpaSupplicant, EVENT_ASSOCINFO, &myEventData ); 1169 1170 /* Since both ASSOC_REQ/RSP and beacon IEs are allocated dynamically by the Utility Adapter - we need to free the buffers */ 1171 os_free( pInfo ); 1172 if( pSelectedBssidInfo ) { 1173 os_free( pSelectedBssidInfo ); 1174 } 1175 } 1176 } 1177 else { 1178 myEventData.assoc_info.req_ies = NULL; 1179 myEventData.assoc_info.req_ies_len = 0; 1180 myEventData.assoc_info.resp_ies = NULL; 1181 myEventData.assoc_info.resp_ies_len = 0; 1182 myEventData.assoc_info.beacon_ies = NULL; 1183 myEventData.assoc_info.beacon_ies_len = 0; 1184 wpa_supplicant_event( mySuppl->hWpaSupplicant, EVENT_ASSOCINFO, &myEventData ); 1185 } 1186 /* We now can notify wpa_supplicant of the association event so it could start key negotiation (if needed) */ 1187 wpa_supplicant_event( mySuppl->hWpaSupplicant, EVENT_ASSOC, NULL ); 1188 /* Allow Disassociation */ 1189 mySuppl->block_disassoc_events = NO_BLOCK; 1190 break; 1191 1192 case IPC_EVENT_DISASSOCIATED: 1193 if( mySuppl->block_disassoc_events != BLOCK_DISASSOC ) { 1194 wpa_printf(MSG_DEBUG,"wpa_supplicant - Disassociated"); 1195 wpa_supplicant_event( mySuppl->hWpaSupplicant, EVENT_DISASSOC, NULL ); 1196 } 1197 else { 1198 wpa_printf(MSG_INFO,"wpa_supplicant - Disassociated (blocked)"); 1199 } 1200 break; 1201 1202 case IPC_EVENT_SCAN_COMPLETE: 1203 wpa_printf(MSG_DEBUG,"wpa_supplicant - IPC_EVENT_SCAN_COMPLETE"); 1204 wpa_supplicant_event( mySuppl->hWpaSupplicant, EVENT_SCAN_RESULTS, NULL ); 1205 break; 1206 1207 case IPC_EVENT_AUTH_SUCC: 1208 wpa_printf(MSG_INFO,"wpa_supplicant - IPC_EVENT_AUTH_SUCC"); 1209 break; 1210 1211 case IPC_EVENT_EAPOL: 1212 wpa_printf(MSG_DEBUG,"wpa_supplicant - EAPOL"); 1213 buf = pData->uBuffer; 1214 wpa_supplicant_rx_eapol( mySuppl->hWpaSupplicant, (UINT8 *)(buf + MAC_ADDR_LEN), 1215 (UINT8 *)(buf + ETHERNET_HDR_LEN), (pData->uBufferSize - ETHERNET_HDR_LEN) ); 1216 break; 1217 1218 case IPC_EVENT_MEDIA_SPECIFIC: 1219 wpa_printf(MSG_DEBUG,"wpa_supplicant - Media_Specific"); 1220 bufLong = (UINT32 *)pData->uBuffer; 1221 /* Check for Authentication type messages from driver */ 1222 if( (*bufLong) == os802_11StatusType_Authentication ) { 1223 pMediaSpecificBuf = (OS_802_11_AUTHENTICATION_REQUEST *)(bufLong + 1); 1224 wpa_printf(MSG_DEBUG,"wpa_supplicant - Media_Specific - Authentication message detected: %u", pMediaSpecificBuf->Flags); 1225 /* Check for MIC failure event */ 1226 if( (pMediaSpecificBuf->Flags == OS_802_11_REQUEST_PAIRWISE_ERROR) || (pMediaSpecificBuf->Flags == OS_802_11_REQUEST_GROUP_ERROR)) { 1227 /* Notify wpa_supplicant of MIC failure */ 1228 myEventData.michael_mic_failure.unicast = 1; 1229 wpa_supplicant_event( mySuppl->hWpaSupplicant, EVENT_MICHAEL_MIC_FAILURE, &myEventData ); 1230 } 1231 /* OS_802_11_REQUEST_REAUTH - is handled automatically */ 1232 /* OS_802_11_REQUEST_KEYUPDATE - no event of this type */ 1233 } 1234 break; 1235 1236 case IPC_EVENT_LINK_SPEED: 1237 bufLong = (UINT32 *)pData->uBuffer; 1238 wpa_printf(MSG_DEBUG,"wpa_supplicant - Link Speed = %u MB/s", ((*bufLong) / 2)); 1239 /* wpa_msg(mySuppl->hWpaSupplicant, MSG_INFO, WPA_EVENT_LINK_SPEED "%u MB/s", ((*bufLong) / 2)); */ 1240 mySuppl->link_speed = (unsigned)((*bufLong) / 2); 1241 break; 1242 1243 case IPC_EVENT_WPA2_PREAUTHENTICATION: 1244 wpa_printf(MSG_DEBUG,"wpa_supplicant - WPA2_PREAUTHENTICATION"); 1245 bufLong = (UINT32 *)pData->uBuffer; 1246 wpa_printf(MSG_DEBUG,"Preauth Status Code = %u",*bufLong); 1247 /* Dm: wpa_supplicant_event( mySuppl->hWpaSupplicant, EVENT_PMKID_CANDIDATE, &data); */ 1248 break; 1249 1250 #ifndef STA_DK_VER_5_0_0_94 1251 case IPC_EVENT_BT_COEX_MODE: 1252 btCoexStatus = (btCoexStatus_t *)pData->uBuffer; 1253 if( (btCoexStatus != NULL) && btCoexStatus->state ) { 1254 wpa_printf(MSG_DEBUG,"wpa_supplicant - BT_COEX_MODE (SG is ON, minTxRate = %d)\n", btCoexStatus->minTxRate); 1255 } 1256 else { 1257 wpa_printf(MSG_DEBUG,"wpa_supplicant - BT_COEX_MODE (SG is OFF)\n"); 1258 } 1259 break; 1260 #endif 1261 case IPC_EVENT_LOW_SNR: 1262 case IPC_EVENT_LOW_RSSI: 1263 break; 1264 1265 default: 1266 wpa_printf(MSG_ERROR,"wpa_supplicant - Unhandled driver event: %d", ((IPC_EVENT_PARAMS*)pData)->uEventType); 1267 break; 1268 } 1269 } 1270 1271 /*----------------------------------------------------------------------------- 1272 Routine Name: wpa_driver_tista_init 1273 Routine Description: init driver interface 1274 Arguments: 1275 priv - pointer to private data structure 1276 ifname - return interface name 1277 Return Value: pointer to driver structure (to be supplied later by supplicant to wrappers) 1278 -----------------------------------------------------------------------------*/ 1279 static void *wpa_driver_tista_init( void *priv, const char *ifname ) 1280 { 1281 struct wpa_driver_ti_data *myDrv; 1282 int status; 1283 UINT32 driverStatus,res; 1284 struct sockaddr_in echoserver; 1285 OS_802_11_MAC_ADDRESS myMac; 1286 #ifdef CONFIG_TI_LOCKFILE 1287 char str[10]; 1288 #endif 1289 1290 wpa_printf(MSG_DEBUG,"Initializing STA-DK %s interface...",SW_VERSION_STR); 1291 #ifdef CONFIG_TI_LOCKFILE 1292 /* Try to open the lock file */ 1293 lfp = open("./.wpa_supplicant_lockfile.pid", (O_RDWR | O_CREAT | O_EXCL), 0640); 1294 if( lfp < 0 ) { 1295 wpa_printf(MSG_ERROR,"Cannot open pid-file...Aborting...\n"); 1296 return( NULL ); 1297 } 1298 /* Try to get a file lock on the pid-file. If another instance is running and already has a lock - we will fail */ 1299 #ifndef ANDROID /* Dm: !!! lockf is not implemented in Android */ 1300 if( lockf(lfp,F_TLOCK,0) < 0 ) { 1301 wpa_printf(MSG_ERROR,"Another instance of wpa_supplicant is running...Aborting...\n"); 1302 return( NULL ); 1303 } 1304 #endif 1305 /* If we got here - it means that no other instance is running - write process id to pid_file */ 1306 sprintf(str, "%d\n", getpid()); 1307 write(lfp,str,os_strlen(str)); /* record pid to lockfile */ 1308 #endif 1309 1310 /* Allocate internal data structure to manage driver */ 1311 myDrv = os_malloc( sizeof(struct wpa_driver_ti_data) ); 1312 1313 /* If failed to allocate */ 1314 if( myDrv == NULL ) { 1315 wpa_printf(MSG_ERROR,"Failed to allocate memory for control structure...Aborting..."); 1316 goto label_init_error_file; 1317 } 1318 1319 /* Zero memory */ 1320 os_memset( myDrv, 0, sizeof(struct wpa_driver_ti_data) ); 1321 1322 /* Initialize Utility Adapter module */ 1323 myDrv->hDriver = TI_AdapterInit( TIWLAN_DRV_NAME ); 1324 1325 /* If couldn't initialize - return NULL to indicate error */ 1326 if( myDrv->hDriver == 0 ) { 1327 wpa_printf(MSG_ERROR,"Error: failed to initialize Utility Adapter interface..."); 1328 goto label_init_error_free; 1329 } 1330 1331 /* Get WLAN interface mac address through Utility Adapter */ 1332 res = TI_GetCurrentAddress( myDrv->hDriver, &myMac ); 1333 1334 if( res == (UINT32)-1 ) { 1335 wpa_printf(MSG_ERROR,"Error: failed to initialize Utility Adapter interface..."); 1336 goto label_init_error_free; 1337 } 1338 1339 os_memcpy( &myDrv->own_addr, &myMac, MAC_ADDR_LEN ); 1340 1341 wpa_driver_tista_register_events( myDrv ); 1342 1343 /* Block disassoc events until connected */ 1344 if( myDrv->block_disassoc_events == NO_BLOCK ) 1345 myDrv->block_disassoc_events = NO_BLOCK_DISASSOC_IN_PROGRESS; 1346 1347 /* Store wpa_supplicant context */ 1348 myDrv->hWpaSupplicant = priv; 1349 1350 myDrv->driverEventsSocket = socket( PF_INET, SOCK_DGRAM, IPPROTO_UDP ); 1351 1352 if( myDrv->driverEventsSocket < 0 ) { 1353 wpa_printf(MSG_ERROR,"Error: failed to create driver events socket... (%s)", strerror(errno)); 1354 goto label_init_error_free; 1355 } 1356 1357 os_memset( &echoserver, 0, sizeof(echoserver) ); /* Clear struct */ 1358 echoserver.sin_family = AF_INET; /* Internet/IP */ 1359 echoserver.sin_addr.s_addr = htonl(INADDR_ANY); /* IP address */ 1360 echoserver.sin_port = htons(TI_DRIVER_MSG_PORT); /* server port */ 1361 1362 if( bind(myDrv->driverEventsSocket, (struct sockaddr *) &echoserver, sizeof(echoserver)) < 0 ) { 1363 wpa_printf(MSG_ERROR,"Error: failed to create driver events socket... (%s)", strerror(errno)); 1364 close(myDrv->driverEventsSocket); 1365 goto label_init_error_free; 1366 } 1367 1368 status = eloop_register_read_sock( myDrv->driverEventsSocket, wpa_driver_tista_receive_driver_event, priv, myDrv ); 1369 1370 if( status != 0 ) { 1371 wpa_printf(MSG_ERROR,"Error: failed to register socket handler..."); 1372 } 1373 1374 wpa_printf(MSG_DEBUG,"driver events socket is 0x%x...",myDrv->driverEventsSocket); 1375 1376 /* Signal that driver is not stopped */ 1377 myDrv->driver_is_loaded = TRUE; 1378 1379 /* Set default scan type */ 1380 myDrv->scan_type = SCAN_TYPE_NORMAL_ACTIVE; 1381 myDrv->force_merge_flag = 0; 1382 scan_init( myDrv ); 1383 1384 /* Set default amount of channels */ 1385 myDrv->scan_channels = check_and_get_build_channels(); 1386 1387 /* Link Speed will be set by the message from the driver */ 1388 myDrv->link_speed = 0; 1389 1390 /* BtCoex mode is read from tiwlan.ini file */ 1391 myDrv->btcoex_mode = 1; /* SG_DISABLE */ 1392 myDrv->btcoex_scan = FALSE; 1393 1394 /* RTS Threshold is read from tiwlan.ini file */ 1395 myDrv->rts_threshold = HAL_CTRL_RTS_THRESHOLD_MAX; 1396 1397 /* Return pointer to our driver structure */ 1398 return( myDrv ); 1399 1400 label_init_error_free: 1401 os_free( myDrv ); 1402 label_init_error_file: 1403 #ifdef CONFIG_TI_LOCKFILE 1404 /* Close and delete the pid-lock-file */ 1405 close(lfp); 1406 unlink("./wpa_supplicant_lockfile.pid"); 1407 #endif 1408 return( NULL ); 1409 } 1410 1411 /*----------------------------------------------------------------------------- 1412 Routine Name: wpa_driver_tista_unload 1413 Routine Description: unload driver 1414 Arguments: 1415 priv - pointer to private data structure 1416 Return Value: None 1417 -----------------------------------------------------------------------------*/ 1418 static void wpa_driver_tista_unload( void *priv ) 1419 { 1420 struct wpa_driver_ti_data *myDrv = (struct wpa_driver_ti_data *)priv; 1421 1422 wpa_printf(MSG_DEBUG,"wpa_driver_tista_unload called"); 1423 /* Unregister driver events */ 1424 wpa_driver_tista_unregister_events( priv ); 1425 /* Close connection socket */ 1426 close(myDrv->driverEventsSocket); 1427 /* Unload Utility Adapter */ 1428 TI_AdapterDeinit( myDrv->hDriver ); 1429 /* Free all allocated memory */ 1430 scan_exit( myDrv ); 1431 os_free( myDrv ); 1432 #ifdef CONFIG_TI_LOCKFILE 1433 /* Close and delete the pid-lock-file */ 1434 close(lfp); 1435 unlink("./wpa_supplicant_lockfile.pid"); 1436 #endif 1437 wpa_printf(MSG_DEBUG,"STA-DK %s interface Deinitialized...bye!", SW_VERSION_STR); 1438 } 1439 1440 /*----------------------------------------------------------------------------- 1441 Routine Name: wpa_driver_tista_get_mac_addr 1442 Routine Description: return WLAN MAC address 1443 Arguments: 1444 priv - pointer to private data structure 1445 Return Value: pointer to BSSID 1446 -----------------------------------------------------------------------------*/ 1447 const u8 *wpa_driver_tista_get_mac_addr( void *priv ) 1448 { 1449 struct wpa_driver_ti_data *myDrv = (struct wpa_driver_ti_data *)priv; 1450 1451 wpa_printf(MSG_DEBUG,"wpa_driver_tista_get_mac_addr called"); 1452 /* If driver is not initialized yet - we cannot access it so return */ 1453 TI_CHECK_DRIVER( myDrv->driver_is_loaded, NULL ); 1454 return( (const u8 *)&myDrv->own_addr ); 1455 } 1456 1457 /*----------------------------------------------------------------------------- 1458 Routine Name: wpa_driver_tista_send_eapol 1459 Routine Description: transmit EAPOL 1460 Arguments: 1461 priv - pointer to private data structure 1462 data - pointer to EAPOL data 1463 data_len - length of EAPOL data 1464 Return Value: None 1465 -----------------------------------------------------------------------------*/ 1466 static int ti_send_eapol( void *priv, const u8 *dest, u16 proto, 1467 const u8 *data, size_t data_len ) 1468 { 1469 struct wpa_driver_ti_data *myDrv = (struct wpa_driver_ti_data *)priv; 1470 u8* DataWithHeader = NULL; 1471 u16 protoNetwork; 1472 int ret = 0; 1473 1474 wpa_printf(MSG_DEBUG,"TI send_eapol called"); 1475 #ifdef IEEE8021X_EAPOL 1476 DataWithHeader = os_malloc(data_len + ETHERNET_HDR_LEN); /* 14 bytes */ 1477 if( DataWithHeader == NULL ) { 1478 wpa_printf(MSG_ERROR,"TI send_eapol failed to alloc full buffer"); 1479 return( -1 ); 1480 } 1481 1482 os_memcpy(DataWithHeader, dest, MAC_ADDR_LEN); /* 6 bytes */ 1483 os_memcpy(DataWithHeader+MAC_ADDR_LEN, myDrv->own_addr, MAC_ADDR_LEN); 1484 protoNetwork = htons(proto); 1485 os_memcpy(DataWithHeader+(MAC_ADDR_LEN<<1), &protoNetwork, sizeof(u16)); /* 2 bytes */ 1486 1487 os_memcpy(DataWithHeader+ETHERNET_HDR_LEN, data, data_len); 1488 data_len += ETHERNET_HDR_LEN; 1489 1490 wpa_hexdump(MSG_DEBUG, "WPA: FULL TX EAPOL-Key", DataWithHeader, data_len); 1491 1492 /* Transmit EAPOL packet */ 1493 ret = TI_Send_EAPOL_Packet( myDrv->hDriver, (void *)DataWithHeader, data_len ); 1494 os_free(DataWithHeader); 1495 #endif 1496 return( TI2WPA_STATUS(ret) ); 1497 } 1498 1499 #ifndef STA_DK_VER_5_0_0_94 1500 /*----------------------------------------------------------------------------- 1501 Routine Name: prepare_filter_struct 1502 Routine Description: fills rx data filter structure according to parameter type 1503 Arguments: 1504 priv - pointer to private data structure 1505 type - type of mac address 1506 dfreq_ptr - pointer to TIWLAN_DATA_FILTER_REQUEST structure 1507 Return Value: 0 - success, -1 - error 1508 -----------------------------------------------------------------------------*/ 1509 static int prepare_filter_struct( void *priv, int type, 1510 TIWLAN_DATA_FILTER_REQUEST *dfreq_ptr ) 1511 { 1512 u8 *macaddr = NULL; 1513 size_t len = 0; 1514 u8 mask = 0; 1515 int ret = -1; 1516 1517 wpa_printf(MSG_ERROR, "%s: type=%d", __func__, type); 1518 switch (type ) { 1519 case RX_SELF_FILTER: 1520 macaddr = (u8 *)wpa_driver_tista_get_mac_addr(priv); 1521 len = MAC_ADDR_LEN; 1522 mask = 0x3F; /* 6 bytes */ 1523 break; 1524 case RX_BROADCAST_FILTER: 1525 macaddr = (u8 *)"\xFF\xFF\xFF\xFF\xFF\xFF"; 1526 len = MAC_ADDR_LEN; 1527 mask = 0x3F; /* 6 bytes */ 1528 break; 1529 case RX_IPV4_MULTICAST_FILTER: 1530 macaddr = (u8 *)"\x01\x00\x5E"; 1531 len = 3; 1532 mask = 0x7; /* 3 bytes */ 1533 break; 1534 case RX_IPV6_MULTICAST_FILTER: 1535 macaddr = (u8 *)"\x33\x33"; 1536 len = 2; 1537 mask = 0x3; /* 2 bytes */ 1538 break; 1539 } 1540 if (len && macaddr) { 1541 dfreq_ptr->Offset = 0; 1542 dfreq_ptr->MaskLength = 1; 1543 dfreq_ptr->Mask[0] = mask; 1544 dfreq_ptr->PatternLength = len; 1545 os_memcpy( dfreq_ptr->Pattern, macaddr, len ); 1546 ret = 0; 1547 } 1548 return( ret ); 1549 } 1550 #endif 1551 1552 /*----------------------------------------------------------------------------- 1553 Routine Name: wpa_driver_tista_driver_cmd 1554 Routine Description: executes driver-specific commands 1555 Arguments: 1556 priv - pointer to private data structure 1557 cmd - command 1558 buf - return buffer 1559 buf_len - buffer length 1560 Return Value: actual buffer length - success, -1 - failure 1561 -----------------------------------------------------------------------------*/ 1562 int wpa_driver_tista_driver_cmd( void *priv, char *cmd, char *buf, size_t buf_len ) 1563 { 1564 struct wpa_driver_ti_data *myDrv = (struct wpa_driver_ti_data *)priv; 1565 int ret = -1, prev_events; 1566 1567 wpa_printf(MSG_DEBUG, "%s %s", __func__, cmd); 1568 1569 if( os_strcasecmp(cmd, "start") == 0 ) { 1570 wpa_printf(MSG_DEBUG,"Start command"); 1571 prev_events = myDrv->block_disassoc_events; 1572 myDrv->block_disassoc_events = myDrv->block_disassoc_prev; 1573 ret = TI_Start( myDrv->hDriver ); 1574 if( ret == OK ) { 1575 /* Signal that driver is not loaded yet */ 1576 myDrv->driver_is_loaded = TRUE; 1577 wpa_msg(myDrv->hWpaSupplicant, MSG_INFO, WPA_EVENT_DRIVER_STATE "STARTED"); 1578 } 1579 else 1580 myDrv->block_disassoc_events = prev_events; 1581 return( TI2WPA_STATUS(ret) ); 1582 } 1583 1584 /* If driver is not initialized yet - we cannot access it so return */ 1585 TI_CHECK_DRIVER( myDrv->driver_is_loaded, -1 ); 1586 1587 if( os_strcasecmp(cmd, "stop") == 0 ) { 1588 wpa_printf(MSG_DEBUG,"Stop command"); 1589 myDrv->block_disassoc_prev = myDrv->block_disassoc_events; 1590 myDrv->block_disassoc_events = BLOCK_DISASSOC; /* Block message */ 1591 ret = TI_Stop( myDrv->hDriver ); 1592 if( ret == OK ) { 1593 /* Signal that driver is not loaded yet */ 1594 myDrv->driver_is_loaded = FALSE; 1595 wpa_msg(myDrv->hWpaSupplicant, MSG_INFO, WPA_EVENT_DRIVER_STATE "STOPPED"); 1596 } 1597 else 1598 myDrv->block_disassoc_events = myDrv->block_disassoc_prev; 1599 } 1600 else if( os_strcasecmp(cmd, "macaddr") == 0 ) { 1601 u8 *macaddr = (u8 *)wpa_driver_tista_get_mac_addr(priv); 1602 wpa_printf(MSG_DEBUG,"Macaddr command"); 1603 wpa_printf(MSG_DEBUG, " Macaddr = " MACSTR, MAC2STR(macaddr)); 1604 ret = snprintf(buf, buf_len, "Macaddr = " MACSTR "\n", MAC2STR(macaddr)); 1605 if (ret < (int)buf_len) { 1606 return( ret ); 1607 } 1608 } 1609 else if( os_strcasecmp(cmd, "scan-passive") == 0 ) { 1610 wpa_printf(MSG_DEBUG,"Scan Passive command"); 1611 myDrv->scan_type = SCAN_TYPE_NORMAL_PASSIVE; 1612 ret = 0; 1613 } 1614 else if( os_strcasecmp(cmd, "scan-active") == 0 ) { 1615 wpa_printf(MSG_DEBUG,"Scan Active command"); 1616 myDrv->scan_type = SCAN_TYPE_NORMAL_ACTIVE; 1617 ret = 0; 1618 } 1619 else if( os_strcasecmp(cmd, "scan-mode") == 0 ) { 1620 wpa_printf(MSG_DEBUG,"Scan Mode command"); 1621 ret = snprintf(buf, buf_len, "ScanMode = %u\n", myDrv->scan_type); 1622 if (ret < (int)buf_len) { 1623 return( ret ); 1624 } 1625 } 1626 else if( os_strcasecmp(cmd, "linkspeed") == 0 ) { 1627 wpa_printf(MSG_DEBUG,"Link Speed command"); 1628 ret = snprintf(buf, buf_len, "LinkSpeed %u\n", myDrv->link_speed); 1629 if (ret < (int)buf_len) { 1630 return( ret ); 1631 } 1632 } 1633 else if( os_strncasecmp(cmd, "scan-channels", 13) == 0 ) { 1634 int noOfChan; 1635 char *cp = cmd + 13; 1636 char *endp; 1637 1638 if (*cp != '\0') { 1639 noOfChan = strtol(cp, &endp, 0); 1640 if (endp != cp) { 1641 wpa_printf(MSG_DEBUG,"Scan Channels command = %d", noOfChan); 1642 if( (noOfChan > 0) && (noOfChan <= MAX_NUMBER_OF_CHANNELS_PER_SCAN) ) { 1643 myDrv->scan_channels = noOfChan; 1644 ret = 0; 1645 } 1646 } 1647 } else { 1648 ret = snprintf(buf, buf_len, "Scan-Channels = %d\n", myDrv->scan_channels); 1649 if (ret < (int)buf_len) { 1650 return( ret ); 1651 } 1652 } 1653 } 1654 else if( os_strcasecmp(cmd, "rssi-approx") == 0 ) { 1655 struct wpa_scan_result *cur_res; 1656 struct wpa_supplicant *wpa_s = (struct wpa_supplicant *)(myDrv->hWpaSupplicant); 1657 int rssi, len; 1658 1659 wpa_printf(MSG_DEBUG,"rssi-approx command"); 1660 1661 if( !wpa_s ) 1662 return( ret ); 1663 cur_res = scan_get_by_bssid( myDrv, wpa_s->bssid ); 1664 if( cur_res ) { 1665 len = (int)(cur_res->ssid_len); 1666 rssi = cur_res->level; 1667 if( (len > 0) && (len <= MAX_SSID_LEN) && (len < (int)buf_len)) { 1668 os_memcpy( (void *)buf, (void *)(cur_res->ssid), len ); 1669 ret = len; 1670 ret += snprintf(&buf[ret], buf_len-len, " rssi %d\n", rssi); 1671 if (ret < (int)buf_len) { 1672 return( ret ); 1673 } 1674 } 1675 } 1676 } 1677 else if( os_strcasecmp(cmd, "rssi") == 0 ) { 1678 #if 1 1679 u8 ssid[MAX_SSID_LEN]; 1680 struct wpa_scan_result *cur_res; 1681 struct wpa_supplicant *wpa_s = (struct wpa_supplicant *)(myDrv->hWpaSupplicant); 1682 int rssi, len; 1683 1684 wpa_printf(MSG_DEBUG,"rssi command"); 1685 1686 ret = TI_GetRSSI( myDrv->hDriver, &rssi ); 1687 if( ret == OK ) { 1688 len = wpa_driver_tista_get_ssid( priv, (u8 *)ssid ); 1689 if( (len > 0) && (len <= MAX_SSID_LEN) && (len < (int)buf_len)) { 1690 os_memcpy( (void *)buf, (void *)ssid, len ); 1691 ret = len; 1692 ret += snprintf(&buf[ret], buf_len-len, " rssi %d\n", rssi); 1693 if( !wpa_s ) 1694 return( ret ); 1695 cur_res = scan_get_by_bssid( myDrv, wpa_s->bssid ); 1696 if( cur_res ) 1697 cur_res->level = rssi; 1698 return( ret ); 1699 } 1700 } 1701 #else 1702 OS_802_11_BSSID_EX bssidInfo; 1703 1704 wpa_printf(MSG_DEBUG,"rssi command"); 1705 1706 ret = TI_GetSelectedBSSIDInfo( myDrv->hDriver, (OS_802_11_BSSID_EX *)&bssidInfo ); 1707 if( ret == OK ) { 1708 if( bssidInfo.Ssid.SsidLength != 0 && bssidInfo.Ssid.SsidLength < buf_len) { 1709 os_memcpy( (void *)buf, (void *)(bssidInfo.Ssid.Ssid), bssidInfo.Ssid.SsidLength ); 1710 ret = bssidInfo.Ssid.SsidLength; 1711 ret += snprintf(&buf[ret], buf_len-ret, " rssi %d\n", bssidInfo.Rssi); 1712 if (ret < (int)buf_len) { 1713 return( ret ); 1714 } 1715 } 1716 ret = -1; 1717 } 1718 #endif 1719 } 1720 else if( os_strncasecmp(cmd, "powermode", 9) == 0 ) { 1721 u32 rtsThreshold = myDrv->rts_threshold; 1722 u32 mode; 1723 char *cp = cmd + 9; 1724 char *endp; 1725 1726 if (*cp != '\0') { 1727 mode = (u32)strtol(cp, &endp, 0); 1728 if (endp != cp) { 1729 wpa_printf(MSG_DEBUG,"Power Mode command = %u", mode); 1730 if( mode <= OS_POWER_MODE_LONG_DOZE ) 1731 ret = TI_ConfigPowerManagement( myDrv->hDriver, mode ); 1732 if( mode == OS_POWER_MODE_ACTIVE ) 1733 rtsThreshold = 0; 1734 if( TI_SetRTSThreshold( myDrv->hDriver, rtsThreshold ) != OK ) 1735 wpa_printf(MSG_DEBUG,"Set RTS threshold = %u failed", rtsThreshold); 1736 } 1737 } 1738 } 1739 else if( os_strncasecmp(cmd, "getpower", 8) == 0 ) { 1740 u32 mode; 1741 1742 ret = TI_GetPowerMode( myDrv->hDriver, (OS_802_11_POWER_PROFILE *)&mode); 1743 if( ret == OK ) { 1744 ret = snprintf(buf, buf_len, "powermode = %u\n", mode); 1745 if (ret < (int)buf_len) { 1746 return( ret ); 1747 } 1748 } 1749 } 1750 else if( os_strncasecmp(cmd, "get-rts-threshold", 17) == 0 ) { 1751 tiUINT32 rtsThreshold = 0; 1752 1753 ret = TI_GetRTSThreshold( myDrv->hDriver, &rtsThreshold ); 1754 wpa_printf(MSG_DEBUG,"Get RTS Threshold command = %d", rtsThreshold); 1755 if( ret == OK ) { 1756 ret = snprintf(buf, buf_len, "rts-threshold = %u\n", rtsThreshold); 1757 if (ret < (int)buf_len) { 1758 return( ret ); 1759 } 1760 } 1761 } 1762 else if( os_strncasecmp(cmd, "set-rts-threshold", 17) == 0 ) { 1763 tiUINT32 rtsThreshold = 0; 1764 char *cp = cmd + 17; 1765 char *endp; 1766 1767 if (*cp != '\0') { 1768 rtsThreshold = (tiUINT32)strtol(cp, &endp, 0); 1769 if (endp != cp) { 1770 wpa_printf(MSG_DEBUG,"RTS Threshold command = %d", rtsThreshold); 1771 if( rtsThreshold <= HAL_CTRL_RTS_THRESHOLD_MAX ) { 1772 ret = TI_SetRTSThreshold( myDrv->hDriver, rtsThreshold ); 1773 if( ret == OK ) { 1774 myDrv->rts_threshold = rtsThreshold; 1775 } 1776 } 1777 } 1778 } 1779 } 1780 else if( os_strcasecmp(cmd, "btcoexscan-start") == 0 ) { 1781 wpa_printf(MSG_DEBUG,"BT Coex Scan Start command"); 1782 myDrv->btcoex_scan = TRUE; 1783 ret = 0; 1784 } 1785 else if( os_strcasecmp(cmd, "btcoexscan-stop") == 0 ) { 1786 wpa_printf(MSG_DEBUG,"BT Coex Scan Stop command"); 1787 myDrv->btcoex_scan = FALSE; 1788 ret = 0; 1789 } 1790 #ifndef STA_DK_VER_5_0_0_94 1791 else if( os_strcasecmp(cmd, "rxfilter-start") == 0 ) { 1792 wpa_printf(MSG_DEBUG,"Rx Data Filter Start command"); 1793 ret = TI_EnableDisableRxDataFilters( myDrv->hDriver, TRUE ); 1794 } 1795 else if( os_strcasecmp(cmd, "rxfilter-stop") == 0 ) { 1796 wpa_printf(MSG_DEBUG,"Rx Data Filter Stop command"); 1797 ret = TI_EnableDisableRxDataFilters( myDrv->hDriver, FALSE ); 1798 } 1799 else if( os_strcasecmp(cmd, "rxfilter-statistics") == 0 ) { 1800 TIWLAN_DATA_FILTER_STATISTICS stats; 1801 int len, i; 1802 1803 wpa_printf(MSG_DEBUG,"Rx Data Filter Statistics command"); 1804 ret = TI_GetRxDataFiltersStatistics( myDrv->hDriver, &stats ); 1805 if( ret == OK ) { 1806 ret = snprintf(buf, buf_len, "RxFilterStat: %u", 1807 stats.UnmatchedPacketsCount); 1808 for(i=0;( i < MAX_NUM_DATA_FILTERS );i++) { 1809 ret += snprintf(&buf[ret], buf_len-ret, " %u", 1810 stats.MatchedPacketsCount[i]); 1811 } 1812 ret += snprintf(&buf[ret], buf_len-ret, "\n"); 1813 if (ret < (int)buf_len) { 1814 return( ret ); 1815 } 1816 } 1817 } 1818 else if( os_strncasecmp(cmd, "rxfilter-add", 12) == 0 ) { 1819 TIWLAN_DATA_FILTER_REQUEST dfreq; 1820 char *cp = cmd + 12; 1821 char *endp; 1822 int type; 1823 1824 if (*cp != '\0') { 1825 type = (int)strtol(cp, &endp, 0); 1826 if (endp != cp) { 1827 wpa_printf(MSG_DEBUG,"Rx Data Filter Add [%d] command", type); 1828 ret = prepare_filter_struct( priv, type, &dfreq ); 1829 if( ret == 0 ) { 1830 ret = TI_AddRxDataFilter( myDrv->hDriver, &dfreq ); 1831 } 1832 } 1833 } 1834 } 1835 else if( os_strncasecmp(cmd, "rxfilter-remove",15) == 0 ) { 1836 wpa_printf(MSG_DEBUG,"Rx Data Filter Remove command"); 1837 TIWLAN_DATA_FILTER_REQUEST dfreq; 1838 char *cp = cmd + 15; 1839 char *endp; 1840 int type; 1841 1842 if (*cp != '\0') { 1843 type = (int)strtol(cp, &endp, 0); 1844 if (endp != cp) { 1845 wpa_printf(MSG_DEBUG,"Rx Data Filter Remove [%d] command", type); 1846 ret = prepare_filter_struct( priv, type, &dfreq ); 1847 if( ret == 0 ) { 1848 ret = TI_RemoveRxDataFilter( myDrv->hDriver, &dfreq ); 1849 } 1850 } 1851 } 1852 } 1853 else if( os_strcasecmp(cmd, "snr") == 0 ) { 1854 u32 snr; 1855 1856 ret = TI_GetSNR( myDrv->hDriver, &snr ); 1857 if( ret == OK ) { 1858 ret = snprintf(buf, buf_len, "snr = %u\n", snr); 1859 if (ret < (int)buf_len) { 1860 return( ret ); 1861 } 1862 } 1863 } 1864 else if( os_strncasecmp(cmd, "btcoexmode", 10) == 0 ) { 1865 u32 mode; 1866 char *cp = cmd + 10; 1867 char *endp; 1868 1869 if (*cp != '\0') { 1870 mode = (u32)strtol(cp, &endp, 0); 1871 if (endp != cp) { 1872 wpa_printf(MSG_DEBUG,"BtCoex Mode command = %u", mode); 1873 ret = TI_SetBtCoeEnable( myDrv->hDriver, mode ); 1874 if( ret == OK ) { 1875 myDrv->btcoex_mode = mode; 1876 } 1877 } 1878 } 1879 } 1880 else if( os_strcasecmp(cmd, "btcoexstat") == 0 ) { 1881 u32 status = myDrv->btcoex_mode; 1882 1883 wpa_printf(MSG_DEBUG,"BtCoex Status"); 1884 ret = TI_SetBtCoeGetStatus( myDrv->hDriver, (tiUINT32 *)&status ); 1885 if( ret == OK ) { 1886 ret = snprintf(buf, buf_len, "btcoexstatus = 0x%x\n", status); 1887 if (ret < (int)buf_len) { 1888 return( ret ); 1889 } 1890 } 1891 } 1892 #endif 1893 else { 1894 wpa_printf(MSG_DEBUG,"Unsupported command"); 1895 } 1896 return( TI2WPA_STATUS(ret) ); 1897 } 1898 1899 /* Fill driver_ops structure to provide wpa_supplicant core with wrapper routines */ 1900 struct wpa_driver_ops wpa_driver_custom_ops = { 1901 .name = TIWLAN_DRV_NAME, 1902 .desc = "TI Station Driver", 1903 .init = wpa_driver_tista_init, 1904 .deinit = wpa_driver_tista_unload, 1905 .get_bssid = wpa_driver_tista_get_bssid, 1906 .get_ssid = wpa_driver_tista_get_ssid, 1907 .set_wpa = wpa_driver_tista_set_wpa, 1908 .set_key = wpa_driver_tista_set_key, 1909 .set_param = NULL, 1910 .set_countermeasures = wpa_driver_tista_set_countermeasures, 1911 .set_drop_unencrypted = wpa_driver_tista_set_drop_unencrypted, 1912 .scan = wpa_driver_tista_scan, 1913 .get_scan_results = wpa_driver_tista_get_scan_results, 1914 .deauthenticate = wpa_driver_tista_deauthenticate, 1915 .disassociate = wpa_driver_tista_disassociate, 1916 .associate = wpa_driver_tista_associate, 1917 .set_auth_alg = wpa_driver_tista_set_auth_alg, 1918 .get_mac_addr = wpa_driver_tista_get_mac_addr, 1919 .send_eapol = ti_send_eapol, 1920 .add_pmkid = NULL, 1921 .remove_pmkid = NULL, 1922 .flush_pmkid = NULL, 1923 .get_capa = NULL, 1924 .poll = NULL, 1925 .get_ifname = NULL, /* Not nesessary */ 1926 .set_operstate = NULL, 1927 #ifdef CONFIG_CLIENT_MLME 1928 .get_hw_modes = NULL, 1929 .set_channel = NULL, 1930 .set_ssid = wpa_driver_tista_set_ssid, 1931 .set_bssid = NULL, 1932 .send_mlme = NULL, 1933 .mlme_add_sta = NULL, 1934 .mlme_remove_sta = NULL, 1935 .mlme_setprotection = NULL, 1936 #endif /* CONFIG_CLIENT_MLME */ 1937 .driver_cmd = wpa_driver_tista_driver_cmd 1938 }; 1939