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
60static TI_INT32 cmdInterpret_Event(IPC_EV_DATA* pData);
61static int cmdInterpret_setSecurityParams (TI_HANDLE hCmdInterpret);
62static int cmdInterpret_initEvents(TI_HANDLE hCmdInterpret);
63static 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
67static 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
71typedef 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 */
85TI_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 */
111TI_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
125void 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 */
139int 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    }
1330cmd_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 */
1340int 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 */
1364static 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 */
1387static 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 */
1406static 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
1552event_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 */
1688static 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
1771void *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