prepare to upload
[debian/uaputl] / uaputl.c
1 /** @file  uaputl.c
2  *
3  *  @brief Program to send AP commands to the driver/firmware of the uAP
4  *         driver.
5  * 
6  * Copyright (C) 2008-2009, Marvell International Ltd. 
7  *
8  * This software file (the "File") is distributed by Marvell International 
9  * Ltd. under the terms of the GNU General Public License Version 2, June 1991 
10  * (the "License").  You may use, redistribute and/or modify this File in 
11  * accordance with the terms and conditions of the License, a copy of which 
12  * is available along with the File in the gpl.txt file or by writing to 
13  * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 
14  * 02111-1307 or on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
15  *
16  * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE 
17  * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE 
18  * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about 
19  * this warranty disclaimer.
20  *
21  */
22 /****************************************************************************
23 Change log:
24     03/01/08: Initial creation
25 ****************************************************************************/
26
27 /****************************************************************************
28         Header files
29 ****************************************************************************/
30 #include <stdarg.h>
31 #include <sys/types.h>
32 #include <unistd.h>
33 #include <sys/socket.h>
34 #include <sys/select.h>
35 #include <stdio.h>
36 #include <getopt.h>
37 #include <netinet/in.h>
38 #include <errno.h>
39 #include <stdlib.h>
40 #include <string.h>
41 #include <ctype.h>
42 #include <linux/if.h>
43 #include <sys/ioctl.h>
44 #include <errno.h>
45 #include "uaputl.h"
46 #include "uapcmd.h"
47
48 /****************************************************************************
49         Definitions
50 ****************************************************************************/
51 /** Default debug level */
52 int debug_level = MSG_NONE;
53
54 /** Enable or disable debug outputs */
55 #define DEBUG   1
56
57 /** Convert character to integer */
58 #define CHAR2INT(x) (((x) >= 'A') ? ((x) - 'A' + 10) : ((x) - '0'))
59
60 /****************************************************************************
61         Global variables
62 ****************************************************************************/
63 /** Device name */
64 static char dev_name[IFNAMSIZ + 1];
65 /** option for cmd */
66 struct option cmd_options[] = {
67     {"help", 0, 0, 'h'},
68     {0, 0, 0, 0}
69 };
70
71 /****************************************************************************
72         Local functions
73 ****************************************************************************/
74 /**
75  *    @brief convert char to hex integer
76  *   
77  *    @param chr          char
78  *    @return             hex integer
79  */
80 unsigned char
81 hexc2bin(char chr)
82 {
83     if (chr >= '0' && chr <= '9')
84         chr -= '0';
85     else if (chr >= 'A' && chr <= 'F')
86         chr -= ('A' - 10);
87     else if (chr >= 'a' && chr <= 'f')
88         chr -= ('a' - 10);
89
90     return chr;
91 }
92
93 /** 
94  *  @brief check protocol is valid or not
95  *
96  *  @param protocol          protocol
97  *
98  *  @return         UAP_SUCCESS or UAP_FAILURE
99  */
100 int
101 is_protocol_valid(int protocol)
102 {
103     int ret = UAP_FAILURE;
104     switch (protocol) {
105     case PROTOCOL_NO_SECURITY:
106     case PROTOCOL_STATIC_WEP:
107     case PROTOCOL_WPA:
108     case PROTOCOL_WPA2:
109     case PROTOCOL_WPA2_MIXED:
110         ret = UAP_SUCCESS;
111         break;
112     default:
113         printf("ERR: Invalid Protocol: %d\n", protocol);
114         break;
115     }
116     return ret;
117 }
118
119 /**
120  *  @brief Function to check valid rate
121  *
122  *                  
123  *  @param  rate    rate to verify
124  *
125  *  return          UAP_SUCCESS or UAP_FAILURE  
126  **/
127 int
128 is_rate_valid(int rate)
129 {
130     int ret = UAP_SUCCESS;
131     switch (rate) {
132     case 2:
133     case 4:
134     case 11:
135     case 22:
136     case 12:
137     case 18:
138     case 24:
139     case 48:
140     case 72:
141     case 96:
142     case 108:
143     case 36:
144         break;
145     default:
146         ret = UAP_FAILURE;
147         break;
148     }
149     return ret;
150 }
151
152 /**
153  *  @brief  detects duplicates rate in array of strings
154  *          Note that 0x82 and 0x2 are same for rate
155  *
156  *  @param  argc    number of elements
157  *  @param  argv    array of strings
158  *  @return UAP_FAILURE or UAP_SUCCESS
159  */
160 inline int
161 has_dup_rate(int argc, char *argv[])
162 {
163     int i, j;
164     /* Check for duplicate */
165     for (i = 0; i < (argc - 1); i++) {
166         for (j = i + 1; j < argc; j++) {
167             if ((A2HEXDECIMAL(argv[i]) & ~BASIC_RATE_SET_BIT) ==
168                 (A2HEXDECIMAL(argv[j]) & ~BASIC_RATE_SET_BIT)) {
169                 return UAP_FAILURE;
170             }
171         }
172     }
173     return UAP_SUCCESS;
174 }
175
176 /**
177  *  @brief Check for mandatory rates
178  *
179  *
180  * 2, 4, 11, 22 must be present 
181  *
182  * 6 12 and 24 must be present for ofdm
183  *
184  *  @param argc     Number of arguments
185  *  @param argv     Pointer to the arguments
186  *  @return         UAP_FAILURE or UAP_SUCCESS
187  *
188  */
189 int
190 check_mandatory_rates(int argc, char **argv)
191 {
192     int i;
193     int tmp;
194     u32 rate_bitmap = 0;
195     int ofdm_enable = 0;
196 #define BITMAP_RATE_1M         0x01
197 #define BITMAP_RATE_2M         0x02
198 #define BITMAP_RATE_5_5M       0x04
199 #define BITMAP_RATE_11M        0x8
200 #define B_RATE_MANDATORY       0x0f
201 #define BITMAP_RATE_6M         0x10
202 #define BITMAP_RATE_12M        0x20
203 #define BITMAP_RATE_24M        0x40
204 #define G_RATE_MANDATORY        0x70
205     for (i = 0; i < argc; i++) {
206         tmp = (A2HEXDECIMAL(argv[i]) & ~BASIC_RATE_SET_BIT);
207         switch (tmp) {
208         case 2:
209             rate_bitmap |= BITMAP_RATE_1M;
210             break;
211         case 4:
212             rate_bitmap |= BITMAP_RATE_2M;
213             break;
214         case 11:
215             rate_bitmap |= BITMAP_RATE_5_5M;
216             break;
217         case 22:
218             rate_bitmap |= BITMAP_RATE_11M;
219             break;
220         case 12:
221             ofdm_enable = 1;
222             rate_bitmap |= BITMAP_RATE_6M;
223             break;
224         case 24:
225             ofdm_enable = 1;
226             rate_bitmap |= BITMAP_RATE_12M;
227             break;
228         case 48:
229             ofdm_enable = 1;
230             rate_bitmap |= BITMAP_RATE_24M;
231             break;
232         case 18:
233         case 36:
234         case 72:
235         case 96:
236         case 108:
237             ofdm_enable = 1;
238             break;
239         }
240     }
241     if ((rate_bitmap & B_RATE_MANDATORY) != B_RATE_MANDATORY) {
242         printf("Basic Rates 2, 4, 11 and 22 (500K units) \n"
243                "must be present in basic or non-basic rates\n");
244         return UAP_FAILURE;
245     }
246     if (ofdm_enable && ((rate_bitmap & G_RATE_MANDATORY) != G_RATE_MANDATORY)) {
247         printf("OFDM Rates 12, 24 and 48 ( 500Kb units)\n"
248                "must be present in basic or non-basic rates\n");
249         return UAP_FAILURE;
250     }
251     return UAP_SUCCESS;
252 }
253
254 /**
255  *  @brief  detects duplicates channel in array of strings
256  *          
257  *  @param  argc    number of elements
258  *  @param  argv    array of strings
259  *  @return UAP_FAILURE or UAP_SUCCESS
260  */
261 inline int
262 has_dup_channel(int argc, char *argv[])
263 {
264     int i, j;
265     /* Check for duplicate */
266     for (i = 0; i < (argc - 1); i++) {
267         for (j = i + 1; j < argc; j++) {
268             if (atoi(argv[i]) == atoi(argv[j])) {
269                 return UAP_FAILURE;
270             }
271         }
272     }
273     return UAP_SUCCESS;
274 }
275
276 /** 
277  *    @brief convert string to hex integer
278  *  
279  *    @param s            A pointer string buffer
280  *    @return             hex integer
281  */
282 unsigned int
283 a2hex(char *s)
284 {
285     unsigned int val = 0;
286     if (!strncasecmp("0x", s, 2)) {
287         s += 2;
288     }
289     while (*s && isxdigit(*s)) {
290         val = (val << 4) + hexc2bin(*s++);
291     }
292     return val;
293 }
294
295 /** 
296  *  @brief Dump hex data
297  *
298  *  @param prompt       A pointer prompt buffer
299  *  @param p            A pointer to data buffer
300  *  @param len          the len of data buffer
301  *  @param delim        delim char
302  *  @return             None
303  */
304 void
305 hexdump_data(char *prompt, void *p, int len, char delim)
306 {
307     int i;
308     unsigned char *s = p;
309
310     if (prompt) {
311         printf("%s: len=%d\n", prompt, (int) len);
312     }
313     for (i = 0; i < len; i++) {
314         if (i != len - 1)
315             printf("%02x%c", *s++, delim);
316         else
317             printf("%02x\n", *s);
318         if ((i + 1) % 16 == 0)
319             printf("\n");
320     }
321     printf("\n");
322 }
323
324 #if DEBUG
325 /** 
326  * @brief           conditional printf
327  *
328  * @param level     severity level of the message
329  * @param fmt       printf format string, followed by optional arguments
330  */
331 void
332 uap_printf(int level, char *fmt, ...)
333 {
334     va_list ap;
335     va_start(ap, fmt);
336     if (level <= debug_level) {
337         vprintf(fmt, ap);
338     }
339     va_end(ap);
340 }
341
342 /** 
343  *  @brief Dump hex data
344  *
345  *  @param prompt       A pointer prompt buffer
346  *  @param p            A pointer to data buffer
347  *  @param len          the len of data buffer
348  *  @param delim        delim char
349  *  @return             None
350  */
351 void
352 hexdump(char *prompt, void *p, int len, char delim)
353 {
354     if (debug_level < MSG_ALL)
355         return;
356     hexdump_data(prompt, p, len, delim);
357 }
358 #endif
359
360 /** 
361  *  @brief      Hex to number 
362  *
363  *  @param c    Hex value
364  *  @return     Integer value or -1
365  */
366 int
367 hex2num(char c)
368 {
369     if (c >= '0' && c <= '9')
370         return c - '0';
371     if (c >= 'a' && c <= 'f')
372         return c - 'a' + 10;
373     if (c >= 'A' && c <= 'F')
374         return c - 'A' + 10;
375
376     return -1;
377 }
378
379 /**
380  *  @brief Show usage information for the sys_info command
381  *
382  *  $return         N/A
383  */
384 void
385 print_sys_info_usage(void)
386 {
387     printf("\nUsage : sys_info\n");
388     return;
389 }
390
391 /**
392  *  @brief Parse domain file for country information
393  *
394  *  @param country  Country name
395  *  @param sub_bands band information 
396  *  @return number of band/ UAP_FAILURE 
397  */
398 u8
399 parse_domain_file(char *country, IEEEtypes_SubbandSet_t * sub_bands)
400 {
401     FILE *fp;
402     char str[64];
403     char domain_name[40];
404     int cflag = 0;
405     int dflag = 0;
406     int found = 0;
407     int j = -1, reset_j = 0;
408     u8 no_of_sub_band = 0;
409     char third;
410     char country2[3];
411
412     fp = fopen("80211d_domain.conf", "r");
413     if (fp == NULL) {
414         printf("File opening Error\n");
415         return UAP_FAILURE;
416     }
417
418     strncpy((char *) country2, country, 2);
419     country2[2] = '\0';
420     third = country[2];
421
422     /** 
423      * Search specific domain name
424      */
425     while (!feof(fp)) {
426         fscanf(fp, "%s", str);
427         if (cflag) {
428             strcpy(domain_name, str);
429             cflag = 0;
430         }
431         if (!strcmp(str, "COUNTRY:")) {
432             /** store next string to domain_name */
433             cflag = 1;
434         }
435
436         if (!strcmp(str, country2)) {
437             /** Country is matched ;)*/
438             if (third && !((third == 'I') || (third == 'O') || (third == ' ')))
439                 found = 0;
440             else
441                 found = 1;
442             break;
443         }
444     }
445
446     if (!found) {
447         printf("No match found for Country = %s in the 80211d_domain.conf \n",
448                country);
449         fclose(fp);
450         found = 0;
451         return UAP_FAILURE;
452     }
453
454     /**
455      * Search domain specific information
456      */
457     while (!feof(fp)) {
458         fscanf(fp, "%s", str);
459
460         if (feof(fp) || (dflag && !strcmp(str, "DOMAIN:"))) {
461             break;
462         }
463
464         if (dflag) {
465             j++;
466             if (strchr(str, ','))
467                 reset_j = 1;
468
469             strcpy(str, strtok(str, ", "));
470
471             if (str == NULL) {
472                 if (reset_j) {
473                     j = -1;
474                     reset_j = 0;
475                 }
476                 continue;
477             }
478
479             if (IS_HEX_OR_DIGIT(str) == UAP_FAILURE) {
480                 printf("ERR: Only Number values are allowed\n");
481                 fclose(fp);
482                 return UAP_FAILURE;
483             }
484
485             switch (j) {
486             case 0:
487                 sub_bands[no_of_sub_band].FirstChan = (u8) A2HEXDECIMAL(str);
488                 break;
489             case 1:
490                 sub_bands[no_of_sub_band].NoOfChan = (u8) A2HEXDECIMAL(str);
491                 break;
492             case 2:
493                 sub_bands[no_of_sub_band++].MaxTxPwr = (u8) A2HEXDECIMAL(str);
494                 break;
495             default:
496                 printf("ERR: Incorrect 80211d_domain.conf file\n");
497                 fclose(fp);
498                 return UAP_FAILURE;
499             }
500
501             if (reset_j) {
502                 j = -1;
503                 reset_j = 0;
504             }
505         }
506
507         if (cflag && !strcmp(str, domain_name)) {
508             /* Followed will be the band details */
509             cflag = 0;
510             dflag = 1;
511         }
512         if (!dflag && !strcmp(str, "DOMAIN:")) {
513             cflag = 1;
514         }
515     }
516     fclose(fp);
517     return (no_of_sub_band);
518
519 }
520
521 /** 
522  *
523  *  @brief Set/Get SNMP MIB
524  *
525  *  @param action 0-GET 1-SET
526  *  @param oid    oid
527  *  @param size   size of oid value
528  *  @param oid_buf  oid value
529  *  @return UAP_FAILURE or UAP_SUCCESS
530  *
531  */
532 int
533 sg_snmp_mib(u16 action, u16 oid, u16 size, u8 * oid_buf)
534 {
535     APCMDBUF_SNMP_MIB *cmd_buf = NULL;
536     TLVBUF_HEADER *tlv = NULL;
537     int ret = UAP_FAILURE;
538     u8 *buf = NULL;
539     u16 buf_len;
540     u16 cmd_len;
541     int i;
542
543     buf_len = sizeof(APCMDBUF_SNMP_MIB) + sizeof(TLVBUF_HEADER) + size;
544     buf = (u8 *) malloc(buf_len);
545     if (!buf) {
546         printf("ERR:Cannot allocate buffer from command!\n");
547         return ret;
548     }
549     bzero((char *) buf, buf_len);
550
551     /* Locate Headers */
552     cmd_buf = (APCMDBUF_SNMP_MIB *) buf;
553     tlv = (TLVBUF_HEADER *) (buf + sizeof(APCMDBUF_SNMP_MIB));
554     cmd_buf->Size = buf_len - BUF_HEADER_SIZE;
555     cmd_buf->Result = 0;
556     cmd_buf->SeqNum = 0;
557     cmd_buf->CmdCode = HostCmd_SNMP_MIB;
558
559     tlv->Type = uap_cpu_to_le16(oid);
560     tlv->Len = uap_cpu_to_le16(size);
561     for (i = 0; action && (i < size); i++) {
562         tlv->Data[i] = oid_buf[i];
563     }
564
565     cmd_buf->Action = uap_cpu_to_le16(action);
566     cmd_len = buf_len;
567     ret = uap_ioctl((u8 *) cmd_buf, &cmd_len, buf_len);
568     if (ret == UAP_SUCCESS) {
569         if (cmd_buf->Result == CMD_SUCCESS) {
570             if (!action) {
571                 /** Reloacte the headers */
572                 tlv =
573                     (TLVBUF_HEADER *) ((u8 *) cmd_buf +
574                                        sizeof(APCMDBUF_SNMP_MIB));
575                 for (i = 0; i < MIN(uap_le16_to_cpu(tlv->Len), size); i++) {
576                     oid_buf[i] = tlv->Data[i];
577                 }
578             }
579             ret = UAP_SUCCESS;
580         } else {
581             printf("ERR:Command Response incorrect!\n");
582             ret = UAP_FAILURE;
583         }
584     } else {
585         printf("ERR:Command sending failed!\n");
586     }
587     free(buf);
588     return ret;
589 }
590
591 /** 
592  *  @brief Creates a sys_info request and sends to the driver
593  *
594  *  Usage: "sys_info"
595  *
596  *  @param argc     Number of arguments
597  *  @param argv     Pointer to the arguments
598  *  @return         N/A
599  */
600 void
601 apcmd_sys_info(int argc, char *argv[])
602 {
603     APCMDBUF_SYS_INFO_REQUEST *cmd_buf = NULL;
604     APCMDBUF_SYS_INFO_RESPONSE *response_buf = NULL;
605     u8 *buf = NULL;
606     u16 cmd_len;
607     u16 buf_len;
608     int ret = UAP_FAILURE;
609     int opt;
610
611     while ((opt = getopt_long(argc, argv, "+", cmd_options, NULL)) != -1) {
612         switch (opt) {
613         default:
614             print_sys_info_usage();
615             return;
616         }
617     }
618     argc -= optind;
619     argv += optind;
620
621     /* Check arguments */
622     if (argc != 0) {
623         printf("ERR:Too many arguments.\n");
624         print_sys_info_usage();
625         return;
626     }
627
628     buf_len =
629         (sizeof(APCMDBUF_SYS_INFO_REQUEST) >=
630          sizeof(APCMDBUF_SYS_INFO_RESPONSE)) ? sizeof(APCMDBUF_SYS_INFO_REQUEST)
631         : sizeof(APCMDBUF_SYS_INFO_RESPONSE);
632
633     /* alloc buf for command */
634     buf = (u8 *) malloc(buf_len);
635
636     if (!buf) {
637         printf("ERR:Cannot allocate buffer from command!\n");
638         return;
639     }
640     bzero((char *) buf, buf_len);
641
642     /* Locate headers */
643     cmd_len = sizeof(APCMDBUF_SYS_INFO_REQUEST);
644     cmd_buf = (APCMDBUF_SYS_INFO_REQUEST *) buf;
645     response_buf = (APCMDBUF_SYS_INFO_RESPONSE *) buf;
646
647     /* Fill the command buffer */
648     cmd_buf->CmdCode = APCMD_SYS_INFO;
649     cmd_buf->Size = cmd_len;
650     cmd_buf->SeqNum = 0;
651     cmd_buf->Result = 0;
652
653     /* Send the command */
654     ret = uap_ioctl((u8 *) cmd_buf, &cmd_len, buf_len);
655
656     /* Process response */
657     if (ret == UAP_SUCCESS) {
658         /* Verify response */
659         if (response_buf->CmdCode != (APCMD_SYS_INFO | APCMD_RESP_CHECK)) {
660             printf("ERR:Corrupted response!\n");
661             free(buf);
662             return;
663         }
664         /* Print response */
665         if (response_buf->Result == CMD_SUCCESS) {
666             printf("System information = %s\n", response_buf->SysInfo);
667         } else {
668             printf("ERR:Could not retrieve system information!\n");
669         }
670     } else {
671         printf("ERR:Command sending failed!\n");
672     }
673
674     free(buf);
675     return;
676 }
677
678 /**
679  *  @brief Show usage information for the powermode command
680  *
681  *  $return         N/A
682  */
683 void
684 print_power_mode_usage(void)
685 {
686     printf
687         ("\nUsage : powermode [MODE] [SLEEP_PARAM=1 CTRL MIN_SLEEP MAX_SLEEP]");
688     printf("\n                  [INACT_PARAM=2 INACTTO MIN_AWAKE MAX_AWAKE]");
689     printf("\nOptions: MODE :     0 - disable power mode");
690     printf("\n                    1 - periodic DTIM power save mode");
691     printf("\n                    2 - inactivity based power save mode");
692     printf("\n   SLEEP_PARAM:");
693     printf
694         ("\n        CTRL:  0 - disable CTS2Self protection frame Tx before PS");
695     printf
696         ("\n               1 - enable CTS2Self protection frame Tx before PS");
697     printf("\n        MIN_SLEEP: Minimum sleep duration in microseconds");
698     printf("\n        MAX_SLEEP: Maximum sleep duration in miroseconds");
699     printf("\n   INACT_PARAM: (only for inactivity based power save mode)");
700     printf("\n          INACTTO: Inactivity timeout in miroseconds");
701     printf("\n        MIN_AWAKE: Minimum awake duration in microseconds");
702     printf("\n        MAX_AWAKE: Maximum awake duration in microseconds");
703     printf("\n          empty - get current power mode\n");
704     return;
705 }
706
707 /** 
708  *  @brief Set/get power mode 
709  *
710  *  @param pm      A pointer to ps_mgmt structure
711  *  @return         N/A
712  */
713 void
714 send_power_mode_ioctl(ps_mgmt * pm)
715 {
716     struct ifreq ifr;
717     s32 sockfd;
718
719     /* Open socket */
720     if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
721         printf("ERR:Cannot open socket\n");
722         return;
723     }
724     /* Initialize the ifr structure */
725     memset(&ifr, 0, sizeof(ifr));
726     strncpy(ifr.ifr_ifrn.ifrn_name, dev_name, strlen(dev_name));
727     ifr.ifr_ifru.ifru_data = (void *) pm;
728     /* Perform ioctl */
729     errno = 0;
730     if (ioctl(sockfd, UAP_POWER_MODE, &ifr)) {
731         perror("");
732         printf("ERR:UAP_POWER_MODE is not supported by %s\n", dev_name);
733         return;
734     }
735     switch (pm->ps_mode) {
736     case 0:
737         printf("power mode = Disabled\n");
738         break;
739     case 1:
740         printf("power mode = Periodic DTIM PS\n");
741         break;
742     case 2:
743         printf("power mode = Inactivity based PS \n");
744         break;
745     }
746     if (pm->flags & PS_FLAG_SLEEP_PARAM) {
747         printf("Sleep param:\n");
748         printf("\tctrl_bitmap=%d\n", (int) pm->sleep_param.ctrl_bitmap);
749         printf("\tmin_sleep=%d us\n", (int) pm->sleep_param.min_sleep);
750         printf("\tmax_sleep=%d us\n", (int) pm->sleep_param.max_sleep);
751     }
752     if (pm->flags & PS_FLAG_INACT_SLEEP_PARAM) {
753         printf("Inactivity sleep param:\n");
754         printf("\tinactivity_to=%d us\n", (int) pm->inact_param.inactivity_to);
755         printf("\tmin_awake=%d us\n", (int) pm->inact_param.min_awake);
756         printf("\tmax_awake=%d us\n", (int) pm->inact_param.max_awake);
757     }
758     /* Close socket */
759     close(sockfd);
760     return;
761 }
762
763 /** 
764  *  @brief Creates power mode request and send to driver
765  *   and sends to the driver
766  *
767  *   Usage: "Usage : powermode [MODE]"
768  *
769  *   Options: MODE :     0 - disable power mode
770  *                       1 - enable power mode
771  *                       2 - get current power mode                         
772  *
773  *  @param argc     Number of arguments
774  *  @param argv     Pointer to the arguments
775  *  @return         N/A
776  */
777 void
778 apcmd_power_mode(int argc, char *argv[])
779 {
780     int opt;
781     ps_mgmt pm;
782     int type = 0;
783     while ((opt = getopt_long(argc, argv, "+", cmd_options, NULL)) != -1) {
784         switch (opt) {
785         default:
786             print_power_mode_usage();
787             return;
788         }
789     }
790     argc -= optind;
791     argv += optind;
792
793     memset(&pm, 0, sizeof(ps_mgmt));
794     /* Check arguments */
795     if ((argc > 9) ||
796         ((argc != 0) && (argc != 1) && (argc != 5) && (argc != 9))) {
797         printf("ERR:wrong arguments.\n");
798         print_power_mode_usage();
799         return;
800     }
801
802     if (argc) {
803         if ((ISDIGIT(argv[0]) == 0) || (atoi(argv[0]) < 0) ||
804             (atoi(argv[0]) > 2)) {
805             printf
806                 ("ERR:Illegal power mode %s. Must be either '0' '1' or '2'.\n",
807                  argv[0]);
808             print_power_mode_usage();
809             return;
810         }
811         pm.flags = PS_FLAG_PS_MODE;
812         pm.ps_mode = atoi(argv[0]);
813         if ((pm.ps_mode == PS_MODE_DISABLE) && (argc > 1)) {
814             printf("ERR: Illegal parameter for disable power mode\n");
815             print_power_mode_usage();
816             return;
817         }
818         if ((pm.ps_mode != PS_MODE_INACTIVITY) && (argc > 5)) {
819             printf("ERR: Illegal parameter\n");
820             print_power_mode_usage();
821             return;
822         }
823         if (argc >= 5) {
824             if ((ISDIGIT(argv[1]) == 0) || (atoi(argv[1]) < 1) ||
825                 (atoi(argv[1]) > 2)) {
826                 printf
827                     ("ERR:Illegal parameter type %s. Must be either '1' or '2'.\n",
828                      argv[1]);
829                 print_power_mode_usage();
830                 return;
831             }
832             type = atoi(argv[1]);
833             if ((type == INACTIVITY_SLEEP_PARAMETER) &&
834                 (pm.ps_mode != PS_MODE_INACTIVITY)) {
835                 printf
836                     ("ERR: inactivity sleep parameter only valid for inactivity power save mode\n");
837                 print_power_mode_usage();
838                 return;
839             }
840             if (type == SLEEP_PARAMETER) {
841                 if ((ISDIGIT(argv[2]) == 0) || (atoi(argv[2]) < 0) ||
842                     (atoi(argv[2]) > 1)) {
843                     printf
844                         ("ERR:Illegal ctrl bitmap = %s. Must be either '0' or '1'.\n",
845                          argv[2]);
846                     print_power_mode_usage();
847                     return;
848                 }
849                 pm.flags |= PS_FLAG_SLEEP_PARAM;
850                 pm.sleep_param.ctrl_bitmap = atoi(argv[2]);
851                 if ((ISDIGIT(argv[3]) == 0) || (ISDIGIT(argv[4]) == 0)) {
852                     printf("ERR:Illegal parameter\n");
853                     print_power_mode_usage();
854                     return;
855                 }
856                 pm.sleep_param.min_sleep = atoi(argv[3]);
857                 pm.sleep_param.max_sleep = atoi(argv[4]);
858                 if (pm.sleep_param.min_sleep > pm.sleep_param.max_sleep) {
859                     printf
860                         ("ERR: MIN_SLEEP value should be less than or equal to MAX_SLEEP\n");
861                     return;
862                 }
863                 if (pm.sleep_param.min_sleep < PS_SLEEP_PARAM_MIN ||
864                     ((pm.sleep_param.max_sleep > PS_SLEEP_PARAM_MAX) &&
865                      pm.sleep_param.ctrl_bitmap)) {
866                     printf
867                         ("ERR: Incorrect value of sleep period. Please check README\n");
868                     return;
869                 }
870             } else {
871                 if ((ISDIGIT(argv[2]) == 0) || (ISDIGIT(argv[3]) == 0) ||
872                     (ISDIGIT(argv[4]) == 0)) {
873                     printf("ERR:Illegal parameter\n");
874                     print_power_mode_usage();
875                     return;
876                 }
877                 pm.flags |= PS_FLAG_INACT_SLEEP_PARAM;
878                 pm.inact_param.inactivity_to = atoi(argv[2]);
879                 pm.inact_param.min_awake = atoi(argv[3]);
880                 pm.inact_param.max_awake = atoi(argv[4]);
881                 if (pm.inact_param.min_awake > pm.inact_param.max_awake) {
882                     printf
883                         ("ERR: MIN_AWAKE value should be less than or equal to MAX_AWAKE\n");
884                     return;
885                 }
886                 if (pm.inact_param.min_awake < PS_AWAKE_PERIOD_MIN) {
887                     printf("ERR: Incorrect value of MIN_AWAKE period.\n");
888                     return;
889                 }
890             }
891         }
892         if (argc == 9) {
893             if ((ISDIGIT(argv[5]) == 0) || (atoi(argv[5]) < 1) ||
894                 (atoi(argv[5]) > 2)) {
895                 printf
896                     ("ERR:Illegal parameter type %s. Must be either '1' or '2'.\n",
897                      argv[5]);
898                 print_power_mode_usage();
899                 return;
900             }
901             if (type == atoi(argv[5])) {
902                 printf("ERR: Duplicate parameter type %s.\n", argv[5]);
903                 print_power_mode_usage();
904                 return;
905             }
906             type = atoi(argv[5]);
907             if (type == SLEEP_PARAMETER) {
908                 if ((ISDIGIT(argv[6]) == 0) || (atoi(argv[6]) < 0) ||
909                     (atoi(argv[6]) > 1)) {
910                     printf
911                         ("ERR:Illegal ctrl bitmap = %s. Must be either '0' or '1'.\n",
912                          argv[6]);
913                     print_power_mode_usage();
914                     return;
915                 }
916                 pm.flags |= PS_FLAG_SLEEP_PARAM;
917                 pm.sleep_param.ctrl_bitmap = atoi(argv[6]);
918                 if ((ISDIGIT(argv[7]) == 0) || (ISDIGIT(argv[8]) == 0)) {
919                     printf("ERR:Illegal parameter\n");
920                     print_power_mode_usage();
921                     return;
922                 }
923                 pm.sleep_param.min_sleep = atoi(argv[7]);
924                 pm.sleep_param.max_sleep = atoi(argv[8]);
925                 if (pm.sleep_param.min_sleep > pm.sleep_param.max_sleep) {
926                     printf
927                         ("ERR: MIN_SLEEP value should be less than or equal to MAX_SLEEP\n");
928                     return;
929                 }
930                 if (pm.sleep_param.min_sleep < PS_SLEEP_PARAM_MIN ||
931                     ((pm.sleep_param.max_sleep > PS_SLEEP_PARAM_MAX) &&
932                      pm.sleep_param.ctrl_bitmap)) {
933                     printf
934                         ("ERR: Incorrect value of sleep period. Please check README\n");
935                     return;
936                 }
937             } else {
938                 if ((ISDIGIT(argv[6]) == 0) || (ISDIGIT(argv[7]) == 0) ||
939                     (ISDIGIT(argv[8]) == 0)) {
940                     printf("ERR:Illegal parameter\n");
941                     print_power_mode_usage();
942                     return;
943                 }
944                 pm.flags |= PS_FLAG_INACT_SLEEP_PARAM;
945                 pm.inact_param.inactivity_to = atoi(argv[6]);
946                 pm.inact_param.min_awake = atoi(argv[7]);
947                 pm.inact_param.max_awake = atoi(argv[8]);
948                 if (pm.inact_param.min_awake > pm.inact_param.max_awake) {
949                     printf
950                         ("ERR: MIN_AWAKE value should be less than or equal to MAX_AWAKE\n");
951                     return;
952                 }
953                 if (pm.inact_param.min_awake < PS_AWAKE_PERIOD_MIN) {
954                     printf("ERR: Incorrect value of MIN_AWAKE period.\n");
955                     return;
956                 }
957             }
958         }
959     }
960     send_power_mode_ioctl(&pm);
961     return;
962 }
963
964 /**
965  *  @brief Show usage information for the sys_reset command
966  *
967  *  $return         N/A
968  */
969 void
970 print_sys_reset_usage(void)
971 {
972     printf("\nUsage : sys_reset\n");
973     return;
974 }
975
976 /** 
977  *  @brief Creates a sys_reset request and sends to the driver
978  *
979  *  Usage: "sys_reset"
980  *
981  *  @param argc     Number of arguments
982  *  @param argv     Pointer to the arguments
983  *  @return         N/A
984  */
985 void
986 apcmd_sys_reset(int argc, char *argv[])
987 {
988     APCMDBUF_SYS_RESET *cmd_buf = NULL;
989     u8 *buffer = NULL;
990     u16 cmd_len;
991     int ret = UAP_FAILURE;
992     int opt;
993     ps_mgmt pm;
994
995     while ((opt = getopt_long(argc, argv, "+", cmd_options, NULL)) != -1) {
996         switch (opt) {
997         default:
998             print_sys_reset_usage();
999             return;
1000         }
1001     }
1002     argc -= optind;
1003     argv += optind;
1004
1005     /* Check arguments */
1006     if (argc != 0) {
1007         printf("ERR:Too many arguments.\n");
1008         print_sys_reset_usage();
1009         return;
1010     }
1011
1012     memset(&pm, 0, sizeof(ps_mgmt));
1013     pm.flags = PS_FLAG_PS_MODE;
1014     pm.ps_mode = PS_MODE_DISABLE;
1015     send_power_mode_ioctl(&pm);
1016
1017     /* Initialize the command length */
1018     cmd_len = sizeof(APCMDBUF_SYS_RESET);
1019
1020     /* Initialize the command buffer */
1021     buffer = (u8 *) malloc(cmd_len);
1022
1023     if (!buffer) {
1024         printf("ERR:Cannot allocate buffer for command!\n");
1025         return;
1026     }
1027     bzero((char *) buffer, cmd_len);
1028
1029     /* Locate headers */
1030     cmd_buf = (APCMDBUF_SYS_RESET *) buffer;
1031
1032     /* Fill the command buffer */
1033     cmd_buf->CmdCode = APCMD_SYS_RESET;
1034     cmd_buf->Size = cmd_len;
1035     cmd_buf->SeqNum = 0;
1036     cmd_buf->Result = 0;
1037
1038     /* Send the command */
1039     ret = uap_ioctl((u8 *) cmd_buf, &cmd_len, cmd_len);
1040
1041     /* Process response */
1042     if (ret == UAP_SUCCESS) {
1043         /* Verify response */
1044         if (cmd_buf->CmdCode != (APCMD_SYS_RESET | APCMD_RESP_CHECK)) {
1045             printf("ERR:Corrupted response!\n");
1046             free(buffer);
1047             return;
1048         }
1049         /* Print response */
1050         if (cmd_buf->Result == CMD_SUCCESS) {
1051             printf("System reset successful!\n");
1052         } else {
1053             printf("ERR:Could not reset system!\n");
1054         }
1055     } else {
1056         printf("ERR:Command sending failed!\n");
1057     }
1058     if (buffer)
1059         free(buffer);
1060     return;
1061 }
1062
1063 /**
1064  *  @brief Show usage information for the bss_start command
1065  *
1066  *  $return         N/A
1067  */
1068 void
1069 print_bss_start_usage(void)
1070 {
1071     printf("\nUsage : bss_start\n");
1072     return;
1073 }
1074
1075 /** 
1076  *  @brief Creates a BSS start request and sends to the driver
1077  *
1078  *   Usage: "bss_start"
1079  *
1080  *  @param argc     Number of arguments
1081  *  @param argv     Pointer to the arguments
1082  *  @return         N/A
1083  */
1084 void
1085 apcmd_bss_start(int argc, char *argv[])
1086 {
1087     APCMDBUF_BSS_START *cmd_buf = NULL;
1088     u8 *buffer = NULL;
1089     u16 cmd_len;
1090     int ret = UAP_FAILURE;
1091     int opt;
1092
1093     while ((opt = getopt_long(argc, argv, "+", cmd_options, NULL)) != -1) {
1094         switch (opt) {
1095         default:
1096             print_bss_start_usage();
1097             return;
1098         }
1099     }
1100     argc -= optind;
1101     argv += optind;
1102
1103     /* Check arguments */
1104     if (argc != 0) {
1105         printf("ERR:Too many arguments.\n");
1106         print_bss_start_usage();
1107         return;
1108     }
1109
1110     /* Initialize the command length */
1111     cmd_len = sizeof(APCMDBUF_BSS_START);
1112
1113     /* Initialize the command buffer */
1114     buffer = (u8 *) malloc(cmd_len);
1115
1116     if (!buffer) {
1117         printf("ERR:Cannot allocate buffer for command!\n");
1118         return;
1119     }
1120     bzero((char *) buffer, cmd_len);
1121
1122     /* Locate headers */
1123     cmd_buf = (APCMDBUF_BSS_START *) buffer;
1124
1125     /* Fill the command buffer */
1126     cmd_buf->CmdCode = APCMD_BSS_START;
1127     cmd_buf->Size = cmd_len;
1128     cmd_buf->SeqNum = 0;
1129     cmd_buf->Result = 0;
1130
1131     /* Send the command */
1132     ret = uap_ioctl((u8 *) cmd_buf, &cmd_len, cmd_len);
1133
1134     /* Process response */
1135     if (ret == UAP_SUCCESS) {
1136         /* Verify response */
1137         if (cmd_buf->CmdCode != (APCMD_BSS_START | APCMD_RESP_CHECK)) {
1138             printf("ERR:Corrupted response!\n");
1139             free(buffer);
1140             return;
1141         }
1142
1143         /* Print response */
1144         if (cmd_buf->Result == CMD_SUCCESS) {
1145             printf("BSS started!\n");
1146         } else if (cmd_buf->Result == BSS_FAILURE_START_INVAL) {
1147             printf("ERR:Could not start BSS! Invalid BSS parameters.\n");
1148         } else if (cmd_buf->Result == BSS_FAILURE_START_REDUNDANT) {
1149             printf("ERR:Could not start BSS! BSS already started.\n");
1150         } else {
1151             printf("ERR:Could not start BSS!\n");
1152         }
1153     } else {
1154         printf("ERR:Command sending failed!\n");
1155     }
1156     if (buffer)
1157         free(buffer);
1158     return;
1159 }
1160
1161 /**
1162  *  @brief Show usage information for the bss_stop command
1163  *
1164  *  $return         N/A
1165  */
1166 void
1167 print_bss_stop_usage(void)
1168 {
1169     printf("\nUsage : bss_stop\n");
1170     return;
1171 }
1172
1173 /** 
1174  *  @brief Creates a BSS stop request and sends to the driver
1175  *
1176  *   Usage: "bss_stop"
1177  *
1178  *  @param argc     Number of arguments
1179  *  @param argv     Pointer to the arguments
1180  *  @return         N/A
1181  */
1182 void
1183 apcmd_bss_stop(int argc, char *argv[])
1184 {
1185     APCMDBUF_BSS_STOP *cmd_buf = NULL;
1186     u8 *buffer = NULL;
1187     u16 cmd_len;
1188     int ret = UAP_FAILURE;
1189     int opt;
1190
1191     while ((opt = getopt_long(argc, argv, "+", cmd_options, NULL)) != -1) {
1192         switch (opt) {
1193         default:
1194             print_bss_stop_usage();
1195             return;
1196         }
1197     }
1198     argc -= optind;
1199     argv += optind;             /* Check arguments */
1200
1201     if (argc != 0) {
1202         printf("ERR:Too many arguments.\n");
1203         print_bss_stop_usage();
1204     }
1205
1206     /* Initialize the command length */
1207     cmd_len = sizeof(APCMDBUF_BSS_STOP);
1208
1209     /* Initialize the command buffer */
1210     buffer = (u8 *) malloc(cmd_len);
1211
1212     if (!buffer) {
1213         printf("ERR:Cannot allocate buffer for command!\n");
1214         return;
1215     }
1216     bzero((char *) buffer, cmd_len);
1217
1218     /* Locate headers */
1219     cmd_buf = (APCMDBUF_BSS_STOP *) buffer;
1220
1221     /* Fill the command buffer */
1222     cmd_buf->CmdCode = APCMD_BSS_STOP;
1223     cmd_buf->Size = cmd_len;
1224     cmd_buf->SeqNum = 0;
1225     cmd_buf->Result = 0;
1226
1227     /* Send the command */
1228     ret = uap_ioctl((u8 *) cmd_buf, &cmd_len, cmd_len);
1229
1230     /* Process response */
1231     if (ret == UAP_SUCCESS) {
1232         /* Verify response */
1233         if (cmd_buf->CmdCode != (APCMD_BSS_STOP | APCMD_RESP_CHECK)) {
1234             printf("ERR:Corrupted response!\n");
1235             free(buffer);
1236             return;
1237         }
1238
1239         /* Print response */
1240         if (cmd_buf->Result == CMD_SUCCESS) {
1241             printf("BSS stopped!\n");
1242         } else if (cmd_buf->Result == BSS_FAILURE_STOP_REDUNDANT) {
1243             printf("ERR:Could not stop BSS! BSS already stopped.\n");
1244         } else if (cmd_buf->Result == BSS_FAILURE_STOP_INVAL) {
1245             printf("ERR:Could not stop BSS! No active BSS.\n");
1246         } else {
1247             printf("ERR:Could not stop BSS!\n");
1248         }
1249     } else {
1250         printf("ERR:Command sending failed!\n");
1251     }
1252     if (buffer)
1253         free(buffer);
1254     return;
1255 }
1256
1257 /**
1258  *  @brief Show usage information for the sta_list command
1259  *
1260  *  $return         N/A
1261  */
1262 void
1263 print_sta_list_usage(void)
1264 {
1265     printf("\nUsage : sta_list\n");
1266     return;
1267 }
1268
1269 /** 
1270  *  @brief Creates a STA list request and sends to the driver
1271  *
1272  *   Usage: "sta_list"
1273  *
1274  *  @param argc     Number of arguments
1275  *  @param argv     Pointer to the arguments
1276  *  @return         N/A
1277  */
1278 void
1279 apcmd_sta_list(int argc, char *argv[])
1280 {
1281     APCMDBUF_STA_LIST_REQUEST *cmd_buf = NULL;
1282     APCMDBUF_STA_LIST_RESPONSE *response_buf = NULL;
1283     u8 *buf = NULL;
1284     u16 buf_len;
1285     TLVBUF_STA_INFO *tlv = NULL;
1286     u16 cmd_len;
1287     u16 response_len;
1288     int ret = UAP_FAILURE;
1289     int i = 0;
1290     int opt;
1291     int rssi = 0;
1292
1293     while ((opt = getopt_long(argc, argv, "+", cmd_options, NULL)) != -1) {
1294         switch (opt) {
1295         default:
1296             print_sta_list_usage();
1297             return;
1298         }
1299     }
1300     argc -= optind;
1301     argv += optind;
1302
1303     /* Check arguments */
1304     if (argc != 0) {
1305         printf("ERR:Too many arguments.\n");
1306         print_sta_list_usage();
1307         return;
1308     }
1309     response_len =
1310         sizeof(APCMDBUF_STA_LIST_RESPONSE) +
1311         (MAX_NUM_CLIENTS * sizeof(TLVBUF_STA_INFO));
1312     if (response_len > sizeof(APCMDBUF_STA_LIST_REQUEST))
1313         buf_len = response_len;
1314     else
1315         buf_len = sizeof(APCMDBUF_STA_LIST_REQUEST);
1316
1317     /* Initialize the command length */
1318     cmd_len = sizeof(APCMDBUF_STA_LIST_REQUEST);
1319
1320     /* Initialize the command buffer */
1321     buf = (u8 *) malloc(buf_len);
1322
1323     if (!buf) {
1324         printf("ERR:Cannot allocate buffer from command!\n");
1325         return;
1326     }
1327     bzero((char *) buf, buf_len);
1328
1329     /* Locate headers */
1330     cmd_buf = (APCMDBUF_STA_LIST_REQUEST *) buf;
1331     response_buf = (APCMDBUF_STA_LIST_RESPONSE *) buf;
1332
1333     /* Fill the command buffer */
1334     cmd_buf->CmdCode = APCMD_STA_LIST;
1335     cmd_buf->Size = cmd_len;
1336     cmd_buf->SeqNum = 0;
1337     cmd_buf->Result = 0;
1338
1339     /* Send the command */
1340     ret = uap_ioctl((u8 *) cmd_buf, &cmd_len, buf_len);
1341     response_buf->StaCount = uap_le16_to_cpu(response_buf->StaCount);
1342
1343     /* Process response */
1344     if (ret == UAP_SUCCESS) {
1345         /* Verify response */
1346         if (response_buf->CmdCode != (APCMD_STA_LIST | APCMD_RESP_CHECK)) {
1347             printf("ERR:Corrupted response!\n");
1348             free(buf);
1349             return;
1350         }
1351
1352         /* Print response */
1353         if (response_buf->Result == CMD_SUCCESS) {
1354             printf("Number of STA = %d\n\n", response_buf->StaCount);
1355             for (i = 0; i < response_buf->StaCount; i++) {
1356                 tlv = (TLVBUF_STA_INFO *) (&response_buf->StaList[i]);
1357                 endian_convert_tlv_header_in(tlv);
1358                 if (tlv) {
1359                     if (tlv->Tag != MRVL_STA_INFO_TLV_ID) {
1360                         printf("STA %d information corrupted.\n", i + 1);
1361                         continue;
1362                     }
1363                     printf("STA %d information:\n", i + 1);
1364                     printf("=====================\n");
1365                     printf("MAC Address: ");
1366                     print_mac(tlv->MacAddress);
1367                     printf("\nPower mfg status: %s\n",
1368                            (tlv->PowerMfgStatus ==
1369                             0) ? "active" : "power save");
1370                                         /** On some platform, s8 is same as unsigned char*/
1371                     rssi = (int) tlv->Rssi;
1372                     if (rssi > 0x7f)
1373                         rssi = -(256 - rssi);
1374                     printf("Rssi : %d dBm\n\n", rssi);
1375                 } else {
1376                     printf("ERR:Unable to find information for STA %d\n\n",
1377                            i + 1);
1378                 }
1379             }
1380         } else {
1381             printf("ERR:Could not get STA list!\n");
1382         }
1383     } else {
1384         printf("ERR:Command sending failed!\n");
1385     }
1386     free(buf);
1387     return;
1388 }
1389
1390 /**
1391  *  @brief Show usage information for the sta_deauth command
1392  *
1393  *  $return         N/A
1394  */
1395 void
1396 print_sta_deauth_usage(void)
1397 {
1398     printf("\nUsage : sta_deauth <STA_MAC_ADDRESS> [REASON_CODE]\n");
1399     return;
1400 }
1401
1402 /** 
1403  *  @brief Creates a STA deauth request and sends to the driver
1404  *
1405  *   Usage: "sta_deauth <STA_MAC_ADDRESS>"
1406  *
1407  *  @param argc     Number of arguments
1408  *  @param argv     Pointer to the arguments
1409  *  @return         N/A
1410  */
1411 void
1412 apcmd_sta_deauth(int argc, char *argv[])
1413 {
1414     APCMDBUF_STA_DEAUTH *cmd_buf = NULL;
1415     u8 *buffer = NULL;
1416     u16 cmd_len;
1417     int ret = UAP_FAILURE;
1418     int opt;
1419
1420     while ((opt = getopt_long(argc, argv, "+", cmd_options, NULL)) != -1) {
1421         switch (opt) {
1422         default:
1423             print_sta_deauth_usage();
1424             return;
1425         }
1426     }
1427     argc -= optind;
1428     argv += optind;
1429
1430     /* Check arguments */
1431     if (argc != 1 && argc != 2) {
1432         printf("ERR:wrong arguments! Must provide STA_MAC_ADDRESS.\n");
1433         printf("\t\t with optional REASON_CODE.\n");
1434         print_sta_deauth_usage();
1435         return;
1436     }
1437
1438     /* Check Reason Code */
1439     if (argc == 2) {
1440         if (IS_HEX_OR_DIGIT(argv[1]) == UAP_FAILURE) {
1441             printf("ERR: Invalid input for reason code\n");
1442             print_sta_deauth_usage();
1443             return;
1444         }
1445     }
1446
1447     /* Initialize the command length */
1448     cmd_len = sizeof(APCMDBUF_STA_DEAUTH);
1449
1450     /* Initialize the command buffer */
1451     buffer = (u8 *) malloc(cmd_len);
1452     if (!buffer) {
1453         printf("ERR:Cannot allocate buffer for command!\n");
1454         return;
1455     }
1456     bzero((char *) buffer, cmd_len);
1457
1458     /* Locate headers */
1459     cmd_buf = (APCMDBUF_STA_DEAUTH *) buffer;
1460
1461     /* Fill the command buffer */
1462     cmd_buf->CmdCode = APCMD_STA_DEAUTH;
1463     cmd_buf->Size = cmd_len - BUF_HEADER_SIZE;
1464     cmd_buf->SeqNum = 0;
1465     cmd_buf->Result = 0;
1466     if ((ret = mac2raw(argv[0], cmd_buf->StaMacAddress)) != UAP_SUCCESS) {
1467         printf("ERR: %s Address\n", ret == UAP_FAILURE ? "Invalid MAC" :
1468                ret == UAP_RET_MAC_BROADCAST ? "Broadcast" : "Multicast");
1469         free(buffer);
1470         return;
1471     }
1472     if (argc == 2) {
1473         cmd_buf->ReasonCode = uap_cpu_to_le16((u16) A2HEXDECIMAL(argv[1]));
1474     }
1475
1476     /* Send the command */
1477     ret = uap_ioctl((u8 *) cmd_buf, &cmd_len, cmd_len);
1478
1479     /* Process response */
1480     if (ret == UAP_SUCCESS) {
1481         /* Verify response */
1482         if (cmd_buf->CmdCode != (APCMD_STA_DEAUTH | APCMD_RESP_CHECK)) {
1483             printf("ERR:Corrupted response!\n");
1484             free(buffer);
1485             return;
1486         }
1487
1488         /* Print response */
1489         if (cmd_buf->Result == CMD_SUCCESS) {
1490             printf("Deauthentication successful!\n");
1491         } else {
1492             printf("ERR:Deauthentication unsuccessful!\n");
1493         }
1494     } else {
1495         printf("ERR:Command sending failed!\n");
1496     }
1497     if (buffer)
1498         free(buffer);
1499     return;
1500 }
1501
1502 /**
1503  *  @brief Show usage information for the coex_config command
1504  *
1505  *  $return         N/A
1506  */
1507 void
1508 print_coex_config_usage(void)
1509 {
1510     printf("\nUsage : coex_config [CONFIG_FILE]\n");
1511     printf
1512         ("\nIf CONFIG_FILE is provided, a 'set' is performed, else a 'get' is performed.\n");
1513     return;
1514 }
1515
1516 /** 
1517  *  @brief Creates a coex_config request and sends to the driver
1518  *
1519  *  Usage: "Usage : coex_config [CONFIG_FILE]"
1520  *
1521  *  @param argc     Number of arguments
1522  *  @param argv     Pointer to the arguments
1523  *  @return         UAP_SUCCESS or UAP_FAILURE
1524  */
1525 void
1526 apcmd_coex_config(int argc, char *argv[])
1527 {
1528     apcmdbuf_coex_config *cmd_buf = NULL;
1529     tlvbuf_coex_common_cfg *coex_common_tlv;
1530     tlvbuf_coex_sco_cfg *coex_sco_tlv;
1531     tlvbuf_coex_acl_cfg *coex_acl_tlv;
1532     tlvbuf_coex_stats *coex_stats_tlv;
1533     u8 *buf = NULL;
1534     u16 cmd_len;
1535     int ret = UAP_FAILURE;
1536     int opt;
1537
1538     while ((opt = getopt_long(argc, argv, "+", cmd_options, NULL)) != -1) {
1539         switch (opt) {
1540         default:
1541             print_coex_config_usage();
1542             return;
1543         }
1544     }
1545     argc -= optind;
1546     argv += optind;
1547
1548     /* Check arguments */
1549     if (argc > 1) {
1550         printf("ERR:Too many arguments.\n");
1551         print_coex_config_usage();
1552         return;
1553     }
1554     if (argc == 1) {
1555         /* Read profile and send command to firmware */
1556         apcmd_coex_config_profile(argc, argv);
1557         return;
1558     }
1559
1560     /* fixed command length */
1561     cmd_len = sizeof(apcmdbuf_coex_config) + sizeof(tlvbuf_coex_common_cfg)
1562         + sizeof(tlvbuf_coex_sco_cfg) + sizeof(tlvbuf_coex_acl_cfg)
1563         + sizeof(tlvbuf_coex_stats);
1564     /* alloc buf for command */
1565     buf = (u8 *) malloc(cmd_len);
1566     if (!buf) {
1567         printf("ERR:Cannot allocate buffer from command!\n");
1568         return;
1569     }
1570     bzero((char *) buf, cmd_len);
1571
1572     cmd_buf = (apcmdbuf_coex_config *) buf;
1573
1574     coex_common_tlv = (tlvbuf_coex_common_cfg *) cmd_buf->tlv_buffer;
1575     coex_common_tlv->Tag = MRVL_BT_COEX_COMMON_CFG_TLV_ID;
1576     coex_common_tlv->Length =
1577         sizeof(tlvbuf_coex_common_cfg) - sizeof(TLVBUF_HEADER);
1578     endian_convert_tlv_header_out(coex_common_tlv);
1579
1580     coex_sco_tlv = (tlvbuf_coex_sco_cfg *) (cmd_buf->tlv_buffer +
1581                                             sizeof(tlvbuf_coex_common_cfg));
1582     coex_sco_tlv->Tag = MRVL_BT_COEX_SCO_CFG_TLV_ID;
1583     coex_sco_tlv->Length = sizeof(tlvbuf_coex_sco_cfg) - sizeof(TLVBUF_HEADER);
1584     endian_convert_tlv_header_out(coex_sco_tlv);
1585
1586     coex_acl_tlv = (tlvbuf_coex_acl_cfg *) (cmd_buf->tlv_buffer +
1587                                             sizeof(tlvbuf_coex_common_cfg) +
1588                                             sizeof(tlvbuf_coex_sco_cfg));
1589     coex_acl_tlv->Tag = MRVL_BT_COEX_ACL_CFG_TLV_ID;
1590     coex_acl_tlv->Length = sizeof(tlvbuf_coex_acl_cfg) - sizeof(TLVBUF_HEADER);
1591     endian_convert_tlv_header_out(coex_acl_tlv);
1592
1593     coex_stats_tlv = (tlvbuf_coex_stats *) (cmd_buf->tlv_buffer +
1594                                             sizeof(tlvbuf_coex_common_cfg) +
1595                                             sizeof(tlvbuf_coex_sco_cfg)
1596                                             + sizeof(tlvbuf_coex_acl_cfg));
1597     coex_stats_tlv->Tag = MRVL_BT_COEX_STATS_TLV_ID;
1598     coex_stats_tlv->Length = sizeof(tlvbuf_coex_stats) - sizeof(TLVBUF_HEADER);
1599     endian_convert_tlv_header_out(coex_stats_tlv);
1600
1601     /* Fill the command buffer */
1602     cmd_buf->CmdCode = HostCmd_ROBUST_COEX;
1603     cmd_buf->Size = cmd_len - BUF_HEADER_SIZE;
1604     cmd_buf->SeqNum = 0;
1605     cmd_buf->Result = 0;
1606     cmd_buf->action = uap_cpu_to_le16(ACTION_GET);
1607
1608     /* Send the command */
1609     ret = uap_ioctl((u8 *) cmd_buf, &cmd_len, cmd_len);
1610
1611     /* Process response */
1612     if (ret == UAP_SUCCESS) {
1613         /* Verify response */
1614         if (cmd_buf->CmdCode != (HostCmd_ROBUST_COEX | APCMD_RESP_CHECK)) {
1615             printf("ERR:Corrupted response!\n");
1616             free(buf);
1617             return;
1618         }
1619         /* Print response */
1620         if (cmd_buf->Result == CMD_SUCCESS) {
1621             printf("BT Coex settings:\n");
1622             print_tlv(buf + sizeof(apcmdbuf_coex_config),
1623                       cmd_buf->Size - sizeof(apcmdbuf_coex_config) +
1624                       BUF_HEADER_SIZE);
1625         } else {
1626             printf("ERR:Could not retrieve coex configuration.\n");
1627         }
1628     } else {
1629         printf("ERR:Command sending failed!\n");
1630     }
1631     free(buf);
1632     return;
1633 }
1634
1635 /**
1636  *  @brief Show usage information for the sys_config command
1637  *
1638  *  $return         N/A
1639  */
1640 void
1641 print_sys_config_usage(void)
1642 {
1643     printf("\nUsage : sys_config [CONFIG_FILE]\n");
1644     printf
1645         ("\nIf CONFIG_FILE is provided, a 'set' is performed, else a 'get' is performed.\n");
1646     printf("CONFIG_FILE is file contain all the Micro AP settings.\n");
1647     return;
1648 }
1649
1650 /**
1651  *  @brief Show usage information for the rdeeprom command
1652  *
1653  *  $return         N/A
1654  */
1655 void
1656 print_apcmd_read_eeprom_usage(void)
1657 {
1658     printf("\nUsage: rdeeprom <offset> <bytecount>\n");
1659     printf("    offset    : 0,4,8,..., multiple of 4\n");
1660     printf("    bytecount : 4-20, multiple of 4\n");
1661     return;
1662 }
1663
1664 /**
1665  *  @brief Show protocol tlv 
1666  *
1667  *  @param tlv     Poniter to protocol tlv
1668  *  
1669  *  $return         N/A
1670  */
1671 void
1672 print_protocol(TLVBUF_PROTOCOL * tlv)
1673 {
1674     switch (tlv->Protocol) {
1675     case 0:
1676     case PROTOCOL_NO_SECURITY:
1677         printf("PROTOCOL = No security\n");
1678         break;
1679     case PROTOCOL_STATIC_WEP:
1680         printf("PROTOCOL = Static WEP\n");
1681         break;
1682     case PROTOCOL_WPA:
1683         printf("PROTOCOL = WPA \n");
1684         break;
1685     case PROTOCOL_WPA2:
1686         printf("PROTOCOL = WPA2 \n");
1687         break;
1688     case PROTOCOL_WPA | PROTOCOL_WPA2:
1689         printf("PROTOCOL = WPA/WPA2 \n");
1690         break;
1691     default:
1692         printf("Unknown PROTOCOL: 0x%x \n", tlv->Protocol);
1693         break;
1694     }
1695 }
1696
1697 /**
1698  *  @brief Show wep tlv 
1699  *
1700  *  @param tlv     Poniter to wep tlv
1701  *  
1702  *  $return         N/A
1703  */
1704 void
1705 print_wep_key(TLVBUF_WEP_KEY * tlv)
1706 {
1707     int i;
1708     if (tlv->Length <= 2) {
1709         printf("wrong wep_key tlv: length=%d\n", tlv->Length);
1710         return;
1711     }
1712     printf("WEP KEY_%d = ", tlv->KeyIndex);
1713     for (i = 0; i < tlv->Length - 2; i++)
1714         printf("%02x ", tlv->Key[i]);
1715     if (tlv->IsDefault)
1716         printf("\nDefault WEP Key = %d\n", tlv->KeyIndex);
1717     else
1718         printf("\n");
1719 }
1720
1721 /** 
1722  *  @brief Parses a command line
1723  *
1724  *  @param line     The line to parse
1725  *  @param args     Pointer to the argument buffer to be filled in
1726  *  @return         Number of arguments in the line or EOF
1727  */
1728 static int
1729 parse_line(char *line, char *args[])
1730 {
1731     int arg_num = 0;
1732     int is_start = 0;
1733     int is_quote = 0;
1734     int length = 0;
1735     int i = 0;
1736
1737     arg_num = 0;
1738     length = strlen(line);
1739     /* Process line */
1740
1741     /* Find number of arguments */
1742     is_start = 0;
1743     is_quote = 0;
1744     for (i = 0; i < length; i++) {
1745         /* Ignore leading spaces */
1746         if (is_start == 0) {
1747             if (line[i] == ' ') {
1748                 continue;
1749             } else if (line[i] == '\t') {
1750                 continue;
1751             } else if (line[i] == '\n') {
1752                 break;
1753             } else {
1754                 is_start = 1;
1755                 args[arg_num] = &line[i];
1756                 arg_num++;
1757             }
1758         }
1759         if (is_start == 1) {
1760             /* Ignore comments */
1761             if (line[i] == '#') {
1762                 line[i] = '\0';
1763                 arg_num--;
1764                 break;
1765             }
1766             /* Separate by '=' */
1767             if (line[i] == '=') {
1768                 line[i] = '\0';
1769                 is_start = 0;
1770                 continue;
1771             }
1772             /* Separate by ',' */
1773             if (line[i] == ',') {
1774                 line[i] = '\0';
1775                 is_start = 0;
1776                 continue;
1777             }
1778             /* Change ',' to ' ', but not inside quotes */
1779             if ((line[i] == ',') && (is_quote == 0)) {
1780                 line[i] = ' ';
1781                 continue;
1782             }
1783         }
1784         /* Remove newlines */
1785         if (line[i] == '\n') {
1786             line[i] = '\0';
1787         }
1788         /* Check for quotes */
1789         if (line[i] == '"') {
1790             is_quote = (is_quote == 1) ? 0 : 1;
1791             continue;
1792         }
1793         if (((line[i] == ' ') || (line[i] == '\t')) && (is_quote == 0)) {
1794             line[i] = '\0';
1795             is_start = 0;
1796             continue;
1797         }
1798     }
1799     return arg_num;
1800 }
1801
1802 /** 
1803  *  @brief      Parse function for a configuration line  
1804  *
1805  *  @param s        Storage buffer for data
1806  *  @param size     Maximum size of data
1807  *  @param stream   File stream pointer
1808  *  @param line     Pointer to current line within the file
1809  *  @param _pos     Output string or NULL
1810  *  @return     String or NULL
1811  */
1812 static char *
1813 config_get_line(char *s, int size, FILE * stream, int *line, char **_pos)
1814 {
1815     char *pos, *end, *sstart;
1816     while (fgets(s, size, stream)) {
1817         (*line)++;
1818         s[size - 1] = '\0';
1819         pos = s;
1820         /* Skip white space from the beginning of line. */
1821         while (*pos == ' ' || *pos == '\t' || *pos == '\r')
1822             pos++;
1823         /* Skip comment lines and empty lines */
1824         if (*pos == '#' || *pos == '\n' || *pos == '\0')
1825             continue;
1826         /* 
1827          * Remove # comments unless they are within a double quoted
1828          * string.
1829          */
1830         sstart = strchr(pos, '"');
1831         if (sstart)
1832             sstart = strrchr(sstart + 1, '"');
1833         if (!sstart)
1834             sstart = pos;
1835         end = strchr(sstart, '#');
1836         if (end)
1837             *end-- = '\0';
1838         else
1839             end = pos + strlen(pos) - 1;
1840         /* Remove trailing white space. */
1841         while (end > pos &&
1842                (*end == '\n' || *end == ' ' || *end == '\t' || *end == '\r'))
1843             *end-- = '\0';
1844         if (*pos == '\0')
1845             continue;
1846         if (_pos)
1847             *_pos = pos;
1848         return pos;
1849     }
1850
1851     if (_pos)
1852         *_pos = NULL;
1853     return NULL;
1854 }
1855
1856 /** 
1857  *  @brief Read the profile and sends to the driver
1858  *
1859  *  @param argc     Number of arguments
1860  *  @param argv     Pointer to the arguments
1861  *  @return         UAP_SUCCESS or UAP_FAILURE
1862  */
1863 void
1864 apcmd_coex_config_profile(int argc, char *argv[])
1865 {
1866     FILE *config_file = NULL;
1867     char *line = NULL;
1868     int i, ret, index, li = 0;
1869     char *pos = NULL;
1870     int arg_num = 0;
1871     char *args[30];
1872     int is_coex_config = 0;
1873     int is_coex_common_config = 0;
1874     int is_coex_sco_config = 0;
1875     int is_coex_acl_config = 0;
1876     u8 *buf = NULL;
1877     apcmdbuf_coex_config *cmd_buf = NULL;
1878     tlvbuf_coex_common_cfg *coex_common_tlv;
1879     tlvbuf_coex_sco_cfg *coex_sco_tlv;
1880     tlvbuf_coex_acl_cfg *coex_acl_tlv;
1881     u16 acl_enabled = 0;
1882     u32 conf_bitmap = 0;
1883     u16 cmd_len = 0, tlv_len = 0;
1884     u16 sco_prot_qtime[4] = { 0, 0, 0, 0 }, sco_prot_rate = 0, sco_acl_freq = 0;
1885     u16 acl_bt_time = 0, acl_wlan_time = 0, acl_prot_rate = 0;
1886
1887     /* Check if file exists */
1888     config_file = fopen(argv[0], "r");
1889     if (config_file == NULL) {
1890         printf("\nERR:Config file can not open.\n");
1891         return;
1892     }
1893     line = (char *) malloc(MAX_CONFIG_LINE);
1894     if (!line) {
1895         printf("ERR:Cannot allocate memory for line\n");
1896         goto done;
1897     }
1898     bzero(line, MAX_CONFIG_LINE);
1899
1900     /* fixed command length */
1901     cmd_len = sizeof(apcmdbuf_coex_config) + sizeof(tlvbuf_coex_common_cfg)
1902         + sizeof(tlvbuf_coex_sco_cfg) + sizeof(tlvbuf_coex_acl_cfg);
1903     /* alloc buf for command */
1904     buf = (u8 *) malloc(cmd_len);
1905     if (!buf) {
1906         printf("ERR:Cannot allocate buffer from command!\n");
1907         goto done;
1908     }
1909     bzero((char *) buf, cmd_len);
1910
1911     cmd_buf = (apcmdbuf_coex_config *) buf;
1912
1913     /* Fill the command buffer */
1914     cmd_buf->CmdCode = HostCmd_ROBUST_COEX;
1915     cmd_buf->Size = cmd_len - BUF_HEADER_SIZE;
1916     cmd_buf->SeqNum = 0;
1917     cmd_buf->Result = 0;
1918     cmd_buf->action = uap_cpu_to_le16(ACTION_SET);
1919
1920     /* Parse file and process */
1921     while (config_get_line(line, MAX_CONFIG_LINE, config_file, &li, &pos)) {
1922 #if DEBUG
1923         uap_printf(MSG_DEBUG, "DBG:Received config line (%d) = %s\n", li, line);
1924 #endif
1925         arg_num = parse_line(line, args);
1926 #if DEBUG
1927         uap_printf(MSG_DEBUG, "DBG:Number of arguments = %d\n", arg_num);
1928         for (i = 0; i < arg_num; i++) {
1929             uap_printf(MSG_DEBUG, "\tDBG:Argument %d. %s\n", i + 1, args[i]);
1930         }
1931 #endif
1932         /* Check for end of Coex configurations */
1933         if (is_coex_acl_config == 1) {
1934             if (strcmp(args[0], "}") == 0) {
1935                 coex_acl_tlv =
1936                     (tlvbuf_coex_acl_cfg *) (cmd_buf->tlv_buffer + tlv_len);
1937                 coex_acl_tlv->Tag = MRVL_BT_COEX_ACL_CFG_TLV_ID;
1938                 coex_acl_tlv->Length =
1939                     sizeof(tlvbuf_coex_acl_cfg) - sizeof(TLVBUF_HEADER);
1940                 endian_convert_tlv_header_out(coex_acl_tlv);
1941                 coex_acl_tlv->enabled = uap_cpu_to_le16(acl_enabled);
1942                 coex_acl_tlv->bt_time = uap_cpu_to_le16(acl_bt_time);
1943                 coex_acl_tlv->wlan_time = uap_cpu_to_le16(acl_wlan_time);
1944                 coex_acl_tlv->protection_rate = uap_cpu_to_le16(acl_prot_rate);
1945                 tlv_len += sizeof(tlvbuf_coex_acl_cfg);
1946                 is_coex_acl_config = 0;
1947             }
1948         } else if (is_coex_sco_config == 1) {
1949             if (strcmp(args[0], "}") == 0) {
1950                 coex_sco_tlv =
1951                     (tlvbuf_coex_sco_cfg *) (cmd_buf->tlv_buffer + tlv_len);
1952                 coex_sco_tlv->Tag = MRVL_BT_COEX_SCO_CFG_TLV_ID;
1953                 coex_sco_tlv->Length =
1954                     sizeof(tlvbuf_coex_sco_cfg) - sizeof(TLVBUF_HEADER);
1955                 endian_convert_tlv_header_out(coex_sco_tlv);
1956                 for (i = 0; i < 4; i++)
1957                     coex_sco_tlv->protection_qtime[i] =
1958                         uap_cpu_to_le16(sco_prot_qtime[i]);
1959                 coex_sco_tlv->protection_rate = uap_cpu_to_le16(sco_prot_rate);
1960                 coex_sco_tlv->acl_frequency = uap_cpu_to_le16(sco_acl_freq);
1961                 tlv_len += sizeof(tlvbuf_coex_sco_cfg);
1962                 is_coex_sco_config = 0;
1963             }
1964         } else if (is_coex_common_config == 1) {
1965             if (strcmp(args[0], "}") == 0) {
1966                 coex_common_tlv =
1967                     (tlvbuf_coex_common_cfg *) (cmd_buf->tlv_buffer + tlv_len);
1968                 coex_common_tlv->Tag = MRVL_BT_COEX_COMMON_CFG_TLV_ID;
1969                 coex_common_tlv->Length =
1970                     sizeof(tlvbuf_coex_common_cfg) - sizeof(TLVBUF_HEADER);
1971                 endian_convert_tlv_header_out(coex_common_tlv);
1972                 coex_common_tlv->config_bitmap = uap_cpu_to_le32(conf_bitmap);
1973                 tlv_len += sizeof(tlvbuf_coex_common_cfg);
1974                 is_coex_common_config = 0;
1975             }
1976         } else if (is_coex_config == 1) {
1977             if (strcmp(args[0], "}") == 0)
1978                 is_coex_config = 0;
1979         }
1980         if (strcmp(args[0], "coex_config") == 0) {
1981             is_coex_config = 1;
1982         } else if (strcmp(args[0], "common_config") == 0) {
1983             is_coex_common_config = 1;
1984         } else if (strcmp(args[0], "sco_config") == 0) {
1985             is_coex_sco_config = 1;
1986         } else if (strcmp(args[0], "acl_config") == 0) {
1987             is_coex_acl_config = 1;
1988         }
1989         if ((strcmp(args[0], "bitmap") == 0) && is_coex_common_config) {
1990             if (is_input_valid(COEX_COMM_BITMAP, arg_num - 1, args + 1) !=
1991                 UAP_SUCCESS) {
1992                 goto done;
1993             }
1994             conf_bitmap = (u32) A2HEXDECIMAL(args[1]);
1995         } else if ((strncmp(args[0], "protectionFromQTime", 19) == 0) &&
1996                    is_coex_sco_config) {
1997             index = atoi(args[0] + strlen("protectionFromQTime"));
1998             if (index < 0 || index > 3) {
1999                 printf("ERR:Incorrect index %d.\n", index);
2000                 goto done;
2001             }
2002             if (is_input_valid(COEX_PROTECTION, arg_num, args) != UAP_SUCCESS) {
2003                 goto done;
2004             }
2005             sco_prot_qtime[index] = (u16) atoi(args[1]);
2006         } else if ((strcmp(args[0], "scoProtectionFromRate") == 0) &&
2007                    is_coex_sco_config) {
2008             if (is_input_valid(COEX_PROTECTION, arg_num, args) != UAP_SUCCESS) {
2009                 goto done;
2010             }
2011             sco_prot_rate = (u16) atoi(args[1]);
2012         } else if ((strcmp(args[0], "aclFrequency") == 0) && is_coex_sco_config) {
2013             if (is_input_valid(COEX_SCO_ACL_FREQ, arg_num - 1, args + 1) !=
2014                 UAP_SUCCESS) {
2015                 goto done;
2016             }
2017             sco_acl_freq = (u16) atoi(args[1]);
2018         } else if ((strcmp(args[0], "enabled") == 0) && is_coex_acl_config) {
2019             if (is_input_valid(COEX_ACL_ENABLED, arg_num - 1, args + 1) !=
2020                 UAP_SUCCESS) {
2021                 goto done;
2022             }
2023             acl_enabled = (u16) atoi(args[1]);
2024         } else if ((strcmp(args[0], "btTime") == 0) && is_coex_acl_config) {
2025             if (is_input_valid(COEX_ACL_BT_TIME, arg_num - 1, args + 1) !=
2026                 UAP_SUCCESS) {
2027                 goto done;
2028             }
2029             acl_bt_time = (u16) atoi(args[1]);
2030         } else if ((strcmp(args[0], "wlanTime") == 0) && is_coex_acl_config) {
2031             if (is_input_valid(COEX_ACL_WLAN_TIME, arg_num - 1, args + 1) !=
2032                 UAP_SUCCESS) {
2033                 goto done;
2034             }
2035             acl_wlan_time = (u16) atoi(args[1]);
2036         } else if ((strcmp(args[0], "aclProtectionFromRate") == 0) &&
2037                    is_coex_acl_config) {
2038             if (is_input_valid(COEX_PROTECTION, arg_num, args) != UAP_SUCCESS) {
2039                 goto done;
2040             }
2041             acl_prot_rate = (u16) atoi(args[1]);
2042         }
2043     }
2044     /* Send the command */
2045     ret = uap_ioctl((u8 *) cmd_buf, &cmd_len, cmd_len);
2046
2047     /* Process response */
2048     if (ret == UAP_SUCCESS) {
2049         /* Verify response */
2050         if (cmd_buf->CmdCode != (HostCmd_ROBUST_COEX | APCMD_RESP_CHECK)) {
2051             printf("ERR:Corrupted response!\n");
2052             goto done;
2053         }
2054         /* Print response */
2055         if (cmd_buf->Result == CMD_SUCCESS) {
2056             printf("BT Coex settings sucessfully set.\n");
2057         } else {
2058             printf("ERR:Could not set coex configuration.\n");
2059         }
2060     } else {
2061         printf("ERR:Command sending failed!\n");
2062     }
2063   done:
2064     fclose(config_file);
2065     if (buf)
2066         free(buf);
2067     if (line)
2068         free(line);
2069 }
2070
2071 /** 
2072  *  @brief Read the profile and sends to the driver
2073  *
2074  *  @param argc     Number of arguments
2075  *  @param argv     Pointer to the arguments
2076  *  @return         UAP_SUCCESS or UAP_FAILURE
2077  */
2078 void
2079 apcmd_sys_config_profile(int argc, char *argv[])
2080 {
2081     FILE *config_file = NULL;
2082     char *line = NULL;
2083     int li = 0;
2084     char *pos = NULL;
2085     int arg_num = 0;
2086     char *args[30];
2087     int i;
2088     int is_ap_config = 0;
2089     int is_custom_ie_config = 0;
2090     int is_ap_mac_filter = 0;
2091     APCMDBUF_SYS_CONFIGURE *cmd_buf = NULL;
2092     u8 *buffer = NULL;
2093     u16 cmd_len = 0;
2094     u16 tlv_len = 0;
2095     u16 ie_len = 0;
2096     u16 ie_buf_len = 0;
2097     u16 mask_ie_index = 0;
2098     int keyindex = -1;
2099     int pairwisecipher = -1;
2100     int groupcipher = -1;
2101     TLVBUF_STA_MAC_ADDR_FILTER *filter_tlv = NULL;
2102     tlvbuf_custom_ie *custom_ie_tlv_head = NULL;
2103     tlvbuf_custom_ie *custom_ie_tlv = NULL;
2104     custom_ie *custom_ie_ptr = NULL;
2105     int custom_ie_tlv_len = 0;
2106     int custom_mask_count = 0;
2107     int custom_buf_count = 0;
2108     int filter_mac_count = -1;
2109     int tx_data_rate = -1;
2110     int mcbc_data_rate = -1;
2111     u8 rate[MAX_RATES];
2112     int found = 0;
2113     char country_80211d[4];
2114     u8 state_80211d;
2115     int flag_80211d = 0;
2116
2117     memset(rate, 0, MAX_RATES);
2118     /* Check if file exists */
2119     config_file = fopen(argv[0], "r");
2120     if (config_file == NULL) {
2121         printf("\nERR:Config file can not open.\n");
2122         return;
2123     }
2124     line = (char *) malloc(MAX_CONFIG_LINE);
2125     if (!line) {
2126         printf("ERR:Cannot allocate memory for line\n");
2127         goto done;
2128     }
2129     bzero(line, MAX_CONFIG_LINE);
2130
2131     /* Parse file and process */
2132     while (config_get_line(line, MAX_CONFIG_LINE, config_file, &li, &pos)) {
2133 #if DEBUG
2134         uap_printf(MSG_DEBUG, "DBG:Received config line (%d) = %s\n", li, line);
2135 #endif
2136         arg_num = parse_line(line, args);
2137 #if DEBUG
2138         uap_printf(MSG_DEBUG, "DBG:Number of arguments = %d\n", arg_num);
2139         for (i = 0; i < arg_num; i++) {
2140             uap_printf(MSG_DEBUG, "\tDBG:Argument %d. %s\n", i + 1, args[i]);
2141         }
2142 #endif
2143         /* Check for end of AP configurations */
2144         if (is_ap_config == 1) {
2145             if (strcmp(args[0], "}") == 0) {
2146                 is_ap_config = 0;
2147                 if (tx_data_rate != -1) {
2148                     if ((!rate[0]) && (tx_data_rate) &&
2149                         (is_tx_rate_valid((u8) tx_data_rate) != UAP_SUCCESS)) {
2150                         printf("ERR: Invalid Tx Data Rate \n");
2151                         goto done;
2152                     }
2153                     if (rate[0] && tx_data_rate) {
2154                         for (i = 0; rate[i] != 0; i++) {
2155                             if ((rate[i] & ~BASIC_RATE_SET_BIT) == tx_data_rate) {
2156                                 found = 1;
2157                                 break;
2158                             }
2159                         }
2160                         if (!found) {
2161                             printf("ERR: Invalid Tx Data Rate \n");
2162                             goto done;
2163                         }
2164                     }
2165
2166                     /* Append a new TLV */
2167                     TLVBUF_TX_DATA_RATE *tlv = NULL;
2168                     tlv_len = sizeof(TLVBUF_TX_DATA_RATE);
2169                     buffer = realloc(buffer, cmd_len + tlv_len);
2170                     if (!buffer) {
2171                         printf("ERR:Cannot append tx data rate TLV!\n");
2172                         goto done;
2173                     }
2174                     cmd_buf = (APCMDBUF_SYS_CONFIGURE *) buffer;
2175                     tlv = (TLVBUF_TX_DATA_RATE *) (buffer + cmd_len);
2176                     cmd_len += tlv_len;
2177                     /* Set TLV fields */
2178                     tlv->Tag = MRVL_TX_DATA_RATE_TLV_ID;
2179                     tlv->Length = 2;
2180                     tlv->TxDataRate = tx_data_rate;
2181                     endian_convert_tlv_header_out(tlv);
2182                     tlv->TxDataRate = uap_cpu_to_le16(tlv->TxDataRate);
2183                 }
2184                 if (mcbc_data_rate != -1) {
2185                     if ((!rate[0]) && (mcbc_data_rate) &&
2186                         (is_mcbc_rate_valid((u8) mcbc_data_rate) !=
2187                          UAP_SUCCESS)) {
2188                         printf("ERR: Invalid Tx Data Rate \n");
2189                         goto done;
2190                     }
2191                     if (rate[0] && mcbc_data_rate) {
2192                         for (i = 0; rate[i] != 0; i++) {
2193                             if (rate[i] & BASIC_RATE_SET_BIT) {
2194                                 if ((rate[i] & ~BASIC_RATE_SET_BIT) ==
2195                                     mcbc_data_rate) {
2196                                     found = 1;
2197                                     break;
2198                                 }
2199                             }
2200                         }
2201                         if (!found) {
2202                             printf("ERR: Invalid MCBC Data Rate \n");
2203                             goto done;
2204                         }
2205                     }
2206
2207                     /* Append a new TLV */
2208                     TLVBUF_MCBC_DATA_RATE *tlv = NULL;
2209                     tlv_len = sizeof(TLVBUF_MCBC_DATA_RATE);
2210                     buffer = realloc(buffer, cmd_len + tlv_len);
2211                     if (!buffer) {
2212                         printf("ERR:Cannot append tx data rate TLV!\n");
2213                         goto done;
2214                     }
2215                     cmd_buf = (APCMDBUF_SYS_CONFIGURE *) buffer;
2216                     tlv = (TLVBUF_MCBC_DATA_RATE *) (buffer + cmd_len);
2217                     cmd_len += tlv_len;
2218                     /* Set TLV fields */
2219                     tlv->Tag = MRVL_MCBC_DATA_RATE_TLV_ID;
2220                     tlv->Length = 2;
2221                     tlv->MCBCdatarate = mcbc_data_rate;
2222                     endian_convert_tlv_header_out(tlv);
2223                     tlv->MCBCdatarate = uap_cpu_to_le16(tlv->MCBCdatarate);
2224                 }
2225
2226                 if ((pairwisecipher >= 0) && (groupcipher >= 0)) {
2227                     if (is_cipher_valid(pairwisecipher, groupcipher) !=
2228                         UAP_SUCCESS) {
2229                         printf
2230                             ("ERR:Wrong group and pair cipher combination!\n");
2231                         goto done;
2232                     }
2233                     TLVBUF_CIPHER *tlv = NULL;
2234                     /* Append a new TLV */
2235                     tlv_len = sizeof(TLVBUF_CIPHER);
2236                     buffer = realloc(buffer, cmd_len + tlv_len);
2237                     if (!buffer) {
2238                         printf("ERR:Cannot append cipher TLV!\n");
2239                         goto done;
2240                     }
2241                     cmd_buf = (APCMDBUF_SYS_CONFIGURE *) buffer;
2242                     tlv = (TLVBUF_CIPHER *) (buffer + cmd_len);
2243                     bzero((char *) tlv, tlv_len);
2244                     cmd_len += tlv_len;
2245                     /* Set TLV fields */
2246                     tlv->Tag = MRVL_CIPHER_TLV_ID;
2247                     tlv->Length = 2;
2248                     tlv->PairwiseCipher = pairwisecipher;
2249                     tlv->GroupCipher = groupcipher;
2250                     endian_convert_tlv_header_out(tlv);
2251                 }
2252                 cmd_buf->Size = cmd_len;
2253                 /* Send collective command */
2254                 uap_ioctl((u8 *) cmd_buf, &cmd_len, cmd_len);
2255                 cmd_len = 0;
2256                 if (buffer) {
2257                     free(buffer);
2258                     buffer = NULL;
2259                 }
2260                 continue;
2261             }
2262         }
2263
2264         /* Check for beginning of AP configurations */
2265         if (strcmp(args[0], "ap_config") == 0) {
2266             is_ap_config = 1;
2267             cmd_len = sizeof(APCMDBUF_SYS_CONFIGURE);
2268             if (buffer) {
2269                 free(buffer);
2270                 buffer = NULL;
2271             }
2272             buffer = (u8 *) malloc(cmd_len);
2273             if (!buffer) {
2274                 printf("ERR:Cannot allocate memory!\n");
2275                 goto done;
2276             }
2277             cmd_buf = (APCMDBUF_SYS_CONFIGURE *) buffer;
2278             cmd_buf->CmdCode = APCMD_SYS_CONFIGURE;
2279             cmd_buf->Size = cmd_len;
2280             cmd_buf->SeqNum = 0;
2281             cmd_buf->Result = 0;
2282             cmd_buf->Action = ACTION_SET;
2283             continue;
2284         }
2285
2286         /* Check for end of AP MAC address filter configurations */
2287         if (is_ap_mac_filter == 1) {
2288             if (strcmp(args[0], "}") == 0) {
2289                 is_ap_mac_filter = 0;
2290                 if (filter_tlv->Count != filter_mac_count) {
2291                     printf
2292                         ("ERR:Number of MAC address provided does not match 'Count'\n");
2293                     goto done;
2294                 }
2295                 if (filter_tlv->FilterMode && (filter_tlv->Count == 0)) {
2296                     printf
2297                         ("ERR:Filter list can not be empty for %s Filter mode\n",
2298                          (filter_tlv->FilterMode == 1) ? "'Allow'" : "'Block'");
2299                     goto done;
2300                 }
2301                 filter_tlv->Length = (filter_tlv->Count * ETH_ALEN) + 2;
2302                 cmd_len -=
2303                     (MAX_MAC_ONESHOT_FILTER - filter_mac_count) * ETH_ALEN;
2304                 cmd_buf->Size = cmd_len;
2305                 endian_convert_tlv_header_out(filter_tlv);
2306                 uap_ioctl((u8 *) cmd_buf, &cmd_len, cmd_len);
2307                 cmd_len = 0;
2308                 if (buffer) {
2309                     free(buffer);
2310                     buffer = NULL;
2311                 }
2312                 continue;
2313             }
2314         }
2315
2316         /* Check for end of custom IE configurations */
2317         if (is_custom_ie_config == 1) {
2318             if (strcmp(args[0], "}") == 0) {
2319                 if (custom_mask_count != custom_buf_count) {
2320                     printf
2321                         ("ERR:custom IE mask count and buffer count does not match\n");
2322                     goto done;
2323                 }
2324                 is_custom_ie_config = 0;
2325                 custom_ie_tlv_head->Length = custom_ie_tlv_len;
2326                 cmd_len -=
2327                     (MAX_IE_BUFFER_LEN * MAX_CUSTOM_IE_COUNT) -
2328                     custom_ie_tlv_len;
2329                 cmd_len -= sizeof(custom_ie) * MAX_CUSTOM_IE_COUNT;
2330                 cmd_buf->Size = cmd_len;
2331                 endian_convert_tlv_header_out(custom_ie_tlv_head);
2332                 uap_ioctl((u8 *) cmd_buf, &cmd_len, cmd_len);
2333                 cmd_len = 0;
2334                 if (buffer) {
2335                     free(buffer);
2336                     buffer = NULL;
2337                 }
2338                 continue;
2339             }
2340         }
2341
2342         if (flag_80211d && (strcmp(args[0], "11d_enable") == 0)) {
2343             if (IS_HEX_OR_DIGIT(args[1]) == UAP_FAILURE) {
2344                 printf("ERR: valid input for state are 0 or 1\n");
2345                 goto done;
2346             }
2347             state_80211d = (u8) A2HEXDECIMAL(args[1]);
2348
2349             if ((state_80211d != 0) && (state_80211d != 1)) {
2350                 printf("ERR: valid input for state are 0 or 1 \n");
2351                 goto done;
2352             }
2353             if (sg_snmp_mib
2354                 (ACTION_SET, OID_80211D_ENABLE, sizeof(state_80211d),
2355                  &state_80211d)
2356                 == UAP_FAILURE) {
2357                 goto done;
2358             }
2359         }
2360
2361         if (strcmp(args[0], "country") == 0) {
2362             APCMDBUF_CFG_80211D *cmd_buf = NULL;
2363             IEEEtypes_SubbandSet_t sub_bands[MAX_SUB_BANDS];
2364             u8 no_of_sub_band = 0;
2365             u16 buf_len;
2366             u16 cmdlen;
2367             u8 *buf = NULL;
2368
2369             if ((strlen(args[1]) > 3) || (strlen(args[1]) < 0)) {
2370                 printf("In-correct country input\n");
2371                 goto done;
2372             }
2373             strcpy(country_80211d, args[1]);
2374             for (i = 0; i < strlen(country_80211d); i++) {
2375                 if ((country_80211d[i] < 'A') || (country_80211d[i] > 'z')) {
2376                     printf("Invalid Country Code\n");
2377                     goto done;
2378                 }
2379                 if (country_80211d[i] > 'Z')
2380                     country_80211d[i] = country_80211d[i] - 'a' + 'A';
2381             }
2382             no_of_sub_band = parse_domain_file(country_80211d, sub_bands);
2383             if (no_of_sub_band == UAP_FAILURE) {
2384                 printf("Parsing Failed\n");
2385                 goto done;
2386             }
2387             buf_len = sizeof(APCMDBUF_CFG_80211D);
2388             buf_len += no_of_sub_band * sizeof(IEEEtypes_SubbandSet_t);
2389             buf = (u8 *) malloc(buf_len);
2390             if (!buf) {
2391                 printf("ERR:Cannot allocate buffer from command!\n");
2392                 goto done;
2393             }
2394             bzero((char *) buf, buf_len);
2395             cmd_buf = (APCMDBUF_CFG_80211D *) buf;
2396             cmdlen = buf_len;
2397             cmd_buf->Size = cmdlen - BUF_HEADER_SIZE;
2398             cmd_buf->Result = 0;
2399             cmd_buf->SeqNum = 0;
2400             cmd_buf->Action = uap_cpu_to_le16(ACTION_SET);
2401             cmd_buf->CmdCode = HostCmd_CMD_802_11D_DOMAIN_INFO;
2402             cmd_buf->Domain.Tag = uap_cpu_to_le16(TLV_TYPE_DOMAIN);
2403             cmd_buf->Domain.Length = uap_cpu_to_le16(sizeof(domain_param_t)
2404                                                      - BUF_HEADER_SIZE
2405                                                      +
2406                                                      (no_of_sub_band *
2407                                                       sizeof
2408                                                       (IEEEtypes_SubbandSet_t)));
2409
2410             memset(cmd_buf->Domain.CountryCode, ' ',
2411                    sizeof(cmd_buf->Domain.CountryCode));
2412             memcpy(cmd_buf->Domain.CountryCode, country_80211d,
2413                    strlen(country_80211d));
2414             memcpy(cmd_buf->Domain.Subband, sub_bands,
2415                    no_of_sub_band * sizeof(IEEEtypes_SubbandSet_t));
2416
2417             /* Send the command */
2418             uap_ioctl((u8 *) cmd_buf, &cmdlen, buf_len);
2419             if (buf)
2420                 free(buf);
2421         }
2422
2423         /* Check for beginning of AP MAC address filter configurations */
2424         if (strcmp(args[0], "ap_mac_filter") == 0) {
2425             is_ap_mac_filter = 1;
2426             cmd_len =
2427                 sizeof(APCMDBUF_SYS_CONFIGURE) +
2428                 sizeof(TLVBUF_STA_MAC_ADDR_FILTER) +
2429                 (MAX_MAC_ONESHOT_FILTER * ETH_ALEN);
2430             if (buffer) {
2431                 free(buffer);
2432                 buffer = NULL;
2433             }
2434             buffer = (u8 *) malloc(cmd_len);
2435             if (!buffer) {
2436                 printf("ERR:Cannot allocate memory!\n");
2437                 goto done;
2438             }
2439             cmd_buf = (APCMDBUF_SYS_CONFIGURE *) buffer;
2440             cmd_buf->CmdCode = APCMD_SYS_CONFIGURE;
2441             cmd_buf->Size = cmd_len;
2442             cmd_buf->SeqNum = 0;
2443             cmd_buf->Result = 0;
2444             cmd_buf->Action = ACTION_SET;
2445             filter_tlv =
2446                 (TLVBUF_STA_MAC_ADDR_FILTER *) (buffer +
2447                                                 sizeof(APCMDBUF_SYS_CONFIGURE));
2448             filter_tlv->Tag = MRVL_STA_MAC_ADDR_FILTER_TLV_ID;
2449             filter_tlv->Length = 2;
2450             filter_tlv->Count = 0;
2451             filter_mac_count = 0;
2452             continue;
2453         }
2454
2455         /* Check for beginning of custom IE configurations */
2456         if (strcmp(args[0], "custom_ie_config") == 0) {
2457             is_custom_ie_config = 1;
2458             cmd_len = sizeof(APCMDBUF_SYS_CONFIGURE) + sizeof(tlvbuf_custom_ie)
2459                 +
2460                 ((MAX_IE_BUFFER_LEN + sizeof(custom_ie)) * MAX_CUSTOM_IE_COUNT);
2461             if (buffer) {
2462                 free(buffer);
2463                 buffer = NULL;
2464             }
2465             buffer = (u8 *) malloc(cmd_len);
2466             if (!buffer) {
2467                 printf("ERR:Cannot allocate memory!\n");
2468                 goto done;
2469             }
2470             cmd_buf = (APCMDBUF_SYS_CONFIGURE *) buffer;
2471             cmd_buf->CmdCode = APCMD_SYS_CONFIGURE;
2472             cmd_buf->Size = cmd_len;
2473             cmd_buf->SeqNum = 0;
2474             cmd_buf->Result = 0;
2475             cmd_buf->Action = ACTION_SET;
2476             custom_ie_tlv =
2477                 (tlvbuf_custom_ie *) (buffer + sizeof(APCMDBUF_SYS_CONFIGURE));
2478             custom_ie_ptr = (custom_ie *) (custom_ie_tlv->ie_data);
2479             custom_ie_tlv_head = custom_ie_tlv;
2480             custom_ie_tlv_head->Tag = MRVL_MGMT_IE_LIST_TLV_ID;
2481             continue;
2482         }
2483
2484         if ((strcmp(args[0], "FilterMode") == 0) && is_ap_mac_filter) {
2485             if ((ISDIGIT(args[1]) == 0) || (atoi(args[1]) < 0) ||
2486                 (atoi(args[1]) > 2)) {
2487                 printf
2488                     ("ERR:Illegal FilterMode paramter %d. Must be either '0', '1', or '2'.\n",
2489                      atoi(args[1]));
2490                 goto done;
2491             }
2492             filter_tlv->FilterMode = atoi(args[1]);
2493             continue;
2494         }
2495         if ((strcmp(args[0], "Count") == 0) && is_ap_mac_filter) {
2496             filter_tlv->Count = atoi(args[1]);
2497             if ((ISDIGIT(args[1]) == 0) ||
2498                 (filter_tlv->Count > MAX_MAC_ONESHOT_FILTER)) {
2499                 printf("ERR: Illegal Count parameter.\n");
2500                 goto done;
2501             }
2502         }
2503         if ((strncmp(args[0], "mac_", 4) == 0) && is_ap_mac_filter) {
2504             if (filter_mac_count < MAX_MAC_ONESHOT_FILTER) {
2505                 if (mac2raw
2506                     (args[1],
2507                      &filter_tlv->MacAddress[filter_mac_count * ETH_ALEN]) !=
2508                     UAP_SUCCESS) {
2509                     printf("ERR: Invalid MAC address %s \n", args[1]);
2510                     goto done;
2511                 }
2512                 filter_mac_count++;
2513             } else {
2514                 printf
2515                     ("ERR: Filter table can not have more than %d MAC addresses\n",
2516                      MAX_MAC_ONESHOT_FILTER);
2517                 goto done;
2518             }
2519         }
2520
2521         /* custom ie configuration parameters */
2522         if ((strncmp(args[0], "MgmtSubtypeMask_", 16) == 0) &&
2523             is_custom_ie_config) {
2524             if (UAP_FAILURE == ishexstring(args[1])) {
2525                 printf("ERR:Illegal MgmtSubtypeMask %s.\n", args[1]);
2526                 goto done;
2527             }
2528             mask_ie_index = (u16) atoi(args[0] + strlen("MgmtSubtypeMask_"));
2529             if (mask_ie_index > 3) {
2530                 printf("ERR:Incorrect index %d.\n", mask_ie_index);
2531                 goto done;
2532             }
2533             custom_ie_ptr->ie_index = uap_cpu_to_le16(mask_ie_index);
2534             custom_ie_ptr->mgmt_subtype_mask = (u16) A2HEXDECIMAL(args[1]);
2535             custom_ie_ptr->mgmt_subtype_mask = uap_cpu_to_le16
2536                 (custom_ie_ptr->mgmt_subtype_mask);
2537             custom_mask_count++;
2538             continue;
2539         }
2540         if ((strncmp(args[0], "IEBuffer_", 9) == 0) && is_custom_ie_config) {
2541             if (UAP_FAILURE == ishexstring(args[1])) {
2542                 printf("ERR:Only hex digits are allowed\n");
2543                 goto done;
2544             }
2545             ie_buf_len = strlen(args[1]);
2546             if (!strncasecmp("0x", args[1], 2)) {
2547                 ie_len = (ie_buf_len - 2 + 1) / 2;
2548                 args[1] += 2;
2549             } else
2550                 ie_len = (ie_buf_len + 1) / 2;
2551
2552             if (ie_len > MAX_IE_BUFFER_LEN) {
2553                 printf("ERR:Incorrect IE length %d\n", ie_buf_len);
2554                 goto done;
2555             }
2556
2557             custom_ie_ptr->ie_index = (u16) atoi(args[0] + strlen("IEBuffer_"));
2558             if (custom_ie_ptr->ie_index != mask_ie_index) {
2559                 printf("ERR:IE buffer%d should follow MgmtSubtypeMask%d\n",
2560                        mask_ie_index, mask_ie_index);
2561                 goto done;
2562             }
2563             custom_ie_ptr->ie_index = uap_cpu_to_le16(custom_ie_ptr->ie_index);
2564             string2raw(args[1], custom_ie_ptr->ie_buffer);
2565             custom_ie_ptr->ie_length = uap_cpu_to_le16(ie_len);
2566             custom_ie_tlv_len += sizeof(custom_ie) + ie_len;
2567             custom_ie_tlv = (tlvbuf_custom_ie *) ((u8 *) custom_ie_tlv
2568                                                   + sizeof(custom_ie) + ie_len);
2569             custom_ie_ptr = (custom_ie *) (custom_ie_tlv->ie_data);
2570             custom_buf_count++;
2571             continue;
2572         }
2573         if (strcmp(args[0], "SSID") == 0) {
2574             if (arg_num == 1) {
2575                 printf("ERR:SSID field is blank!\n");
2576                 goto done;
2577             } else {
2578                 TLVBUF_SSID *tlv = NULL;
2579                 if (args[1][0] == '"') {
2580                     args[1]++;
2581                 }
2582                 if (args[1][strlen(args[1]) - 1] == '"') {
2583                     args[1][strlen(args[1]) - 1] = '\0';
2584                 }
2585                 if ((strlen(args[1]) > MAX_SSID_LENGTH) ||
2586                     (strlen(args[1]) == 0)) {
2587                     printf("ERR:SSID length out of range (%d to %d).\n",
2588                            MIN_SSID_LENGTH, MAX_SSID_LENGTH);
2589                     goto done;
2590                 }
2591                 /* Append a new TLV */
2592                 tlv_len = sizeof(TLVBUF_SSID) + strlen(args[1]);
2593                 buffer = realloc(buffer, cmd_len + tlv_len);
2594                 if (!buffer) {
2595                     printf("ERR:Cannot realloc SSID TLV!\n");
2596                     goto done;
2597                 }
2598                 cmd_buf = (APCMDBUF_SYS_CONFIGURE *) buffer;
2599                 tlv = (TLVBUF_SSID *) (buffer + cmd_len);
2600                 cmd_len += tlv_len;
2601                 /* Set TLV fields */
2602                 tlv->Tag = MRVL_SSID_TLV_ID;
2603                 tlv->Length = strlen(args[1]);
2604                 memcpy(tlv->Ssid, args[1], tlv->Length);
2605                 endian_convert_tlv_header_out(tlv);
2606             }
2607         }
2608         if (strcmp(args[0], "BeaconPeriod") == 0) {
2609             if (is_input_valid(BEACONPERIOD, arg_num - 1, args + 1) !=
2610                 UAP_SUCCESS) {
2611                 goto done;
2612             }
2613             TLVBUF_BEACON_PERIOD *tlv = NULL;
2614             /* Append a new TLV */
2615             tlv_len = sizeof(TLVBUF_BEACON_PERIOD);
2616             buffer = realloc(buffer, cmd_len + tlv_len);
2617             if (!buffer) {
2618                 printf("ERR:Cannot realloc beacon period TLV!\n");
2619                 goto done;
2620             }
2621             cmd_buf = (APCMDBUF_SYS_CONFIGURE *) buffer;
2622             tlv = (TLVBUF_BEACON_PERIOD *) (buffer + cmd_len);
2623             cmd_len += tlv_len;
2624             /* Set TLV fields */
2625             tlv->Tag = MRVL_BEACON_PERIOD_TLV_ID;
2626             tlv->Length = 2;
2627             tlv->BeaconPeriod_ms = (u16) atoi(args[1]);
2628             endian_convert_tlv_header_out(tlv);
2629             tlv->BeaconPeriod_ms = uap_cpu_to_le16(tlv->BeaconPeriod_ms);
2630         }
2631         if (strcmp(args[0], "ChanList") == 0) {
2632             if (is_input_valid(SCANCHANNELS, arg_num - 1, args + 1) !=
2633                 UAP_SUCCESS) {
2634                 goto done;
2635             }
2636
2637             TLVBUF_CHANNEL_LIST *tlv = NULL;
2638             CHANNEL_LIST *pChanList = NULL;
2639             /* Append a new TLV */
2640             tlv_len =
2641                 sizeof(TLVBUF_CHANNEL_LIST) +
2642                 ((arg_num - 1) * sizeof(CHANNEL_LIST));
2643             buffer = realloc(buffer, cmd_len + tlv_len);
2644             if (!buffer) {
2645                 printf("ERR:Cannot append channel list TLV!\n");
2646                 goto done;
2647             }
2648             cmd_buf = (APCMDBUF_SYS_CONFIGURE *) buffer;
2649             tlv = (TLVBUF_CHANNEL_LIST *) (buffer + cmd_len);
2650             cmd_len += tlv_len;
2651             /* Set TLV fields */
2652             tlv->Tag = MRVL_CHANNELLIST_TLV_ID;
2653             tlv->Length = sizeof(CHANNEL_LIST) * (arg_num - 1);
2654             pChanList = (CHANNEL_LIST *) tlv->ChanList;
2655             for (i = 0; i < (arg_num - 1); i++) {
2656                 pChanList->ChanNumber = (u8) atoi(args[i + 1]);
2657                 pChanList->BandConfigType = 0;
2658                 pChanList++;
2659             }
2660             endian_convert_tlv_header_out(tlv);
2661         }
2662         if (strcmp(args[0], "Channel") == 0) {
2663             if (is_input_valid(CHANNEL, arg_num - 1, args + 1) != UAP_SUCCESS) {
2664                 goto done;
2665             }
2666             TLVBUF_CHANNEL_CONFIG *tlv = NULL;
2667             /* Append a new TLV */
2668             tlv_len = sizeof(TLVBUF_CHANNEL_CONFIG);
2669             buffer = realloc(buffer, cmd_len + tlv_len);
2670             if (!buffer) {
2671                 printf("ERR:Cannot append channel TLV!\n");
2672                 goto done;
2673             }
2674             cmd_buf = (APCMDBUF_SYS_CONFIGURE *) buffer;
2675             tlv = (TLVBUF_CHANNEL_CONFIG *) (buffer + cmd_len);
2676             cmd_len += tlv_len;
2677             /* Set TLV fields */
2678             tlv->Tag = MRVL_CHANNELCONFIG_TLV_ID;
2679             tlv->Length = 2;
2680             tlv->ChanNumber = (u8) atoi(args[1]);
2681             if ((arg_num - 1) == 2)
2682                 tlv->BandConfigType = atoi(args[2]) ? BAND_CONFIG_ACS_MODE : 0;
2683             else
2684                 tlv->BandConfigType = 0;
2685             endian_convert_tlv_header_out(tlv);
2686         }
2687         if (strcmp(args[0], "AP_MAC") == 0) {
2688             int ret;
2689             TLVBUF_AP_MAC_ADDRESS *tlv = NULL;
2690             /* Append a new TLV */
2691             tlv_len = sizeof(TLVBUF_AP_MAC_ADDRESS);
2692             buffer = realloc(buffer, cmd_len + tlv_len);
2693             if (!buffer) {
2694                 printf("ERR:Cannot append channel TLV!\n");
2695                 goto done;
2696             }
2697             cmd_buf = (APCMDBUF_SYS_CONFIGURE *) buffer;
2698             tlv = (TLVBUF_AP_MAC_ADDRESS *) (buffer + cmd_len);
2699             cmd_len += tlv_len;
2700             cmd_buf->Action = ACTION_SET;
2701             tlv->Tag = MRVL_AP_MAC_ADDRESS_TLV_ID;
2702             tlv->Length = ETH_ALEN;
2703             if ((ret = mac2raw(args[1], tlv->ApMacAddr)) != UAP_SUCCESS) {
2704                 printf("ERR: %s Address \n",
2705                        ret == UAP_FAILURE ? "Invalid MAC" : ret ==
2706                        UAP_RET_MAC_BROADCAST ? "Broadcast" : "Multicast");
2707                 goto done;
2708             }
2709             endian_convert_tlv_header_out(tlv);
2710         }
2711
2712         if (strcmp(args[0], "RxAntenna") == 0) {
2713             if ((ISDIGIT(args[1]) != UAP_SUCCESS) || (atoi(args[1]) < 0) ||
2714                 (atoi(args[1]) > 1)) {
2715                 printf("ERR: Invalid Antenna value\n");
2716                 goto done;
2717             }
2718             TLVBUF_ANTENNA_CTL *tlv = NULL;
2719             /* Append a new TLV */
2720             tlv_len = sizeof(TLVBUF_ANTENNA_CTL);
2721             buffer = realloc(buffer, cmd_len + tlv_len);
2722             if (!buffer) {
2723                 printf("ERR:Cannot append channel TLV!\n");
2724                 goto done;
2725             }
2726             cmd_buf = (APCMDBUF_SYS_CONFIGURE *) buffer;
2727             tlv = (TLVBUF_ANTENNA_CTL *) (buffer + cmd_len);
2728             cmd_len += tlv_len;
2729             cmd_buf->Action = ACTION_SET;
2730             tlv->Tag = MRVL_ANTENNA_CTL_TLV_ID;
2731             tlv->Length = 2;
2732             tlv->WhichAntenna = 0;
2733             tlv->AntennaMode = atoi(args[1]);
2734             endian_convert_tlv_header_out(tlv);
2735         }
2736
2737         if (strcmp(args[0], "TxAntenna") == 0) {
2738             if ((ISDIGIT(args[1]) != UAP_SUCCESS) || (atoi(args[1]) < 0) ||
2739                 (atoi(args[1]) > 1)) {
2740                 printf("ERR: Invalid Antenna value\n");
2741                 goto done;
2742             }
2743             TLVBUF_ANTENNA_CTL *tlv = NULL;
2744             /* Append a new TLV */
2745             tlv_len = sizeof(TLVBUF_ANTENNA_CTL);
2746             buffer = realloc(buffer, cmd_len + tlv_len);
2747             if (!buffer) {
2748                 printf("ERR:Cannot append channel TLV!\n");
2749                 goto done;
2750             }
2751             cmd_buf = (APCMDBUF_SYS_CONFIGURE *) buffer;
2752             tlv = (TLVBUF_ANTENNA_CTL *) (buffer + cmd_len);
2753             cmd_len += tlv_len;
2754             cmd_buf->Action = ACTION_SET;
2755             tlv->Tag = MRVL_ANTENNA_CTL_TLV_ID;
2756             tlv->Length = 2;
2757             tlv->WhichAntenna = 1;
2758             tlv->AntennaMode = atoi(args[1]);
2759             endian_convert_tlv_header_out(tlv);
2760         }
2761         if (strcmp(args[0], "Rate") == 0) {
2762             if (is_input_valid(RATE, arg_num - 1, args + 1) != UAP_SUCCESS) {
2763                 printf("ERR: Invalid Rate input\n");
2764                 goto done;
2765             }
2766             TLVBUF_RATES *tlv = NULL;
2767             /* Append a new TLV */
2768             tlv_len = sizeof(TLVBUF_RATES) + arg_num - 1;
2769             buffer = realloc(buffer, cmd_len + tlv_len);
2770             if (!buffer) {
2771                 printf("ERR:Cannot append rates TLV!\n");
2772                 goto done;
2773             }
2774             cmd_buf = (APCMDBUF_SYS_CONFIGURE *) buffer;
2775             tlv = (TLVBUF_RATES *) (buffer + cmd_len);
2776             cmd_len += tlv_len;
2777             /* Set TLV fields */
2778             tlv->Tag = MRVL_RATES_TLV_ID;
2779             tlv->Length = arg_num - 1;
2780             for (i = 0; i < tlv->Length; i++) {
2781                 rate[i] = tlv->OperationalRates[i] =
2782                     (u8) A2HEXDECIMAL(args[i + 1]);
2783             }
2784             endian_convert_tlv_header_out(tlv);
2785         }
2786         if (strcmp(args[0], "TxPowerLevel") == 0) {
2787             if (is_input_valid(TXPOWER, arg_num - 1, args + 1) != UAP_SUCCESS) {
2788                 printf("ERR:Invalid TxPowerLevel \n");
2789                 goto done;
2790             } else {
2791                 TLVBUF_TX_POWER *tlv = NULL;
2792                 /* Append a new TLV */
2793                 tlv_len = sizeof(TLVBUF_TX_POWER);
2794                 buffer = realloc(buffer, cmd_len + tlv_len);
2795                 if (!buffer) {
2796                     printf("ERR:Cannot append tx power level TLV!\n");
2797                     goto done;
2798                 }
2799                 cmd_buf = (APCMDBUF_SYS_CONFIGURE *) buffer;
2800                 tlv = (TLVBUF_TX_POWER *) (buffer + cmd_len);
2801                 cmd_len += tlv_len;
2802                 /* Set TLV fields */
2803                 tlv->Tag = MRVL_TX_POWER_TLV_ID;
2804                 tlv->Length = 1;
2805                 tlv->TxPower_dBm = (u8) atoi(args[1]);
2806                 endian_convert_tlv_header_out(tlv);
2807             }
2808         }
2809         if (strcmp(args[0], "BroadcastSSID") == 0) {
2810             if (is_input_valid(BROADCASTSSID, arg_num - 1, args + 1) !=
2811                 UAP_SUCCESS) {
2812                 goto done;
2813             }
2814             TLVBUF_BCAST_SSID_CTL *tlv = NULL;
2815             /* Append a new TLV */
2816             tlv_len = sizeof(TLVBUF_BCAST_SSID_CTL);
2817             buffer = realloc(buffer, cmd_len + tlv_len);
2818             if (!buffer) {
2819                 printf("ERR:Cannot append SSID broadcast control TLV!\n");
2820                 goto done;
2821             }
2822             cmd_buf = (APCMDBUF_SYS_CONFIGURE *) buffer;
2823             tlv = (TLVBUF_BCAST_SSID_CTL *) (buffer + cmd_len);
2824             cmd_len += tlv_len;
2825             /* Set TLV fields */
2826             tlv->Tag = MRVL_BCAST_SSID_CTL_TLV_ID;
2827             tlv->Length = 1;
2828             tlv->BcastSsidCtl = (u8) atoi(args[1]);
2829             endian_convert_tlv_header_out(tlv);
2830         }
2831         if (strcmp(args[0], "RTSThreshold") == 0) {
2832             if (is_input_valid(RTSTHRESH, arg_num - 1, args + 1) != UAP_SUCCESS) {
2833                 goto done;
2834             }
2835             TLVBUF_RTS_THRESHOLD *tlv = NULL;
2836             /* Append a new TLV */
2837             tlv_len = sizeof(TLVBUF_RTS_THRESHOLD);
2838             buffer = realloc(buffer, cmd_len + tlv_len);
2839             if (!buffer) {
2840                 printf("ERR:Cannot append RTS threshold TLV!\n");
2841                 goto done;
2842             }
2843             cmd_buf = (APCMDBUF_SYS_CONFIGURE *) buffer;
2844             tlv = (TLVBUF_RTS_THRESHOLD *) (buffer + cmd_len);
2845             cmd_len += tlv_len;
2846             /* Set TLV fields */
2847             tlv->Tag = MRVL_RTS_THRESHOLD_TLV_ID;
2848             tlv->Length = 2;
2849             tlv->RtsThreshold = (u16) atoi(args[1]);
2850             endian_convert_tlv_header_out(tlv);
2851             tlv->RtsThreshold = uap_cpu_to_le16(tlv->RtsThreshold);
2852         }
2853         if (strcmp(args[0], "FragThreshold") == 0) {
2854             if (is_input_valid(FRAGTHRESH, arg_num - 1, args + 1) !=
2855                 UAP_SUCCESS) {
2856                 goto done;
2857             }
2858             TLVBUF_FRAG_THRESHOLD *tlv = NULL;
2859             /* Append a new TLV */
2860             tlv_len = sizeof(TLVBUF_FRAG_THRESHOLD);
2861             buffer = realloc(buffer, cmd_len + tlv_len);
2862             if (!buffer) {
2863                 printf("ERR:Cannot append Fragmentation threshold TLV!\n");
2864                 goto done;
2865             }
2866             cmd_buf = (APCMDBUF_SYS_CONFIGURE *) buffer;
2867             tlv = (TLVBUF_FRAG_THRESHOLD *) (buffer + cmd_len);
2868             cmd_len += tlv_len;
2869             /* Set TLV fields */
2870             tlv->Tag = MRVL_FRAG_THRESHOLD_TLV_ID;
2871             tlv->Length = 2;
2872             tlv->FragThreshold = (u16) atoi(args[1]);
2873             endian_convert_tlv_header_out(tlv);
2874             tlv->FragThreshold = uap_cpu_to_le16(tlv->FragThreshold);
2875         }
2876         if (strcmp(args[0], "DTIMPeriod") == 0) {
2877             if (is_input_valid(DTIMPERIOD, arg_num - 1, args + 1) !=
2878                 UAP_SUCCESS) {
2879                 goto done;
2880             }
2881             TLVBUF_DTIM_PERIOD *tlv = NULL;
2882             /* Append a new TLV */
2883             tlv_len = sizeof(TLVBUF_DTIM_PERIOD);
2884             buffer = realloc(buffer, cmd_len + tlv_len);
2885             if (!buffer) {
2886                 printf("ERR:Cannot append DTIM period TLV!\n");
2887                 goto done;
2888             }
2889             cmd_buf = (APCMDBUF_SYS_CONFIGURE *) buffer;
2890             tlv = (TLVBUF_DTIM_PERIOD *) (buffer + cmd_len);
2891             cmd_len += tlv_len;
2892             /* Set TLV fields */
2893             tlv->Tag = MRVL_DTIM_PERIOD_TLV_ID;
2894             tlv->Length = 1;
2895             tlv->DtimPeriod = (u8) atoi(args[1]);
2896             endian_convert_tlv_header_out(tlv);
2897         }
2898         if (strcmp(args[0], "RadioControl") == 0) {
2899             if (is_input_valid(RADIOCONTROL, arg_num - 1, args + 1) !=
2900                 UAP_SUCCESS) {
2901                 goto done;
2902             }
2903             TLVBUF_RADIO_CTL *tlv = NULL;
2904             /* Append a new TLV */
2905             tlv_len = sizeof(TLVBUF_RADIO_CTL);
2906             buffer = realloc(buffer, cmd_len + tlv_len);
2907             if (!buffer) {
2908                 printf("ERR:Cannot append radio control TLV!\n");
2909                 goto done;
2910             }
2911             cmd_buf = (APCMDBUF_SYS_CONFIGURE *) buffer;
2912             tlv = (TLVBUF_RADIO_CTL *) (buffer + cmd_len);
2913             cmd_len += tlv_len;
2914             /* Set TLV fields */
2915             tlv->Tag = MRVL_RADIO_CTL_TLV_ID;
2916             tlv->Length = 1;
2917             tlv->RadioCtl = (u8) atoi(args[1]);
2918             endian_convert_tlv_header_out(tlv);
2919         }
2920         if (strcmp(args[0], "RSNReplayProtection") == 0) {
2921             if (is_input_valid(RSNREPLAYPROT, arg_num - 1, args + 1) !=
2922                 UAP_SUCCESS) {
2923                 goto done;
2924             }
2925             tlvbuf_rsn_replay_prot *tlv = NULL;
2926             /* Append a new TLV */
2927             tlv_len = sizeof(tlvbuf_rsn_replay_prot);
2928             buffer = realloc(buffer, cmd_len + tlv_len);
2929             if (!buffer) {
2930                 printf("ERR:Cannot append RSN replay protection TLV!\n");
2931                 goto done;
2932             }
2933             cmd_buf = (APCMDBUF_SYS_CONFIGURE *) buffer;
2934             tlv = (tlvbuf_rsn_replay_prot *) (buffer + cmd_len);
2935             cmd_len += tlv_len;
2936             /* Set TLV fields */
2937             tlv->Tag = MRVL_RSN_REPLAY_PROT_TLV_ID;
2938             tlv->Length = 1;
2939             tlv->rsn_replay_prot = (u8) atoi(args[1]);
2940             endian_convert_tlv_header_out(tlv);
2941         }
2942         if (strcmp(args[0], "TxDataRate") == 0) {
2943             if (is_input_valid(TXDATARATE, arg_num - 1, args + 1) !=
2944                 UAP_SUCCESS) {
2945                 goto done;
2946             }
2947             tx_data_rate = (u16) A2HEXDECIMAL(args[1]);
2948         }
2949         if (strcmp(args[0], "MCBCdataRate") == 0) {
2950             if (is_input_valid(MCBCDATARATE, arg_num - 1, args + 1) !=
2951                 UAP_SUCCESS) {
2952                 goto done;
2953             }
2954             mcbc_data_rate = (u16) A2HEXDECIMAL(args[1]);
2955         }
2956         if (strcmp(args[0], "PktFwdCtl") == 0) {
2957             if (is_input_valid(PKTFWD, arg_num - 1, args + 1) != UAP_SUCCESS) {
2958                 goto done;
2959             }
2960             TLVBUF_PKT_FWD_CTL *tlv = NULL;
2961             /* Append a new TLV */
2962             tlv_len = sizeof(TLVBUF_PKT_FWD_CTL);
2963             buffer = realloc(buffer, cmd_len + tlv_len);
2964             if (!buffer) {
2965                 printf("ERR:Cannot append packet forwarding control TLV!\n");
2966                 goto done;
2967             }
2968             cmd_buf = (APCMDBUF_SYS_CONFIGURE *) buffer;
2969             tlv = (TLVBUF_PKT_FWD_CTL *) (buffer + cmd_len);
2970             cmd_len += tlv_len;
2971             /* Set TLV fields */
2972             tlv->Tag = MRVL_PKT_FWD_CTL_TLV_ID;
2973             tlv->Length = 1;
2974             tlv->PktFwdCtl = (u8) atoi(args[1]);
2975             endian_convert_tlv_header_out(tlv);
2976         }
2977         if (strcmp(args[0], "StaAgeoutTimer") == 0) {
2978             if (is_input_valid(STAAGEOUTTIMER, arg_num - 1, args + 1) !=
2979                 UAP_SUCCESS) {
2980                 goto done;
2981             }
2982             TLVBUF_STA_AGEOUT_TIMER *tlv = NULL;
2983             /* Append a new TLV */
2984             tlv_len = sizeof(TLVBUF_STA_AGEOUT_TIMER);
2985             buffer = realloc(buffer, cmd_len + tlv_len);
2986             if (!buffer) {
2987                 printf("ERR:Cannot append STA ageout timer TLV!\n");
2988                 goto done;
2989             }
2990             cmd_buf = (APCMDBUF_SYS_CONFIGURE *) buffer;
2991             tlv = (TLVBUF_STA_AGEOUT_TIMER *) (buffer + cmd_len);
2992             cmd_len += tlv_len;
2993             /* Set TLV fields */
2994             tlv->Tag = MRVL_STA_AGEOUT_TIMER_TLV_ID;
2995             tlv->Length = 4;
2996             tlv->StaAgeoutTimer_ms = (u32) atoi(args[1]);
2997             endian_convert_tlv_header_out(tlv);
2998             tlv->StaAgeoutTimer_ms = uap_cpu_to_le32(tlv->StaAgeoutTimer_ms);
2999         }
3000         if (strcmp(args[0], "AuthMode") == 0) {
3001             if (is_input_valid(AUTHMODE, arg_num - 1, args + 1) != UAP_SUCCESS) {
3002                 goto done;
3003             }
3004             TLVBUF_AUTH_MODE *tlv = NULL;
3005             if ((atoi(args[1]) < 0) || (atoi(args[1]) > 1)) {
3006                 printf
3007                     ("ERR:Illegal AuthMode parameter. Must be either '0' or '1'.\n");
3008                 goto done;
3009             }
3010             /* Append a new TLV */
3011             tlv_len = sizeof(TLVBUF_AUTH_MODE);
3012             buffer = realloc(buffer, cmd_len + tlv_len);
3013             if (!buffer) {
3014                 printf("ERR:Cannot append auth mode TLV!\n");
3015                 goto done;
3016             }
3017             cmd_buf = (APCMDBUF_SYS_CONFIGURE *) buffer;
3018             tlv = (TLVBUF_AUTH_MODE *) (buffer + cmd_len);
3019             cmd_len += tlv_len;
3020             /* Set TLV fields */
3021             tlv->Tag = MRVL_AUTH_TLV_ID;
3022             tlv->Length = 1;
3023             tlv->AuthMode = (u8) atoi(args[1]);
3024             endian_convert_tlv_header_out(tlv);
3025         }
3026         if (strcmp(args[0], "KeyIndex") == 0) {
3027             if (arg_num == 1) {
3028                 printf("KeyIndex is blank!\n");
3029                 goto done;
3030             } else {
3031                 if (ISDIGIT(args[1]) == 0) {
3032                     printf
3033                         ("ERR:Illegal KeyIndex parameter. Must be either '0', '1', '2', or '3'.\n");
3034                     goto done;
3035                 }
3036                 keyindex = atoi(args[1]);
3037                 if ((keyindex < 0) || (keyindex > 3)) {
3038                     printf
3039                         ("ERR:Illegal KeyIndex parameter. Must be either '0', '1', '2', or '3'.\n");
3040                     goto done;
3041                 }
3042             }
3043         }
3044         if (strncmp(args[0], "Key_", 4) == 0) {
3045             if (arg_num == 1) {
3046                 printf("ERR:%s is blank!\n", args[0]);
3047                 goto done;
3048             } else {
3049                 TLVBUF_WEP_KEY *tlv = NULL;
3050                 int key_len = 0;
3051                 if (args[1][0] == '"') {
3052                     if ((strlen(args[1]) != 2) && (strlen(args[1]) != 7) &&
3053                         (strlen(args[1]) != 15)) {
3054                         printf("ERR:Wrong key length!\n");
3055                         goto done;
3056                     }
3057                     key_len = strlen(args[1]) - 2;
3058                 } else {
3059                     if ((strlen(args[1]) != 0) && (strlen(args[1]) != 10) &&
3060                         (strlen(args[1]) != 26)) {
3061                         printf("ERR:Wrong key length!\n");
3062                         goto done;
3063                     }
3064                     if (UAP_FAILURE == ishexstring(args[1])) {
3065                         printf
3066                             ("ERR:Only hex digits are allowed when key length is 10 or 26\n");
3067                         goto done;
3068                     }
3069                     key_len = strlen(args[1]) / 2;
3070                 }
3071                 /* Append a new TLV */
3072                 tlv_len = sizeof(TLVBUF_WEP_KEY) + key_len;
3073                 buffer = realloc(buffer, cmd_len + tlv_len);
3074                 if (!buffer) {
3075                     printf("ERR:Cannot append WEP key configurations TLV!\n");
3076                     goto done;
3077                 }
3078                 cmd_buf = (APCMDBUF_SYS_CONFIGURE *) buffer;
3079                 tlv = (TLVBUF_WEP_KEY *) (buffer + cmd_len);
3080                 cmd_len += tlv_len;
3081                 /* Set TLV fields */
3082                 tlv->Tag = MRVL_WEP_KEY_TLV_ID;
3083                 tlv->Length = key_len + 2;
3084                 if (strcmp(args[0], "Key_0") == 0) {
3085                     tlv->KeyIndex = 0;
3086                 } else if (strcmp(args[0], "Key_1") == 0) {
3087                     tlv->KeyIndex = 1;
3088                 } else if (strcmp(args[0], "Key_2") == 0) {
3089                     tlv->KeyIndex = 2;
3090                 } else if (strcmp(args[0], "Key_3") == 0) {
3091                     tlv->KeyIndex = 3;
3092                 }
3093                 if (keyindex == tlv->KeyIndex) {
3094                     tlv->IsDefault = 1;
3095                 } else {
3096                     tlv->IsDefault = 0;
3097                 }
3098                 if (args[1][0] == '"') {
3099                     memcpy(tlv->Key, &args[1][1], strlen(args[1]) - 2);
3100                 } else {
3101                     string2raw(args[1], tlv->Key);
3102                 }
3103                 endian_convert_tlv_header_out(tlv);
3104             }
3105         }
3106         if (strcmp(args[0], "PSK") == 0) {
3107             if (arg_num == 1) {
3108                 printf("ERR:PSK is blank!\n");
3109                 goto done;
3110             } else {
3111                 TLVBUF_WPA_PASSPHRASE *tlv = NULL;
3112                 if (args[1][0] == '"') {
3113                     args[1]++;
3114                 }
3115                 if (args[1][strlen(args[1]) - 1] == '"') {
3116                     args[1][strlen(args[1]) - 1] = '\0';
3117                 }
3118                 tlv_len = sizeof(TLVBUF_WPA_PASSPHRASE) + strlen(args[1]);
3119                 if (strlen(args[1]) > MAX_WPA_PASSPHRASE_LENGTH) {
3120                     printf("ERR:PSK too long.\n");
3121                     goto done;
3122                 }
3123                 if (strlen(args[1]) < MIN_WPA_PASSPHRASE_LENGTH) {
3124                     printf("ERR:PSK too short.\n");
3125                     goto done;
3126                 }
3127                 if (strlen(args[1]) == MAX_WPA_PASSPHRASE_LENGTH) {
3128                     if (UAP_FAILURE == ishexstring(args[1])) {
3129                         printf
3130                             ("ERR:Only hex digits are allowed when passphrase's length is 64\n");
3131                         goto done;
3132                     }
3133                 }
3134                 /* Append a new TLV */
3135                 buffer = realloc(buffer, cmd_len + tlv_len);
3136                 if (!buffer) {
3137                     printf("ERR:Cannot append WPA passphrase TLV!\n");
3138                     goto done;
3139                 }
3140                 cmd_buf = (APCMDBUF_SYS_CONFIGURE *) buffer;
3141                 tlv = (TLVBUF_WPA_PASSPHRASE *) (buffer + cmd_len);
3142                 cmd_len += tlv_len;
3143                 /* Set TLV fields */
3144                 tlv->Tag = MRVL_WPA_PASSPHRASE_TLV_ID;
3145                 tlv->Length = strlen(args[1]);
3146                 memcpy(tlv->Passphrase, args[1], tlv->Length);
3147                 endian_convert_tlv_header_out(tlv);
3148             }
3149         }
3150         if (strcmp(args[0], "Protocol") == 0) {
3151             if (is_input_valid(PROTOCOL, arg_num - 1, args + 1) != UAP_SUCCESS) {
3152                 goto done;
3153             }
3154             TLVBUF_PROTOCOL *tlv = NULL;
3155             /* Append a new TLV */
3156             tlv_len = sizeof(TLVBUF_PROTOCOL);
3157             buffer = realloc(buffer, cmd_len + tlv_len);
3158             if (!buffer) {
3159                 printf("ERR:Cannot append protocol TLV!\n");
3160                 goto done;
3161             }
3162             cmd_buf = (APCMDBUF_SYS_CONFIGURE *) buffer;
3163             tlv = (TLVBUF_PROTOCOL *) (buffer + cmd_len);
3164             cmd_len += tlv_len;
3165             /* Set TLV fields */
3166             tlv->Tag = MRVL_PROTOCOL_TLV_ID;
3167             tlv->Length = 2;
3168             tlv->Protocol = (u16) atoi(args[1]);
3169             endian_convert_tlv_header_out(tlv);
3170             tlv->Protocol = uap_cpu_to_le16(tlv->Protocol);
3171             if (atoi(args[1]) & (PROTOCOL_WPA | PROTOCOL_WPA2)) {
3172                 TLVBUF_AKMP *tlv = NULL;
3173                 /* Append a new TLV */
3174                 tlv_len = sizeof(TLVBUF_AKMP);
3175                 buffer = realloc(buffer, cmd_len + tlv_len);
3176                 if (!buffer) {
3177                     printf("ERR:Cannot append AKMP TLV!\n");
3178                     goto done;
3179                 }
3180                 cmd_buf = (APCMDBUF_SYS_CONFIGURE *) buffer;
3181                 tlv = (TLVBUF_AKMP *) (buffer + cmd_len);
3182                 cmd_len += tlv_len;
3183                 /* Set TLV fields */
3184                 tlv->Tag = MRVL_AKMP_TLV_ID;
3185                 tlv->Length = 2;
3186                 tlv->KeyMgmt = KEY_MGMT_PSK;
3187                 endian_convert_tlv_header_out(tlv);
3188                 tlv->KeyMgmt = uap_cpu_to_le16(tlv->KeyMgmt);
3189             }
3190         }
3191         if (strcmp(args[0], "PairwiseCipher") == 0) {
3192             if (arg_num == 1) {
3193                 printf("ERR:PairwiseCipher is blank!\n");
3194                 goto done;
3195             } else {
3196                 if (ISDIGIT(args[1]) == 0) {
3197                     printf
3198                         ("ERR:Illegal PairwiseCipher parameter. Must be either bit '2' or '3'.\n");
3199                     goto done;
3200                 }
3201                 pairwisecipher = atoi(args[1]);
3202                 if (pairwisecipher & ~CIPHER_BITMAP) {
3203                     printf
3204                         ("ERR:Illegal PairwiseCipher parameter. Must be either bit '2' or '3'.\n");
3205                     goto done;
3206                 }
3207             }
3208         }
3209         if (strcmp(args[0], "GroupCipher") == 0) {
3210             if (arg_num == 1) {
3211                 printf("ERR:GroupCipher is blank!\n");
3212                 goto done;
3213             } else {
3214                 if (ISDIGIT(args[1]) == 0) {
3215                     printf
3216                         ("ERR:Illegal GroupCipher parameter. Must be either bit '2' or '3'.\n");
3217                     goto done;
3218                 }
3219                 groupcipher = atoi(args[1]);
3220                 if (groupcipher & ~CIPHER_BITMAP) {
3221                     printf
3222                         ("ERR:Illegal GroupCipher parameter. Must be either bit '2' or '3'.\n");
3223                     goto done;
3224                 }
3225             }
3226         }
3227         if (strcmp(args[0], "GroupRekeyTime") == 0) {
3228             if (is_input_valid(GROUPREKEYTIMER, arg_num - 1, args + 1) !=
3229                 UAP_SUCCESS) {
3230                 goto done;
3231             }
3232             TLVBUF_GROUP_REKEY_TIMER *tlv = NULL;
3233
3234             /* Append a new TLV */
3235             tlv_len = sizeof(TLVBUF_GROUP_REKEY_TIMER);
3236             buffer = realloc(buffer, cmd_len + tlv_len);
3237             if (!buffer) {
3238                 printf("ERR:Cannot append protocol TLV!\n");
3239                 goto done;
3240             }
3241             cmd_buf = (APCMDBUF_SYS_CONFIGURE *) buffer;
3242             tlv = (TLVBUF_GROUP_REKEY_TIMER *) (buffer + cmd_len);
3243             cmd_len += tlv_len;
3244             /* Set TLV fields */
3245             tlv->Tag = MRVL_GRP_REKEY_TIME_TLV_ID;
3246             tlv->Length = 4;
3247             tlv->GroupRekeyTime_sec = (u32) atoi(args[1]);
3248             endian_convert_tlv_header_out(tlv);
3249             tlv->GroupRekeyTime_sec = uap_cpu_to_le32(tlv->GroupRekeyTime_sec);
3250         }
3251         if (strcmp(args[0], "MaxStaNum") == 0) {
3252             if (is_input_valid(MAXSTANUM, arg_num - 1, args + 1) != UAP_SUCCESS) {
3253                 goto done;
3254             }
3255             TLVBUF_MAX_STA_NUM *tlv = NULL;
3256
3257             /* Append a new TLV */
3258             tlv_len = sizeof(TLVBUF_MAX_STA_NUM);
3259             buffer = realloc(buffer, cmd_len + tlv_len);
3260             if (!buffer) {
3261                 printf("ERR:Cannot realloc max station number TLV!\n");
3262                 goto done;
3263             }
3264             cmd_buf = (APCMDBUF_SYS_CONFIGURE *) buffer;
3265             tlv = (TLVBUF_MAX_STA_NUM *) (buffer + cmd_len);
3266             cmd_len += tlv_len;
3267             /* Set TLV fields */
3268             tlv->Tag = MRVL_MAX_STA_CNT_TLV_ID;
3269             tlv->Length = 2;
3270             tlv->Max_sta_num = (u16) atoi(args[1]);
3271             endian_convert_tlv_header_out(tlv);
3272             tlv->Max_sta_num = uap_cpu_to_le16(tlv->Max_sta_num);
3273         }
3274         if (strcmp(args[0], "Retrylimit") == 0) {
3275             if (is_input_valid(RETRYLIMIT, arg_num - 1, args + 1) !=
3276                 UAP_SUCCESS) {
3277                 goto done;
3278             }
3279             TLVBUF_RETRY_LIMIT *tlv = NULL;
3280
3281             /* Append a new TLV */
3282             tlv_len = sizeof(TLVBUF_RETRY_LIMIT);
3283             buffer = realloc(buffer, cmd_len + tlv_len);
3284             if (!buffer) {
3285                 printf("ERR:Cannot realloc retry limit TLV!\n");
3286                 goto done;
3287             }
3288             cmd_buf = (APCMDBUF_SYS_CONFIGURE *) buffer;
3289             tlv = (TLVBUF_RETRY_LIMIT *) (buffer + cmd_len);
3290             cmd_len += tlv_len;
3291             /* Set TLV fields */
3292             tlv->Tag = MRVL_RETRY_LIMIT_TLV_ID;
3293             tlv->Length = 1;
3294             tlv->retry_limit = (u8) atoi(args[1]);
3295             endian_convert_tlv_header_out(tlv);
3296         }
3297 #if DEBUG
3298         if (cmd_len != 0) {
3299             hexdump("Command Buffer", (void *) cmd_buf, cmd_len, ' ');
3300         }
3301 #endif
3302     }
3303   done:
3304     fclose(config_file);
3305     if (buffer)
3306         free(buffer);
3307     if (line)
3308         free(line);
3309 }
3310
3311 /**
3312  *  @brief Show usage information for the cfg_80211d command
3313  *
3314  *  $return         N/A
3315  */
3316 void
3317 print_apcmd_cfg_80211d_usage(void)
3318 {
3319     printf("\nUsage: cfg_80211d <state 0/1> <country Country_code> \n");
3320     return;
3321 }
3322
3323 /**
3324  *  @brief Show usage information for the uap_stats command
3325  *
3326  *  $return         N/A
3327  */
3328 void
3329 print_apcmd_uap_stats(void)
3330 {
3331     printf("Usage: uap_stats \n");
3332     return;
3333 }
3334
3335 /**
3336  *  SNMP MIB OIDs Table
3337  */
3338 static oids_table snmp_oids[] = {
3339     {0x0b, 4, "dot11LocalTKIPMICFailures"},
3340     {0x0c, 4, "dot11CCMPDecryptErrors"},
3341     {0x0d, 4, "dot11WEPUndecryptableCount"},
3342     {0x0e, 4, "dot11WEPICVErrorCount"},
3343     {0x0f, 4, "dot11DecryptFailureCount"},
3344     {0x12, 4, "dot11FailedCount"},
3345     {0x13, 4, "dot11RetryCount"},
3346     {0x14, 4, "dot11MultipleRetryCount"},
3347     {0x15, 4, "dot11FrameDuplicateCount"},
3348     {0x16, 4, "dot11RTSSuccessCount"},
3349     {0x17, 4, "dot11RTSFailureCount"},
3350     {0x18, 4, "dot11ACKFailureCount"},
3351     {0x19, 4, "dot11ReceivedFragmentCount"},
3352     {0x1a, 4, "dot11MulticastReceivedFrameCount"},
3353     {0x1b, 4, "dot11FCSErrorCount"},
3354     {0x1c, 4, "dot11TransmittedFrameCount"},
3355     {0x1d, 4, "dot11RSNATKIPCounterMeasuresInvoked"},
3356     {0x1e, 4, "dot11RSNA4WayHandshakeFailures"},
3357     {0x1f, 4, "dot11MulticastTransmittedFrameCount"}
3358 };
3359
3360 /** 
3361  *  @brief Get uAP stats
3362  *
3363  *  @param argc     Number of arguments
3364  *  @param argv     Pointer to the arguments
3365  *  
3366  *  @return         NA
3367  */
3368 void
3369 apcmd_uap_stats(int argc, char *argv[])
3370 {
3371     u8 no_of_oids = sizeof(snmp_oids) / sizeof(snmp_oids[0]);
3372     u16 i, j;
3373     int size;
3374     APCMDBUF_SNMP_MIB *cmd_buf = NULL;
3375     u8 *buf = NULL;
3376     TLVBUF_HEADER *tlv = NULL;
3377     u16 cmd_len = 0;
3378     u16 buf_len = 0;
3379     u8 ret;
3380     int opt;
3381     u16 oid_size;
3382
3383     while ((opt = getopt_long(argc, argv, "+", cmd_options, NULL)) != -1) {
3384         switch (opt) {
3385         default:
3386             print_apcmd_uap_stats();
3387             return;
3388         }
3389     }
3390
3391     argc -= optind;
3392     argv += optind;
3393     if (argc) {
3394         printf("Error: Invalid Input\n");
3395         print_apcmd_uap_stats();
3396         return;
3397     }
3398
3399     /**  Command Header */
3400     buf_len += sizeof(APCMDBUF_SNMP_MIB);
3401
3402     for (i = 0; i < no_of_oids; i++) {
3403         /** 
3404          * size of Oid + Oid_value + Oid_size 
3405          */
3406         buf_len += snmp_oids[i].len + sizeof(TLVBUF_HEADER);
3407     }
3408     buf = (u8 *) malloc(buf_len);
3409     if (!buf) {
3410         printf("ERR:Cannot allocate buffer from command!\n");
3411         return;
3412     }
3413     bzero((char *) buf, buf_len);
3414
3415     /* Locate Headers */
3416     cmd_buf = (APCMDBUF_SNMP_MIB *) buf;
3417     cmd_buf->Size = buf_len - BUF_HEADER_SIZE;
3418     cmd_buf->Result = 0;
3419     cmd_buf->SeqNum = 0;
3420     cmd_buf->CmdCode = HostCmd_SNMP_MIB;
3421     cmd_buf->Action = uap_cpu_to_le16(ACTION_GET);
3422
3423     tlv = (TLVBUF_HEADER *) ((u8 *) cmd_buf + sizeof(APCMDBUF_SNMP_MIB));
3424     /* Add oid, oid_size and oid_value for each OID */
3425     for (i = 0; i < no_of_oids; i++) {
3426         /** Copy Index as Oid */
3427         tlv->Type = uap_cpu_to_le16(snmp_oids[i].type);
3428         /** Copy its size */
3429         tlv->Len = uap_cpu_to_le16(snmp_oids[i].len);
3430         /** Next TLV */
3431         tlv = (TLVBUF_HEADER *) & (tlv->Data[snmp_oids[i].len]);
3432     }
3433     cmd_len = buf_len;
3434     ret = uap_ioctl((u8 *) cmd_buf, &cmd_len, buf_len);
3435     if (ret == UAP_SUCCESS) {
3436         if (cmd_buf->Result == CMD_SUCCESS) {
3437             tlv =
3438                 (TLVBUF_HEADER *) ((u8 *) cmd_buf + sizeof(APCMDBUF_SNMP_MIB));
3439
3440             size =
3441                 cmd_buf->Size - (sizeof(APCMDBUF_SNMP_MIB) - BUF_HEADER_SIZE);
3442
3443             while (size >= sizeof(TLVBUF_HEADER)) {
3444                 tlv->Type = uap_le16_to_cpu(tlv->Type);
3445                 for (i = 0; i < no_of_oids; i++) {
3446                     if (snmp_oids[i].type == tlv->Type) {
3447                         printf("%s: ", snmp_oids[i].name);
3448                         break;
3449                     }
3450                 }
3451                 oid_size = uap_le16_to_cpu(tlv->Len);
3452                 switch (oid_size) {
3453                 case 1:
3454                     printf("%d", (unsigned int) tlv->Data[0]);
3455                     break;
3456                 case 2:
3457                     printf("%d",
3458                            (unsigned int) uap_le16_to_cpu(*(u16 *) tlv->Data));
3459                     break;
3460                 case 4:
3461                     printf("%ld",
3462                            (unsigned long) uap_le32_to_cpu(*(u32 *) tlv->Data));
3463                     break;
3464                 default:
3465                     for (j = 0; j < oid_size; j++) {
3466                         printf("%d ", (u8) tlv->Data[i]);
3467                     }
3468                     break;
3469                 }
3470                 /** Next TLV */
3471                 tlv = (TLVBUF_HEADER *) & (tlv->Data[oid_size]);
3472                 size -= (sizeof(TLVBUF_HEADER) + oid_size);
3473                 size = (size > 0) ? size : 0;
3474                 printf("\n");
3475             }
3476
3477         } else {
3478             printf("ERR:Command Response incorrect!\n");
3479         }
3480     } else {
3481         printf("ERR:Command sending failed!\n");
3482     }
3483     free(buf);
3484 }
3485
3486 /**
3487  *  @brief parser for sys_cfg_80211d input 
3488  *
3489  *  @param argc     Number of arguments
3490  *  @param argv     Pointer to the arguments
3491  *  @param output   stores indexes for "state, country"
3492  *                  arguments
3493  *
3494  *  @return         NA
3495  *
3496  */
3497 void
3498 parse_input_80211d(int argc, char **argv, int output[2][2])
3499 {
3500     int i, j, k = 0;
3501     char *keywords[2] = { "state", "country" };
3502
3503     for (i = 0; i < 2; i++)
3504         output[i][0] = -1;
3505
3506     for (i = 0; i < argc; i++) {
3507         for (j = 0; j < 2; j++) {
3508             if (strcmp(argv[i], keywords[j]) == 0) {
3509                 output[j][1] = output[j][0] = i;
3510                 k = j;
3511                 break;
3512             }
3513         }
3514         output[k][1] += 1;
3515     }
3516 }
3517
3518 /**
3519  *  @brief Set/Get 802.11D country information 
3520  *
3521  *  Usage: cfg_80211d state country_code 
3522  *  
3523  *  State 0 or 1
3524  *  
3525  *  @param argc     Number of arguments
3526  *  @param argv     Pointer to the arguments
3527  *  @return         N/A
3528  */
3529 void
3530 apcmd_cfg_80211d(int argc, char *argv[])
3531 {
3532     APCMDBUF_CFG_80211D *cmd_buf = NULL;
3533     IEEEtypes_SubbandSet_t *subband = NULL;
3534     u8 *buf = NULL;
3535     u16 cmd_len;
3536     u16 buf_len;
3537     int output[2][2];
3538     int ret = UAP_FAILURE;
3539     int opt;
3540     int i, j;
3541     u8 state = 0;
3542     char country[4] = { ' ', ' ', 0, 0 };
3543     u8 sflag = 0, cflag = 0;
3544     IEEEtypes_SubbandSet_t sub_bands[MAX_SUB_BANDS];
3545     u8 no_of_sub_band = 0;
3546
3547     while ((opt = getopt_long(argc, argv, "+", cmd_options, NULL)) != -1) {
3548         switch (opt) {
3549         default:
3550             print_apcmd_cfg_80211d_usage();
3551             return;
3552         }
3553     }
3554     argc -= optind;
3555     argv += optind;
3556
3557     if (argc) {
3558         /** SET */
3559         parse_input_80211d(argc, argv, output);
3560
3561         /** state */
3562         if ((output[0][0] != -1) && (output[0][1] > output[0][0])) {
3563             if ((output[0][1] - output[0][0]) != 2) {
3564                 printf("ERR: Invalid state inputs\n");
3565                 print_apcmd_cfg_80211d_usage();
3566                 return;
3567             }
3568
3569             if (IS_HEX_OR_DIGIT(argv[output[0][0] + 1]) == UAP_FAILURE) {
3570                 printf("ERR: valid input for state are 0 or 1\n");
3571                 print_apcmd_cfg_80211d_usage();
3572                 return;
3573             }
3574             state = (u8) A2HEXDECIMAL(argv[output[0][0] + 1]);
3575
3576             if ((state != 0) && (state != 1)) {
3577                 printf("ERR: valid input for state are 0 or 1 \n");
3578                 print_apcmd_cfg_80211d_usage();
3579                 return;
3580             }
3581             sflag = 1;
3582         }
3583
3584         /** country */
3585         if ((output[1][0] != -1) && (output[1][1] > output[1][0])) {
3586             if ((output[1][1] - output[1][0]) > 2) {
3587                 printf("ERR: Invalid country inputs\n");
3588                 print_apcmd_cfg_80211d_usage();
3589                 return;
3590             }
3591             if ((strlen(argv[output[1][0] + 1]) > 3) ||
3592                 (strlen(argv[output[1][0] + 1]) < 0)) {
3593                 print_apcmd_cfg_80211d_usage();
3594                 return;
3595             }
3596
3597             strcpy(country, argv[output[1][0] + 1]);
3598
3599             for (i = 0; i < strlen(country); i++) {
3600                 if ((country[i] < 'A') || (country[i] > 'z')) {
3601                     printf("Invalid Country Code\n");
3602                     print_apcmd_cfg_80211d_usage();
3603                     return;
3604                 }
3605                 if (country[i] > 'Z')
3606                     country[i] = country[i] - 'a' + 'A';
3607             }
3608
3609             cflag = 1;
3610
3611            /** Get domain information from the file */
3612             no_of_sub_band = parse_domain_file(country, sub_bands);
3613             if (no_of_sub_band == UAP_FAILURE) {
3614                 printf("Parsing Failed\n");
3615                 return;
3616             }
3617         }
3618     }
3619
3620     if (argc && !cflag && !sflag) {
3621         printf("ERR: Invalid input\n");
3622         print_apcmd_cfg_80211d_usage();
3623         return;
3624     }
3625
3626     if (sflag && !cflag) {
3627         /**
3628          * Update MIB only and return
3629          */
3630         if (sg_snmp_mib(ACTION_SET, OID_80211D_ENABLE, sizeof(state), &state) ==
3631             UAP_SUCCESS) {
3632             printf("802.11d %sd \n", state ? "enable" : "disable");
3633         }
3634         return;
3635     }
3636
3637     buf_len = sizeof(APCMDBUF_CFG_80211D);
3638
3639     if (cflag) {
3640         buf_len += no_of_sub_band * sizeof(IEEEtypes_SubbandSet_t);
3641     } else { /** Get */
3642         buf_len += MAX_SUB_BANDS * sizeof(IEEEtypes_SubbandSet_t);
3643     }
3644
3645     buf = (u8 *) malloc(buf_len);
3646     if (!buf) {
3647         printf("ERR:Cannot allocate buffer from command!\n");
3648         return;
3649     }
3650     bzero((char *) buf, buf_len);
3651     /* Locate headers */
3652     cmd_buf = (APCMDBUF_CFG_80211D *) buf;
3653     cmd_len = argc ? buf_len :
3654                  /** set */
3655         (sizeof(APCMDBUF_CFG_80211D) - sizeof(domain_param_t)); /** Get */
3656
3657     cmd_buf->Size = cmd_len - BUF_HEADER_SIZE;
3658     cmd_buf->Result = 0;
3659     cmd_buf->SeqNum = 0;
3660     cmd_buf->Action = argc ? ACTION_SET : ACTION_GET;
3661     cmd_buf->Action = uap_cpu_to_le16(cmd_buf->Action);
3662     cmd_buf->CmdCode = HostCmd_CMD_802_11D_DOMAIN_INFO;
3663
3664     if (cflag) {
3665         cmd_buf->Domain.Tag = uap_cpu_to_le16(TLV_TYPE_DOMAIN);
3666         cmd_buf->Domain.Length = uap_cpu_to_le16(sizeof(domain_param_t)
3667                                                  - BUF_HEADER_SIZE
3668                                                  +
3669                                                  (no_of_sub_band *
3670                                                   sizeof
3671                                                   (IEEEtypes_SubbandSet_t)));
3672
3673         memset(cmd_buf->Domain.CountryCode, ' ',
3674                sizeof(cmd_buf->Domain.CountryCode));
3675         memcpy(cmd_buf->Domain.CountryCode, country, strlen(country));
3676         memcpy(cmd_buf->Domain.Subband, sub_bands,
3677                no_of_sub_band * sizeof(IEEEtypes_SubbandSet_t));
3678     }
3679
3680     /* Send the command */
3681     ret = uap_ioctl((u8 *) cmd_buf, &cmd_len, buf_len);
3682     if (ret == UAP_SUCCESS) {
3683         if (cmd_buf->Result == CMD_SUCCESS) {
3684             if (argc) {
3685                 printf("Set executed successfully\n");
3686                 if (sflag) {
3687                     if (sg_snmp_mib
3688                         (ACTION_SET, OID_80211D_ENABLE, sizeof(state),
3689                          &state) == UAP_SUCCESS) {
3690                         printf("802.11d %sd \n", state ? "enable" : "disable");
3691                     }
3692                 }
3693             } else {
3694                 j = uap_le16_to_cpu(cmd_buf->Domain.Length);
3695                 if (sg_snmp_mib
3696                     (ACTION_GET, OID_80211D_ENABLE, sizeof(state), &state)
3697                     == UAP_SUCCESS) {
3698                     printf("State = %sd\n", state ? "enable" : "disable");
3699                 }
3700
3701                 if (!(cmd_buf->Domain.CountryCode[0] |
3702                       cmd_buf->Domain.CountryCode[1] |
3703                       cmd_buf->Domain.CountryCode[2])) {
3704                     printf("Dot11d = country code is not set.\n");
3705                 } else {
3706                     printf("Country string = %c%c%c",
3707                            cmd_buf->Domain.CountryCode[0],
3708                            cmd_buf->Domain.CountryCode[1],
3709                            cmd_buf->Domain.CountryCode[2]);
3710                     j -= sizeof(cmd_buf->Domain.CountryCode);
3711                     subband =
3712                         (IEEEtypes_SubbandSet_t *) cmd_buf->Domain.Subband;
3713                     printf("\nSub-band info=");
3714                     // printf("\n\t\t(First Channel, Number of Channels,
3715                     // Maximum TX Power) \n"); 
3716                     printf("\t(1st, #chan, MAX-power) \n");
3717                     for (i = 0; i < (j / 3); i++) {
3718                         printf("\t\t(%d, \t%d, \t%d dbm)\n", subband->FirstChan,
3719                                subband->NoOfChan, subband->MaxTxPwr);
3720                         subband++;
3721                     }
3722                 }
3723             }
3724         } else {
3725             printf("ERR:Command Response incorrect!\n");
3726         }
3727     } else {
3728         printf("ERR:Command sending failed!\n");
3729     }
3730     free(buf);
3731     return;
3732 }
3733
3734 /** 
3735  *  @brief Creates a sys_config request and sends to the driver
3736  *
3737  *  Usage: "Usage : sys_config [CONFIG_FILE]"
3738  *
3739  *  @param argc     Number of arguments
3740  *  @param argv     Pointer to the arguments
3741  *  @return         UAP_SUCCESS or UAP_FAILURE
3742  */
3743 void
3744 apcmd_sys_config(int argc, char *argv[])
3745 {
3746     APCMDBUF_SYS_CONFIGURE *cmd_buf = NULL;
3747     u8 *buf = NULL;
3748     u16 cmd_len;
3749     u16 buf_len;
3750     int ret = UAP_FAILURE;
3751     int opt;
3752     char **argv_dummy;
3753     ps_mgmt pm;
3754
3755     while ((opt = getopt_long(argc, argv, "+", cmd_options, NULL)) != -1) {
3756         switch (opt) {
3757         default:
3758             print_sys_config_usage();
3759             return;
3760         }
3761     }
3762     argc -= optind;
3763     argv += optind;
3764
3765     /* Check arguments */
3766     if (argc > 1) {
3767         printf("ERR:Too many arguments.\n");
3768         print_sys_config_usage();
3769         return;
3770     }
3771     if (argc == 1) {
3772         /* Read profile and send command to firmware */
3773         apcmd_sys_config_profile(argc, argv);
3774         return;
3775     }
3776
3777         /** Query AP's setting */
3778     buf_len = MRVDRV_SIZE_OF_CMD_BUFFER;
3779
3780     /* alloc buf for command */
3781     buf = (u8 *) malloc(buf_len);
3782
3783     if (!buf) {
3784         printf("ERR:Cannot allocate buffer from command!\n");
3785         return;
3786     }
3787     bzero((char *) buf, buf_len);
3788
3789     /* Locate headers */
3790     cmd_len = sizeof(APCMDBUF_SYS_CONFIGURE);
3791     cmd_buf = (APCMDBUF_SYS_CONFIGURE *) buf;
3792
3793     /* Fill the command buffer */
3794     cmd_buf->CmdCode = APCMD_SYS_CONFIGURE;
3795     cmd_buf->Size = cmd_len - BUF_HEADER_SIZE;
3796     cmd_buf->SeqNum = 0;
3797     cmd_buf->Result = 0;
3798
3799     /* Send the command */
3800     ret = uap_ioctl((u8 *) cmd_buf, &cmd_len, buf_len);
3801
3802     /* Process response */
3803     if (ret == UAP_SUCCESS) {
3804         /* Verify response */
3805         if (cmd_buf->CmdCode != (APCMD_SYS_CONFIGURE | APCMD_RESP_CHECK)) {
3806             printf("ERR:Corrupted response!\n");
3807             free(buf);
3808             return;
3809         }
3810         /* Print response */
3811         if (cmd_buf->Result == CMD_SUCCESS) {
3812             printf("AP settings:\n");
3813             print_tlv(buf + sizeof(APCMDBUF_SYS_CONFIGURE),
3814                       cmd_buf->Size - sizeof(APCMDBUF_SYS_CONFIGURE) +
3815                       BUF_HEADER_SIZE);
3816             printf("\n802.11D setting:\n");
3817             apcmd_cfg_80211d(1, argv_dummy);
3818         } else {
3819             printf("ERR:Could not retrieve system configure\n");
3820         }
3821     } else {
3822         printf("ERR:Command sending failed!\n");
3823     }
3824     free(buf);
3825     memset(&pm, 0, sizeof(ps_mgmt));
3826     send_power_mode_ioctl(&pm);
3827     return;
3828 }
3829
3830 /** 
3831  *  @brief Send read/write command along with register details to the driver
3832  *  @param reg      reg type
3833  *  @param offset   pointer to register offset string
3834  *  @param strvalue pointer to value string
3835  *  @return         UAP_SUCCESS or UAP_FAILURE
3836  */
3837 int
3838 apcmd_regrdwr_process(int reg, s8 * offset, s8 * strvalue)
3839 {
3840     APCMDBUF_REG_RDWR *cmd_buf = NULL;
3841     u8 *buf = NULL;
3842     u16 cmd_len;
3843     u16 buf_len;
3844     int ret = UAP_FAILURE;
3845     s8 *whichreg;
3846
3847     buf_len = sizeof(APCMDBUF_REG_RDWR);
3848
3849     /* alloc buf for command */
3850     buf = (u8 *) malloc(buf_len);
3851
3852     if (!buf) {
3853         printf("ERR:Cannot allocate buffer from command!\n");
3854         return UAP_FAILURE;
3855     }
3856     bzero((char *) buf, buf_len);
3857
3858     /* Locate headers */
3859     cmd_len = sizeof(APCMDBUF_REG_RDWR);
3860     cmd_buf = (APCMDBUF_REG_RDWR *) buf;
3861
3862     /* Fill the command buffer */
3863     cmd_buf->Size = cmd_len - BUF_HEADER_SIZE;
3864     cmd_buf->SeqNum = 0;
3865     cmd_buf->Result = 0;
3866
3867     switch (reg) {
3868     case CMD_MAC:
3869         whichreg = "MAC";
3870         cmd_buf->CmdCode = HostCmd_CMD_MAC_REG_ACCESS;
3871         break;
3872     case CMD_BBP:
3873         whichreg = "BBP";
3874         cmd_buf->CmdCode = HostCmd_CMD_BBP_REG_ACCESS;
3875         break;
3876     case CMD_RF:
3877         cmd_buf->CmdCode = HostCmd_CMD_RF_REG_ACCESS;
3878         whichreg = "RF";
3879         break;
3880     default:
3881         printf("Invalid register set specified.\n");
3882         free(buf);
3883         return UAP_FAILURE;
3884     }
3885     if (strvalue) {
3886         cmd_buf->Action = 1;    // WRITE
3887     } else {
3888         cmd_buf->Action = 0;    // READ
3889     }
3890     cmd_buf->Action = uap_cpu_to_le16(cmd_buf->Action);
3891     cmd_buf->Offset = A2HEXDECIMAL(offset);
3892     cmd_buf->Offset = uap_cpu_to_le16(cmd_buf->Offset);
3893     if (strvalue) {
3894         cmd_buf->Value = A2HEXDECIMAL(strvalue);
3895         cmd_buf->Value = uap_cpu_to_le32(cmd_buf->Value);
3896     }
3897
3898     /* Send the command */
3899     ret = uap_ioctl((u8 *) cmd_buf, &cmd_len, buf_len);
3900
3901     /* Process response */
3902     if (ret == UAP_SUCCESS) {
3903         if (cmd_buf->Result == CMD_SUCCESS) {
3904             printf("Successfully executed the command\n");
3905             printf("%s[0x%04hx] = 0x%08lx\n",
3906                    whichreg, uap_le16_to_cpu(cmd_buf->Offset),
3907                    uap_le32_to_cpu(cmd_buf->Value));
3908         } else {
3909             printf("ERR:Command sending failed!\n");
3910             free(buf);
3911             return UAP_FAILURE;
3912         }
3913     } else {
3914         printf("ERR:Command sending failed!\n");
3915         free(buf);
3916         return UAP_FAILURE;
3917     }
3918
3919     free(buf);
3920     return UAP_SUCCESS;
3921 }
3922
3923 /**
3924  *  @brief Send read command for EEPROM 
3925  *
3926  *  Usage: "Usage : rdeeprom <offset> <byteCount>"
3927  *
3928  *  @param argc     Number of arguments
3929  *  @param argv     Pointer to the arguments
3930  *  @return         N/A
3931  */
3932 void
3933 apcmd_read_eeprom(int argc, char *argv[])
3934 {
3935     APCMDBUF_EEPROM_ACCESS *cmd_buf = NULL;
3936     u8 *buf = NULL;
3937     u16 cmd_len;
3938     u16 buf_len;
3939     u16 byteCount, offset;
3940     int ret = UAP_FAILURE;
3941     int opt;
3942     while ((opt = getopt_long(argc, argv, "+", cmd_options, NULL)) != -1) {
3943         switch (opt) {
3944         default:
3945             print_apcmd_read_eeprom_usage();
3946             return;
3947         }
3948     }
3949     argc -= optind;
3950     argv += optind;
3951
3952     /* Check arguments */
3953     if (!argc || (argc && is_input_valid(RDEEPROM, argc, argv) != UAP_SUCCESS)) {
3954         print_apcmd_read_eeprom_usage();
3955         return;
3956     }
3957     offset = A2HEXDECIMAL(argv[0]);
3958     byteCount = A2HEXDECIMAL(argv[1]);
3959
3960     buf_len = sizeof(APCMDBUF_EEPROM_ACCESS) + MAX_EEPROM_LEN;
3961     buf = (u8 *) malloc(buf_len);
3962     if (!buf) {
3963         printf("ERR:Cannot allocate buffer from command!\n");
3964         return;
3965     }
3966     bzero((char *) buf, buf_len);
3967
3968     /* Locate headers */
3969     cmd_buf = (APCMDBUF_EEPROM_ACCESS *) buf;
3970     cmd_len = sizeof(APCMDBUF_EEPROM_ACCESS);
3971
3972     cmd_buf->Size = sizeof(APCMDBUF_EEPROM_ACCESS) - BUF_HEADER_SIZE;
3973     cmd_buf->Result = 0;
3974     cmd_buf->SeqNum = 0;
3975     cmd_buf->Action = 0;
3976
3977     cmd_buf->CmdCode = HostCmd_EEPROM_ACCESS;
3978     cmd_buf->Offset = uap_cpu_to_le16(offset);
3979     cmd_buf->ByteCount = uap_cpu_to_le16(byteCount);
3980
3981     /* Send the command */
3982     ret = uap_ioctl((u8 *) cmd_buf, &cmd_len, buf_len);
3983
3984     /* Process response */
3985     if (ret == UAP_SUCCESS) {
3986         if (cmd_buf->Result == CMD_SUCCESS) {
3987             printf("Successfully executed the command\n");
3988             byteCount = uap_le16_to_cpu(cmd_buf->ByteCount);
3989             offset = uap_le16_to_cpu(cmd_buf->Offset);
3990             hexdump_data("EEPROM", (void *) cmd_buf->Value, byteCount, ' ');
3991         } else {
3992             printf("ERR:Command Response incorrect!\n");
3993         }
3994     } else {
3995         printf("ERR:Command sending failed!\n");
3996     }
3997
3998     free(buf);
3999     return;
4000 }
4001
4002 /**
4003  *  @brief Show usage information for the regrdwr command
4004  *  command
4005  *
4006  *  $return         N/A
4007  */
4008 void
4009 print_regrdwr_usage(void)
4010 {
4011     printf("\nUsage : uaputl.exe regrdwr <TYPE> <OFFSET> [value]\n");
4012     printf("\nTYPE Options: 0     - read/write MAC register");
4013     printf("\n              1     - read/write BBP register");
4014     printf("\n              2     - read/write RF register");
4015     printf("\n");
4016     return;
4017
4018 }
4019
4020 /** 
4021  *  @brief Provides interface to perform read/write operations on regsiters
4022  *  @param argc     Number of arguments
4023  *  @param argv     Pointer to the arguments
4024  *  @return         N/A
4025  */
4026 void
4027 apcmd_regrdwr(int argc, char *argv[])
4028 {
4029     int opt;
4030     s32 reg;
4031     while ((opt = getopt_long(argc, argv, "+", cmd_options, NULL)) != -1) {
4032         switch (opt) {
4033         default:
4034             print_regrdwr_usage();
4035             return;
4036         }
4037     }
4038     argc -= optind;
4039     argv += optind;
4040
4041     /* Check arguments */
4042     if ((argc < 2) || (argc > 3)) {
4043         printf("ERR:wrong arguments.\n");
4044         print_regrdwr_usage();
4045         return;
4046     }
4047     if ((atoi(argv[0]) != 0) && (atoi(argv[0]) != 1) && (atoi(argv[0]) != 2)) {
4048         printf("ERR:Illegal register type %s. Must be either '0','1' or '2'.\n",
4049                argv[0]);
4050         print_regrdwr_usage();
4051         return;
4052     }
4053     reg = atoi(argv[0]);
4054     apcmd_regrdwr_process(reg, argv[1], argc > 2 ? argv[2] : NULL);
4055     return;
4056 }
4057
4058 /**
4059  *    @brief Show usage information for the memaccess command
4060  *    command
4061  *    
4062  *    $return         N/A
4063  */
4064 void
4065 print_memaccess_usage(void)
4066 {
4067     printf("\nUsage : uaputl.exe memaccess <ADDRESS> [value]\n");
4068     printf("\nRead/Write memory location");
4069     printf("\nADDRESS: Address of the memory location to be read/written");
4070     printf("\nValue  : Value to be written at that address\n");
4071     return;
4072 }
4073
4074 /** 
4075  *  @brief Provides interface to perform read/write memory location
4076  *  @param argc     Number of arguments
4077  *  @param argv     Pointer to the arguments
4078  *  @return         N/A
4079  */
4080 void
4081 apcmd_memaccess(int argc, char *argv[])
4082 {
4083     int opt;
4084     APCMDBUF_MEM_ACCESS *cmd_buf = NULL;
4085     u8 *buf = NULL;
4086     u16 cmd_len;
4087     u16 buf_len;
4088     int ret = UAP_FAILURE;
4089     s8 *address = NULL;
4090     s8 *value = NULL;
4091
4092     while ((opt = getopt_long(argc, argv, "+", cmd_options, NULL)) != -1) {
4093         switch (opt) {
4094         default:
4095             print_memaccess_usage();
4096             return;
4097         }
4098     }
4099     argc -= optind;
4100     argv += optind;
4101
4102     /* Check arguments */
4103     if ((argc < 1) || (argc > 2)) {
4104         printf("ERR:wrong arguments.\n");
4105         print_memaccess_usage();
4106         return;
4107     }
4108
4109     address = argv[0];
4110     if (argc == 2)
4111         value = argv[1];
4112
4113     buf_len = sizeof(APCMDBUF_MEM_ACCESS);
4114
4115     /* alloc buf for command */
4116     buf = (u8 *) malloc(buf_len);
4117
4118     if (!buf) {
4119         printf("ERR:Cannot allocate buffer from command!\n");
4120         return;
4121     }
4122     bzero((char *) buf, buf_len);
4123     /* Locate headers */
4124     cmd_len = sizeof(APCMDBUF_MEM_ACCESS);
4125     cmd_buf = (APCMDBUF_MEM_ACCESS *) buf;
4126
4127     /* Fill the command buffer */
4128     cmd_buf->Size = cmd_len - BUF_HEADER_SIZE;
4129     cmd_buf->SeqNum = 0;
4130     cmd_buf->Result = 0;
4131     cmd_buf->CmdCode = HostCmd_CMD_MEM_ACCESS;
4132
4133     if (value)
4134         cmd_buf->Action = 1;    // WRITE
4135     else
4136         cmd_buf->Action = 0;    // READ
4137
4138     cmd_buf->Action = uap_cpu_to_le16(cmd_buf->Action);
4139     cmd_buf->Address = A2HEXDECIMAL(address);
4140     cmd_buf->Address = uap_cpu_to_le32(cmd_buf->Address);
4141
4142     if (value) {
4143         cmd_buf->Value = A2HEXDECIMAL(value);
4144         cmd_buf->Value = uap_cpu_to_le32(cmd_buf->Value);
4145     }
4146
4147     /* Send the command */
4148     ret = uap_ioctl((u8 *) cmd_buf, &cmd_len, buf_len);
4149
4150     /* Process response */
4151     if (ret == UAP_SUCCESS) {
4152         if (cmd_buf->Result == CMD_SUCCESS) {
4153             printf("Successfully executed the command\n");
4154             printf("[0x%04lx] = 0x%08lx\n",
4155                    uap_le32_to_cpu(cmd_buf->Address),
4156                    uap_le32_to_cpu(cmd_buf->Value));
4157         } else {
4158             printf("ERR:Command sending failed!\n");
4159             free(buf);
4160             return;
4161         }
4162     } else {
4163         printf("ERR:Command sending failed!\n");
4164         free(buf);
4165         return;
4166     }
4167     free(buf);
4168     return;
4169 }
4170
4171 /**
4172  *    @brief Show usage information for sys_debug command
4173  *    command
4174  *    
4175  *    $return         N/A
4176  */
4177 void
4178 print_sys_debug_usage(void)
4179 {
4180     printf("\nUsage : uaputl.exe sys_debug <subcmd> [parameter]\n");
4181     printf("\nSet/Get debug parameter");
4182     printf("\nsubcmd: used to set/get debug parameters or set user scan");
4183     printf("\nparameter  :  parameters for specific subcmd");
4184     printf("\n          If no [parameter] are given, it return");
4185     printf("\n          debug parameters for selected subcmd");
4186     printf("\n\n");
4187     return;
4188 }
4189
4190 /** 
4191  *  @brief Creates a sys_debug request and sends to the driver
4192  *  @param argc     Number of arguments
4193  *  @param argv     Pointer to the arguments
4194  *  @return         N/A
4195  */
4196 void
4197 apcmd_sys_debug(int argc, char *argv[])
4198 {
4199     APCMDBUF_SYS_DEBUG *cmd_buf = NULL;
4200     u8 *buffer = NULL;
4201     u16 cmd_len;
4202     u16 buf_len;
4203     u32 subcmd = 0;
4204     int ret = UAP_FAILURE;
4205     int opt;
4206     s8 *value = NULL;
4207     u32 parameter = 0;
4208     while ((opt = getopt_long(argc, argv, "+", cmd_options, NULL)) != -1) {
4209         switch (opt) {
4210         default:
4211             print_sys_debug_usage();
4212             return;
4213         }
4214     }
4215     argc -= optind;
4216     argv += optind;
4217     /* Check arguments */
4218     if ((argc == 0) || (argc > 2)) {
4219         printf("ERR:wrong arguments.\n");
4220         print_sys_debug_usage();
4221         return;
4222     } else {
4223         if (argc == 2) {
4224             value = argv[1];
4225             parameter = A2HEXDECIMAL(value);
4226         }
4227     }
4228     subcmd = atoi(argv[0]);
4229     /* Initialize the command length */
4230     if (subcmd == DEBUG_SUBCOMMAND_CHANNEL_SCAN) {
4231         buf_len =
4232             sizeof(APCMDBUF_SYS_DEBUG) +
4233             MAX_CHANNELS * sizeof(CHANNEL_SCAN_ENTRY_T);
4234         cmd_len = sizeof(APCMDBUF_SYS_DEBUG) - sizeof(debugConfig_t);
4235     } else {
4236         cmd_len = sizeof(APCMDBUF_SYS_DEBUG);
4237         buf_len = cmd_len;
4238     }
4239
4240     /* Initialize the command buffer */
4241     buffer = (u8 *) malloc(buf_len);
4242     if (!buffer) {
4243         printf("ERR:Cannot allocate buffer for command!\n");
4244         return;
4245     }
4246     bzero((char *) buffer, buf_len);
4247
4248     /* Locate headers */
4249     cmd_buf = (APCMDBUF_SYS_DEBUG *) buffer;
4250
4251     /* Fill the command buffer */
4252     cmd_buf->CmdCode = APCMD_SYS_DEBUG;
4253     cmd_buf->Size = cmd_len - BUF_HEADER_SIZE;
4254     cmd_buf->SeqNum = 0;
4255     cmd_buf->Result = 0;
4256     cmd_buf->subcmd = subcmd;
4257     if (subcmd == DEBUG_SUBCOMMAND_CHANNEL_SCAN) {
4258         cmd_buf->Action = ACTION_SET;
4259     } else {
4260         if (argc == 1) {
4261             cmd_buf->Action = ACTION_GET;
4262         } else {
4263             cmd_buf->Action = ACTION_SET;
4264             if (subcmd == DEBUG_SUBCOMMAND_GMODE)
4265                 cmd_buf->debugConfig.globalDebugMode = (u8) parameter;
4266             else if (subcmd == DEBUG_SUBCOMMAND_MAJOREVTMASK) {
4267                 cmd_buf->debugConfig.debugMajorIdMask = parameter;
4268                 cmd_buf->debugConfig.debugMajorIdMask =
4269                     uap_cpu_to_le32(cmd_buf->debugConfig.debugMajorIdMask);
4270             } else {
4271                 cmd_buf->debugConfig.value = uap_cpu_to_le32(parameter);
4272             }
4273         }
4274     }
4275     cmd_buf->Action = uap_cpu_to_le16(cmd_buf->Action);
4276     cmd_buf->subcmd = uap_cpu_to_le32(cmd_buf->subcmd);
4277
4278     /* Send the command */
4279     ret = uap_ioctl((u8 *) cmd_buf, &cmd_len, buf_len);
4280
4281     /* Process response */
4282     if (ret == UAP_SUCCESS) {
4283         /* Verify response */
4284         if (cmd_buf->CmdCode != (APCMD_SYS_DEBUG | APCMD_RESP_CHECK)) {
4285             printf("ERR:Corrupted response! CmdCode=%x\n", cmd_buf->CmdCode);
4286             free(buffer);
4287             return;
4288         }
4289         /* Print response */
4290         if (cmd_buf->Result == CMD_SUCCESS) {
4291             if (subcmd == DEBUG_SUBCOMMAND_CHANNEL_SCAN) {
4292                 int i = 0;
4293                 CHANNEL_SCAN_ENTRY_T *cst = NULL;
4294                 if (cmd_buf->Size <
4295                     (sizeof(APCMDBUF_SYS_DEBUG) - BUF_HEADER_SIZE)) {
4296                     printf
4297                         ("ERR: Invalid command response size, cmd_buf->Size = %x\n",
4298                          cmd_buf->Size);
4299                     free(buffer);
4300                     return;
4301                 }
4302                 for (i = 0; i < cmd_buf->debugConfig.cs_entry.numChannels; i++) {
4303                     if (i == 0) {
4304                         printf
4305                             ("\n------------------------------------------------------");
4306                         printf("\nChan\tNumAPs\tCCA_Count\tDuration\tWeight");
4307                         printf
4308                             ("\n------------------------------------------------------");
4309                         cst = cmd_buf->debugConfig.cs_entry.cst;
4310                     }
4311                     printf("\n%d\t%d\t%ld\t\t%ld\t\t%ld", cst->chan_num,
4312                            cst->num_of_aps,
4313                            cst->CCA_count, cst->duration, cst->channel_weight);
4314                     cst++;
4315                 }
4316                 printf
4317                     ("\n------------------------------------------------------\n");
4318             } else {
4319                 if (argc == 1) {
4320                     if (subcmd == DEBUG_SUBCOMMAND_GMODE) {
4321                         printf("globalDebugmode=%d\n",
4322                                cmd_buf->debugConfig.globalDebugMode);
4323                     } else if (subcmd == DEBUG_SUBCOMMAND_MAJOREVTMASK) {
4324                         printf("MajorId mask=0x%08lx\n",
4325                                uap_le32_to_cpu(cmd_buf->debugConfig.
4326                                                debugMajorIdMask));
4327                     } else {
4328                         printf("Value = %ld\n",
4329                                uap_le32_to_cpu(cmd_buf->debugConfig.value));
4330                     }
4331                 } else {
4332                     printf("set debug parameter successful\n");
4333                 }
4334             }
4335         } else {
4336             if (argc == 1) {
4337                 printf("ERR:Could not get debug parameter!\n");
4338             } else {
4339                 printf("ERR:Could not set debug parameter!\n");
4340             }
4341         }
4342     } else {
4343         printf("ERR:Command sending failed!\n");
4344     }
4345     if (buffer)
4346         free(buffer);
4347     return;
4348 }
4349
4350 /** structure of command table*/
4351 typedef struct
4352 {
4353     /** command name */
4354     char *cmd;
4355     /** command function pointer */
4356     void (*func) (int argc, char *argv[]);
4357     /**command usuage */
4358     char *help;
4359 } command_table;
4360
4361 /** ap command table */
4362 static command_table ap_command[] = {
4363     {"sys_config", apcmd_sys_config, "\tSet/get uAP's profile"},
4364     {"sys_info", apcmd_sys_info, "\tDisplay system info"},
4365     {"sys_reset", apcmd_sys_reset, "\tReset uAP"},
4366     {"bss_start", apcmd_bss_start, "\tStart the BSS"},
4367     {"bss_stop", apcmd_bss_stop, "\tStop the BSS"},
4368     {"sta_deauth", apcmd_sta_deauth, "\tDeauth client"},
4369     {"sta_list", apcmd_sta_list, "\tDisplay list of clients"},
4370     {"sys_cfg_ap_mac_address", apcmd_sys_cfg_ap_mac_address,
4371      "Set/get uAP mac address"},
4372     {"sys_cfg_ssid", apcmd_sys_cfg_ssid, "\tSet/get uAP ssid"},
4373     {"sys_cfg_beacon_period", apcmd_sys_cfg_beacon_period,
4374      "Set/get uAP beacon period"},
4375     {"sys_cfg_dtim_period", apcmd_sys_cfg_dtim_period,
4376      "Set/get uAP dtim period"},
4377     {"sys_cfg_channel", apcmd_sys_cfg_channel, "\tSet/get uAP radio channel"},
4378     {"sys_cfg_scan_channels", apcmd_sys_cfg_scan_channels,
4379      "Set/get uAP radio channel list"},
4380     {"sys_cfg_rates", apcmd_sys_cfg_rates, "\tSet/get uAP rates"},
4381     {"sys_cfg_rates_ext", apcmd_sys_cfg_rates_ext,
4382      "Set/get uAP rates (extended)"},
4383     {"sys_cfg_tx_power", apcmd_sys_cfg_tx_power, "Set/get uAP tx power"},
4384     {"sys_cfg_bcast_ssid_ctl", apcmd_sys_cfg_bcast_ssid_ctl,
4385      "Set/get uAP broadcast ssid"},
4386     {"sys_cfg_preamble_ctl", apcmd_sys_cfg_preamble_ctl, "Get uAP preamble"},
4387     {"sys_cfg_antenna_ctl", apcmd_sys_cfg_antenna_ctl,
4388      "Set/get uAP tx/rx antenna"},
4389     {"sys_cfg_rts_threshold", apcmd_sys_cfg_rts_threshold,
4390      "Set/get uAP rts threshold"},
4391     {"sys_cfg_frag_threshold", apcmd_sys_cfg_frag_threshold,
4392      "Set/get uAP frag threshold"},
4393     {"sys_cfg_radio_ctl", apcmd_sys_cfg_radio_ctl, "Set/get uAP radio on/off"},
4394     {"sys_cfg_tx_data_rate", apcmd_sys_cfg_tx_data_rate, "Set/get uAP tx rate"},
4395     {"sys_cfg_mcbc_data_rate", apcmd_sys_cfg_mcbc_data_rate,
4396      "Set/get uAP MCBC rate"},
4397     {"sys_cfg_rsn_replay_prot", apcmd_sys_cfg_rsn_replay_prot,
4398      "Set/get RSN replay protection"},
4399     {"sys_cfg_pkt_fwd_ctl", apcmd_sys_cfg_pkt_fwd_ctl,
4400      "Set/get uAP packet forwarding"},
4401     {"sys_cfg_sta_ageout_timer", apcmd_sys_cfg_sta_ageout_timer,
4402      "Set/get station ageout timer"},
4403     {"sys_cfg_auth", apcmd_sys_cfg_auth, "\tSet/get uAP authentication mode"},
4404     {"sys_cfg_protocol", apcmd_sys_cfg_protocol,
4405      "Set/get uAP security protocol"},
4406     {"sys_cfg_wep_key", apcmd_sys_cfg_wep_key, "\tSet/get uAP wep key"},
4407     {"sys_cfg_cipher", apcmd_sys_cfg_cipher, "\tSet/get uAP WPA/WPA cipher"},
4408     {"sys_cfg_wpa_passphrase", apcmd_sys_cfg_wpa_passphrase,
4409      "Set/get uAP WPA or WPA2 passphrase"},
4410     {"sys_cfg_group_rekey_timer", apcmd_sys_cfg_group_rekey_timer,
4411      "Set/get uAP group re-key time"},
4412     {"sys_cfg_max_sta_num", apcmd_sys_cfg_max_sta_num,
4413      "Set/get uAP max station number"},
4414     {"sys_cfg_retry_limit", apcmd_sys_cfg_retry_limit,
4415      "Set/get uAP retry limit number"},
4416     {"sys_cfg_custom_ie", apcmd_sys_cfg_custom_ie,
4417      "\tSet/get custom IE configuration"},
4418     {"sta_filter_table", apcmd_sta_filter_table, "Set/get uAP mac filter"},
4419     {"regrdwr", apcmd_regrdwr, "\t\tRead/Write register command"},
4420     {"memaccess", apcmd_memaccess, "\tRead/Write to a memory address command"},
4421     {"rdeeprom", apcmd_read_eeprom, "\tRead EEPROM "},
4422     {"cfg_data", apcmd_cfg_data,
4423      "\tGet/Set configuration file from/to firmware"},
4424     {"sys_debug", apcmd_sys_debug, "\tSet/Get debug parameter"},
4425     {"sys_cfg_80211d", apcmd_cfg_80211d, "\tSet/Get 802.11D info"},
4426     {"uap_stats", apcmd_uap_stats, "\tGet uAP stats"},
4427     {"powermode", apcmd_power_mode, "\tSet/get uAP power mode"},
4428     {"coex_config", apcmd_coex_config, "\tSet/get uAP BT coex configuration"},
4429     {NULL, NULL, 0}
4430 };
4431
4432 /** 
4433  *  @brief Prints usage information of uaputl
4434  *
4435  *  @return          N/A
4436  */
4437 static void
4438 print_tool_usage(void)
4439 {
4440     int i;
4441     printf("uaputl.exe - uAP utility ver %s\n", UAP_VERSION);
4442     printf("Usage:\n"
4443            "\tuaputl.exe [options] <command> [command parameters]\n");
4444     printf("Options:\n"
4445            "\t--help\tDisplay help\n"
4446            "\t-v\tDisplay version\n"
4447            "\t-i <interface>\n" "\t-d <debug_level=0|1|2>\n");
4448     printf("Commands:\n");
4449     for (i = 0; ap_command[i].cmd; i++)
4450         printf("\t%-4s\t\t%s\n", ap_command[i].cmd, ap_command[i].help);
4451     printf("\n"
4452            "For more information on the usage of each command use:\n"
4453            "\tuaputl.exe <command> --help\n");
4454 }
4455
4456 /****************************************************************************
4457         Global functions
4458 ****************************************************************************/
4459 /** option parameter*/
4460 static struct option ap_options[] = {
4461     {"help", 0, NULL, 'h'},
4462     {"interface", 1, NULL, 'i'},
4463     {"debug", 1, NULL, 'd'},
4464     {"version", 0, NULL, 'v'},
4465     {NULL, 0, NULL, '\0'}
4466 };
4467
4468 /**
4469  *    @brief isdigit for String.
4470  *   
4471  *    @param x            char string
4472  *    @return             UAP_FAILURE for non-digit.
4473  *                        UAP_SUCCESS for digit
4474  */
4475 inline int
4476 ISDIGIT(char *x)
4477 {
4478     int i;
4479     for (i = 0; i < strlen(x); i++)
4480         if (isdigit(x[i]) == 0)
4481             return UAP_FAILURE;
4482     return UAP_SUCCESS;
4483 }
4484
4485 /** 
4486  *  @brief Checkes a particular input for validatation.
4487  *
4488  *  @param cmd      Type of input
4489  *  @param argc     Number of arguments
4490  *  @param argv     Pointer to the arguments
4491  *  @return         UAP_SUCCESS or UAP_FAILURE
4492  */
4493 int
4494 is_input_valid(valid_inputs cmd, int argc, char *argv[])
4495 {
4496     int i;
4497     int ret = UAP_SUCCESS;
4498     if (argc == 0)
4499         return UAP_FAILURE;
4500     switch (cmd) {
4501     case RDEEPROM:
4502         if (argc != 2) {
4503             printf(" ERR: Argument count mismatch\n");
4504             ret = UAP_FAILURE;
4505         } else {
4506             if ((ISDIGIT(argv[0]) == 0) || (ISDIGIT(argv[1]) == 0) ||
4507                 (A2HEXDECIMAL(argv[0]) & 0x03) ||
4508                 (A2HEXDECIMAL(argv[0]) < 0) ||
4509                 (A2HEXDECIMAL(argv[1]) & 0x03) ||
4510                 (A2HEXDECIMAL(argv[1]) < 4) || (A2HEXDECIMAL(argv[1]) > 20)) {
4511                 printf(" ERR: Invalid inputs for Read EEPROM\n");
4512                 ret = UAP_FAILURE;
4513             }
4514         }
4515         break;
4516     case SCANCHANNELS:
4517         if (argc > MAX_CHANNELS) {
4518             printf("ERR: Invalid List of Channels\n");
4519             ret = UAP_FAILURE;
4520         } else {
4521             for (i = 0; i < argc; i++) {
4522                 if ((ISDIGIT(argv[i]) == 0) || (atoi(argv[i]) < 1) ||
4523                     (atoi(argv[i]) > MAX_CHANNELS)) {
4524                     printf("ERR: Channel must be in the range of 1 to %d\n",
4525                            MAX_CHANNELS);
4526                     ret = UAP_FAILURE;
4527                     break;
4528                 }
4529             }
4530             if ((ret != UAP_FAILURE) &&
4531                 (has_dup_channel(argc, argv) != UAP_SUCCESS)) {
4532                 printf("ERR: Duplicate channel values entered\n");
4533                 ret = UAP_FAILURE;
4534             }
4535         }
4536         break;
4537     case TXPOWER:
4538         if ((argc > 1) || (ISDIGIT(argv[0]) == 0)) {
4539             printf("ERR:Invalid Transmit power\n");
4540             ret = UAP_FAILURE;
4541         } else {
4542             if ((atoi(argv[0]) < MIN_TX_POWER) ||
4543                 (atoi(argv[0]) > MAX_TX_POWER)) {
4544                 printf("ERR: TX Powar must be in the rage of %d to %d. \n",
4545                        MIN_TX_POWER, MAX_TX_POWER);
4546                 ret = UAP_FAILURE;
4547             }
4548         }
4549         break;
4550     case PROTOCOL:
4551         if ((argc > 1) || (ISDIGIT(argv[0]) == 0)) {
4552             printf("ERR:Invalid Protocol\n");
4553             ret = UAP_FAILURE;
4554         } else
4555             ret = is_protocol_valid(atoi(argv[0]));
4556         break;
4557     case CHANNEL:
4558         if ((argc != 1) && (argc != 2)) {
4559             printf("ERR: Incorrect arguments for channel.\n");
4560             ret = UAP_FAILURE;
4561         } else {
4562             if (argc == 2) {
4563                 if ((ISDIGIT(argv[1]) == 0) || (atoi(argv[1]) < 0) ||
4564                     (atoi(argv[1]) > 1)) {
4565                     printf("ERR: MODE must be either 0 or 1\n");
4566                     ret = UAP_FAILURE;
4567                 }
4568                 if ((atoi(argv[1]) == 1) && (atoi(argv[0]) != 0)) {
4569                     printf("ERR: Channel must be 0 for ACS; MODE = 1.\n");
4570                     ret = UAP_FAILURE;
4571                 }
4572             }
4573             if ((argc == 1) || (atoi(argv[1]) == 0)) {
4574                 if ((ISDIGIT(argv[0]) == 0) || (atoi(argv[0]) < 1) ||
4575                     (atoi(argv[0]) > MAX_CHANNELS)) {
4576                     printf("ERR: Channel must be in the range of 1 to %d\n",
4577                            MAX_CHANNELS);
4578                     ret = UAP_FAILURE;
4579                 }
4580             }
4581         }
4582         break;
4583     case RATE:
4584         if (argc > MAX_RATES) {
4585             printf("ERR: Incorrect number of RATES arguments.\n");
4586             ret = UAP_FAILURE;
4587         } else {
4588             for (i = 0; i < argc; i++) {
4589                 if ((IS_HEX_OR_DIGIT(argv[i]) == UAP_FAILURE) ||
4590                     (is_rate_valid(A2HEXDECIMAL(argv[i]) & ~BASIC_RATE_SET_BIT)
4591                      != UAP_SUCCESS)) {
4592                     printf("ERR:Unsupported rate.\n");
4593                     ret = UAP_FAILURE;
4594                     break;
4595                 }
4596             }
4597             if ((ret != UAP_FAILURE) &&
4598                 (has_dup_rate(argc, argv) != UAP_SUCCESS)) {
4599                 printf("ERR: Duplicate rate values entered\n");
4600                 ret = UAP_FAILURE;
4601             }
4602             if (check_mandatory_rates(argc, argv) != UAP_SUCCESS) {
4603                 ret = UAP_FAILURE;
4604             }
4605         }
4606         break;
4607     case BROADCASTSSID:
4608         if (argc != 1) {
4609             printf("ERR:wrong BROADCASTSSID arguments.\n");
4610             ret = UAP_FAILURE;
4611         } else {
4612             if ((ISDIGIT(argv[0]) == 0) ||
4613                 ((atoi(argv[0]) != 0) && (atoi(argv[0]) != 1))) {
4614                 printf
4615                     ("ERR:Illegal parameter %s for BROADCASTSSID. Must be either '0' or '1'.\n",
4616                      argv[0]);
4617                 ret = UAP_FAILURE;
4618             }
4619         }
4620         break;
4621     case RTSTHRESH:
4622         if (argc != 1) {
4623             printf("ERR:Incorrect number of arguments for RTSTHRESHOLD\n");
4624             ret = UAP_FAILURE;
4625         } else if ((ISDIGIT(argv[0]) == 0) || (atoi(argv[0]) < 0) ||
4626                    (atoi(argv[0]) > MAX_RTS_THRESHOLD)) {
4627             printf
4628                 ("ERR:Illegal RTSTHRESHOLD %s. The value must between 0 and %d\n",
4629                  argv[0], MAX_RTS_THRESHOLD);
4630             ret = UAP_FAILURE;
4631         }
4632         break;
4633     case FRAGTHRESH:
4634         if (argc != 1) {
4635             printf("ERR:Incorrect number of arguments for FRAGTHRESH\n");
4636             ret = UAP_FAILURE;
4637         } else if ((ISDIGIT(argv[0]) == 0) ||
4638                    (atoi(argv[0]) < MIN_FRAG_THRESHOLD) ||
4639                    (atoi(argv[0]) > MAX_FRAG_THRESHOLD)) {
4640             printf
4641                 ("ERR:Illegal FRAGTHRESH %s. The value must between %d and %d\n",
4642                  argv[0], MIN_FRAG_THRESHOLD, MAX_FRAG_THRESHOLD);
4643             ret = UAP_FAILURE;
4644         }
4645         break;
4646     case DTIMPERIOD:
4647         if (argc != 1) {
4648             printf("ERR:Incorrect number of arguments for DTIMPERIOD\n");
4649             ret = UAP_FAILURE;
4650         } else if ((ISDIGIT(argv[0]) == 0) || (atoi(argv[0]) < 1) ||
4651                    (atoi(argv[0]) > MAX_DTIM_PERIOD)) {
4652             printf("ERR: DTIMPERIOD Value must be in range of 1 to %d\n",
4653                    MAX_DTIM_PERIOD);
4654             ret = UAP_FAILURE;
4655         }
4656         break;
4657     case RADIOCONTROL:
4658         if (argc != 1) {
4659             printf("ERR:Incorrect number of arguments for RADIOCONTROL\n");
4660             ret = UAP_FAILURE;
4661         } else {
4662             if ((ISDIGIT(argv[0]) == 0) || (atoi(argv[0]) < 0) ||
4663                 (atoi(argv[0]) > 1)) {
4664                 printf
4665                     ("ERR:Illegal RADIOCONTROL parameter %s. Must be either '0' or '1'.\n",
4666                      argv[0]);
4667                 ret = UAP_FAILURE;
4668             }
4669         }
4670         break;
4671     case RSNREPLAYPROT:
4672         if (argc != 1) {
4673             printf("ERR:wrong RSNREPLAYPROT arguments.\n");
4674             ret = UAP_FAILURE;
4675         } else {
4676             if ((ISDIGIT(argv[0]) == 0) ||
4677                 ((atoi(argv[0]) != 0) && (atoi(argv[0]) != 1))) {
4678                 printf
4679                     ("ERR:Illegal parameter %s for RSNREPLAYPROT. Must be either '0' or '1'.\n",
4680                      argv[0]);
4681                 ret = UAP_FAILURE;
4682             }
4683         }
4684         break;
4685     case MCBCDATARATE:
4686     case TXDATARATE:
4687         if (argc != 1) {
4688             printf("ERR:Incorrect number of arguments for DATARATE\n");
4689             ret = UAP_FAILURE;
4690         } else {
4691             if (IS_HEX_OR_DIGIT(argv[0]) == UAP_FAILURE) {
4692                 printf("ERR: invalid data rate\n");
4693                 ret = UAP_FAILURE;
4694             } else if ((A2HEXDECIMAL(argv[0]) != 0) &&
4695                        (is_rate_valid
4696                         (A2HEXDECIMAL(argv[0]) & ~BASIC_RATE_SET_BIT) !=
4697                         UAP_SUCCESS)) {
4698                 printf("ERR: invalid data rate\n");
4699                 ret = UAP_FAILURE;
4700             }
4701         }
4702         break;
4703     case PKTFWD:
4704         if (argc != 1) {
4705             printf("ERR:Incorrect number of arguments for PKTFWD.\n");
4706             ret = UAP_FAILURE;
4707         } else if ((ISDIGIT(argv[0]) == 0) ||
4708                    ((atoi(argv[0]) != 0) && (atoi(argv[0]) != 1))) {
4709             printf
4710                 ("ERR:Illegal PKTFWD parameter %s. Must be either '0' or '1'.\n",
4711                  argv[0]);
4712             ret = UAP_FAILURE;
4713         }
4714         break;
4715     case STAAGEOUTTIMER:
4716         if (argc != 1) {
4717             printf("ERR:Incorrect number of arguments for STAAGEOUTTIMER.\n");
4718             ret = UAP_FAILURE;
4719         } else {
4720             if ((ISDIGIT(argv[0]) == 0) || ((atoi(argv[0]) != 0) &&
4721                                             ((atoi(argv[0]) <
4722                                               MIN_STAGE_OUT_TIME) ||
4723                                              (atoi(argv[0]) >
4724                                               MAX_STAGE_OUT_TIME)))) {
4725                 printf
4726                     ("ERR:Illegal STAAGEOUTTIMER %s. Must be between %d and %d.\n",
4727                      argv[0], MIN_STAGE_OUT_TIME, MAX_STAGE_OUT_TIME);
4728                 ret = UAP_FAILURE;
4729             }
4730         }
4731         break;
4732     case AUTHMODE:
4733         if (argc != 1) {
4734             printf("ERR:Incorrect number of arguments for AUTHMODE\n");
4735             ret = UAP_FAILURE;
4736         } else {
4737             if ((ISDIGIT(argv[0]) == 0) || (atoi(argv[0]) < 0) ||
4738                 (atoi(argv[0]) > 1)) {
4739                 printf
4740                     ("ERR:Illegal AUTHMODE parameter %s. Must be either '0', or '1'.\n",
4741                      argv[0]);
4742                 ret = UAP_FAILURE;
4743             }
4744         }
4745         break;
4746     case GROUPREKEYTIMER:
4747         if (argc != 1) {
4748             printf("ERR:Incorrect number of arguments for GROUPREKEYTIMER.\n");
4749             ret = UAP_FAILURE;
4750         } else {
4751             if ((ISDIGIT(argv[0]) == 0) || (atoi(argv[0]) < 0) ||
4752                 (atoi(argv[0]) > MAX_GRP_TIMER)) {
4753                 printf("ERR: GROUPREKEYTIMER range is [0:%d] (0 for disable)\n",
4754                        MAX_GRP_TIMER);
4755                 ret = UAP_FAILURE;
4756             }
4757         }
4758         break;
4759     case MAXSTANUM:
4760         if (argc != 1) {
4761             printf("ERR:Incorrect number of arguments for MAXSTANUM\n");
4762             ret = UAP_FAILURE;
4763         } else {
4764             if ((ISDIGIT(argv[0]) == 0) || (atoi(argv[0]) > 8) ||
4765                 (atoi(argv[0]) < 0)) {
4766                 printf("ERR:STA_NUM must be in the range of [0:8] %s.\n",
4767                        argv[0]);
4768                 ret = UAP_FAILURE;
4769             }
4770         }
4771         break;
4772     case BEACONPERIOD:
4773         if (argc != 1) {
4774             printf("ERR:Incorrect number of argument for BEACONPERIOD.\n");
4775             ret = UAP_FAILURE;
4776         } else {
4777             if ((ISDIGIT(argv[0]) == 0) || (atoi(argv[0]) < MIN_BEACON_PERIOD)
4778                 || (atoi(argv[0]) > MAX_BEACON_PERIOD)) {
4779                 printf("ERR: BEACONPERIOD must be in range of %d to %d.\n",
4780                        MIN_BEACON_PERIOD, MAX_BEACON_PERIOD);
4781                 ret = UAP_FAILURE;
4782             }
4783         }
4784         break;
4785     case RETRYLIMIT:
4786         if (argc != 1) {
4787             printf("ERR:Incorrect number of arguments for RETRY LIMIT\n");
4788             ret = UAP_FAILURE;
4789         } else {
4790             if ((ISDIGIT(argv[0]) == 0) || (atoi(argv[0]) > MAX_RETRY_LIMIT) ||
4791                 (atoi(argv[0]) < 0)) {
4792                 printf
4793                     ("ERR:RETRY_LIMIT must be in the range of [0:%d]. The  input was %s.\n",
4794                      MAX_RETRY_LIMIT, argv[0]);
4795                 ret = UAP_FAILURE;
4796             }
4797         }
4798         break;
4799     case COEX_COMM_BITMAP:
4800         if (argc != 1) {
4801             printf("ERR:Incorrect number of arguments for Bitmap.\n");
4802             ret = UAP_FAILURE;
4803         } else {
4804             /* Only bit 0 is supported now, hence check for 1 or 0 */
4805             if ((IS_HEX_OR_DIGIT(argv[0]) == 0) || (atoi(argv[0]) < 0) ||
4806                 (atoi(argv[0]) > 1)) {
4807                 printf("ERR: Bitmap must have value of 1 or 0.\n");
4808                 ret = UAP_FAILURE;
4809             }
4810         }
4811         break;
4812     case COEX_SCO_ACL_FREQ:
4813         if (argc != 1) {
4814             printf("ERR:Incorrect number of arguments for aclFrequency.\n");
4815             ret = UAP_FAILURE;
4816         } else {
4817             if (ISDIGIT(argv[0]) == 0) {
4818                 printf("ERR: Incorrect value for aclFrequency.\n");
4819                 ret = UAP_FAILURE;
4820             }
4821         }
4822         break;
4823     case COEX_ACL_ENABLED:
4824         if (argc != 1) {
4825             printf("ERR:Incorrect number of arguments for (acl) enabled.\n");
4826             ret = UAP_FAILURE;
4827         } else {
4828             if ((ISDIGIT(argv[0]) == 0) || (atoi(argv[0]) < 0) ||
4829                 (atoi(argv[0]) > 1)) {
4830                 printf("ERR: (acl) enabled must have value of 1 or 0.\n");
4831                 ret = UAP_FAILURE;
4832             }
4833         }
4834         break;
4835     case COEX_ACL_BT_TIME:
4836     case COEX_ACL_WLAN_TIME:
4837         if (argc != 1) {
4838             printf("ERR:Incorrect number of arguments for bt/wlan time.\n");
4839             ret = UAP_FAILURE;
4840         } else {
4841             if (ISDIGIT(argv[0]) == 0) {
4842                 printf("ERR: Incorrect value for bt/wlan time.\n");
4843                 ret = UAP_FAILURE;
4844             }
4845         }
4846         break;
4847     case COEX_PROTECTION:
4848         if (argc != 2) {
4849             printf("ERR:Incorrect number of arguments for %s.\n", argv[0]);
4850             ret = UAP_FAILURE;
4851         } else {
4852             if (ISDIGIT(argv[1]) == 0) {
4853                 printf("ERR: Incorrect value for %s.\n", argv[0]);
4854                 ret = UAP_FAILURE;
4855             }
4856         }
4857         break;
4858     default:
4859         ret = UAP_FAILURE;
4860         break;
4861     }
4862     return ret;
4863 }
4864
4865 /** 
4866  *  @brief Converts colon separated MAC address to hex value
4867  *
4868  *  @param mac      A pointer to the colon separated MAC string
4869  *  @param raw      A pointer to the hex data buffer
4870  *  @return         UAP_SUCCESS or UAP_FAILURE
4871  *                  UAP_RET_MAC_BROADCAST  - if broadcast mac
4872  *                  UAP_RET_MAC_MULTICAST - if multicast mac
4873  */
4874 int
4875 mac2raw(char *mac, u8 * raw)
4876 {
4877     unsigned int temp_raw[ETH_ALEN];
4878     int num_tokens = 0;
4879     int i;
4880     if (strlen(mac) != ((2 * ETH_ALEN) + (ETH_ALEN - 1))) {
4881         return UAP_FAILURE;
4882     }
4883     num_tokens = sscanf(mac, "%2x:%2x:%2x:%2x:%2x:%2x",
4884                         temp_raw + 0, temp_raw + 1, temp_raw + 2, temp_raw + 3,
4885                         temp_raw + 4, temp_raw + 5);
4886     if (num_tokens != ETH_ALEN) {
4887         return UAP_FAILURE;
4888     }
4889     for (i = 0; i < num_tokens; i++)
4890         raw[i] = (u8) temp_raw[i];
4891
4892     if (memcmp(raw, "\xff\xff\xff\xff\xff\xff", ETH_ALEN) == 0) {
4893         return UAP_RET_MAC_BROADCAST;
4894     } else if (raw[0] & 0x01) {
4895         return UAP_RET_MAC_MULTICAST;
4896     }
4897     return UAP_SUCCESS;
4898 }
4899
4900 /** 
4901  *  @brief Converts a string to hex value
4902  *
4903  *  @param str      A pointer to the string
4904  *  @param raw      A pointer to the raw data buffer
4905  *  @return         Number of bytes read
4906  */
4907 int
4908 string2raw(char *str, unsigned char *raw)
4909 {
4910     int len = (strlen(str) + 1) / 2;
4911
4912     do {
4913         if (!isxdigit(*str)) {
4914             return -1;
4915         }
4916         *str = toupper(*str);
4917         *raw = CHAR2INT(*str) << 4;
4918         ++str;
4919         *str = toupper(*str);
4920         if (*str == '\0')
4921             break;
4922         *raw |= CHAR2INT(*str);
4923         ++raw;
4924     } while (*++str != '\0');
4925     return len;
4926 }
4927
4928 /** 
4929  *  @brief Prints a MAC address in colon separated form from hex data
4930  *
4931  *  @param raw      A pointer to the hex data buffer
4932  *  @return         N/A
4933  */
4934 void
4935 print_mac(u8 * raw)
4936 {
4937     printf("%02x:%02x:%02x:%02x:%02x:%02x", (unsigned int) raw[0],
4938            (unsigned int) raw[1], (unsigned int) raw[2], (unsigned int) raw[3],
4939            (unsigned int) raw[4], (unsigned int) raw[5]);
4940     return;
4941 }
4942
4943 /** 
4944  *  @brief              check hex string
4945  *  
4946  *  @param hex          A pointer to hex string
4947  *  @return             UAP_SUCCESS or UAP_FAILURE
4948  */
4949 int
4950 ishexstring(void *hex)
4951 {
4952     int i, a;
4953     char *p = hex;
4954     int len = strlen(p);
4955     if (!strncasecmp("0x", p, 2)) {
4956         p += 2;
4957         len -= 2;
4958     }
4959     for (i = 0; i < len; i++) {
4960         a = hex2num(*p);
4961         if (a < 0)
4962             return UAP_FAILURE;
4963         p++;
4964     }
4965     return UAP_SUCCESS;
4966 }
4967
4968 /**
4969  *  @brief Show auth tlv 
4970  *
4971  *  @param tlv     Poniter to auth tlv
4972  *  
4973  *  $return         N/A
4974  */
4975 void
4976 print_auth(TLVBUF_AUTH_MODE * tlv)
4977 {
4978     switch (tlv->AuthMode) {
4979     case 0:
4980         printf("AUTHMODE = Open authentication\n");
4981         break;
4982     case 1:
4983         printf("AUTHMODE = Shared key authentication\n");
4984         break;
4985     case 2:
4986         printf("AUTHMODE = Auto (open and shared key)\n");
4987         break;
4988     default:
4989         printf("ERR: Invalid authmode=%d\n", tlv->AuthMode);
4990         break;
4991     }
4992 }
4993
4994 /**
4995  *
4996  *  @brief Show cipher tlv 
4997  *
4998  *  @param tlv     Poniter to cipher tlv
4999  *  
5000  *  $return         N/A
5001  */
5002 void
5003 print_cipher(TLVBUF_CIPHER * tlv)
5004 {
5005     switch (tlv->PairwiseCipher) {
5006     case CIPHER_TKIP:
5007         printf("PairwiseCipher = TKIP\n");
5008         break;
5009     case CIPHER_AES_CCMP:
5010         printf("PairwiseCipher = AES CCMP\n");
5011         break;
5012     case CIPHER_TKIP | CIPHER_AES_CCMP:
5013         printf("PairwiseCipher = TKIP + AES CCMP\n");
5014         break;
5015     case CIPHER_NONE:
5016         printf("PairwiseCipher =  None\n");
5017         break;
5018     default:
5019         printf("Unknown Pairwise cipher 0x%x\n", tlv->PairwiseCipher);
5020         break;
5021     }
5022     switch (tlv->GroupCipher) {
5023     case CIPHER_TKIP:
5024         printf("GroupCipher = TKIP\n");
5025         break;
5026     case CIPHER_AES_CCMP:
5027         printf("GroupCipher = AES CCMP\n");
5028         break;
5029     case CIPHER_NONE:
5030         printf("GroupCipher = None\n");
5031         break;
5032     default:
5033         printf("Unknown Group cipher 0x%x\n", tlv->GroupCipher);
5034         break;
5035     }
5036 }
5037
5038 /**
5039  *  @brief Show mac filter tlv 
5040  *
5041  *  @param tlv     Poniter to filter tlv
5042  *  
5043  *  $return         N/A
5044  */
5045 void
5046 print_mac_filter(TLVBUF_STA_MAC_ADDR_FILTER * tlv)
5047 {
5048     int i;
5049     switch (tlv->FilterMode) {
5050     case 0:
5051         printf("Filter Mode = Filter table is disabled\n");
5052         return;
5053     case 1:
5054         printf
5055             ("Filter Mode = Allow mac address specified in the allwed list\n");
5056         break;
5057     case 2:
5058         printf
5059             ("Filter Mode = Block MAC addresses specified in the  banned list\n");
5060         break;
5061     }
5062     for (i = 0; i < tlv->Count; i++) {
5063         printf("MAC_%d = ", i);
5064         print_mac(&tlv->MacAddress[i * ETH_ALEN]);
5065         printf("\n");
5066     }
5067 }
5068
5069 /**
5070  *  @brief Show rate tlv 
5071  *
5072  *  @param tlv      Poniter to rate tlv
5073  *  
5074  *  $return         N/A
5075  */
5076 void
5077 print_rate(TLVBUF_RATES * tlv)
5078 {
5079     int flag = 0;
5080     int i;
5081     printf("Basic Rates =");
5082     for (i = 0; i < tlv->Length; i++) {
5083         if (tlv->OperationalRates[i] > (BASIC_RATE_SET_BIT - 1)) {
5084             flag = flag ? : 1;
5085             printf(" 0x%x", tlv->OperationalRates[i]);
5086         }
5087     }
5088     printf("%s\nNon-Basic Rates =", flag ? "" : " ( none ) ");
5089     for (flag = 0, i = 0; i < tlv->Length; i++) {
5090         if (tlv->OperationalRates[i] < BASIC_RATE_SET_BIT) {
5091             flag = flag ? : 1;
5092             printf(" 0x%x", tlv->OperationalRates[i]);
5093         }
5094     }
5095     printf("%s\n", flag ? "" : " ( none ) ");
5096 }
5097
5098 /**
5099  *  @brief Show all the tlv in the buf
5100  *
5101  *  @param buf     Poniter to tlv buffer
5102  *  @param len     tlv buffer len
5103  *  
5104  *  $return         N/A
5105  */
5106 void
5107 print_tlv(u8 * buf, u16 len)
5108 {
5109     TLVBUF_HEADER *pCurrentTlv = (TLVBUF_HEADER *) buf;
5110     int tlvBufLeft = len;
5111     u16 tlvType;
5112     u16 tlvLen;
5113     u16 custom_ie_len;
5114     u8 ssid[33];
5115     int i = 0;
5116     TLVBUF_AP_MAC_ADDRESS *mac_tlv;
5117     TLVBUF_SSID *ssid_tlv;
5118     TLVBUF_BEACON_PERIOD *beacon_tlv;
5119     TLVBUF_DTIM_PERIOD *dtim_tlv;
5120     TLVBUF_RATES *rates_tlv;
5121     TLVBUF_TX_POWER *txpower_tlv;
5122     TLVBUF_BCAST_SSID_CTL *bcast_tlv;
5123     TLVBUF_PREAMBLE_CTL *preamble_tlv;
5124     TLVBUF_ANTENNA_CTL *antenna_tlv;
5125     TLVBUF_RTS_THRESHOLD *rts_tlv;
5126     TLVBUF_RADIO_CTL *radio_tlv;
5127     TLVBUF_TX_DATA_RATE *txrate_tlv;
5128     TLVBUF_MCBC_DATA_RATE *mcbcrate_tlv;
5129     TLVBUF_PKT_FWD_CTL *pkt_fwd_tlv;
5130     TLVBUF_STA_AGEOUT_TIMER *ageout_tlv;
5131     TLVBUF_AUTH_MODE *auth_tlv;
5132     TLVBUF_PROTOCOL *proto_tlv;
5133     TLVBUF_AKMP *akmp_tlv;
5134     TLVBUF_CIPHER *cipher_tlv;
5135     TLVBUF_GROUP_REKEY_TIMER *rekey_tlv;
5136     TLVBUF_WPA_PASSPHRASE *psk_tlv;
5137     TLVBUF_WEP_KEY *wep_tlv;
5138     TLVBUF_FRAG_THRESHOLD *frag_tlv;
5139     TLVBUF_STA_MAC_ADDR_FILTER *filter_tlv;
5140     TLVBUF_MAX_STA_NUM *max_sta_tlv;
5141     TLVBUF_RETRY_LIMIT *retry_limit_tlv;
5142     TLVBUF_CHANNEL_CONFIG *channel_tlv;
5143     TLVBUF_CHANNEL_LIST *chnlist_tlv;
5144     tlvbuf_custom_ie *custom_ie_tlv;
5145     custom_ie *custom_ie_ptr;
5146     tlvbuf_coex_common_cfg *coex_common_tlv;
5147     tlvbuf_coex_sco_cfg *coex_sco_tlv;
5148     tlvbuf_coex_acl_cfg *coex_acl_tlv;
5149     tlvbuf_coex_stats *coex_stats_tlv;
5150     CHANNEL_LIST *pChanList;
5151 #ifdef DEBUG
5152     uap_printf(MSG_DEBUG, "tlv total len=%d\n", len);
5153 #endif
5154     while (tlvBufLeft >= (int) sizeof(TLVBUF_HEADER)) {
5155         tlvType = uap_le16_to_cpu(pCurrentTlv->Type);
5156         tlvLen = uap_le16_to_cpu(pCurrentTlv->Len);
5157         if ((sizeof(TLVBUF_HEADER) + tlvLen) > tlvBufLeft) {
5158             printf("wrong tlv: tlvLen=%d, tlvBufLeft=%d\n", tlvLen, tlvBufLeft);
5159             break;
5160         }
5161         switch (tlvType) {
5162         case MRVL_AP_MAC_ADDRESS_TLV_ID:
5163             mac_tlv = (TLVBUF_AP_MAC_ADDRESS *) pCurrentTlv;
5164             printf("AP MAC address = ");
5165             print_mac(mac_tlv->ApMacAddr);
5166             printf("\n");
5167             break;
5168         case MRVL_SSID_TLV_ID:
5169             memset(ssid, 0, sizeof(ssid));
5170             ssid_tlv = (TLVBUF_SSID *) pCurrentTlv;
5171             memcpy(ssid, ssid_tlv->Ssid, ssid_tlv->Length);
5172             printf("SSID = %s\n", ssid);
5173             break;
5174         case MRVL_BEACON_PERIOD_TLV_ID:
5175             beacon_tlv = (TLVBUF_BEACON_PERIOD *) pCurrentTlv;
5176             beacon_tlv->BeaconPeriod_ms =
5177                 uap_le16_to_cpu(beacon_tlv->BeaconPeriod_ms);
5178             printf("Beacon period = %d\n", beacon_tlv->BeaconPeriod_ms);
5179             break;
5180         case MRVL_DTIM_PERIOD_TLV_ID:
5181             dtim_tlv = (TLVBUF_DTIM_PERIOD *) pCurrentTlv;
5182             printf("DTIM period = %d\n", dtim_tlv->DtimPeriod);
5183             break;
5184         case MRVL_CHANNELCONFIG_TLV_ID:
5185             channel_tlv = (TLVBUF_CHANNEL_CONFIG *) pCurrentTlv;
5186             printf("Channel = %d\n", channel_tlv->ChanNumber);
5187             printf("Channel Select Mode = %s\n",
5188                    (channel_tlv->BandConfigType == 0) ? "Manual" : "ACS");
5189             break;
5190         case MRVL_CHANNELLIST_TLV_ID:
5191             chnlist_tlv = (TLVBUF_CHANNEL_LIST *) pCurrentTlv;
5192             printf("Channels List = ");
5193             pChanList = (CHANNEL_LIST *) & (chnlist_tlv->ChanList);
5194             if (chnlist_tlv->Length % sizeof(CHANNEL_LIST)) {
5195                 break;
5196             }
5197             for (i = 0; i < (chnlist_tlv->Length / sizeof(CHANNEL_LIST)); i++) {
5198                 printf("%d ", pChanList->ChanNumber);
5199                 pChanList++;
5200             }
5201             printf("\n");
5202             break;
5203         case MRVL_RATES_TLV_ID:
5204             rates_tlv = (TLVBUF_RATES *) pCurrentTlv;
5205             print_rate(rates_tlv);
5206             break;
5207         case MRVL_TX_POWER_TLV_ID:
5208             txpower_tlv = (TLVBUF_TX_POWER *) pCurrentTlv;
5209             printf("Tx power = %d dBm\n", txpower_tlv->TxPower_dBm);
5210             break;
5211         case MRVL_BCAST_SSID_CTL_TLV_ID:
5212             bcast_tlv = (TLVBUF_BCAST_SSID_CTL *) pCurrentTlv;
5213             printf("SSID broadcast = %s\n",
5214                    (bcast_tlv->BcastSsidCtl == 1) ? "enabled" : "disabled");
5215             break;
5216         case MRVL_PREAMBLE_CTL_TLV_ID:
5217             preamble_tlv = (TLVBUF_PREAMBLE_CTL *) pCurrentTlv;
5218             printf("Preamble type = %s\n", (preamble_tlv->PreambleType == 0) ?
5219                    "auto" : ((preamble_tlv->PreambleType == 1) ? "short" :
5220                              "long"));
5221             break;
5222         case MRVL_ANTENNA_CTL_TLV_ID:
5223             antenna_tlv = (TLVBUF_ANTENNA_CTL *) pCurrentTlv;
5224             printf("%s antenna = %s\n", (antenna_tlv->WhichAntenna == 0) ?
5225                    "Rx" : "Tx", (antenna_tlv->AntennaMode == 0) ? "A" : "B");
5226             break;
5227         case MRVL_RTS_THRESHOLD_TLV_ID:
5228             rts_tlv = (TLVBUF_RTS_THRESHOLD *) pCurrentTlv;
5229             rts_tlv->RtsThreshold = uap_le16_to_cpu(rts_tlv->RtsThreshold);
5230             printf("RTS threshold = %d\n", rts_tlv->RtsThreshold);
5231             break;
5232         case MRVL_FRAG_THRESHOLD_TLV_ID:
5233             frag_tlv = (TLVBUF_FRAG_THRESHOLD *) pCurrentTlv;
5234             frag_tlv->FragThreshold = uap_le16_to_cpu(frag_tlv->FragThreshold);
5235             printf("Fragmentation threshold = %d\n", frag_tlv->FragThreshold);
5236             break;
5237         case MRVL_RADIO_CTL_TLV_ID:
5238             radio_tlv = (TLVBUF_RADIO_CTL *) pCurrentTlv;
5239             printf("Radio = %s\n", (radio_tlv->RadioCtl == 0) ? "on" : "off");
5240             break;
5241         case MRVL_TX_DATA_RATE_TLV_ID:
5242             txrate_tlv = (TLVBUF_TX_DATA_RATE *) pCurrentTlv;
5243             txrate_tlv->TxDataRate = uap_le16_to_cpu(txrate_tlv->TxDataRate);
5244             if (txrate_tlv->TxDataRate == 0)
5245                 printf("Tx data rate = auto\n");
5246             else
5247                 printf("Tx data rate = 0x%x\n", txrate_tlv->TxDataRate);
5248             break;
5249         case MRVL_MCBC_DATA_RATE_TLV_ID:
5250             mcbcrate_tlv = (TLVBUF_MCBC_DATA_RATE *) pCurrentTlv;
5251             mcbcrate_tlv->MCBCdatarate =
5252                 uap_le16_to_cpu(mcbcrate_tlv->MCBCdatarate);
5253             if (mcbcrate_tlv->MCBCdatarate == 0)
5254                 printf("MCBC data rate = auto\n");
5255             else
5256                 printf("MCBC data rate = 0x%x\n", mcbcrate_tlv->MCBCdatarate);
5257             break;
5258         case MRVL_PKT_FWD_CTL_TLV_ID:
5259             pkt_fwd_tlv = (TLVBUF_PKT_FWD_CTL *) pCurrentTlv;
5260             printf("Firmware = %s\n", (pkt_fwd_tlv->PktFwdCtl == 0) ?
5261                    "forwards all packets to the host" :
5262                    "handles intra-BSS packets");
5263             break;
5264         case MRVL_STA_AGEOUT_TIMER_TLV_ID:
5265             ageout_tlv = (TLVBUF_STA_AGEOUT_TIMER *) pCurrentTlv;
5266             ageout_tlv->StaAgeoutTimer_ms =
5267                 uap_le32_to_cpu(ageout_tlv->StaAgeoutTimer_ms);
5268             printf("STA ageout timer = %d\n",
5269                    (int) ageout_tlv->StaAgeoutTimer_ms);
5270             break;
5271         case MRVL_AUTH_TLV_ID:
5272             auth_tlv = (TLVBUF_AUTH_MODE *) pCurrentTlv;
5273             print_auth(auth_tlv);
5274             break;
5275         case MRVL_PROTOCOL_TLV_ID:
5276             proto_tlv = (TLVBUF_PROTOCOL *) pCurrentTlv;
5277             proto_tlv->Protocol = uap_le16_to_cpu(proto_tlv->Protocol);
5278             print_protocol(proto_tlv);
5279             break;
5280         case MRVL_AKMP_TLV_ID:
5281             akmp_tlv = (TLVBUF_AKMP *) pCurrentTlv;
5282             if (uap_le16_to_cpu(akmp_tlv->KeyMgmt) == KEY_MGMT_PSK)
5283                 printf("KeyMgmt = PSK\n");
5284             else
5285                 printf("KeyMgmt = NONE\n");
5286             break;
5287         case MRVL_CIPHER_TLV_ID:
5288             cipher_tlv = (TLVBUF_CIPHER *) pCurrentTlv;
5289             print_cipher(cipher_tlv);
5290             break;
5291         case MRVL_GRP_REKEY_TIME_TLV_ID:
5292             rekey_tlv = (TLVBUF_GROUP_REKEY_TIMER *) pCurrentTlv;
5293             if (rekey_tlv->GroupRekeyTime_sec == 0)
5294                 printf("Group re-key time = disabled\n");
5295             else
5296                 printf("Group re-key time = %ld second\n",
5297                        uap_le32_to_cpu(rekey_tlv->GroupRekeyTime_sec));
5298             break;
5299         case MRVL_WPA_PASSPHRASE_TLV_ID:
5300             psk_tlv = (TLVBUF_WPA_PASSPHRASE *) pCurrentTlv;
5301             if (psk_tlv->Length > 0) {
5302                 printf("WPA passphrase = ");
5303                 for (i = 0; i < psk_tlv->Length; i++)
5304                     printf("%c", psk_tlv->Passphrase[i]);
5305                 printf("\n");
5306             } else
5307                 printf("WPA passphrase = None\n");
5308             break;
5309         case MRVL_WEP_KEY_TLV_ID:
5310             wep_tlv = (TLVBUF_WEP_KEY *) pCurrentTlv;
5311             print_wep_key(wep_tlv);
5312             break;
5313         case MRVL_STA_MAC_ADDR_FILTER_TLV_ID:
5314             filter_tlv = (TLVBUF_STA_MAC_ADDR_FILTER *) pCurrentTlv;
5315             print_mac_filter(filter_tlv);
5316             break;
5317         case MRVL_MAX_STA_CNT_TLV_ID:
5318             max_sta_tlv = (TLVBUF_MAX_STA_NUM *) pCurrentTlv;
5319             printf("Max Station Number = %d\n", max_sta_tlv->Max_sta_num);
5320             break;
5321         case MRVL_RETRY_LIMIT_TLV_ID:
5322             retry_limit_tlv = (TLVBUF_RETRY_LIMIT *) pCurrentTlv;
5323             printf("Retry Limit = %d\n", retry_limit_tlv->retry_limit);
5324             break;
5325         case MRVL_MGMT_IE_LIST_TLV_ID:
5326             custom_ie_tlv = (tlvbuf_custom_ie *) pCurrentTlv;
5327             custom_ie_len = tlvLen;
5328             custom_ie_ptr = (custom_ie *) (custom_ie_tlv->ie_data);
5329             while (custom_ie_len >= sizeof(custom_ie)) {
5330                 printf("Index [%d]\n",
5331                        uap_le16_to_cpu(custom_ie_ptr->ie_index));
5332                 printf("Management Subtype Mask = 0x%02x\n",
5333                        uap_le16_to_cpu(custom_ie_ptr->mgmt_subtype_mask));
5334                 hexdump_data("IE Buffer", (void *) custom_ie_ptr->ie_buffer,
5335                              uap_le16_to_cpu(custom_ie_ptr->ie_length), ' ');
5336                 custom_ie_len -=
5337                     sizeof(custom_ie) +
5338                     uap_le16_to_cpu(custom_ie_ptr->ie_length);
5339                 custom_ie_ptr =
5340                     (custom_ie *) ((u8 *) custom_ie_ptr + sizeof(custom_ie) +
5341                                    uap_le16_to_cpu(custom_ie_ptr->ie_length));
5342             }
5343             break;
5344         case MRVL_BT_COEX_COMMON_CFG_TLV_ID:
5345             printf("Coex common configuration:\n");
5346             coex_common_tlv = (tlvbuf_coex_common_cfg *) pCurrentTlv;
5347             printf("\tConfig Bitmap = 0x%02lx\n",
5348                    uap_le32_to_cpu(coex_common_tlv->config_bitmap));
5349             break;
5350
5351         case MRVL_BT_COEX_SCO_CFG_TLV_ID:
5352             printf("Coex sco configuration:\n");
5353             coex_sco_tlv = (tlvbuf_coex_sco_cfg *) pCurrentTlv;
5354             for (i = 0; i < 4; i++)
5355                 printf("\tQtime protection [%d] = %d usecs\n", i,
5356                        uap_le16_to_cpu(coex_sco_tlv->protection_qtime[i]));
5357             printf("\tProtection frame rate = %d\n",
5358                    uap_le16_to_cpu(coex_sco_tlv->protection_rate));
5359             printf("\tACL frequency = %d\n",
5360                    uap_le16_to_cpu(coex_sco_tlv->acl_frequency));
5361             break;
5362
5363         case MRVL_BT_COEX_ACL_CFG_TLV_ID:
5364             printf("Coex acl configuration: ");
5365             coex_acl_tlv = (tlvbuf_coex_acl_cfg *) pCurrentTlv;
5366             coex_acl_tlv->enabled = uap_le16_to_cpu(coex_acl_tlv->enabled);
5367             printf("%s\n", (coex_acl_tlv->enabled) ? "enabled" : "disabled");
5368             if (coex_acl_tlv->enabled) {
5369                 printf("\tBT time = %d usecs\n",
5370                        uap_le16_to_cpu(coex_acl_tlv->bt_time));
5371                 printf("\tWLan time = %d usecs\n",
5372                        uap_le16_to_cpu(coex_acl_tlv->wlan_time));
5373                 printf("\tProtection frame rate = %d\n",
5374                        uap_le16_to_cpu(coex_acl_tlv->protection_rate));
5375             }
5376             break;
5377
5378         case MRVL_BT_COEX_STATS_TLV_ID:
5379             printf("Coex statistics: \n");
5380             coex_stats_tlv = (tlvbuf_coex_stats *) pCurrentTlv;
5381             printf("\tNull not sent = %ld\n",
5382                    uap_le32_to_cpu(coex_stats_tlv->null_not_sent));
5383             printf("\tNull queued = %ld\n",
5384                    uap_le32_to_cpu(coex_stats_tlv->null_queued));
5385             printf("\tNull not queued = %ld\n",
5386                    uap_le32_to_cpu(coex_stats_tlv->null_not_queued));
5387             printf("\tCF End queued = %ld\n",
5388                    uap_le32_to_cpu(coex_stats_tlv->cf_end_queued));
5389             printf("\tCF End not queued = %ld\n",
5390                    uap_le32_to_cpu(coex_stats_tlv->cf_end_not_queued));
5391             printf("\tNull allocation failures = %ld\n",
5392                    uap_le32_to_cpu(coex_stats_tlv->null_alloc_fail));
5393             printf("\tCF End allocation failures = %ld\n",
5394                    uap_le32_to_cpu(coex_stats_tlv->cf_end_alloc_fail));
5395             break;
5396         default:
5397             break;
5398         }
5399         tlvBufLeft -= (sizeof(TLVBUF_HEADER) + tlvLen);
5400         pCurrentTlv = (TLVBUF_HEADER *) (pCurrentTlv->Data + tlvLen);
5401     }
5402     return;
5403 }
5404
5405 /** 
5406  *  @brief Performs the ioctl operation to send the command to
5407  *  the driver.
5408  *
5409  *  @param cmd           Pointer to the command buffer
5410  *  @param size          Pointer to the command size. This value is
5411  *                       overwritten by the function with the size of the
5412  *                       received response.
5413  *  @param buf_size      Size of the allocated command buffer
5414  *  @return              UAP_SUCCESS or UAP_FAILURE
5415  */
5416 int
5417 uap_ioctl(u8 * cmd, u16 * size, u16 buf_size)
5418 {
5419     struct ifreq ifr;
5420     APCMDBUF *header = NULL;
5421     s32 sockfd;
5422
5423     if (buf_size < *size) {
5424         printf("buf_size should not less than cmd buffer size\n");
5425         return UAP_FAILURE;
5426     }
5427
5428     /* Open socket */
5429     if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
5430         printf("ERR:Cannot open socket\n");
5431         return UAP_FAILURE;
5432     }
5433     *(u32 *) cmd = buf_size - BUF_HEADER_SIZE;
5434
5435     /* Initialize the ifr structure */
5436     memset(&ifr, 0, sizeof(ifr));
5437     strncpy(ifr.ifr_ifrn.ifrn_name, dev_name, strlen(dev_name));
5438     ifr.ifr_ifru.ifru_data = (void *) cmd;
5439     header = (APCMDBUF *) cmd;
5440     header->Size = *size - BUF_HEADER_SIZE;
5441     if (header->CmdCode == APCMD_SYS_CONFIGURE) {
5442         APCMDBUF_SYS_CONFIGURE *sys_cfg;
5443         sys_cfg = (APCMDBUF_SYS_CONFIGURE *) cmd;
5444         sys_cfg->Action = uap_cpu_to_le16(sys_cfg->Action);
5445     }
5446     endian_convert_request_header(header);
5447 #if DEBUG
5448     /* Dump request buffer */
5449     hexdump("Request buffer", (void *) cmd, *size, ' ');
5450 #endif
5451     /* Perform ioctl */
5452     errno = 0;
5453     if (ioctl(sockfd, UAPHOSTCMD, &ifr)) {
5454         perror("");
5455         printf("ERR:UAPHOSTCMD is not supported by %s\n", dev_name);
5456         close(sockfd);
5457         return UAP_FAILURE;
5458     }
5459     endian_convert_response_header(header);
5460     header->CmdCode &= HostCmd_CMD_ID_MASK;
5461     header->CmdCode |= APCMD_RESP_CHECK;
5462     *size = header->Size;
5463
5464     /* Validate response size */
5465     if (*size > (buf_size - BUF_HEADER_SIZE)) {
5466         printf
5467             ("ERR:Response size (%d) greater than buffer size (%d)! Aborting!\n",
5468              *size, buf_size);
5469         close(sockfd);
5470         return UAP_FAILURE;
5471     }
5472 #if DEBUG
5473     /* Dump respond buffer */
5474     hexdump("Respond buffer", (void *) header, header->Size + BUF_HEADER_SIZE,
5475             ' ');
5476 #endif
5477
5478     /* Close socket */
5479     close(sockfd);
5480     return UAP_SUCCESS;
5481 }
5482
5483 /** 
5484  *  @brief check cipher is valid or not
5485  *
5486  *  @param pairwisecipher    pairwise cipher
5487  *  @param groupcipher       group cipher
5488  *  @return         UAP_SUCCESS or UAP_FAILURE
5489  */
5490 int
5491 is_cipher_valid(int pairwisecipher, int groupcipher)
5492 {
5493     if ((pairwisecipher == CIPHER_NONE) && (groupcipher == CIPHER_NONE))
5494         return UAP_SUCCESS;
5495     if ((pairwisecipher == CIPHER_TKIP) && (groupcipher == CIPHER_TKIP))
5496         return UAP_SUCCESS;
5497     if ((pairwisecipher == CIPHER_AES_CCMP) && (groupcipher == CIPHER_AES_CCMP))
5498         return UAP_SUCCESS;
5499     if ((pairwisecipher == CIPHER_BITMAP) && (groupcipher == CIPHER_TKIP))
5500         return UAP_SUCCESS;
5501     return UAP_FAILURE;
5502 }
5503
5504 /** 
5505  *  @brief The main function
5506  *
5507  *  @param argc     Number of arguments
5508  *  @param argv     Pointer to the arguments
5509  *  @return         0 or 1
5510  */
5511 int
5512 main(int argc, char *argv[])
5513 {
5514     int opt, i;
5515     memset(dev_name, 0, sizeof(dev_name));
5516     strcpy(dev_name, DEFAULT_DEV_NAME);
5517
5518     /* parse arguments */
5519     while ((opt = getopt_long(argc, argv, "+hi:d:v", ap_options, NULL)) != -1) {
5520         switch (opt) {
5521         case 'i':
5522             if (strlen(optarg) < IFNAMSIZ) {
5523                 memset(dev_name, 0, sizeof(dev_name));
5524                 strncpy(dev_name, optarg, strlen(optarg));
5525             }
5526             printf("dev_name:%s\n", dev_name);
5527             break;
5528         case 'v':
5529             printf("uaputl.exe - uAP utility ver %s\n", UAP_VERSION);
5530             exit(0);
5531         case 'd':
5532             debug_level = strtoul(optarg, NULL, 10);
5533             uap_printf(MSG_DEBUG, "debug_level=%x\n", debug_level);
5534             break;
5535         case 'h':
5536         default:
5537             print_tool_usage();
5538             exit(0);
5539         }
5540     }
5541
5542     argc -= optind;
5543     argv += optind;
5544     optind = 0;
5545
5546     if (argc < 1) {
5547         print_tool_usage();
5548         exit(1);
5549     }
5550
5551     /* process command */
5552     for (i = 0; ap_command[i].cmd; i++) {
5553         if (strncmp(ap_command[i].cmd, argv[0], strlen(ap_command[i].cmd)))
5554             continue;
5555         if (strlen(ap_command[i].cmd) != strlen(argv[0]))
5556             continue;
5557         ap_command[i].func(argc, argv);
5558         break;
5559     }
5560     if (!ap_command[i].cmd) {
5561         printf("ERR: %s is not supported\n", argv[0]);
5562         exit(1);
5563     }
5564     return 0;
5565 }