| /** @file wifidirectutl.c |
| * |
| * @brief Program to configure WifiDirect parameters. |
| * |
| * Copyright (C) 2008-2017, Marvell International Ltd. |
| * |
| * This software file (the "File") is distributed by Marvell International |
| * Ltd. under the terms of the GNU General Public License Version 2, June 1991 |
| * (the "License"). You may use, redistribute and/or modify this File in |
| * accordance with the terms and conditions of the License, a copy of which |
| * is available along with the File in the gpl.txt file or by writing to |
| * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA |
| * 02111-1307 or on the worldwide web at http://www.gnu.org/licenses/gpl.txt. |
| * |
| * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE |
| * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE |
| * ARE EXPRESSLY DISCLAIMED. The License provides additional details about |
| * this warranty disclaimer. |
| * |
| */ |
| /**************************************************************************** |
| Change log: |
| 07/10/09: Initial creation |
| ****************************************************************************/ |
| |
| /**************************************************************************** |
| Header files |
| ****************************************************************************/ |
| #include <stdarg.h> |
| #include <sys/types.h> |
| #include <unistd.h> |
| #include <sys/socket.h> |
| #include <sys/select.h> |
| #include <stdio.h> |
| #include <getopt.h> |
| #include <netinet/in.h> |
| #include <arpa/inet.h> |
| #include <errno.h> |
| #include <stdlib.h> |
| #include <string.h> |
| #include <ctype.h> |
| #include <linux/if.h> |
| #include <sys/ioctl.h> |
| #include <errno.h> |
| #include <linux/wireless.h> |
| #include "wifidirectutl.h" |
| #include "wifi_display.h" |
| /**************************************************************************** |
| Definitions |
| ****************************************************************************/ |
| |
| /** Convert character to integer */ |
| #define CHAR2INT(x) (((x) >= 'A') ? ((x) - 'A' + 10) : ((x) - '0')) |
| |
| /** Uncomment this to enable DEBUG */ |
| /* #define DEBUG */ |
| |
| /**************************************************************************** |
| Global variables |
| ****************************************************************************/ |
| /** Device name */ |
| char dev_name[IFNAMSIZ + 1]; |
| /** Option for cmd */ |
| struct option cmd_options[] = { |
| {"help", 0, 0, 'h'}, |
| {0, 0, 0, 0} |
| }; |
| |
| /**************************************************************************** |
| Local functions |
| ***************************************************************************/ |
| /** |
| * @brief Dump hex data |
| * |
| * @param p A pointer to data buffer |
| * @param len The len of data buffer |
| * @param delim Deliminator character |
| * @return Hex integer |
| */ |
| #ifdef DEBUG |
| static void |
| hexdump(void *p, t_s32 len, char delim) |
| { |
| t_s32 i; |
| t_u8 *s = p; |
| printf("HexDump: len=%d\n", (int)len); |
| for (i = 0; i < len; i++) { |
| if (i != len - 1) |
| printf("%02x%c", *s++, delim); |
| else |
| printf("%02x\n", *s); |
| if ((i + 1) % 16 == 0) |
| printf("\n"); |
| } |
| } |
| #endif |
| |
| static int |
| wifidir_use_fixed_ie_indices(void) |
| { |
| #define WIFIDIR_USE_FIXED_IE_INDICES "WIFIDIR_USE_FIXED_IE_INDICES" |
| char *ret = getenv(WIFIDIR_USE_FIXED_IE_INDICES); |
| |
| if (ret != NULL && *ret == '1') { |
| printf("Using fixed ie indices 0 and 1 for P2P and WPS IEs"); |
| return 1; |
| } else { |
| return 0; |
| } |
| } |
| |
| /** |
| * @brief Converts a string to hex value |
| * |
| * @param str A pointer to the string |
| * @param raw A pointer to the raw data buffer |
| * @return Number of bytes read |
| */ |
| static int |
| string2raw(char *str, unsigned char *raw) |
| { |
| int len = (strlen(str) + 1) / 2; |
| |
| do { |
| if (!isxdigit(*str)) { |
| return -1; |
| } |
| *str = toupper(*str); |
| *raw = CHAR2INT(*str) << 4; |
| ++str; |
| *str = toupper(*str); |
| if (*str == '\0') |
| break; |
| *raw |= CHAR2INT(*str); |
| ++raw; |
| } while (*++str != '\0'); |
| return len; |
| } |
| |
| /** |
| * @brief Convert string to hex integer |
| * |
| * @param s A pointer string buffer |
| * @return Hex integer |
| */ |
| unsigned int |
| a2hex(char *s) |
| { |
| unsigned int val = 0; |
| if (!strncasecmp("0x", s, 2)) { |
| s += 2; |
| } |
| while (*s && isxdigit(*s)) { |
| val = (val << 4) + hexc2bin(*s++); |
| } |
| return val; |
| } |
| |
| /** |
| * @brief Hex to number |
| * |
| * @param c Hex value |
| * @return Integer value or -1 |
| */ |
| static int |
| hex2num(char c) |
| { |
| if (c >= '0' && c <= '9') |
| return c - '0'; |
| if (c >= 'a' && c <= 'f') |
| return c - 'a' + 10; |
| if (c >= 'A' && c <= 'F') |
| return c - 'A' + 10; |
| |
| return -1; |
| } |
| |
| /** |
| * @brief Convert char to hex integer |
| * |
| * @param chr Char |
| * @return Hex integer |
| */ |
| unsigned char |
| hexc2bin(char chr) |
| { |
| if (chr >= '0' && chr <= '9') |
| chr -= '0'; |
| else if (chr >= 'A' && chr <= 'F') |
| chr -= ('A' - 10); |
| else if (chr >= 'a' && chr <= 'f') |
| chr -= ('a' - 10); |
| |
| return chr; |
| } |
| |
| /** |
| * @brief Check hex string |
| * |
| * @param hex A pointer to hex string |
| * @return SUCCESS or FAILURE |
| */ |
| static int |
| ishexstring(void *hex) |
| { |
| int i, a; |
| char *p = hex; |
| int len = strlen(p); |
| if (!strncasecmp("0x", p, 2)) { |
| p += 2; |
| len -= 2; |
| } |
| for (i = 0; i < len; i++) { |
| a = hex2num(*p); |
| if (a < 0) |
| return FAILURE; |
| p++; |
| } |
| return SUCCESS; |
| } |
| |
| /** |
| * @brief Prints a MAC address in colon separated form from hex data |
| * |
| * @param raw A pointer to the hex data buffer |
| * @return N/A |
| */ |
| static void |
| print_mac(t_u8 *raw) |
| { |
| printf("%02x:%02x:%02x:%02x:%02x:%02x", (unsigned int)raw[0], |
| (unsigned int)raw[1], (unsigned int)raw[2], (unsigned int)raw[3], |
| (unsigned int)raw[4], (unsigned int)raw[5]); |
| return; |
| } |
| |
| /** |
| * @brief Converts colon separated MAC address to hex value |
| * |
| * @param mac A pointer to the colon separated MAC string |
| * @param raw A pointer to the hex data buffer |
| * @return SUCCESS or FAILURE |
| * WIFIDIRECT_RET_MAC_BROADCAST - if broadcast mac |
| * WIFIDIRECT_RET_MAC_MULTICAST - if multicast mac |
| */ |
| int |
| mac2raw(char *mac, t_u8 *raw) |
| { |
| unsigned int temp_raw[ETH_ALEN]; |
| int num_tokens = 0; |
| int i; |
| if (strlen(mac) != ((2 * ETH_ALEN) + (ETH_ALEN - 1))) { |
| return FAILURE; |
| } |
| num_tokens = sscanf(mac, "%2x:%2x:%2x:%2x:%2x:%2x", |
| temp_raw + 0, temp_raw + 1, temp_raw + 2, |
| temp_raw + 3, temp_raw + 4, temp_raw + 5); |
| if (num_tokens != ETH_ALEN) { |
| return FAILURE; |
| } |
| for (i = 0; i < num_tokens; i++) |
| raw[i] = (t_u8)temp_raw[i]; |
| |
| if (memcmp(raw, "\xff\xff\xff\xff\xff\xff", ETH_ALEN) == 0) { |
| return WIFIDIRECT_RET_MAC_BROADCAST; |
| } else if (raw[0] & 0x01) { |
| return WIFIDIRECT_RET_MAC_MULTICAST; |
| } |
| return SUCCESS; |
| } |
| |
| /** |
| * @brief Prints usage information of wifidirectutl |
| * |
| * @return N/A |
| */ |
| static void |
| print_tool_usage(void) |
| { |
| |
| printf("Usage:\n"); |
| printf("./wifidirectutl <iface> wifidirect_mode [mode]\n" |
| "./wifidirectutl <iface> wifidirect_config [*.conf]\n" |
| "./wifidirectutl <iface> wifidirect_params_config [*.conf]\n" |
| "./wifidirectutl <iface> wifidirect_action_frame <*.conf>|" |
| " <PeerAddr> <Category> <OuiSubtype> <DialogToken>\n" |
| "./wifidirectutl <iface> wifidirect_discovery_request <*.conf>\n" |
| "./wifidirectutl <iface> wifidirect_discovery_response <*.conf>\n" |
| "./wifidirectutl <iface> wifidirect_gas_comeback_request <*.conf>\n" |
| "./wifidirectutl <iface> wifidirect_gas_comeback_response <*.conf>\n" |
| "./wifidirectutl <iface> wifidisplay_config [*.conf]\n" |
| "./wifidirectutl <iface> wifidisplay_mode [enable/disable]\n" |
| "./wifidirectutl <iface> wifidisplay_update_devinfo [value]\n" |
| "./wifidirectutl <iface> wifidisplay_update_coupledsink_bitmap [value <= 255]\n" |
| "./wifidirectutl <iface> wifidisplay_discovery_request [*.config]\n" |
| "./wifidirectutl <iface> wifidisplay_discovery_response [*.config]\n"); |
| printf("\nPlease see example configuration file config/wifidirect.conf\n\n"); |
| printf("Configuration API:\n"); |
| printf("./wifidirectutl <iface> wifidirect_cfg_discovery_period [<MinDiscPeriod> <MaxDiscPeriod>]\n" "./wifidirectutl <iface> wifidirect_cfg_intent [IntentValue]\n" "./wifidirectutl <iface> wifidirect_cfg_capability [<deviceCapability> <groupCapability>]\n" "./wifidirectutl <iface> wifidirect_cfg_noa <enable | disable> [<counttype> <duration> <interval>]\n" "./wifidirectutl <iface> wifidirect_cfg_opp_ps [<enable> <CTWindow>]\n" "./wifidirectutl <iface> wifidirect_cfg_invitation_list [mac_address]\n" "./wifidirectutl <iface> wifidirect_cfg_listen_channel [listenChannel]\n" "./wifidirectutl <iface> wifidirect_cfg_op_channel [operatingChannel]\n" "./wifidirecttul <iface> wifidirect_cfg_persistent_group_record [index] [role]\n" " [<groupbss> <deviceId> <ssid> <psk>] [peermac1] [peermac2]\n" "./wifidirecttul <iface> wifidirect_cfg_persistent_group_invoke [index] | <cancel>\n" "./wifidirectutl <iface> wifidirect_cfg_presence_req_params [<type> <duration> <interval>]\n" "./wifidirectutl <iface> wifidirect_cfg_ext_listen_time [<duration> <interval>]\n"); |
| |
| } |
| |
| /** |
| * @brief Parses a command line |
| * |
| * @param line The line to parse |
| * @param args Pointer to the argument buffer to be filled in |
| * @return Number of arguments in the line or EOF |
| */ |
| int |
| parse_line(char *line, char *args[]) |
| { |
| int arg_num = 0; |
| int is_start = 0; |
| int is_quote = 0; |
| int is_escape = 0; |
| int length = 0; |
| int i = 0; |
| int j = 0; |
| |
| arg_num = 0; |
| length = strlen(line); |
| /* Process line */ |
| |
| /* Find number of arguments */ |
| is_start = 0; |
| is_quote = 0; |
| for (i = 0; i < length; i++) { |
| /* Ignore leading spaces */ |
| if (is_start == 0) { |
| if (line[i] == ' ') { |
| continue; |
| } else if (line[i] == '\t') { |
| continue; |
| } else if (line[i] == '\n') { |
| break; |
| } else { |
| is_start = 1; |
| args[arg_num] = &line[i]; |
| arg_num++; |
| } |
| } |
| if (is_start == 1) { |
| if ((line[i] == '\\') && (i < (length - 1))) { |
| if (line[i + 1] == '"') { |
| is_escape = 1; |
| for (j = i; j < length - 1; j++) { |
| line[j] = line[j + 1]; |
| } |
| line[length - 1] = '\0'; |
| continue; |
| } |
| } |
| /* Ignore comments */ |
| if (line[i] == '#') { |
| if (is_quote == 0) { |
| line[i] = '\0'; |
| arg_num--; |
| } |
| break; |
| } |
| /* Separate by '=' */ |
| if (line[i] == '=') { |
| if (is_quote == 0) { |
| line[i] = '\0'; |
| is_start = 0; |
| continue; |
| } |
| } |
| /* Separate by ',' */ |
| if (line[i] == ',') { |
| if (is_quote == 0) { |
| line[i] = '\0'; |
| is_start = 0; |
| continue; |
| } |
| } |
| /* Change ',' to ' ', but not inside quotes */ |
| if ((line[i] == ',') && (is_quote == 0)) { |
| line[i] = ' '; |
| continue; |
| } |
| } |
| /* Remove newlines */ |
| if (line[i] == '\n') { |
| line[i] = '\0'; |
| } |
| /* Check for quotes */ |
| if (line[i] == '"') { |
| if (is_escape) { |
| is_escape = 0; |
| /* no change in is_quote */ |
| } else { |
| is_quote = (is_quote == 1) ? 0 : 1; |
| } |
| continue; |
| } |
| if (((line[i] == ' ') || (line[i] == '\t')) && (is_quote == 0)) { |
| line[i] = '\0'; |
| is_start = 0; |
| continue; |
| } |
| } |
| return arg_num; |
| } |
| |
| /** |
| * @brief Parse function for a configuration line |
| * |
| * @param s Storage buffer for data |
| * @param size Maximum size of data |
| * @param stream File stream pointer |
| * @param line Pointer to current line within the file |
| * @param _pos Output string or NULL |
| * @return String or NULL |
| */ |
| char * |
| config_get_line(char *s, int size, FILE * stream, int *line, char **_pos) |
| { |
| char *pos, *end, *sstart; |
| while (fgets(s, size, stream)) { |
| (*line)++; |
| s[size - 1] = '\0'; |
| pos = s; |
| /* Skip white space from the beginning of line. */ |
| while (*pos == ' ' || *pos == '\t' || *pos == '\r') |
| pos++; |
| /* Skip comment lines and empty lines */ |
| if (*pos == '#' || *pos == '\n' || *pos == '\0') |
| continue; |
| /* |
| * Remove # comments unless they are within a double quoted |
| * string. |
| */ |
| sstart = strchr(pos, '"'); |
| if (sstart) |
| sstart = strrchr(sstart + 1, '"'); |
| if (!sstart) |
| sstart = pos; |
| end = strchr(sstart, '#'); |
| if (end) |
| *end-- = '\0'; |
| else |
| end = pos + strlen(pos) - 1; |
| /* Remove trailing white space. */ |
| while (end > pos && |
| (*end == '\n' || *end == ' ' || *end == '\t' || |
| *end == '\r')) |
| *end-- = '\0'; |
| if (*pos == '\0') |
| continue; |
| if (_pos) |
| *_pos = pos; |
| return pos; |
| } |
| |
| if (_pos) |
| *_pos = NULL; |
| return NULL; |
| } |
| |
| /** |
| * @brief Detects duplicates channel in array of strings |
| * |
| * @param argc Number of elements |
| * @param argv Array of strings |
| * @return UAP_FAILURE or UAP_SUCCESS |
| */ |
| static inline int |
| has_dup_channel(int argc, char *argv[]) |
| { |
| int i, j; |
| /* Check for duplicate */ |
| for (i = 0; i < (argc - 1); i++) { |
| for (j = i + 1; j < argc; j++) { |
| if (atoi(argv[i]) == atoi(argv[j])) { |
| return FAILURE; |
| } |
| } |
| } |
| return SUCCESS; |
| } |
| |
| /** |
| * @brief Performs the ioctl operation to send the command to |
| * the driver. |
| * |
| * @param cmd Pointer to the command buffer |
| * @param size Pointer to the command size. This value is |
| * overwritten by the function with the size of the |
| * received response. |
| * @param buf_size Size of the allocated command buffer |
| * @return SUCCESS or FAILURE |
| */ |
| int |
| wifidirect_ioctl(t_u8 *cmd, t_u16 *size, t_u16 buf_size) |
| { |
| struct ifreq ifr; |
| mrvl_priv_cmd *mrvl_cmd = NULL; |
| t_u8 *buf = NULL, *temp = NULL; |
| wifidirectcmdbuf *header = NULL; |
| t_s32 sockfd; |
| t_u16 mrvl_header_len = 0; |
| int ret = SUCCESS; |
| |
| if (buf_size < *size) { |
| printf("buf_size should not less than cmd buffer size\n"); |
| return FAILURE; |
| } |
| |
| /* Open socket */ |
| if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { |
| printf("ERR:Cannot open socket\n"); |
| return FAILURE; |
| } |
| *(t_u32 *)cmd = buf_size - BUF_HEADER_SIZE; |
| |
| mrvl_header_len = strlen(CMD_MARVELL) + strlen(PRIV_CMD_HOSTCMD); |
| buf = (unsigned char *)malloc(buf_size + sizeof(mrvl_priv_cmd) + |
| mrvl_header_len); |
| if (buf == NULL) |
| return FAILURE; |
| |
| memset(buf, 0, buf_size + sizeof(mrvl_priv_cmd) + mrvl_header_len); |
| /* Fill up buffer */ |
| mrvl_cmd = (mrvl_priv_cmd *)buf; |
| mrvl_cmd->buf = buf + sizeof(mrvl_priv_cmd); |
| mrvl_cmd->used_len = 0; |
| mrvl_cmd->total_len = buf_size + mrvl_header_len; |
| /* Copy Marvell command string */ |
| temp = mrvl_cmd->buf; |
| strncpy((char *)temp, CMD_MARVELL, strlen(CMD_MARVELL)); |
| temp += (strlen(CMD_MARVELL)); |
| /* Insert command string */ |
| strncpy((char *)temp, PRIV_CMD_HOSTCMD, strlen(PRIV_CMD_HOSTCMD)); |
| temp += (strlen(PRIV_CMD_HOSTCMD)); |
| |
| memcpy(temp, (t_u8 *)cmd, *size); |
| |
| /* Initialize the ifr structure */ |
| memset(&ifr, 0, sizeof(ifr)); |
| strncpy(ifr.ifr_ifrn.ifrn_name, dev_name, IFNAMSIZ - 1); |
| ifr.ifr_ifru.ifru_data = (void *)mrvl_cmd; |
| header = (wifidirectcmdbuf *)(buf + sizeof(mrvl_priv_cmd) + |
| mrvl_header_len); |
| header->size = *size - BUF_HEADER_SIZE; |
| #ifdef DEBUG |
| /* Debug print */ |
| hexdump(mrvl_cmd, *size + sizeof(mrvl_priv_cmd) + mrvl_header_len, ' '); |
| #endif |
| endian_convert_request_header(header); |
| |
| /* Perform ioctl */ |
| errno = 0; |
| if (ioctl(sockfd, MRVLPRIVCMD, &ifr)) { |
| perror(""); |
| printf("ERR:MRVLPRIVCMD is not supported by %s\n", dev_name); |
| ret = FAILURE; |
| goto done; |
| } |
| endian_convert_response_header(header); |
| header->cmd_code &= HostCmd_CMD_ID_MASK; |
| header->cmd_code |= WIFIDIRECTCMD_RESP_CHECK; |
| *size = header->size; |
| memcpy(cmd, buf + sizeof(mrvl_priv_cmd) + mrvl_header_len, |
| *size + BUF_HEADER_SIZE); |
| #ifdef DEBUG |
| /* Debug print */ |
| hexdump(mrvl_cmd, |
| *size + BUF_HEADER_SIZE + sizeof(mrvl_priv_cmd) + |
| mrvl_header_len, ' '); |
| #endif |
| |
| /* Validate response size */ |
| if (*size > (buf_size - BUF_HEADER_SIZE)) { |
| printf("ERR:Response size (%d) greater than buffer size (%d)! Aborting!\n", *size, buf_size); |
| ret = FAILURE; |
| goto done; |
| } |
| done: |
| /* Close socket */ |
| close(sockfd); |
| if (buf) |
| free(buf); |
| return ret; |
| } |
| |
| /** |
| * @brief Show usage information for the wifidirect_gas_comeback_discovery commands |
| * |
| * $return N/A |
| */ |
| static void |
| print_wifidirect_gas_comeback_usage(void) |
| { |
| printf("\nUsage : wifidirect_gas_comeback_request/response [CONFIG_FILE]\n"); |
| printf("CONFIG_FILE contains WIFIDIRECT GAS comeback request/response payload.\n"); |
| return; |
| } |
| |
| /** |
| * @brief Creates a wifidirect_gas_comeback_service_discovery request/response and |
| * sends to the driver |
| * |
| * Usage: "Usage : wifidirect_gas_comeback_request/response [CONFIG_FILE]" |
| * |
| * @param argc Number of arguments |
| * @param argv Pointer to the arguments |
| * @return SUCCESS or FAILURE |
| **/ |
| static void |
| wifidirectcmd_gas_comeback_discovery(int argc, char *argv[]) |
| { |
| wifidirect_gas_comeback_request *req_buf = NULL; |
| wifidirect_gas_comeback_response *resp_buf = NULL; |
| char *line = NULL; |
| FILE *config_file = NULL; |
| int i, opt, li = 0, arg_num = 0, ret = 0, wifidirect_level = 0; |
| char *args[30], *pos = NULL, wifidirect_mac[20], wifidirect_cmd[40]; |
| t_u8 dev_address[ETH_ALEN], cmd_found = 0; |
| t_u8 *buffer = NULL, *tmp_buffer = NULL; |
| t_u8 req_resp = 0; /* req = 0, resp = 1 */ |
| t_u16 cmd_len = 0, query_len = 0, vendor_len = 0, service_len = 0; |
| t_u16 dns_len = 0, record_len = 0, upnp_len = 0; |
| |
| strncpy(wifidirect_cmd, argv[2], sizeof(wifidirect_cmd) - 1); |
| while ((opt = getopt_long(argc, argv, "+", cmd_options, NULL)) != -1) { |
| switch (opt) { |
| default: |
| print_wifidirect_gas_comeback_usage(); |
| return; |
| } |
| } |
| argc -= optind; |
| argv += optind; |
| |
| /* Check arguments */ |
| if (argc != 3) { |
| printf("ERR:Incorrect number of arguments.\n"); |
| print_wifidirect_gas_comeback_usage(); |
| return; |
| } |
| |
| /* Check if file exists */ |
| config_file = fopen(argv[2], "r"); |
| if (config_file == NULL) { |
| printf("\nERR:Config file can not open.\n"); |
| return; |
| } |
| line = (char *)malloc(MAX_CONFIG_LINE); |
| if (!line) { |
| printf("ERR:Cannot allocate memory for line\n"); |
| goto done; |
| } |
| memset(line, 0, MAX_CONFIG_LINE); |
| |
| /* Parse file and process */ |
| while (config_get_line(line, MAX_CONFIG_LINE, config_file, &li, &pos)) { |
| arg_num = parse_line(line, args); |
| if (!cmd_found && |
| strncmp(args[0], wifidirect_cmd, strlen(args[0]))) |
| continue; |
| cmd_found = 1; |
| |
| if (strcmp(args[0], "wifidirect_gas_comeback_request") == 0) { |
| wifidirect_level = |
| WIFIDIRECT_DISCOVERY_REQUEST_RESPONSE; |
| /* For wifidirect_service_gas_comeback, basic initialization here */ |
| /* Subtract extra two bytes added as a part of query request structure */ |
| cmd_len = sizeof(wifidirect_gas_comeback_request) - 2; |
| buffer = (t_u8 *)malloc(cmd_len); |
| if (!buffer) { |
| printf("ERR:Cannot allocate memory!\n"); |
| goto done; |
| } |
| req_buf = (wifidirect_gas_comeback_request *)buffer; |
| req_buf->cmd_code = |
| HostCmd_CMD_WIFIDIRECT_SERVICE_DISCOVERY; |
| req_buf->size = cmd_len; |
| req_buf->seq_num = 0; |
| req_buf->result = 0; |
| |
| } else if (strcmp(args[0], "wifidirect_gas_comeback_response") |
| == 0) { |
| wifidirect_level = |
| WIFIDIRECT_DISCOVERY_REQUEST_RESPONSE; |
| req_resp = 1; |
| /* For wifidirect_service_discovery, basic initialization here */ |
| /* Subtract extra two bytes added as a part of query response structure */ |
| cmd_len = sizeof(wifidirect_gas_comeback_response) - 2; |
| buffer = (t_u8 *)malloc(cmd_len); |
| if (!buffer) { |
| printf("ERR:Cannot allocate memory!\n"); |
| goto done; |
| } |
| resp_buf = (wifidirect_gas_comeback_response *)buffer; |
| resp_buf->cmd_code = |
| HostCmd_CMD_WIFIDIRECT_SERVICE_DISCOVERY; |
| resp_buf->size = cmd_len; |
| resp_buf->seq_num = 0; |
| resp_buf->result = 0; |
| |
| } else if (strcmp(args[0], "PeerAddr") == 0) { |
| strncpy(wifidirect_mac, args[1], 20); |
| if ((ret = |
| mac2raw(wifidirect_mac, dev_address)) != SUCCESS) { |
| printf("ERR: %s Address \n", |
| ret == FAILURE ? "Invalid MAC" : ret == |
| WIFIDIRECT_RET_MAC_BROADCAST ? |
| "Broadcast" : "Multicast"); |
| goto done; |
| } |
| (!req_resp) ? memcpy(req_buf->peer_mac_addr, |
| dev_address, |
| ETH_ALEN) : memcpy(resp_buf-> |
| peer_mac_addr, |
| dev_address, |
| ETH_ALEN); |
| |
| } else if (strcmp(args[0], "Category") == 0) { |
| if (is_input_valid |
| (WIFIDIRECT_CATEGORY, arg_num - 1, args + 1) |
| != SUCCESS) { |
| goto done; |
| |
| } |
| (!req_resp) ? (req_buf->category = |
| (t_u8)atoi(args[1])) : (resp_buf-> |
| category = |
| (t_u8) |
| atoi(args[1])); |
| } else if (strcmp(args[0], "Action") == 0) { |
| if (is_input_valid |
| (WIFIDIRECT_ACTION, arg_num - 1, args + 1) |
| != SUCCESS) { |
| goto done; |
| } |
| (!req_resp) ? (req_buf->action = |
| (t_u8)A2HEXDECIMAL(args[1])) |
| : (resp_buf->action = |
| (t_u8)A2HEXDECIMAL(args[1])); |
| } else if (strcmp(args[0], "DialogToken") == 0) { |
| if (is_input_valid |
| (WIFIDIRECT_DIALOGTOKEN, arg_num - 1, args + 1) |
| != SUCCESS) { |
| goto done; |
| } |
| (!req_resp) ? (req_buf->dialog_taken = |
| (t_u8)atoi(args[1])) : (resp_buf-> |
| dialog_taken = |
| (t_u8) |
| atoi(args[1])); |
| } else if (strcmp(args[0], "StatusCode") == 0) { |
| resp_buf->status_code = (t_u16)A2HEXDECIMAL(args[1]); |
| resp_buf->status_code = |
| cpu_to_le16(resp_buf->status_code); |
| } else if (strcmp(args[0], "GasComebackDelay") == 0) { |
| if (is_input_valid |
| (WIFIDIRECT_GAS_COMEBACK_DELAY, arg_num - 1, |
| args + 1) |
| != SUCCESS) { |
| goto done; |
| } |
| resp_buf->gas_reply = (t_u16)A2HEXDECIMAL(args[1]); |
| resp_buf->gas_reply = cpu_to_le16(resp_buf->gas_reply); |
| } else if (strcmp(args[0], "GasResponseFragID") == 0) { |
| resp_buf->gas_fragment_id = (t_u8)A2HEXDECIMAL(args[1]); |
| } else if (strcmp(args[0], "AdvertizementProtocolIE") == 0) { |
| if (is_input_valid |
| (WIFIDIRECT_DISC_ADPROTOIE, arg_num - 1, args + 1) |
| != SUCCESS) { |
| goto done; |
| } |
| for (i = 0; i < arg_num - 1; i++) |
| resp_buf->advertize_protocol_ie[i] = |
| (t_u8)A2HEXDECIMAL(args[i + 1]); |
| } else if (strcmp(args[0], "InfoId") == 0) { |
| if (is_input_valid |
| (WIFIDIRECT_DISC_INFOID, arg_num - 1, args + 1) |
| != SUCCESS) { |
| goto done; |
| } |
| for (i = 0; i < arg_num - 1; i++) |
| resp_buf->info_id[i] = |
| (t_u8)A2HEXDECIMAL(args[i + 1]); |
| query_len += arg_num - 1; |
| } else if (strcmp(args[0], "OUI") == 0) { |
| if (is_input_valid |
| (WIFIDIRECT_OUI, arg_num - 1, args + 1) |
| != SUCCESS) { |
| goto done; |
| } |
| for (i = 0; i < arg_num - 1; i++) |
| resp_buf->oui[i] = |
| (t_u8)A2HEXDECIMAL(args[i + 1]); |
| service_len += arg_num - 1; |
| query_len += arg_num - 1; |
| } else if (strcmp(args[0], "OUISubType") == 0) { |
| if (is_input_valid |
| (WIFIDIRECT_OUISUBTYPE, arg_num - 1, args + 1) |
| != SUCCESS) { |
| goto done; |
| } |
| resp_buf->oui_sub_type = (t_u8)atoi(args[1]); |
| service_len++; |
| query_len++; |
| } else if (strcmp(args[0], "QueryRequestLen") == 0 || |
| strcmp(args[0], "QueryResponseLen") == 0) { |
| wifidirect_level = WIFIDIRECT_DISCOVERY_QUERY; |
| } else if (strcmp(args[0], "RequestLen") == 0 || |
| strcmp(args[0], "ResponseLen") == 0) { |
| wifidirect_level = WIFIDIRECT_DISCOVERY_SERVICE; |
| query_len += 2; |
| } else if (strcmp(args[0], "VendorLen") == 0) { |
| wifidirect_level = WIFIDIRECT_DISCOVERY_VENDOR; |
| service_len += 2; |
| query_len += 2; |
| } else if (strcmp(args[0], "QueryData") == 0 || |
| strcmp(args[0], "ResponseData") == 0) { |
| wifidirect_level = |
| WIFIDIRECT_DISCOVERY_QUERY_RESPONSE_PER_PROTOCOL; |
| } else if (strcmp(args[0], "ServiceProtocol") == 0) { |
| if (is_input_valid |
| (WIFIDIRECT_DISC_SERVICEPROTO, arg_num - 1, |
| args + 1) |
| != SUCCESS) { |
| goto done; |
| } |
| resp_buf->service_protocol = (t_u8)atoi(args[1]); |
| vendor_len++; |
| service_len++; |
| query_len++; |
| /* |
| * For uPnP, due to union allocation, a extra byte is allocated |
| * reduce it here for uPnP |
| */ |
| cmd_len--; |
| } else if (strcmp(args[0], "ServiceUpdateIndicator") == 0) { |
| if (is_input_valid |
| (WIFIDIRECT_SERVICEUPDATE_INDICATOR, arg_num - 1, |
| args + 1) |
| != SUCCESS) { |
| goto done; |
| } |
| resp_buf->service_update_indicator = |
| cpu_to_le16((t_u16)atoi(args[1])); |
| service_len += 2; |
| query_len += 2; |
| } else if (strcmp(args[0], "ServiceTransactionId") == 0) { |
| if (is_input_valid |
| (WIFIDIRECT_DISC_SERVICETRANSACID, arg_num - 1, |
| args + 1) |
| != SUCCESS) { |
| goto done; |
| } |
| resp_buf->service_transaction_id = (t_u8)atoi(args[1]); |
| vendor_len++; |
| service_len++; |
| query_len++; |
| } else if (strcmp(args[0], "ServiceStatus") == 0) { |
| if (is_input_valid |
| (WIFIDIRECT_DISC_SERVICE_STATUS, arg_num - 1, |
| args + 1) |
| != SUCCESS) { |
| goto done; |
| } |
| resp_buf->disc_status_code = (t_u8)atoi(args[1]); |
| vendor_len++; |
| service_len++; |
| query_len++; |
| } else if (strcmp(args[0], "DNSName") == 0) { |
| if (args[1][0] == '"') { |
| args[1]++; |
| if (args[1][strlen(args[1]) - 1] == '"') |
| args[1][strlen(args[1]) - 1] = '\0'; |
| |
| dns_len = strlen(args[1]); |
| tmp_buffer = realloc(buffer, cmd_len + dns_len); |
| if (!tmp_buffer) { |
| printf("ERR:Cannot add DNS name to buffer!\n"); |
| goto done; |
| } else { |
| buffer = tmp_buffer; |
| tmp_buffer = NULL; |
| } |
| strncpy((char *)resp_buf->disc_resp.u.bonjour. |
| dns, args[1], strlen(args[1])); |
| } else { |
| /* HEX input */ |
| dns_len = arg_num - 1; |
| tmp_buffer = realloc(buffer, cmd_len + dns_len); |
| if (!tmp_buffer) { |
| printf("ERR:Cannot add DNS name to buffer!\n"); |
| goto done; |
| } else { |
| buffer = tmp_buffer; |
| tmp_buffer = NULL; |
| } |
| for (i = 0; i < arg_num - 1; i++) |
| resp_buf->disc_resp.u.bonjour.dns[i] = |
| (t_u8)A2HEXDECIMAL(args[i + 1]); |
| } |
| cmd_len += dns_len; |
| vendor_len += dns_len; |
| service_len += dns_len; |
| query_len += dns_len; |
| } else if (strcmp(args[0], "DNSType") == 0) { |
| if (is_input_valid |
| (WIFIDIRECT_DISC_DNSTYPE, arg_num - 1, args + 1) |
| != SUCCESS) { |
| goto done; |
| } |
| *(&resp_buf->disc_resp.u.bonjour.dns_type + dns_len) = |
| (t_u8)A2HEXDECIMAL(args[1]); |
| vendor_len++; |
| service_len++; |
| query_len++; |
| } else if (strcmp(args[0], "BonjourVersion") == 0) { |
| if (is_input_valid |
| (WIFIDIRECT_DISC_BONJOUR_VERSION, arg_num - 1, |
| args + 1) |
| != SUCCESS) { |
| goto done; |
| } |
| *(&resp_buf->disc_resp.u.bonjour.version + dns_len) = |
| (t_u8)atoi(args[1]); |
| vendor_len++; |
| service_len++; |
| query_len++; |
| } else if (strcmp(args[0], "uPnPVersion") == 0) { |
| if (is_input_valid |
| (WIFIDIRECT_DISC_UPNP_VERSION, arg_num - 1, |
| args + 1) |
| != SUCCESS) { |
| goto done; |
| } |
| resp_buf->disc_resp.u.upnp.version = |
| (t_u8)A2HEXDECIMAL(args[1]); |
| vendor_len++; |
| service_len++; |
| query_len++; |
| } else if (strcmp(args[0], "uPnPQueryValue") == 0 || |
| strcmp(args[0], "uPnPResponseValue") == 0) { |
| if (args[1][0] == '"') { |
| args[1]++; |
| if (args[1][strlen(args[1]) - 1] == '"') |
| args[1][strlen(args[1]) - 1] = '\0'; |
| |
| upnp_len = strlen(args[1]); |
| tmp_buffer = |
| realloc(buffer, cmd_len + upnp_len); |
| if (!tmp_buffer) { |
| printf("ERR:Cannot add uPnP value to buffer!\n"); |
| goto done; |
| } else { |
| buffer = tmp_buffer; |
| tmp_buffer = NULL; |
| } |
| strncpy((char *)resp_buf->disc_resp.u.upnp. |
| value, args[1], upnp_len); |
| } else { |
| /* HEX input */ |
| upnp_len = arg_num - 1; |
| tmp_buffer = |
| realloc(buffer, cmd_len + upnp_len); |
| if (!tmp_buffer) { |
| printf("ERR:Cannot add uPnP value to buffer!\n"); |
| goto done; |
| } else { |
| buffer = tmp_buffer; |
| tmp_buffer = NULL; |
| } |
| for (i = 0; i < arg_num - 1; i++) |
| resp_buf->disc_resp.u.upnp.value[i] = |
| (t_u8)A2HEXDECIMAL(args[i + 1]); |
| } |
| cmd_len += upnp_len; |
| vendor_len += upnp_len; |
| service_len += upnp_len; |
| query_len += upnp_len; |
| } else if (strcmp(args[0], "RecordData") == 0) { |
| if (args[1][0] == '"') { |
| args[1]++; |
| if (args[1][strlen(args[1]) - 1] == '"') |
| args[1][strlen(args[1]) - 1] = '\0'; |
| |
| record_len = strlen(args[1]); |
| tmp_buffer = |
| realloc(buffer, cmd_len + record_len); |
| if (!tmp_buffer) { |
| printf("ERR:Cannot add Record name to buffer!\n"); |
| goto done; |
| } else { |
| buffer = tmp_buffer; |
| tmp_buffer = NULL; |
| } |
| if (!req_resp) { |
| printf("ERR:Cannot add Record name to buffer!\n"); |
| goto done; |
| } |
| strncpy((char *)resp_buf->disc_resp.u.bonjour. |
| record, args[1], strlen(args[1])); |
| } else { |
| /* HEX input */ |
| record_len = arg_num - 1; |
| tmp_buffer = |
| realloc(buffer, cmd_len + record_len); |
| if (!tmp_buffer) { |
| printf("ERR:Cannot add Record name to buffer!\n"); |
| goto done; |
| } else { |
| buffer = tmp_buffer; |
| tmp_buffer = NULL; |
| } |
| if (!req_resp) { |
| printf("ERR:Cannot add Record name to buffer!\n"); |
| goto done; |
| } |
| for (i = 0; i < arg_num - 1; i++) |
| resp_buf->disc_resp.u.bonjour. |
| record[i] = |
| (t_u8)A2HEXDECIMAL(args[i + 1]); |
| |
| } |
| cmd_len += record_len; |
| vendor_len += record_len; |
| service_len += record_len; |
| query_len += record_len; |
| } else if (strcmp(args[0], "}") == 0) { |
| switch (wifidirect_level) { |
| case WIFIDIRECT_DISCOVERY_QUERY: |
| resp_buf->query_len = cpu_to_le16(query_len); |
| break; |
| case WIFIDIRECT_DISCOVERY_SERVICE: |
| resp_buf->response_len = |
| cpu_to_le16(service_len); |
| break; |
| case WIFIDIRECT_DISCOVERY_VENDOR: |
| resp_buf->vendor_len = cpu_to_le16(vendor_len); |
| break; |
| default: |
| break; |
| } |
| if (wifidirect_level) { |
| if (wifidirect_level == |
| WIFIDIRECT_DISCOVERY_REQUEST_RESPONSE) |
| break; |
| wifidirect_level--; |
| } |
| } |
| } |
| /* Send collective command */ |
| wifidirect_ioctl((t_u8 *)buffer, &cmd_len, cmd_len); |
| done: |
| fclose(config_file); |
| if (buffer) |
| free(buffer); |
| if (line) |
| free(line); |
| } |
| |
| /** |
| * @brief Show usage information for the wifidirect_discovery commands |
| * |
| * $return N/A |
| */ |
| static void |
| print_wifidirect_discovery_usage(void) |
| { |
| printf("\nUsage : wifidirect_discovery_request/response [CONFIG_FILE]\n"); |
| printf("CONFIG_FILE contains WIFIDIRECT service discovery payload.\n"); |
| return; |
| } |
| |
| /** |
| * @brief Creates a wifidirect_service_discovery request/response and |
| * sends to the driver |
| * |
| * Usage: "Usage : wifidirect_discovery_request/response [CONFIG_FILE]" |
| * |
| * @param argc Number of arguments |
| * @param argv Pointer to the arguments |
| * @return SUCCESS or FAILURE |
| **/ |
| static void |
| wifidirectcmd_service_discovery(int argc, char *argv[]) |
| { |
| wifidirect_discovery_request *req_buf = NULL; |
| wifidirect_discovery_response *resp_buf = NULL; |
| char *line = NULL; |
| FILE *config_file = NULL; |
| int i, opt, li = 0, arg_num = 0, ret = 0, wifidirect_level = 0; |
| char *args[30], *pos = NULL, wifidirect_mac[20], wifidirect_cmd[32]; |
| t_u8 dev_address[ETH_ALEN], cmd_found = 0; |
| t_u8 *buffer = NULL, *tmp_buffer = NULL; |
| t_u8 req_resp = 0; /* req = 0, resp = 1 */ |
| t_u16 cmd_len = 0, query_len = 0, vendor_len = 0, service_len = 0; |
| t_u16 dns_len = 0, record_len = 0, upnp_len = 0; |
| |
| strncpy(wifidirect_cmd, argv[2], sizeof(wifidirect_cmd) - 1); |
| while ((opt = getopt_long(argc, argv, "+", cmd_options, NULL)) != -1) { |
| switch (opt) { |
| default: |
| print_wifidirect_discovery_usage(); |
| return; |
| } |
| } |
| argc -= optind; |
| argv += optind; |
| |
| /* Check arguments */ |
| if (argc != 3) { |
| printf("ERR:Incorrect number of arguments.\n"); |
| print_wifidirect_discovery_usage(); |
| return; |
| } |
| |
| /* Check if file exists */ |
| config_file = fopen(argv[2], "r"); |
| if (config_file == NULL) { |
| printf("\nERR:Config file can not open.\n"); |
| return; |
| } |
| line = (char *)malloc(MAX_CONFIG_LINE); |
| if (!line) { |
| printf("ERR:Cannot allocate memory for line\n"); |
| goto done; |
| } |
| memset(line, 0, MAX_CONFIG_LINE); |
| |
| /* Parse file and process */ |
| while (config_get_line(line, MAX_CONFIG_LINE, config_file, &li, &pos)) { |
| arg_num = parse_line(line, args); |
| if (!cmd_found && |
| strncmp(args[0], wifidirect_cmd, strlen(args[0]))) |
| continue; |
| cmd_found = 1; |
| |
| if (strcmp(args[0], "wifidirect_discovery_request") == 0) { |
| wifidirect_level = |
| WIFIDIRECT_DISCOVERY_REQUEST_RESPONSE; |
| /* For wifidirect_service_discovery, basic initialization here */ |
| cmd_len = sizeof(wifidirect_discovery_request); |
| buffer = (t_u8 *)malloc(cmd_len); |
| if (!buffer) { |
| printf("ERR:Cannot allocate memory!\n"); |
| goto done; |
| } |
| req_buf = (wifidirect_discovery_request *)buffer; |
| req_buf->cmd_code = |
| HostCmd_CMD_WIFIDIRECT_SERVICE_DISCOVERY; |
| req_buf->size = cmd_len; |
| req_buf->seq_num = 0; |
| req_buf->result = 0; |
| |
| } else if (strcmp(args[0], "wifidirect_discovery_response") == |
| 0) { |
| wifidirect_level = |
| WIFIDIRECT_DISCOVERY_REQUEST_RESPONSE; |
| req_resp = 1; |
| /* For wifidirect_service_discovery, basic initialization here */ |
| cmd_len = sizeof(wifidirect_discovery_response); |
| buffer = (t_u8 *)malloc(cmd_len); |
| if (!buffer) { |
| printf("ERR:Cannot allocate memory!\n"); |
| goto done; |
| } |
| resp_buf = (wifidirect_discovery_response *)buffer; |
| resp_buf->cmd_code = |
| HostCmd_CMD_WIFIDIRECT_SERVICE_DISCOVERY; |
| resp_buf->size = cmd_len; |
| resp_buf->seq_num = 0; |
| resp_buf->result = 0; |
| |
| } else if (strcmp(args[0], "PeerAddr") == 0) { |
| strncpy(wifidirect_mac, args[1], 20 - 1); |
| if ((ret = |
| mac2raw(wifidirect_mac, dev_address)) != SUCCESS) { |
| printf("ERR: %s Address \n", |
| ret == FAILURE ? "Invalid MAC" : ret == |
| WIFIDIRECT_RET_MAC_BROADCAST ? |
| "Broadcast" : "Multicast"); |
| goto done; |
| } |
| (!req_resp) ? memcpy(req_buf->peer_mac_addr, |
| dev_address, |
| ETH_ALEN) : memcpy(resp_buf-> |
| peer_mac_addr, |
| dev_address, |
| ETH_ALEN); |
| |
| } else if (strcmp(args[0], "Category") == 0) { |
| if (is_input_valid |
| (WIFIDIRECT_CATEGORY, arg_num - 1, args + 1) |
| != SUCCESS) { |
| goto done; |
| |
| } |
| (!req_resp) ? (req_buf->category = |
| (t_u8)atoi(args[1])) : (resp_buf-> |
| category = |
| (t_u8) |
| atoi(args[1])); |
| } else if (strcmp(args[0], "Action") == 0) { |
| if (is_input_valid |
| (WIFIDIRECT_ACTION, arg_num - 1, args + 1) |
| != SUCCESS) { |
| goto done; |
| } |
| (!req_resp) ? (req_buf->action = |
| (t_u8)A2HEXDECIMAL(args[1])) |
| : (resp_buf->action = |
| (t_u8)A2HEXDECIMAL(args[1])); |
| } else if (strcmp(args[0], "DialogToken") == 0) { |
| if (is_input_valid |
| (WIFIDIRECT_DIALOGTOKEN, arg_num - 1, args + 1) |
| != SUCCESS) { |
| goto done; |
| } |
| (!req_resp) ? (req_buf->dialog_taken = |
| (t_u8)atoi(args[1])) : (resp_buf-> |
| dialog_taken = |
| (t_u8) |
| atoi(args[1])); |
| } else if (strcmp(args[0], "StatusCode") == 0) { |
| resp_buf->status_code = (t_u8)atoi(args[1]); |
| } else if (strcmp(args[0], "GasComebackDelay") == 0) { |
| if (is_input_valid |
| (WIFIDIRECT_GAS_COMEBACK_DELAY, arg_num - 1, |
| args + 1) |
| != SUCCESS) { |
| goto done; |
| } |
| resp_buf->gas_reply = (t_u16)A2HEXDECIMAL(args[1]); |
| resp_buf->gas_reply = cpu_to_le16(resp_buf->gas_reply); |
| } else if (strcmp(args[0], "AdvertizementProtocolIE") == 0) { |
| if (is_input_valid |
| (WIFIDIRECT_DISC_ADPROTOIE, arg_num - 1, args + 1) |
| != SUCCESS) { |
| goto done; |
| } |
| if (!req_resp) { |
| for (i = 0; i < arg_num - 1; i++) |
| req_buf->advertize_protocol_ie[i] = |
| (t_u8)A2HEXDECIMAL(args[i + 1]); |
| } else { |
| for (i = 0; i < arg_num - 1; i++) |
| resp_buf->advertize_protocol_ie[i] = |
| (t_u8)A2HEXDECIMAL(args[i + 1]); |
| } |
| } else if (strcmp(args[0], "InfoId") == 0) { |
| if (is_input_valid |
| (WIFIDIRECT_DISC_INFOID, arg_num - 1, args + 1) |
| != SUCCESS) { |
| goto done; |
| } |
| if (!req_resp) { |
| for (i = 0; i < arg_num - 1; i++) |
| req_buf->info_id[i] = |
| (t_u8)A2HEXDECIMAL(args[i + 1]); |
| } else { |
| for (i = 0; i < arg_num - 1; i++) |
| resp_buf->info_id[i] = |
| (t_u8)A2HEXDECIMAL(args[i + 1]); |
| } |
| query_len += arg_num - 1; |
| } else if (strcmp(args[0], "OUI") == 0) { |
| if (is_input_valid |
| (WIFIDIRECT_OUI, arg_num - 1, args + 1) |
| != SUCCESS) { |
| goto done; |
| } |
| if (!req_resp) { |
| for (i = 0; i < arg_num - 1; i++) |
| req_buf->oui[i] = |
| (t_u8)A2HEXDECIMAL(args[i + 1]); |
| } else { |
| for (i = 0; i < arg_num - 1; i++) |
| resp_buf->oui[i] = |
| (t_u8)A2HEXDECIMAL(args[i + 1]); |
| } |
| service_len += arg_num - 1; |
| query_len += arg_num - 1; |
| } else if (strcmp(args[0], "OUISubType") == 0) { |
| if (is_input_valid |
| (WIFIDIRECT_OUISUBTYPE, arg_num - 1, args + 1) |
| != SUCCESS) { |
| goto done; |
| } |
| (!req_resp) ? (req_buf->oui_sub_type = |
| (t_u8)atoi(args[1])) : (resp_buf-> |
| oui_sub_type = |
| (t_u8) |
| atoi(args[1])); |
| service_len++; |
| query_len++; |
| } else if (strcmp(args[0], "QueryRequestLen") == 0 || |
| strcmp(args[0], "QueryResponseLen") == 0) { |
| wifidirect_level = WIFIDIRECT_DISCOVERY_QUERY; |
| } else if (strcmp(args[0], "RequestLen") == 0 || |
| strcmp(args[0], "ResponseLen") == 0) { |
| wifidirect_level = WIFIDIRECT_DISCOVERY_SERVICE; |
| query_len += 2; |
| } else if (strcmp(args[0], "VendorLen") == 0) { |
| wifidirect_level = WIFIDIRECT_DISCOVERY_VENDOR; |
| service_len += 2; |
| query_len += 2; |
| } else if (strcmp(args[0], "QueryData") == 0 || |
| strcmp(args[0], "ResponseData") == 0) { |
| wifidirect_level = |
| WIFIDIRECT_DISCOVERY_QUERY_RESPONSE_PER_PROTOCOL; |
| } else if (strcmp(args[0], "ServiceProtocol") == 0) { |
| if (is_input_valid |
| (WIFIDIRECT_DISC_SERVICEPROTO, arg_num - 1, |
| args + 1) |
| != SUCCESS) { |
| goto done; |
| } |
| if (!req_resp) { |
| req_buf->service_protocol = (t_u8)atoi(args[1]); |
| /* |
| * For uPnP, due to union allocation, a extra byte |
| * is allocated reduce it here for uPnP |
| */ |
| if (req_buf->service_protocol == 2) |
| cmd_len--; |
| } else { |
| resp_buf->service_protocol = |
| (t_u8)atoi(args[1]); |
| if (resp_buf->service_protocol == 2) |
| cmd_len--; |
| } |
| vendor_len++; |
| service_len++; |
| query_len++; |
| } else if (strcmp(args[0], "ServiceUpdateIndicator") == 0) { |
| if (is_input_valid |
| (WIFIDIRECT_SERVICEUPDATE_INDICATOR, arg_num - 1, |
| args + 1) |
| != SUCCESS) { |
| goto done; |
| } |
| (!req_resp) ? (req_buf->service_update_indicator = |
| cpu_to_le16((t_u16)atoi(args[1]))) : |
| (resp_buf->service_update_indicator = |
| cpu_to_le16((t_u16)atoi(args[1]))); |
| service_len += 2; |
| query_len += 2; |
| } else if (strcmp(args[0], "ServiceTransactionId") == 0) { |
| if (is_input_valid |
| (WIFIDIRECT_DISC_SERVICETRANSACID, arg_num - 1, |
| args + 1) |
| != SUCCESS) { |
| goto done; |
| } |
| (!req_resp) ? (req_buf->service_transaction_id = |
| (t_u8)atoi(args[1])) : (resp_buf-> |
| service_transaction_id |
| = |
| (t_u8) |
| atoi(args[1])); |
| vendor_len++; |
| service_len++; |
| query_len++; |
| } else if (strcmp(args[0], "ServiceStatus") == 0) { |
| if (is_input_valid |
| (WIFIDIRECT_DISC_SERVICE_STATUS, arg_num - 1, |
| args + 1) |
| != SUCCESS) { |
| goto done; |
| } |
| resp_buf->disc_status_code = (t_u8)atoi(args[1]); |
| vendor_len++; |
| service_len++; |
| query_len++; |
| } else if (strcmp(args[0], "DNSName") == 0) { |
| if (args[1][0] == '"') { |
| args[1]++; |
| if (args[1][strlen(args[1]) - 1] == '"') |
| args[1][strlen(args[1]) - 1] = '\0'; |
| |
| dns_len = strlen(args[1]); |
| tmp_buffer = realloc(buffer, cmd_len + dns_len); |
| if (!tmp_buffer) { |
| printf("ERR:Cannot add DNS name to buffer!\n"); |
| goto done; |
| } else { |
| buffer = tmp_buffer; |
| tmp_buffer = NULL; |
| } |
| (!req_resp) ? |
| (strncpy |
| ((char *)req_buf->disc_query.u.bonjour. |
| dns, args[1], |
| strlen(args[1]))) : (strncpy((char *) |
| resp_buf-> |
| disc_resp. |
| u. |
| bonjour. |
| dns, |
| args[1], |
| strlen |
| (args |
| [1]))); |
| } else { |
| /* HEX input */ |
| dns_len = arg_num - 1; |
| tmp_buffer = realloc(buffer, cmd_len + dns_len); |
| if (!tmp_buffer) { |
| printf("ERR:Cannot add DNS name to buffer!\n"); |
| goto done; |
| } else { |
| buffer = tmp_buffer; |
| tmp_buffer = NULL; |
| } |
| if (!req_resp) { |
| for (i = 0; i < arg_num - 1; i++) |
| req_buf->disc_query.u.bonjour. |
| dns[i] = |
| (t_u8) |
| A2HEXDECIMAL(args |
| [i + 1]); |
| } else { |
| for (i = 0; i < arg_num - 1; i++) |
| resp_buf->disc_resp.u.bonjour. |
| dns[i] = |
| (t_u8) |
| A2HEXDECIMAL(args |
| [i + 1]); |
| } |
| } |
| cmd_len += dns_len; |
| vendor_len += dns_len; |
| service_len += dns_len; |
| query_len += dns_len; |
| } else if (strcmp(args[0], "DNSType") == 0) { |
| if (is_input_valid |
| (WIFIDIRECT_DISC_DNSTYPE, arg_num - 1, args + 1) |
| != SUCCESS) { |
| goto done; |
| } |
| (!req_resp) ? |
| (* |
| (&req_buf->disc_query.u.bonjour.dns_type + |
| dns_len) = |
| (t_u8)A2HEXDECIMAL(args[1])) : (*(&resp_buf-> |
| disc_resp.u. |
| bonjour. |
| dns_type + |
| dns_len) = |
| (t_u8) |
| A2HEXDECIMAL |
| (args[1])); |
| vendor_len++; |
| service_len++; |
| query_len++; |
| } else if (strcmp(args[0], "BonjourVersion") == 0) { |
| if (is_input_valid |
| (WIFIDIRECT_DISC_BONJOUR_VERSION, arg_num - 1, |
| args + 1) |
| != SUCCESS) { |
| goto done; |
| } |
| (!req_resp) ? |
| (* |
| (&req_buf->disc_query.u.bonjour.version + |
| dns_len) = |
| (t_u8)atoi(args[1])) : (*(&resp_buf->disc_resp. |
| u.bonjour.version + |
| dns_len) = |
| (t_u8)atoi(args[1])); |
| vendor_len++; |
| service_len++; |
| query_len++; |
| } else if (strcmp(args[0], "uPnPVersion") == 0) { |
| if (is_input_valid |
| (WIFIDIRECT_DISC_UPNP_VERSION, arg_num - 1, |
| args + 1) |
| != SUCCESS) { |
| goto done; |
| } |
| (!req_resp) ? |
| (req_buf->disc_query.u.upnp.version = |
| (t_u8)A2HEXDECIMAL(args[1])) : (resp_buf-> |
| disc_resp.u. |
| upnp.version = |
| (t_u8) |
| A2HEXDECIMAL |
| (args[1])); |
| vendor_len++; |
| service_len++; |
| query_len++; |
| } else if (strcmp(args[0], "uPnPQueryValue") == 0 || |
| strcmp(args[0], "uPnPResponseValue") == 0) { |
| if (args[1][0] == '"') { |
| args[1]++; |
| if (args[1][strlen(args[1]) - 1] == '"') |
| args[1][strlen(args[1]) - 1] = '\0'; |
| |
| upnp_len = strlen(args[1]); |
| tmp_buffer = |
| realloc(buffer, cmd_len + upnp_len); |
| if (!tmp_buffer) { |
| printf("ERR:Cannot add uPnP value to buffer!\n"); |
| goto done; |
| } else { |
| buffer = tmp_buffer; |
| tmp_buffer = NULL; |
| } |
| (!req_resp) ? |
| (strncpy |
| ((char *)req_buf->disc_query.u.upnp. |
| value, args[1], |
| upnp_len)) : (strncpy((char *) |
| resp_buf-> |
| disc_resp.u. |
| upnp.value, |
| args[1], |
| upnp_len)); |
| } else { |
| /* HEX input */ |
| upnp_len = arg_num - 1; |
| tmp_buffer = |
| realloc(buffer, cmd_len + upnp_len); |
| if (!tmp_buffer) { |
| printf("ERR:Cannot add uPnP value to buffer!\n"); |
| goto done; |
| } else { |
| buffer = tmp_buffer; |
| tmp_buffer = NULL; |
| } |
| if (!req_resp) { |
| for (i = 0; i < arg_num - 1; i++) |
| req_buf->disc_query.u.upnp. |
| value[i] = |
| (t_u8) |
| A2HEXDECIMAL(args |
| [i + 1]); |
| } else { |
| for (i = 0; i < arg_num - 1; i++) |
| resp_buf->disc_resp.u.upnp. |
| value[i] = |
| (t_u8) |
| A2HEXDECIMAL(args |
| [i + 1]); |
| } |
| } |
| cmd_len += upnp_len; |
| vendor_len += upnp_len; |
| service_len += upnp_len; |
| query_len += upnp_len; |
| } else if (strcmp(args[0], "RecordData") == 0) { |
| if (args[1][0] == '"') { |
| args[1]++; |
| if (args[1][strlen(args[1]) - 1] == '"') |
| args[1][strlen(args[1]) - 1] = '\0'; |
| |
| record_len = strlen(args[1]); |
| tmp_buffer = |
| realloc(buffer, cmd_len + record_len); |
| if (!tmp_buffer) { |
| printf("ERR:Cannot add Record name to buffer!\n"); |
| goto done; |
| } else { |
| buffer = tmp_buffer; |
| tmp_buffer = NULL; |
| } |
| if (!req_resp) { |
| printf("ERR:Cannot add Record name to buffer!\n"); |
| goto done; |
| } |
| strncpy((char *)resp_buf->disc_resp.u.bonjour. |
| record + dns_len, args[1], |
| strlen(args[1])); |
| } else { |
| /* HEX input */ |
| record_len = arg_num - 1; |
| tmp_buffer = |
| realloc(buffer, cmd_len + record_len); |
| if (!tmp_buffer) { |
| printf("ERR:Cannot add Record name to buffer!\n"); |
| goto done; |
| } else { |
| buffer = tmp_buffer; |
| tmp_buffer = NULL; |
| } |
| if (!req_resp) { |
| printf("ERR:Cannot add Record name to buffer!\n"); |
| goto done; |
| } |
| for (i = 0; i < arg_num - 1; i++) |
| *(&resp_buf->disc_resp.u.bonjour. |
| record[i] + dns_len) = |
| (t_u8)A2HEXDECIMAL(args[i + 1]); |
| } |
| cmd_len += record_len; |
| vendor_len += record_len; |
| service_len += record_len; |
| query_len += record_len; |
| } else if (strcmp(args[0], "}") == 0) { |
| switch (wifidirect_level) { |
| case WIFIDIRECT_DISCOVERY_QUERY: |
| (!req_resp) ? (req_buf->query_len = |
| cpu_to_le16(query_len)) |
| : (resp_buf->query_len = |
| cpu_to_le16(query_len)); |
| break; |
| case WIFIDIRECT_DISCOVERY_SERVICE: |
| (!req_resp) ? (req_buf->request_len = |
| cpu_to_le16(service_len)) |
| : (resp_buf->response_len = |
| cpu_to_le16(service_len)); |
| break; |
| case WIFIDIRECT_DISCOVERY_VENDOR: |
| (!req_resp) ? (req_buf->vendor_len = |
| cpu_to_le16(vendor_len)) |
| : (resp_buf->vendor_len = |
| cpu_to_le16(vendor_len)); |
| break; |
| default: |
| break; |
| } |
| if (wifidirect_level) { |
| if (wifidirect_level == |
| WIFIDIRECT_DISCOVERY_REQUEST_RESPONSE) |
| break; |
| wifidirect_level--; |
| } |
| } |
| } |
| /* Send collective command */ |
| wifidirect_ioctl((t_u8 *)buffer, &cmd_len, cmd_len); |
| done: |
| fclose(config_file); |
| if (buffer) |
| free(buffer); |
| if (line) |
| free(line); |
| } |
| |
| /** |
| * @brief Show usage information for the wifidirect_config command |
| * |
| * $return N/A |
| */ |
| static void |
| print_wifidirect_config_usage(void) |
| { |
| printf("\nUsage : wifidirect_config [CONFIG_FILE]\n"); |
| printf("\nIf CONFIG_FILE is provided, a 'set' is performed, else a 'get' is performed.\n"); |
| printf("CONFIG_FILE contains all WIFIDIRECT parameters.\n"); |
| return; |
| } |
| |
| /** |
| * @brief Read the wifidirect parameters and sends to the driver |
| * |
| * @param file_name File to open for configuration parameters. |
| * @param cmd_name Command Name for which parameters are read. |
| * @param pbuf Pointer to output buffer |
| * @param ie_len_wifidirect Length of wifidirect parameters to return |
| * @param ie_len_wps Length of WPS parameters to return |
| * @return SUCCESS or FAILURE |
| */ |
| static const t_u8 wifidirect_oui[] = { 0x50, 0x6F, 0x9A, 0x09 }; |
| static const t_u8 wps_oui[] = { 0x00, 0x50, 0xF2, 0x04 }; |
| |
| static void |
| wifidirect_file_params_config(char *file_name, char *cmd_name, t_u8 *pbuf, |
| t_u16 *ie_len_wifidirect, t_u16 *ie_len_wps) |
| { |
| FILE *config_file = NULL; |
| char *line = NULL; |
| int i = 0, li = 0, arg_num = 0, ret = 0, wifidirect_level = |
| 0, no_of_chan_entries = 0, no_of_noa = 0; |
| int secondary_index = -1, flag = 1, group_secondary_index = -1; |
| char **args = NULL; |
| char *pos = NULL; |
| char wifidirect_mac[20], country[4], wifidirect_ssid[33]; |
| char WPS_manufacturer[33], WPS_modelname[33], WPS_devicename[33], |
| wifi_group_direct_ssid[33]; |
| t_u8 dev_channels[MAX_CHANNELS]; |
| t_u8 iface_list[ETH_ALEN * MAX_INTERFACE_ADDR_COUNT]; |
| t_u8 dev_address[ETH_ALEN]; |
| t_u8 group_dev_address[ETH_ALEN]; |
| t_u8 *extra = NULL; |
| t_u8 *buffer = pbuf; |
| t_u16 cmd_len_wifidirect = 0, cmd_len_wps = 0, tlv_len = 0, extra_len = |
| 0, temp = 0; |
| t_u16 wps_model_len = 0, wps_serial_len = 0, wps_vendor_len = 0; |
| t_u16 pri_category = 0, pri_sub_category = 0, config_methods = 0; |
| t_u16 sec_category = 0, sec_sub_category = 0, group_sec_sub_category = |
| 0, group_sec_category = 0; |
| t_u16 avail_period = 0, avail_interval = 0; |
| t_u8 secondary_oui[4], group_secondary_oui[4]; |
| t_u16 WPS_specconfigmethods = 0, WPS_associationstate = 0, |
| WPS_configurationerror = 0, WPS_devicepassword = 0; |
| t_u8 dev_capability = 0, group_capability = 0, cmd_found = 0, |
| group_owner_intent = 0, primary_oui[4], iface_count = 0, |
| regulatory_class = 0, channel_number = 0, manageability = 0, |
| op_regulatory_class = 0, op_channel_number = |
| 0, invitation_flag = 0; |
| t_u8 WPS_version = 0, WPS_setupstate = 0, WPS_requesttype = |
| 0, WPS_responsetype = |
| 0, WPS_UUID[WPS_UUID_MAX_LEN], |
| WPS_primarydevicetype[WPS_DEVICE_TYPE_MAX_LEN], WPS_RFband = |
| 0, WPS_modelnumber[32], WPS_serialnumber[32], WPS_VendorExt[32]; |
| t_u8 go_config_timeout = 0, client_config_timeout = 0; |
| t_u8 secondary_dev_count = 0, group_secondary_dev_count = 0; |
| t_u16 temp16 = 0; |
| t_u8 secondary_dev_info[WPS_DEVICE_TYPE_LEN * |
| MAX_SECONDARY_DEVICE_COUNT]; |
| t_u8 group_secondary_dev_info[WPS_DEVICE_TYPE_LEN * |
| MAX_GROUP_SECONDARY_DEVICE_COUNT]; |
| t_u8 wifidirect_client_dev_count = 0, wifidirect_client_dev_index = |
| 0, temp8 = 0; |
| wifidirect_client_dev_info |
| wifidirect_client_dev_info_list[MAX_SECONDARY_DEVICE_COUNT]; |
| t_u8 wifidirect_total_secondary_dev_count = 0; |
| t_u8 wifidirect_group_total_ssid_len = 0, tlv_offset = |
| 0, temp_dev_size = 0; |
| t_u8 noa_index = 0, opp_ps = 0, ctwindow_opp_ps = 0, count_type = 0; |
| t_u32 duration = 0, interval = 0, start_time = 0; |
| t_u16 total_chan_len = 0; |
| t_u8 chan_entry_regulatory_class = 0, chan_entry_num_of_channels = 0; |
| t_u8 *chan_entry_list = NULL; |
| t_u8 *chan_buf = NULL; |
| noa_descriptor noa_descriptor_list[MAX_NOA_DESCRIPTORS]; |
| /* Check if file exists */ |
| config_file = fopen(file_name, "r"); |
| if (config_file == NULL) { |
| printf("\nERR:Config file can not open.\n"); |
| return; |
| } |
| |
| /* Memory allocations */ |
| line = (char *)malloc(MAX_CONFIG_LINE); |
| if (!line) { |
| printf("ERR:Cannot allocate memory for line\n"); |
| goto done; |
| } |
| memset(line, 0, MAX_CONFIG_LINE); |
| |
| extra = (t_u8 *)malloc(MAX_CONFIG_LINE); |
| if (!extra) { |
| printf("ERR:Cannot allocate memory for extra\n"); |
| goto done; |
| } |
| memset(extra, 0, MAX_CONFIG_LINE); |
| |
| args = (char **)malloc(sizeof(char *) * MAX_ARGS_NUM); |
| if (!args) { |
| printf("ERR:Cannot allocate memory for args\n"); |
| goto done; |
| } |
| memset(args, 0, (sizeof(char *) * MAX_ARGS_NUM)); |
| |
| if (!wifidir_use_fixed_ie_indices()) { |
| special_mask_custom_ie_buf *wifidirect_ie_buf; |
| wifidirect_ie_buf = (special_mask_custom_ie_buf *)buffer; |
| memcpy(&wifidirect_ie_buf->Oui[0], wifidirect_oui, |
| sizeof(wifidirect_oui)); |
| cmd_len_wifidirect += sizeof(wifidirect_oui); |
| } |
| /* Parse file and process */ |
| while (config_get_line(line, MAX_CONFIG_LINE, config_file, &li, &pos)) { |
| arg_num = parse_line(line, args); |
| if (!cmd_found && strncmp(args[0], cmd_name, strlen(args[0]))) |
| continue; |
| cmd_found = 1; |
| if (strcmp(args[0], "wifidirect_config") == 0) { |
| wifidirect_level = WIFIDIRECT_PARAMS_CONFIG; |
| } else if (strcmp(args[0], "Capability") == 0) { |
| wifidirect_level = WIFIDIRECT_CAPABILITY_CONFIG; |
| } else if (strcmp(args[0], "GroupOwnerIntent") == 0) { |
| wifidirect_level = WIFIDIRECT_GROUP_OWNER_INTENT_CONFIG; |
| } else if (strcmp(args[0], "Channel") == 0) { |
| wifidirect_level = WIFIDIRECT_CHANNEL_CONFIG; |
| } else if (strcmp(args[0], "OperatingChannel") == 0) { |
| wifidirect_level = WIFIDIRECT_OPCHANNEL_CONFIG; |
| } else if (strcmp(args[0], "InfrastructureManageabilityInfo") == |
| 0) { |
| wifidirect_level = WIFIDIRECT_MANAGEABILITY_CONFIG; |
| } else if (strcmp(args[0], "InvitationFlagBitmap") == 0) { |
| wifidirect_level = WIFIDIRECT_INVITATION_FLAG_CONFIG; |
| } else if (strcmp(args[0], "ChannelList") == 0) { |
| wifidirect_level = WIFIDIRECT_CHANNEL_LIST_CONFIG; |
| } else if (strcmp(args[0], "NoticeOfAbsence") == 0) { |
| wifidirect_level = WIFIDIRECT_NOTICE_OF_ABSENCE; |
| } else if (strcmp(args[0], "NoA_descriptor") == 0) { |
| wifidirect_level = WIFIDIRECT_NOA_DESCRIPTOR; |
| } else if (strcmp(args[0], "DeviceInfo") == 0) { |
| wifidirect_level = WIFIDIRECT_DEVICE_INFO_CONFIG; |
| } else if (strcmp(args[0], "SecondaryDeviceType") == 0) { |
| wifidirect_level = WIFIDIRECT_DEVICE_SEC_INFO_CONFIG; |
| } else if (strcmp(args[0], "GroupInfo") == 0) { |
| wifidirect_level = WIFIDIRECT_GROUP_INFO_CONFIG; |
| } else if (strcmp(args[0], "GroupSecondaryDeviceTypes") == 0) { |
| wifidirect_level = WIFIDIRECT_GROUP_SEC_INFO_CONFIG; |
| } else if (strcmp(args[0], "GroupWifiDirectDeviceTypes") == 0) { |
| wifidirect_level = WIFIDIRECT_GROUP_CLIENT_INFO_CONFIG; |
| } else if (strcmp(args[0], "GroupId") == 0) { |
| wifidirect_level = WIFIDIRECT_GROUP_ID_CONFIG; |
| } else if (strcmp(args[0], "GroupBSSId") == 0) { |
| wifidirect_level = WIFIDIRECT_GROUP_BSS_ID_CONFIG; |
| } else if (strcmp(args[0], "DeviceId") == 0) { |
| wifidirect_level = WIFIDIRECT_DEVICE_ID_CONFIG; |
| } else if (strcmp(args[0], "Interface") == 0) { |
| wifidirect_level = WIFIDIRECT_INTERFACE_CONFIG; |
| } else if (strcmp(args[0], "ConfigurationTimeout") == 0) { |
| wifidirect_level = WIFIDIRECT_TIMEOUT_CONFIG; |
| } else if (strcmp(args[0], "ExtendedListenTime") == 0) { |
| wifidirect_level = WIFIDIRECT_EXTENDED_TIME_CONFIG; |
| } else if (strcmp(args[0], "IntendedIntfAddress") == 0) { |
| wifidirect_level = WIFIDIRECT_INTENDED_ADDR_CONFIG; |
| } else if (strcmp(args[0], "WPSIE") == 0) { |
| wifidirect_level = WIFIDIRECT_WPSIE; |
| } else if (strcmp(args[0], "Extra") == 0) { |
| wifidirect_level = WIFIDIRECT_EXTRA; |
| } else if (strcmp(args[0], "WIFIDIRECT_MAC") == 0 || |
| strcmp(args[0], "GroupAddr") == 0 || |
| strcmp(args[0], "GroupBssId") == 0 || |
| strcmp(args[0], "InterfaceAddress") == 0 || |
| strcmp(args[0], "GroupInterfaceAddress") == 0 || |
| strcmp(args[0], "DeviceAddress") == 0) { |
| strncpy(wifidirect_mac, args[1], 20 - 1); |
| if ((ret = |
| mac2raw(wifidirect_mac, dev_address)) != SUCCESS) { |
| printf("ERR: %s Address \n", |
| ret == FAILURE ? "Invalid MAC" : ret == |
| WIFIDIRECT_RET_MAC_BROADCAST ? |
| "Broadcast" : "Multicast"); |
| goto done; |
| } |
| } else if (strncmp(args[0], "GroupWifiDirectDeviceAddress", 21) |
| == 0) { |
| strncpy(wifidirect_mac, args[1], 20 - 1); |
| if ((ret = |
| mac2raw(wifidirect_mac, |
| group_dev_address)) != SUCCESS) { |
| printf("ERR: %s Address \n", |
| ret == FAILURE ? "Invalid MAC" : ret == |
| WIFIDIRECT_RET_MAC_BROADCAST ? |
| "Broadcast" : "Multicast"); |
| goto done; |
| } |
| wifidirect_client_dev_index++; |
| if (wifidirect_client_dev_index > |
| wifidirect_client_dev_count) { |
| printf("ERR: No of Client Dev count is less than no of client dev configs!!\n"); |
| goto done; |
| } |
| group_secondary_index = 0; |
| tlv_offset = |
| wifidirect_group_total_ssid_len + |
| wifidirect_total_secondary_dev_count * |
| WPS_DEVICE_TYPE_LEN; |
| memcpy(wifidirect_client_dev_info_list |
| [wifidirect_client_dev_index - |
| 1].wifidirect_dev_address + tlv_offset, |
| group_dev_address, ETH_ALEN); |
| } else if (strncmp(args[0], "GroupWifiDirectIntfAddress", 19) == |
| 0) { |
| strncpy(wifidirect_mac, args[1], 20 - 1); |
| if ((ret = |
| mac2raw(wifidirect_mac, |
| group_dev_address)) != SUCCESS) { |
| printf("ERR: %s Address \n", |
| ret == FAILURE ? "Invalid MAC" : ret == |
| WIFIDIRECT_RET_MAC_BROADCAST ? |
| "Broadcast" : "Multicast"); |
| goto done; |
| } |
| memcpy(wifidirect_client_dev_info_list |
| [wifidirect_client_dev_index - |
| 1].wifidirect_intf_address + tlv_offset, |
| group_dev_address, ETH_ALEN); |
| } else if (strncmp(args[0], "GroupWifiDirectDeviceCapab", 19) == |
| 0) { |
| if (is_input_valid |
| (WIFIDIRECT_DEVICECAPABILITY, arg_num - 1, |
| args + 1) != SUCCESS) { |
| goto done; |
| } |
| temp8 = (t_u8)atoi(args[1]); |
| memcpy(&wifidirect_client_dev_info_list |
| [wifidirect_client_dev_index - |
| 1].wifidirect_dev_capability + tlv_offset, |
| &temp8, sizeof(temp8)); |
| } else if (strncmp |
| (args[0], "GroupWifiDirectWPSConfigMethods", |
| 24) == 0) { |
| if (is_input_valid |
| (WIFIDIRECT_WPSCONFMETHODS, arg_num - 1, |
| args + 1) != SUCCESS) { |
| goto done; |
| } |
| temp16 = (t_u16)A2HEXDECIMAL(args[1]); |
| memcpy(&wifidirect_client_dev_info_list |
| [wifidirect_client_dev_index - |
| 1].config_methods + tlv_offset, &temp16, |
| sizeof(temp16)); |
| (t_u16)A2HEXDECIMAL(args[1]); |
| } else if (strncmp |
| (args[0], "GroupPrimaryDeviceTypeCategory", |
| 30) == 0) { |
| if (is_input_valid |
| (WIFIDIRECT_PRIDEVTYPECATEGORY, arg_num - 1, |
| args + 1) != SUCCESS) { |
| goto done; |
| } |
| pri_category = (t_u16)atoi(args[1]); |
| temp16 = htons(pri_category); |
| memcpy(&wifidirect_client_dev_info_list |
| [wifidirect_client_dev_index - |
| 1].primary_category + tlv_offset, &temp16, |
| sizeof(temp16)); |
| } else if (strncmp(args[0], "GroupPrimaryDeviceTypeOUI", 25) == |
| 0) { |
| if (is_input_valid |
| (WIFIDIRECT_PRIDEVTYPEOUI, arg_num - 1, |
| args + 1) != SUCCESS) { |
| goto done; |
| } |
| for (i = 0; i < 4; i++) { |
| temp8 = (t_u8)A2HEXDECIMAL(args[i + 1]); |
| memcpy(&wifidirect_client_dev_info_list |
| [wifidirect_client_dev_index - |
| 1].primary_oui[i] |
| + tlv_offset, &temp8, sizeof(temp8)); |
| } |
| } else if (strncmp |
| (args[0], "GroupPrimaryDeviceTypeSubCategory", |
| 33) == 0) { |
| if (is_input_valid |
| (WIFIDIRECT_PRIDEVTYPESUBCATEGORY, arg_num - 1, |
| args + 1) != SUCCESS) { |
| goto done; |
| } |
| pri_sub_category = (t_u16)atoi(args[1]); |
| temp16 = htons(pri_sub_category); |
| memcpy(&wifidirect_client_dev_info_list |
| [wifidirect_client_dev_index - |
| 1].primary_subcategory + tlv_offset, &temp16, |
| sizeof(temp16)); |
| } else if (strncmp(args[0], "GroupSecondaryDeviceCount", 25) == |
| 0) { |
| if (is_input_valid |
| (WIFIDIRECT_GROUP_SECONDARYDEVCOUNT, arg_num - 1, |
| args + 1) != SUCCESS) { |
| goto done; |
| } |
| group_secondary_dev_count = (t_u8)atoi(args[1]); |
| memcpy(&wifidirect_client_dev_info_list |
| [wifidirect_client_dev_index - |
| 1].wifidirect_secondary_dev_count + tlv_offset, |
| &group_secondary_dev_count, |
| sizeof(group_secondary_dev_count)); |
| wifidirect_total_secondary_dev_count += |
| group_secondary_dev_count; |
| if (group_secondary_dev_count) |
| memset(group_secondary_dev_info, 0, |
| sizeof(group_secondary_dev_info)); |
| } else if (strncmp |
| (args[0], "GroupSecondaryDeviceTypeCategory", |
| 30) == 0) { |
| if (is_input_valid |
| (WIFIDIRECT_PRIDEVTYPECATEGORY, arg_num - 1, |
| args + 1) != SUCCESS) { |
| goto done; |
| } |
| sec_category = (t_u16)atoi(args[1]); |
| group_sec_category = cpu_to_le16(sec_category); |
| group_secondary_index++; |
| } else if (strncmp(args[0], "GroupSecondaryDeviceTypeOUI", 27) |
| == 0) { |
| if (is_input_valid |
| (WIFIDIRECT_PRIDEVTYPEOUI, arg_num - 1, |
| args + 1) != SUCCESS) { |
| goto done; |
| } |
| for (i = 0; i < 4; i++) |
| group_secondary_oui[i] = |
| (t_u8)A2HEXDECIMAL(args[i + 1]); |
| } else if (strncmp |
| (args[0], "GroupSecondaryDeviceTypeSubCategory", |
| 35) == 0) { |
| if (is_input_valid |
| (WIFIDIRECT_PRIDEVTYPESUBCATEGORY, arg_num - 1, |
| args + 1) != SUCCESS) { |
| goto done; |
| } |
| if (group_secondary_index < 0 || |
| group_secondary_index >= |
| MAX_SECONDARY_DEVICE_COUNT) { |
| printf("Error in configuration file %s:%d", |
| file_name, li); |
| goto done; |
| } |
| sec_sub_category = (t_u16)atoi(args[1]); |
| group_sec_sub_category = |
| cpu_to_le16(group_sec_sub_category); |
| if (group_secondary_dev_count) { |
| memcpy(&group_secondary_dev_info |
| [(group_secondary_index - |
| 1) * WPS_DEVICE_TYPE_LEN], |
| &group_sec_category, sizeof(t_u16)); |
| memcpy(&group_secondary_dev_info |
| [((group_secondary_index - |
| 1) * WPS_DEVICE_TYPE_LEN) + 2], |
| group_secondary_oui, |
| sizeof(secondary_oui)); |
| memcpy(&group_secondary_dev_info |
| [((group_secondary_index - |
| 1) * WPS_DEVICE_TYPE_LEN) + 6], |
| &group_sec_sub_category, sizeof(t_u16)); |
| } |
| |
| } else if (strncmp(args[0], "GroupWifiDirectDeviceCount", 19) == |
| 0) { |
| if (is_input_valid |
| (WIFIDIRECT_SECONDARYDEVCOUNT, arg_num - 1, |
| args + 1) != SUCCESS) { |
| goto done; |
| } |
| wifidirect_client_dev_count = (t_u8)atoi(args[1]); |
| } else if (strncmp(args[0], "GroupWifiDirectDeviceName", 18) == |
| 0) { |
| |
| if (is_input_valid |
| (WIFIDIRECT_GROUP_WIFIDIRECT_DEVICE_NAME, |
| arg_num - 1, args + 1) != SUCCESS) { |
| goto done; |
| } |
| |
| strncpy(wifi_group_direct_ssid, args[1] + 1, |
| strlen(args[1]) - 2); |
| wifi_group_direct_ssid[strlen(args[1]) - 2] = '\0'; |
| temp = htons(SC_Device_Name); |
| memcpy(((t_u8 *) |
| &wifidirect_client_dev_info_list |
| [wifidirect_client_dev_index - |
| 1].wifidirect_device_name_type + tlv_offset), |
| &temp, sizeof(temp)); |
| temp = htons(strlen(wifi_group_direct_ssid)); |
| memcpy(((t_u8 *) |
| &wifidirect_client_dev_info_list |
| [wifidirect_client_dev_index - |
| 1].wifidirect_device_name_len + tlv_offset), |
| &temp, sizeof(temp)); |
| memset(((t_u8 *) |
| &wifidirect_client_dev_info_list |
| [wifidirect_client_dev_index - |
| 1].wifidirect_device_name + tlv_offset), 0, |
| strlen(wifi_group_direct_ssid)); |
| memcpy(((t_u8 *) |
| &wifidirect_client_dev_info_list |
| [wifidirect_client_dev_index - |
| 1].wifidirect_device_name + tlv_offset), |
| &wifi_group_direct_ssid, |
| strlen(wifi_group_direct_ssid)); |
| wifidirect_group_total_ssid_len += |
| strlen(wifi_group_direct_ssid); |
| |
| if (wifidirect_client_dev_index - 1) { |
| temp_dev_size = |
| sizeof(wifidirect_client_dev_info) + |
| strlen(wifi_group_direct_ssid) + |
| group_secondary_dev_count * |
| WPS_DEVICE_TYPE_LEN; |
| memcpy(&wifidirect_client_dev_info_list |
| [wifidirect_client_dev_index - |
| 1].dev_length + (tlv_offset - |
| (group_secondary_dev_count |
| * |
| WPS_DEVICE_TYPE_LEN)), |
| &temp_dev_size, sizeof(temp_dev_size)); |
| } else { |
| |
| temp_dev_size = |
| sizeof(wifidirect_client_dev_info) + |
| strlen(wifi_group_direct_ssid) + |
| group_secondary_dev_count * |
| WPS_DEVICE_TYPE_LEN; |
| wifidirect_client_dev_info_list |
| [wifidirect_client_dev_index - |
| 1].dev_length = |
| sizeof(wifidirect_client_dev_info) + |
| strlen(wifi_group_direct_ssid) + |
| group_secondary_dev_count * |
| WPS_DEVICE_TYPE_LEN; |
| } |
| } else if (strcmp(args[0], "DeviceCapability") == 0) { |
| if (is_input_valid |
| (WIFIDIRECT_DEVICECAPABILITY, arg_num - 1, |
| args + 1) != SUCCESS) { |
| goto done; |
| } |
| dev_capability = (t_u8)atoi(args[1]); |
| } else if (strcmp(args[0], "GroupCapability") == 0) { |
| if (is_input_valid |
| (WIFIDIRECT_GROUPCAPABILITY, arg_num - 1, |
| args + 1) != SUCCESS) { |
| goto done; |
| } |
| group_capability = (t_u8)atoi(args[1]); |
| } else if (strcmp(args[0], "Intent") == 0) { |
| /* Intent -> 0 - 15 */ |
| if (is_input_valid |
| (WIFIDIRECT_INTENT, arg_num - 1, |
| args + 1) != SUCCESS) { |
| goto done; |
| } |
| group_owner_intent = (t_u8)atoi(args[1]); |
| } else if (strcmp(args[0], "RegulatoryClass") == 0) { |
| if (is_input_valid |
| (WIFIDIRECT_REGULATORYCLASS, arg_num - 1, |
| args + 1) != SUCCESS) { |
| goto done; |
| } |
| regulatory_class = (t_u8)atoi(args[1]); |
| } else if (strcmp(args[0], "ChannelNumber") == 0) { |
| if (is_input_valid(CHANNEL, arg_num - 1, args + 1) != |
| SUCCESS) { |
| goto done; |
| } |
| channel_number = (t_u8)atoi(args[1]); |
| } else if (strcmp(args[0], "OpRegulatoryClass") == 0) { |
| if (is_input_valid |
| (WIFIDIRECT_REGULATORYCLASS, arg_num - 1, |
| args + 1) != SUCCESS) { |
| goto done; |
| } |
| op_regulatory_class = (t_u8)atoi(args[1]); |
| } else if (strcmp(args[0], "OpChannelNumber") == 0) { |
| if (is_input_valid(CHANNEL, arg_num - 1, args + 1) != |
| SUCCESS) { |
| goto done; |
| } |
| op_channel_number = (t_u8)atoi(args[1]); |
| } else if (strcmp(args[0], "Manageability") == 0) { |
| if (is_input_valid |
| (WIFIDIRECT_MANAGEABILITY, arg_num - 1, args + 1) |
| != SUCCESS) { |
| goto done; |
| } |
| manageability = (t_u8)atoi(args[1]); |
| } else if (strcmp(args[0], "InvitationFlag") == 0) { |
| if (is_input_valid |
| (WIFIDIRECT_INVITATIONFLAG, arg_num - 1, args + 1) |
| != SUCCESS) { |
| goto done; |
| } |
| invitation_flag = (t_u8)atoi(args[1]); |
| } else if (strcmp(args[0], "CountryString") == 0) { |
| if (is_input_valid |
| (WIFIDIRECT_COUNTRY, arg_num - 1, |
| args + 1) != SUCCESS) { |
| goto done; |
| } |
| strncpy(country, args[1] + 1, 3); |
| country[strlen(args[1]) - 2] = '\0'; |
| } else if (strncmp(args[0], "Regulatory_Class_", 17) == 0) { |
| if (is_input_valid |
| (WIFIDIRECT_REGULATORYCLASS, arg_num - 1, |
| args + 1) != SUCCESS) { |
| goto done; |
| } |
| if (!no_of_chan_entries) { |
| chan_entry_list = |
| (t_u8 *)malloc(MAX_BUFFER_SIZE); |
| if (!chan_entry_list) { |
| printf("ERR:cannot allocate memory for chan_entry_list!\n"); |
| goto done; |
| } |
| memset(chan_entry_list, 0, MAX_BUFFER_SIZE); |
| chan_buf = chan_entry_list; |
| } |
| no_of_chan_entries++; |
| chan_entry_regulatory_class = (t_u8)atoi(args[1]); |
| } else if (strncmp(args[0], "NumofChannels", 13) == 0) { |
| if (is_input_valid |
| (WIFIDIRECT_NO_OF_CHANNELS, arg_num - 1, |
| args + 1) != SUCCESS) { |
| goto done; |
| } |
| chan_entry_num_of_channels = (t_u8)atoi(args[1]); |
| } else if (strncmp(args[0], "ChanList", 8) == 0) { |
| if (chan_entry_num_of_channels != (arg_num - 1)) { |
| printf("ERR:no of channels in ChanList and NumofChannels do not match!\n"); |
| goto done; |
| } |
| if (is_input_valid(SCANCHANNELS, arg_num - 1, args + 1) |
| != SUCCESS) { |
| goto done; |
| } |
| for (i = 0; i < chan_entry_num_of_channels; i++) |
| dev_channels[i] = (t_u8)atoi(args[i + 1]); |
| total_chan_len += chan_entry_num_of_channels; |
| memcpy(chan_buf, &chan_entry_regulatory_class, |
| sizeof(t_u8)); |
| memcpy(chan_buf + 1, &chan_entry_num_of_channels, |
| sizeof(t_u8)); |
| memcpy(chan_buf + 2, dev_channels, |
| chan_entry_num_of_channels); |
| chan_buf += |
| sizeof(t_u8) + sizeof(t_u8) + |
| chan_entry_num_of_channels; |
| } else if (strcmp(args[0], "NoA_Index") == 0) { |
| if (is_input_valid |
| (WIFIDIRECT_NOA_INDEX, arg_num - 1, |
| args + 1) != SUCCESS) { |
| goto done; |
| } |
| noa_index = (t_u8)atoi(args[1]); |
| } else if (strcmp(args[0], "OppPS") == 0) { |
| if (is_input_valid |
| (WIFIDIRECT_OPP_PS, arg_num - 1, |
| args + 1) != SUCCESS) { |
| goto done; |
| } |
| opp_ps = (t_u8)atoi(args[1]); |
| } else if (strcmp(args[0], "CTWindow") == 0) { |
| if (is_input_valid |
| (WIFIDIRECT_CTWINDOW, arg_num - 1, |
| args + 1) != SUCCESS) { |
| goto done; |
| } |
| if ((opp_ps != 0) && (atoi(args[1]) < 10)) { |
| printf("ERR: CTwindow should be greater than or equal to 10 if opp_ps is set!\n"); |
| goto done; |
| } |
| ctwindow_opp_ps = |
| (t_u8)atoi(args[1]) | SET_OPP_PS(opp_ps); |
| } else if (strncmp(args[0], "CountType", 9) == 0) { |
| if (is_input_valid |
| (WIFIDIRECT_COUNT_TYPE, arg_num - 1, |
| args + 1) != SUCCESS) { |
| goto done; |
| } |
| no_of_noa++; |
| if (no_of_noa > MAX_NOA_DESCRIPTORS) { |
| printf("Number of descriptors should not be greater than %d\n", MAX_NOA_DESCRIPTORS); |
| goto done; |
| } |
| count_type = (t_u8)atoi(args[1]); |
| noa_descriptor_list[no_of_noa - 1].count_type = |
| count_type; |
| } else if (strncmp(args[0], "Duration", 8) == 0) { |
| if (is_input_valid |
| (WIFIDIRECT_DURATION, arg_num - 1, |
| args + 1) != SUCCESS) { |
| goto done; |
| } |
| duration = (t_u32)atoi(args[1]); |
| duration = cpu_to_le32(duration); |
| noa_descriptor_list[no_of_noa - 1].duration = duration; |
| } else if (strncmp(args[0], "Interval", 8) == 0) { |
| if (is_input_valid |
| (WIFIDIRECT_INTERVAL, arg_num - 1, |
| args + 1) != SUCCESS) { |
| goto done; |
| } |
| interval = (t_u32)atoi(args[1]); |
| interval = cpu_to_le32(interval); |
| noa_descriptor_list[no_of_noa - 1].interval = interval; |
| } else if (strncmp(args[0], "StartTime", 9) == 0) { |
| if (is_input_valid |
| (WIFIDIRECT_START_TIME, arg_num - 1, |
| args + 1) != SUCCESS) { |
| goto done; |
| } |
| start_time = (t_u32)atoi(args[1]); |
| start_time = cpu_to_le32(start_time); |
| noa_descriptor_list[no_of_noa - 1].start_time = |
| start_time; |
| } else if (strcmp(args[0], "PrimaryDeviceTypeCategory") == 0) { |
| if (is_input_valid |
| (WIFIDIRECT_PRIDEVTYPECATEGORY, arg_num - 1, |
| args + 1) != SUCCESS) { |
| goto done; |
| } |
| pri_category = (t_u16)atoi(args[1]); |
| } else if (strcmp(args[0], "PrimaryDeviceTypeOUI") == 0) { |
| if (is_input_valid |
| (WIFIDIRECT_PRIDEVTYPEOUI, arg_num - 1, |
| args + 1) != SUCCESS) { |
| goto done; |
| } |
| for (i = 0; i < 4; i++) |
| primary_oui[i] = |
| (t_u8)A2HEXDECIMAL(args[i + 1]); |
| } else if (strcmp(args[0], "PrimaryDeviceTypeSubCategory") == 0) { |
| if (is_input_valid |
| (WIFIDIRECT_PRIDEVTYPESUBCATEGORY, arg_num - 1, |
| args + 1) != SUCCESS) { |
| goto done; |
| } |
| pri_sub_category = (t_u16)atoi(args[1]); |
| } else if (strcmp(args[0], "SecondaryDeviceCount") == 0) { |
| if (is_input_valid |
| (WIFIDIRECT_SECONDARYDEVCOUNT, arg_num - 1, |
| args + 1) != SUCCESS) { |
| goto done; |
| } |
| secondary_dev_count = (t_u8)atoi(args[1]); |
| if (secondary_dev_count) |
| memset(secondary_dev_info, 0, |
| sizeof(secondary_dev_info)); |
| } else if (strncmp(args[0], "SecondaryDeviceTypeCategory", 27) |
| == 0) { |
| if (is_input_valid |
| (WIFIDIRECT_PRIDEVTYPECATEGORY, arg_num - 1, |
| args + 1) != SUCCESS) { |
| goto done; |
| } |
| sec_category = (t_u16)atoi(args[1]); |
| sec_category = htons(sec_category); |
| secondary_index++; |
| } else if (strncmp(args[0], "SecondaryDeviceTypeOUI", 22) == 0) { |
| if (is_input_valid |
| (WIFIDIRECT_PRIDEVTYPEOUI, arg_num - 1, |
| args + 1) != SUCCESS) { |
| goto done; |
| } |
| for (i = 0; i < 4; i++) |
| secondary_oui[i] = |
| (t_u8)A2HEXDECIMAL(args[i + 1]); |
| } else if (strncmp |
| (args[0], "SecondaryDeviceTypeSubCategory", |
| 30) == 0) { |
| if (is_input_valid |
| (WIFIDIRECT_PRIDEVTYPESUBCATEGORY, arg_num - 1, |
| args + 1) != SUCCESS) { |
| goto done; |
| } |
| if (secondary_index < 0 || |
| secondary_index >= MAX_SECONDARY_DEVICE_COUNT) { |
| printf("Error in configuration file %s:%d", |
| file_name, li); |
| goto done; |
| } |
| sec_sub_category = (t_u16)atoi(args[1]); |
| sec_sub_category = htons(sec_sub_category); |
| if (secondary_dev_count) { |
| memcpy(&secondary_dev_info |
| [secondary_index * WPS_DEVICE_TYPE_LEN], |
| &sec_category, sizeof(t_u16)); |
| memcpy(&secondary_dev_info |
| [(secondary_index * |
| WPS_DEVICE_TYPE_LEN) + 2], |
| secondary_oui, sizeof(secondary_oui)); |
| memcpy(&secondary_dev_info |
| [(secondary_index * |
| WPS_DEVICE_TYPE_LEN) + 6], |
| &sec_sub_category, sizeof(t_u16)); |
| } |
| } else if (strcmp(args[0], "InterfaceAddressCount") == 0) { |
| if (is_input_valid |
| (WIFIDIRECT_INTERFACECOUNT, arg_num - 1, |
| args + 1) != SUCCESS) { |
| goto done; |
| } |
| iface_count = (t_u8)atoi(args[1]); |
| } else if (strcmp(args[0], "InterfaceAddressList") == 0) { |
| if (iface_count != (arg_num - 1)) { |
| printf("Incorrect address list for %d entries.\n", iface_count); |
| goto done; |
| } |
| for (i = 0; |
| i < iface_count && i < MAX_INTERFACE_ADDR_COUNT; |
| i++) { |
| if ((ret = |
| mac2raw(args[i + 1], |
| &iface_list[i * ETH_ALEN])) != |
| SUCCESS) { |
| printf("ERR: %s Address \n", |
| ret == |
| FAILURE ? "Invalid MAC" : ret == |
| WIFIDIRECT_RET_MAC_BROADCAST ? |
| "Broadcast" : "Multicast"); |
| goto done; |
| } |
| } |
| } else if (strcmp(args[0], "GroupConfigurationTimeout") == 0) { |
| if (is_input_valid |
| (WIFIDIRECT_ATTR_CONFIG_TIMEOUT, arg_num - 1, |
| args + 1) != SUCCESS) { |
| goto done; |
| } |
| go_config_timeout = (t_u8)atoi(args[1]); |
| } else if (strcmp(args[0], "ClientConfigurationTimeout") == 0) { |
| if (is_input_valid |
| (WIFIDIRECT_ATTR_CONFIG_TIMEOUT, arg_num - 1, |
| args + 1) != SUCCESS) { |
| goto done; |
| } |
| client_config_timeout = (t_u8)atoi(args[1]); |
| } else if (strcmp(args[0], "AvailabilityPeriod") == 0) { |
| if (is_input_valid |
| (WIFIDIRECT_ATTR_EXTENDED_TIME, arg_num - 1, |
| args + 1) != SUCCESS) { |
| goto done; |
| } |
| avail_period = (t_u16)atoi(args[1]); |
| } else if (strcmp(args[0], "AvailabilityInterval") == 0) { |
| if (is_input_valid |
| (WIFIDIRECT_ATTR_EXTENDED_TIME, arg_num - 1, |
| args + 1) != SUCCESS) { |
| goto done; |
| } |
| avail_interval = (t_u16)atoi(args[1]); |
| } else if (strcmp(args[0], "WPSConfigMethods") == 0) { |
| if (is_input_valid |
| (WIFIDIRECT_WPSCONFMETHODS, arg_num - 1, |
| args + 1) != SUCCESS) { |
| goto done; |
| } |
| config_methods = (t_u16)A2HEXDECIMAL(args[1]); |
| } else if (strcmp(args[0], "DeviceName") == 0 || |
| strcmp(args[0], "GroupSsId") == 0) { |
| if (is_input_valid |
| (WIFIDIRECT_WPSDEVICENAME, arg_num - 1, |
| args + 1) != SUCCESS) { |
| goto done; |
| } |
| memset(wifidirect_ssid, 0, sizeof(wifidirect_ssid)); |
| strncpy(wifidirect_ssid, args[1], |
| sizeof(wifidirect_ssid) - 1); |
| } else if (strcmp(args[0], "WPSVersion") == 0) { |
| if (is_input_valid |
| (WIFIDIRECT_WPSVERSION, arg_num - 1, |
| args + 1) != SUCCESS) { |
| goto done; |
| } |
| WPS_version = (t_u8)A2HEXDECIMAL(args[1]); |
| } else if (strcmp(args[0], "WPSSetupState") == 0) { |
| if (is_input_valid |
| (WIFIDIRECT_WPSSETUPSTATE, arg_num - 1, |
| args + 1) != SUCCESS) { |
| goto done; |
| } |
| WPS_setupstate = (t_u8)A2HEXDECIMAL(args[1]); |
| } else if (strcmp(args[0], "WPSDeviceName") == 0) { |
| if (is_input_valid |
| (WIFIDIRECT_WPSDEVICENAME, arg_num - 1, |
| args + 1) != SUCCESS) { |
| goto done; |
| } |
| memset(WPS_devicename, 0, sizeof(WPS_devicename)); |
| strncpy(WPS_devicename, args[1], |
| sizeof(WPS_devicename) - 1); |
| } else if (strcmp(args[0], "WPSRequestType") == 0) { |
| if (is_input_valid |
| (WIFIDIRECT_WPSREQRESPTYPE, arg_num - 1, |
| args + 1) != SUCCESS) { |
| goto done; |
| } |
| WPS_requesttype = (t_u8)A2HEXDECIMAL(args[1]); |
| } else if (strcmp(args[0], "WPSResponseType") == 0) { |
| if (is_input_valid |
| (WIFIDIRECT_WPSREQRESPTYPE, arg_num - 1, |
| args + 1) != SUCCESS) { |
| goto done; |
| } |
| WPS_responsetype = (t_u8)A2HEXDECIMAL(args[1]); |
| } else if (strcmp(args[0], "WPSSpecConfigMethods") == 0) { |
| if (is_input_valid |
| (WIFIDIRECT_WPSSPECCONFMETHODS, arg_num - 1, |
| args + 1) != SUCCESS) { |
| goto done; |
| } |
| WPS_specconfigmethods = (t_u16)A2HEXDECIMAL(args[1]); |
| } else if (strcmp(args[0], "WPSUUID") == 0) { |
| if (is_input_valid |
| (WIFIDIRECT_WPSUUID, arg_num - 1, |
| args + 1) != SUCCESS) { |
| goto done; |
| } |
| for (i = 0; i < WPS_UUID_MAX_LEN; i++) |
| WPS_UUID[i] = (t_u8)A2HEXDECIMAL(args[i + 1]); |
| } else if (strcmp(args[0], "WPSPrimaryDeviceType") == 0) { |
| if (is_input_valid |
| (WIFIDIRECT_WPSPRIMARYDEVICETYPE, arg_num - 1, |
| args + 1) != SUCCESS) { |
| goto done; |
| } |
| for (i = 0; i < WPS_DEVICE_TYPE_MAX_LEN; i++) |
| WPS_primarydevicetype[i] = |
| (t_u8)A2HEXDECIMAL(args[i + 1]); |
| } else if (strcmp(args[0], "WPSRFBand") == 0) { |
| if (is_input_valid |
| (WIFIDIRECT_WPSRFBAND, arg_num - 1, |
| args + 1) != SUCCESS) { |
| goto done; |
| } |
| WPS_RFband = (t_u8)A2HEXDECIMAL(args[1]); |
| } else if (strcmp(args[0], "WPSAssociationState") == 0) { |
| if (is_input_valid |
| (WIFIDIRECT_WPSASSOCIATIONSTATE, arg_num - 1, |
| args + 1) != SUCCESS) { |
| goto done; |
| } |
| WPS_associationstate = (t_u16)A2HEXDECIMAL(args[1]); |
| } else if (strcmp(args[0], "WPSConfigurationError") == 0) { |
| if (is_input_valid |
| (WIFIDIRECT_WPSCONFIGURATIONERROR, arg_num - 1, |
| args + 1) != SUCCESS) { |
| goto done; |
| } |
| WPS_configurationerror = (t_u16)A2HEXDECIMAL(args[1]); |
| } else if (strcmp(args[0], "WPSDevicePassword") == 0) { |
| if (is_input_valid |
| (WIFIDIRECT_WPSDEVICEPASSWORD, arg_num - 1, |
| args + 1) != SUCCESS) { |
| goto done; |
| } |
| WPS_devicepassword = (t_u16)A2HEXDECIMAL(args[1]); |
| } else if (strcmp(args[0], "WPSManufacturer") == 0) { |
| if (is_input_valid |
| (WIFIDIRECT_WPSMANUFACTURER, arg_num - 1, |
| args + 1) != SUCCESS) { |
| goto done; |
| } |
| memset(WPS_manufacturer, 0, sizeof(WPS_manufacturer)); |
| strncpy(WPS_manufacturer, args[1], |
| sizeof(WPS_manufacturer)); |
| } else if (strcmp(args[0], "WPSModelName") == 0) { |
| if (is_input_valid |
| (WIFIDIRECT_WPSMODELNAME, arg_num - 1, |
| args + 1) != SUCCESS) { |
| goto done; |
| } |
| memset(WPS_modelname, 0, sizeof(WPS_modelname)); |
| strncpy(WPS_modelname, args[1], sizeof(WPS_modelname)); |
| } else if (strcmp(args[0], "WPSModelNumber") == 0) { |
| if (is_input_valid |
| (WIFIDIRECT_WPSMODELNUMBER, arg_num - 1, |
| args + 1) != SUCCESS) { |
| goto done; |
| } |
| for (i = 0; i < arg_num - 1; i++) |
| WPS_modelnumber[i] = |
| (t_u8)A2HEXDECIMAL(args[i + 1]); |
| wps_model_len = arg_num - 1; |
| } else if (strcmp(args[0], "WPSSerialNumber") == 0) { |
| if (is_input_valid |
| (WIFIDIRECT_WPSSERIALNUMBER, arg_num - 1, |
| args + 1) != SUCCESS) { |
| goto done; |
| } |
| for (i = 0; i < arg_num - 1; i++) |
| WPS_serialnumber[i] = |
| (t_u8)A2HEXDECIMAL(args[i + 1]); |
| wps_serial_len = arg_num - 1; |
| } else if (strcmp(args[0], "WPSVendorExtension") == 0) { |
| for (i = 0; i < arg_num - 1; i++) |
| WPS_VendorExt[i] = |
| (t_u8)A2HEXDECIMAL(args[i + 1]); |
| wps_vendor_len = arg_num - 1; |
| } else if (strcmp(args[0], "Buffer") == 0) { |
| for (i = 0; i < arg_num - 1; i++) |
| extra[i] = (t_u8)A2HEXDECIMAL(args[i + 1]); |
| extra_len = arg_num - 1; |
| } else if (strcmp(args[0], "}") == 0) { |
| /* Based on level, populate appropriate struct */ |
| switch (wifidirect_level) { |
| case WIFIDIRECT_DEVICE_ID_CONFIG: |
| { |
| tlvbuf_wifidirect_device_id *tlv = NULL; |
| /* Append a new TLV */ |
| tlv_len = |
| sizeof |
| (tlvbuf_wifidirect_device_id); |
| tlv = (tlvbuf_wifidirect_device_id |
| *)(buffer + cmd_len_wifidirect); |
| cmd_len_wifidirect += tlv_len; |
| /* Set TLV fields */ |
| tlv->tag = |
| TLV_TYPE_WIFIDIRECT_DEVICE_ID; |
| tlv->length = |
| tlv_len - (sizeof(t_u8) + |
| sizeof(t_u16)); |
| memcpy(tlv->dev_mac_address, |
| dev_address, ETH_ALEN); |
| endian_convert_tlv_wifidirect_header_out |
| (tlv); |
| break; |
| } |
| case WIFIDIRECT_CAPABILITY_CONFIG: |
| { |
| tlvbuf_wifidirect_capability *tlv = |
| NULL; |
| /* Append a new TLV */ |
| tlv_len = |
| sizeof |
| (tlvbuf_wifidirect_capability); |
| tlv = (tlvbuf_wifidirect_capability |
| *)(buffer + cmd_len_wifidirect); |
| cmd_len_wifidirect += tlv_len; |
| /* Set TLV fields */ |
| tlv->tag = |
| TLV_TYPE_WIFIDIRECT_CAPABILITY; |
| tlv->length = |
| tlv_len - (sizeof(t_u8) + |
| sizeof(t_u16)); |
| tlv->dev_capability = dev_capability; |
| tlv->group_capability = |
| group_capability; |
| endian_convert_tlv_wifidirect_header_out |
| (tlv); |
| break; |
| } |
| case WIFIDIRECT_GROUP_OWNER_INTENT_CONFIG: |
| { |
| tlvbuf_wifidirect_group_owner_intent |
| *tlv = NULL; |
| /* Append a new TLV */ |
| tlv_len = |
| sizeof |
| (tlvbuf_wifidirect_group_owner_intent); |
| tlv = (tlvbuf_wifidirect_group_owner_intent *)(buffer + cmd_len_wifidirect); |
| cmd_len_wifidirect += tlv_len; |
| /* Set TLV fields */ |
| tlv->tag = |
| TLV_TYPE_WIFIDIRECT_GROUPOWNER_INTENT; |
| tlv->length = |
| tlv_len - (sizeof(t_u8) + |
| sizeof(t_u16)); |
| tlv->dev_intent = group_owner_intent; |
| endian_convert_tlv_wifidirect_header_out |
| (tlv); |
| break; |
| } |
| case WIFIDIRECT_MANAGEABILITY_CONFIG: |
| { |
| tlvbuf_wifidirect_manageability *tlv = |
| NULL; |
| /* Append a new TLV */ |
| tlv_len = |
| sizeof |
| (tlvbuf_wifidirect_manageability); |
| tlv = (tlvbuf_wifidirect_manageability |
| *)(buffer + cmd_len_wifidirect); |
| cmd_len_wifidirect += tlv_len; |
| /* Set TLV fields */ |
| tlv->tag = |
| TLV_TYPE_WIFIDIRECT_MANAGEABILITY; |
| tlv->length = |
| tlv_len - (sizeof(t_u8) + |
| sizeof(t_u16)); |
| tlv->manageability = manageability; |
| endian_convert_tlv_wifidirect_header_out |
| (tlv); |
| break; |
| } |
| case WIFIDIRECT_INVITATION_FLAG_CONFIG: |
| { |
| tlvbuf_wifidirect_invitation_flag *tlv = |
| NULL; |
| /* Append a new TLV */ |
| tlv_len = |
| sizeof |
| (tlvbuf_wifidirect_invitation_flag); |
| tlv = (tlvbuf_wifidirect_invitation_flag |
| *)(buffer + cmd_len_wifidirect); |
| cmd_len_wifidirect += tlv_len; |
| /* Set TLV fields */ |
| tlv->tag = |
| TLV_TYPE_WIFIDIRECT_INVITATION_FLAG; |
| tlv->length = |
| tlv_len - (sizeof(t_u8) + |
| sizeof(t_u16)); |
| tlv->invitation_flag |= invitation_flag; |
| endian_convert_tlv_wifidirect_header_out |
| (tlv); |
| break; |
| } |
| case WIFIDIRECT_CHANNEL_LIST_CONFIG: |
| { |
| tlvbuf_wifidirect_channel_list *tlv = |
| NULL; |
| /* Append a new TLV */ |
| tlv_len = |
| sizeof |
| (tlvbuf_wifidirect_channel_list) |
| + |
| no_of_chan_entries * |
| sizeof(chan_entry) + |
| total_chan_len; |
| tlv = (tlvbuf_wifidirect_channel_list |
| *)(buffer + cmd_len_wifidirect); |
| cmd_len_wifidirect += tlv_len; |
| /* Set TLV fields */ |
| tlv->tag = |
| TLV_TYPE_WIFIDIRECT_CHANNEL_LIST; |
| tlv->length = |
| tlv_len - (sizeof(t_u8) + |
| sizeof(t_u16)); |
| memcpy(tlv->country_string, country, 3); |
| if (tlv->country_string[2] == 0) |
| tlv->country_string[2] = |
| WIFIDIRECT_COUNTRY_LAST_BYTE; |
| memcpy(tlv->wifidirect_chan_entry_list, |
| chan_entry_list, |
| (tlv->length - 3)); |
| endian_convert_tlv_wifidirect_header_out |
| (tlv); |
| break; |
| } |
| case WIFIDIRECT_NOTICE_OF_ABSENCE: |
| { |
| tlvbuf_wifidirect_notice_of_absence *tlv |
| = NULL; |
| /* Append a new TLV */ |
| tlv_len = |
| sizeof |
| (tlvbuf_wifidirect_notice_of_absence) |
| + |
| no_of_noa * |
| sizeof(noa_descriptor); |
| tlv = (tlvbuf_wifidirect_notice_of_absence *)(buffer + cmd_len_wifidirect); |
| cmd_len_wifidirect += tlv_len; |
| /* Set TLV fields */ |
| tlv->tag = |
| TLV_TYPE_WIFIDIRECT_NOTICE_OF_ABSENCE; |
| tlv->length = |
| tlv_len - (sizeof(t_u8) + |
| sizeof(t_u16)); |
| tlv->noa_index = noa_index; |
| tlv->ctwindow_opp_ps = ctwindow_opp_ps; |
| memcpy(tlv-> |
| wifidirect_noa_descriptor_list, |
| noa_descriptor_list, |
| no_of_noa * |
| sizeof(noa_descriptor)); |
| endian_convert_tlv_wifidirect_header_out |
| (tlv); |
| flag = 1; |
| break; |
| } |
| case WIFIDIRECT_NOA_DESCRIPTOR: |
| { |
| wifidirect_level = |
| WIFIDIRECT_NOTICE_OF_ABSENCE; |
| flag = 0; |
| break; |
| } |
| case WIFIDIRECT_CHANNEL_CONFIG: |
| { |
| tlvbuf_wifidirect_channel *tlv = NULL; |
| /* Append a new TLV */ |
| tlv_len = |
| sizeof |
| (tlvbuf_wifidirect_channel); |
| tlv = (tlvbuf_wifidirect_channel |
| *)(buffer + cmd_len_wifidirect); |
| cmd_len_wifidirect += tlv_len; |
| /* Set TLV fields */ |
| tlv->tag = TLV_TYPE_WIFIDIRECT_CHANNEL; |
| tlv->length = |
| tlv_len - (sizeof(t_u8) + |
| sizeof(t_u16)); |
| memcpy(tlv->country_string, country, 3); |
| if (tlv->country_string[2] == 0) |
| tlv->country_string[2] = |
| WIFIDIRECT_COUNTRY_LAST_BYTE; |
| tlv->regulatory_class = |
| regulatory_class; |
| tlv->channel_number = channel_number; |
| endian_convert_tlv_wifidirect_header_out |
| (tlv); |
| break; |
| } |
| case WIFIDIRECT_OPCHANNEL_CONFIG: |
| { |
| tlvbuf_wifidirect_channel *tlv = NULL; |
| /* Append a new TLV */ |
| tlv_len = |
| sizeof |
| (tlvbuf_wifidirect_channel); |
| tlv = (tlvbuf_wifidirect_channel |
| *)(buffer + cmd_len_wifidirect); |
| cmd_len_wifidirect += tlv_len; |
| /* Set TLV fields */ |
| tlv->tag = |
| TLV_TYPE_WIFIDIRECT_OPCHANNEL; |
| tlv->length = |
| tlv_len - (sizeof(t_u8) + |
| sizeof(t_u16)); |
| memcpy(tlv->country_string, country, 3); |
| if (tlv->country_string[2] == 0) |
| tlv->country_string[2] = |
| WIFIDIRECT_COUNTRY_LAST_BYTE; |
| tlv->regulatory_class = |
| op_regulatory_class; |
| tlv->channel_number = op_channel_number; |
| endian_convert_tlv_wifidirect_header_out |
| (tlv); |
| break; |
| } |
| |
| case WIFIDIRECT_DEVICE_INFO_CONFIG: |
| { |
| tlvbuf_wifidirect_device_info *tlv = |
| NULL; |
| /* Append a new TLV */ |
| tlv_len = |
| sizeof |
| (tlvbuf_wifidirect_device_info) |
| + |
| secondary_dev_count * |
| WPS_DEVICE_TYPE_LEN + |
| strlen(wifidirect_ssid); |
| tlv = (tlvbuf_wifidirect_device_info |
| *)(buffer + cmd_len_wifidirect); |
| cmd_len_wifidirect += tlv_len; |
| /* Set TLV fields */ |
| tlv->tag = |
| TLV_TYPE_WIFIDIRECT_DEVICE_INFO; |
| tlv->length = |
| tlv_len - (sizeof(t_u8) + |
| sizeof(t_u16)); |
| memcpy(tlv->dev_address, dev_address, |
| ETH_ALEN); |
| tlv->config_methods = |
| htons(config_methods); |
| tlv->primary_category = |
| htons(pri_category); |
| memcpy(tlv->primary_oui, primary_oui, |
| 4); |
| tlv->primary_subcategory = |
| htons(pri_sub_category); |
| tlv->secondary_dev_count = |
| secondary_dev_count; |
| endian_convert_tlv_wifidirect_header_out |
| (tlv); |
| /* Parameters within secondary_dev_info are already htons'ed */ |
| memcpy(tlv->secondary_dev_info, |
| secondary_dev_info, |
| secondary_dev_count * |
| WPS_DEVICE_TYPE_LEN); |
| temp = htons(SC_Device_Name); |
| memcpy(((t_u8 *)(&tlv-> |
| device_name_type)) + |
| secondary_dev_count * |
| WPS_DEVICE_TYPE_LEN, &temp, |
| sizeof(temp)); |
| temp = htons(strlen(wifidirect_ssid)); |
| memcpy(((t_u8 *)(&tlv-> |
| device_name_len)) + |
| secondary_dev_count * |
| WPS_DEVICE_TYPE_LEN, &temp, |
| sizeof(temp)); |
| memcpy(((t_u8 *)(&tlv->device_name)) + |
| secondary_dev_count * |
| WPS_DEVICE_TYPE_LEN, |
| wifidirect_ssid, |
| strlen(wifidirect_ssid)); |
| flag = 1; |
| break; |
| } |
| case WIFIDIRECT_GROUP_INFO_CONFIG: |
| { |
| tlvbuf_wifidirect_group_info *tlv = |
| NULL; |
| /* Append a new TLV */ |
| tlv_offset = |
| wifidirect_group_total_ssid_len |
| + |
| wifidirect_total_secondary_dev_count |
| * WPS_DEVICE_TYPE_LEN; |
| tlv_len = |
| sizeof |
| (tlvbuf_wifidirect_group_info) |
| + |
| wifidirect_client_dev_count * |
| sizeof |
| (wifidirect_client_dev_info) + |
| tlv_offset; |
| tlv = (tlvbuf_wifidirect_group_info |
| *)(buffer + cmd_len_wifidirect); |
| cmd_len_wifidirect += tlv_len; |
| /* Set TLV fields */ |
| tlv->tag = |
| TLV_TYPE_WIFIDIRECT_GROUP_INFO; |
| tlv->length = tlv_len; |
| memcpy(tlv->wifidirect_client_dev_list, |
| wifidirect_client_dev_info_list, |
| wifidirect_client_dev_count * |
| sizeof |
| (wifidirect_client_dev_info) + |
| tlv_offset); |
| /* Parameters within secondary_dev_info are already htons'ed */ |
| //wps_hexdump(DEBUG_WLAN,"Group Info Hexdump:", (t_u8*)tlv, tlv_len); |
| endian_convert_tlv_wifidirect_header_out |
| (tlv); |
| flag = 1; |
| break; |
| } |
| case WIFIDIRECT_GROUP_SEC_INFO_CONFIG: |
| { |
| wifidirect_level = |
| WIFIDIRECT_GROUP_CLIENT_INFO_CONFIG; |
| |
| if (wifidirect_client_dev_index && |
| group_secondary_index) { |
| memset(((t_u8 *) |
| &wifidirect_client_dev_info_list |
| [wifidirect_client_dev_index |
| - |
| 1]. |
| wifidirect_secondary_dev_info |
| + tlv_offset), 0, |
| group_secondary_index * |
| WPS_DEVICE_TYPE_LEN); |
| memcpy(((t_u8 *) |
| &wifidirect_client_dev_info_list |
| [wifidirect_client_dev_index |
| - |
| 1]. |
| wifidirect_secondary_dev_info |
| + tlv_offset), |
| &group_secondary_dev_info, |
| group_secondary_index * |
| WPS_DEVICE_TYPE_LEN); |
| } |
| tlv_offset = |
| wifidirect_group_total_ssid_len |
| + |
| wifidirect_total_secondary_dev_count |
| * WPS_DEVICE_TYPE_LEN; |
| flag = 0; |
| break; |
| } |
| case WIFIDIRECT_GROUP_CLIENT_INFO_CONFIG: |
| { |
| wifidirect_level = |
| WIFIDIRECT_GROUP_INFO_CONFIG; |
| flag = 0; |
| break; |
| } |
| case WIFIDIRECT_DEVICE_SEC_INFO_CONFIG: |
| { |
| wifidirect_level = |
| WIFIDIRECT_DEVICE_INFO_CONFIG; |
| flag = 0; |
| break; |
| } |
| case WIFIDIRECT_GROUP_ID_CONFIG: |
| { |
| tlvbuf_wifidirect_group_id *tlv = NULL; |
| /* Append a new TLV */ |
| tlv_len = |
| sizeof |
| (tlvbuf_wifidirect_group_id) + |
| strlen(wifidirect_ssid); |
| tlv = (tlvbuf_wifidirect_group_id |
| *)(buffer + cmd_len_wifidirect); |
| cmd_len_wifidirect += tlv_len; |
| /* Set TLV fields */ |
| tlv->tag = TLV_TYPE_WIFIDIRECT_GROUP_ID; |
| tlv->length = |
| tlv_len - (sizeof(t_u8) + |
| sizeof(t_u16)); |
| memcpy(tlv->group_address, dev_address, |
| ETH_ALEN); |
| memcpy(tlv->group_ssid, wifidirect_ssid, |
| strlen(wifidirect_ssid)); |
| endian_convert_tlv_wifidirect_header_out |
| (tlv); |
| break; |
| } |
| case WIFIDIRECT_GROUP_BSS_ID_CONFIG: |
| { |
| tlvbuf_wifidirect_group_bss_id *tlv = |
| NULL; |
| /* Append a new TLV */ |
| tlv_len = |
| sizeof |
| (tlvbuf_wifidirect_group_bss_id); |
| tlv = (tlvbuf_wifidirect_group_bss_id |
| *)(buffer + cmd_len_wifidirect); |
| cmd_len_wifidirect += tlv_len; |
| /* Set TLV fields */ |
| tlv->tag = |
| TLV_TYPE_WIFIDIRECT_GROUP_BSS_ID; |
| tlv->length = |
| tlv_len - (sizeof(t_u8) + |
| sizeof(t_u16)); |
| memcpy(tlv->group_bssid, dev_address, |
| ETH_ALEN); |
| endian_convert_tlv_wifidirect_header_out |
| (tlv); |
| break; |
| } |
| case WIFIDIRECT_INTERFACE_CONFIG: |
| { |
| tlvbuf_wifidirect_interface *tlv = NULL; |
| /* Append a new TLV */ |
| tlv_len = |
| sizeof |
| (tlvbuf_wifidirect_interface) |
| + iface_count * ETH_ALEN; |
| tlv = (tlvbuf_wifidirect_interface |
| *)(buffer + cmd_len_wifidirect); |
| cmd_len_wifidirect += tlv_len; |
| /* Set TLV fields */ |
| tlv->tag = |
| TLV_TYPE_WIFIDIRECT_INTERFACE; |
| tlv->length = |
| tlv_len - (sizeof(t_u8) + |
| sizeof(t_u16)); |
| memcpy(tlv->interface_id, dev_address, |
| ETH_ALEN); |
| tlv->interface_count = iface_count; |
| memcpy(tlv->interface_idlist, |
| iface_list, |
| iface_count * ETH_ALEN); |
| endian_convert_tlv_wifidirect_header_out |
| (tlv); |
| break; |
| } |
| |
| case WIFIDIRECT_TIMEOUT_CONFIG: |
| { |
| tlvbuf_wifidirect_config_timeout *tlv = |
| NULL; |
| /* Append a new TLV */ |
| tlv_len = |
| sizeof |
| (tlvbuf_wifidirect_config_timeout); |
| tlv = (tlvbuf_wifidirect_config_timeout |
| *)(buffer + cmd_len_wifidirect); |
| cmd_len_wifidirect += tlv_len; |
| /* Set TLV fields */ |
| tlv->tag = |
| TLV_TYPE_WIFIDIRECT_CONFIG_TIMEOUT; |
| tlv->length = |
| tlv_len - (sizeof(t_u8) + |
| sizeof(t_u16)); |
| tlv->group_config_timeout = |
| go_config_timeout; |
| tlv->device_config_timeout = |
| client_config_timeout; |
| endian_convert_tlv_wifidirect_header_out |
| (tlv); |
| break; |
| } |
| case WIFIDIRECT_EXTENDED_TIME_CONFIG: |
| { |
| tlvbuf_wifidirect_ext_listen_time *tlv = |
| NULL; |
| /* Append a new TLV */ |
| tlv_len = |
| sizeof |
| (tlvbuf_wifidirect_ext_listen_time); |
| tlv = (tlvbuf_wifidirect_ext_listen_time |
| *)(buffer + cmd_len_wifidirect); |
| cmd_len_wifidirect += tlv_len; |
| /* Set TLV fields */ |
| tlv->tag = |
| TLV_TYPE_WIFIDIRECT_EXTENDED_LISTEN_TIME; |
| tlv->length = |
| tlv_len - (sizeof(t_u8) + |
| sizeof(t_u16)); |
| tlv->availability_period = |
| le16_to_cpu(avail_period); |
| tlv->availability_interval = |
| le16_to_cpu(avail_interval); |
| endian_convert_tlv_wifidirect_header_out |
| (tlv); |
| break; |
| } |
| case WIFIDIRECT_INTENDED_ADDR_CONFIG: |
| { |
| tlvbuf_wifidirect_intended_addr *tlv = |
| NULL; |
| /* Append a new TLV */ |
| tlv_len = |
| sizeof |
| (tlvbuf_wifidirect_intended_addr); |
| tlv = (tlvbuf_wifidirect_intended_addr |
| *)(buffer + cmd_len_wifidirect); |
| cmd_len_wifidirect += tlv_len; |
| /* Set TLV fields */ |
| tlv->tag = |
| TLV_TYPE_WIFIDIRECT_INTENDED_ADDRESS; |
| tlv->length = |
| tlv_len - (sizeof(t_u8) + |
| sizeof(t_u16)); |
| memcpy(tlv->group_address, dev_address, |
| ETH_ALEN); |
| endian_convert_tlv_wifidirect_header_out |
| (tlv); |
| break; |
| } |
| |
| case WIFIDIRECT_WPSIE: |
| { |
| #ifdef DEBUG |
| /* Debug print */ |
| hexdump(buffer, cmd_len_wifidirect, |
| ' '); |
| #endif |
| /* Append TLV for WPSVersion */ |
| tlvbuf_wps_ie *tlv = NULL; |
| tlv_len = |
| sizeof(tlvbuf_wps_ie) + |
| sizeof(WPS_version); |
| tlv = (tlvbuf_wps_ie *)(buffer + |
| cmd_len_wifidirect |
| + |
| sizeof |
| (custom_ie) + |
| cmd_len_wps); |
| |
| if (!wifidir_use_fixed_ie_indices()) { |
| special_mask_custom_ie_buf |
| *wps_ie_buf; |
| wps_ie_buf = |
| (special_mask_custom_ie_buf |
| *)tlv; |
| memcpy(&wps_ie_buf->Oui[0], |
| wps_oui, |
| sizeof(wps_oui)); |
| cmd_len_wps += sizeof(wps_oui); |
| } |
| tlv = (tlvbuf_wps_ie *)(buffer + |
| cmd_len_wifidirect |
| + |
| sizeof |
| (custom_ie) + |
| cmd_len_wps); |
| tlv->tag = SC_Version; |
| tlv->length = |
| tlv_len - 2 * sizeof(t_u16); |
| *(tlv->data) = WPS_version; |
| endian_convert_tlv_wps_header_out(tlv); |
| cmd_len_wps += tlv_len; |
| |
| /* Append TLV for WPSSetupState */ |
| tlv_len = |
| sizeof(tlvbuf_wps_ie) + |
| sizeof(WPS_setupstate); |
| tlv = (tlvbuf_wps_ie *)(buffer + |
| cmd_len_wifidirect |
| + |
| sizeof |
| (custom_ie) + |
| cmd_len_wps); |
| tlv->tag = SC_Simple_Config_State; |
| tlv->length = |
| tlv_len - 2 * sizeof(t_u16); |
| *(tlv->data) = WPS_setupstate; |
| endian_convert_tlv_wps_header_out(tlv); |
| cmd_len_wps += tlv_len; |
| |
| /* Append TLV for WPSRequestType */ |
| tlv_len = |
| sizeof(tlvbuf_wps_ie) + |
| sizeof(WPS_requesttype); |
| tlv = (tlvbuf_wps_ie *)(buffer + |
| cmd_len_wifidirect |
| + |
| sizeof |
| (custom_ie) + |
| cmd_len_wps); |
| tlv->tag = SC_Request_Type; |
| tlv->length = |
| tlv_len - 2 * sizeof(t_u16); |
| *(tlv->data) = WPS_requesttype; |
| endian_convert_tlv_wps_header_out(tlv); |
| cmd_len_wps += tlv_len; |
| |
| /* Append TLV for WPSResponseType */ |
| tlv_len = |
| sizeof(tlvbuf_wps_ie) + |
| sizeof(WPS_responsetype); |
| tlv = (tlvbuf_wps_ie *)(buffer + |
| cmd_len_wifidirect |
| + |
| sizeof |
| (custom_ie) + |
| cmd_len_wps); |
| tlv->tag = SC_Response_Type; |
| tlv->length = |
| tlv_len - 2 * sizeof(t_u16); |
| *(tlv->data) = WPS_responsetype; |
| endian_convert_tlv_wps_header_out(tlv); |
| cmd_len_wps += tlv_len; |
| |
| /* Append TLV for WPSSpecConfigMethods */ |
| tlv_len = |
| sizeof(tlvbuf_wps_ie) + |
| sizeof(WPS_specconfigmethods); |
| tlv = (tlvbuf_wps_ie *)(buffer + |
| cmd_len_wifidirect |
| + |
| sizeof |
| (custom_ie) + |
| cmd_len_wps); |
| tlv->tag = SC_Config_Methods; |
| tlv->length = |
| tlv_len - 2 * sizeof(t_u16); |
| temp = htons(WPS_specconfigmethods); |
| memcpy((t_u16 *)tlv->data, &temp, |
| sizeof(temp)); |
| endian_convert_tlv_wps_header_out(tlv); |
| cmd_len_wps += tlv_len; |
| |
| /* Append TLV for WPSUUID */ |
| tlv_len = |
| sizeof(tlvbuf_wps_ie) + |
| sizeof(WPS_UUID); |
| tlv = (tlvbuf_wps_ie *)(buffer + |
| cmd_len_wifidirect |
| + |
| sizeof |
| (custom_ie) + |
| cmd_len_wps); |
| tlv->tag = SC_UUID_E; |
| tlv->length = |
| tlv_len - 2 * sizeof(t_u16); |
| memcpy(tlv->data, WPS_UUID, |
| WPS_UUID_MAX_LEN); |
| endian_convert_tlv_wps_header_out(tlv); |
| cmd_len_wps += tlv_len; |
| |
| /* Append TLV for WPSPrimaryDeviceType */ |
| tlv_len = |
| sizeof(tlvbuf_wps_ie) + |
| sizeof(WPS_primarydevicetype); |
| tlv = (tlvbuf_wps_ie *)(buffer + |
| cmd_len_wifidirect |
| + |
| sizeof |
| (custom_ie) + |
| cmd_len_wps); |
| tlv->tag = SC_Primary_Device_Type; |
| tlv->length = |
| tlv_len - 2 * sizeof(t_u16); |
| memcpy(tlv->data, WPS_primarydevicetype, |
| WPS_DEVICE_TYPE_MAX_LEN); |
| endian_convert_tlv_wps_header_out(tlv); |
| cmd_len_wps += tlv_len; |
| |
| /* Append TLV for WPSRFBand */ |
| tlv_len = |
| sizeof(tlvbuf_wps_ie) + |
| sizeof(WPS_RFband); |
| tlv = (tlvbuf_wps_ie *)(buffer + |
| cmd_len_wifidirect |
| + |
| sizeof |
| (custom_ie) + |
| cmd_len_wps); |
| tlv->tag = SC_RF_Band; |
| tlv->length = |
| tlv_len - 2 * sizeof(t_u16); |
| *(tlv->data) = WPS_RFband; |
| endian_convert_tlv_wps_header_out(tlv); |
| cmd_len_wps += tlv_len; |
| |
| /* Append TLV for WPSAssociationState */ |
| tlv_len = |
| sizeof(tlvbuf_wps_ie) + |
| sizeof(WPS_associationstate); |
| tlv = (tlvbuf_wps_ie *)(buffer + |
| cmd_len_wifidirect |
| + |
| sizeof |
| (custom_ie) + |
| cmd_len_wps); |
| tlv->tag = SC_Association_State; |
| tlv->length = |
| tlv_len - 2 * sizeof(t_u16); |
| temp = htons(WPS_associationstate); |
| memcpy((t_u16 *)tlv->data, &temp, |
| sizeof(temp)); |
| endian_convert_tlv_wps_header_out(tlv); |
| cmd_len_wps += tlv_len; |
| |
| /* Append TLV for WPSConfigurationError */ |
| tlv_len = |
| sizeof(tlvbuf_wps_ie) + |
| sizeof(WPS_configurationerror); |
| tlv = (tlvbuf_wps_ie *)(buffer + |
| cmd_len_wifidirect |
| + |
| sizeof |
| (custom_ie) + |
| cmd_len_wps); |
| tlv->tag = SC_Configuration_Error; |
| tlv->length = |
| tlv_len - 2 * sizeof(t_u16); |
| temp = htons(WPS_configurationerror); |
| memcpy((t_u16 *)tlv->data, &temp, |
| sizeof(temp)); |
| endian_convert_tlv_wps_header_out(tlv); |
| cmd_len_wps += tlv_len; |
| |
| /* Append TLV for WPSDevicePassword */ |
| tlv_len = |
| sizeof(tlvbuf_wps_ie) + |
| sizeof(WPS_devicepassword); |
| tlv = (tlvbuf_wps_ie *)(buffer + |
| cmd_len_wifidirect |
| + |
| sizeof |
| (custom_ie) + |
| cmd_len_wps); |
| tlv->tag = SC_Device_Password_ID; |
| tlv->length = |
| tlv_len - 2 * sizeof(t_u16); |
| temp = htons(WPS_devicepassword); |
| memcpy((t_u16 *)tlv->data, &temp, |
| sizeof(temp)); |
| endian_convert_tlv_wps_header_out(tlv); |
| cmd_len_wps += tlv_len; |
| |
| /* Append TLV for WPSDeviceName */ |
| tlv_len = |
| sizeof(tlvbuf_wps_ie) + |
| strlen(WPS_devicename); |
| tlv = (tlvbuf_wps_ie *)(buffer + |
| cmd_len_wifidirect |
| + |
| sizeof |
| (custom_ie) + |
| cmd_len_wps); |
| tlv->tag = SC_Device_Name; |
| tlv->length = |
| tlv_len - 2 * sizeof(t_u16); |
| memcpy(tlv->data, WPS_devicename, |
| strlen(WPS_devicename)); |
| endian_convert_tlv_wps_header_out(tlv); |
| cmd_len_wps += tlv_len; |
| |
| /* Append TLV for WPSManufacturer */ |
| tlv_len = |
| sizeof(tlvbuf_wps_ie) + |
| strlen(WPS_manufacturer); |
| tlv = (tlvbuf_wps_ie *)(buffer + |
| cmd_len_wifidirect |
| + |
| sizeof |
| (custom_ie) + |
| cmd_len_wps); |
| tlv->tag = SC_Manufacturer; |
| tlv->length = |
| tlv_len - 2 * sizeof(t_u16); |
| memcpy(tlv->data, WPS_manufacturer, |
| strlen(WPS_manufacturer)); |
| endian_convert_tlv_wps_header_out(tlv); |
| cmd_len_wps += tlv_len; |
| |
| /* Append TLV for WPSModelName */ |
| tlv_len = |
| sizeof(tlvbuf_wps_ie) + |
| strlen(WPS_modelname); |
| tlv = (tlvbuf_wps_ie *)(buffer + |
| cmd_len_wifidirect |
| + |
| sizeof |
| (custom_ie) + |
| cmd_len_wps); |
| tlv->tag = SC_Model_Name; |
| tlv->length = |
| tlv_len - 2 * sizeof(t_u16); |
| memcpy(tlv->data, WPS_modelname, |
| strlen(WPS_modelname)); |
| endian_convert_tlv_wps_header_out(tlv); |
| cmd_len_wps += tlv_len; |
| |
| /* Append TLV for WPSModelNumber */ |
| tlv_len = |
| sizeof(tlvbuf_wps_ie) + |
| wps_model_len; |
| tlv = (tlvbuf_wps_ie *)(buffer + |
| cmd_len_wifidirect |
| + |
| sizeof |
| (custom_ie) + |
| cmd_len_wps); |
| tlv->tag = SC_Model_Number; |
| tlv->length = |
| tlv_len - 2 * sizeof(t_u16); |
| memcpy(tlv->data, WPS_modelnumber, |
| wps_model_len); |
| endian_convert_tlv_wps_header_out(tlv); |
| cmd_len_wps += tlv_len; |
| |
| /* Append TLV for WPSSerialNumber */ |
| tlv_len = |
| sizeof(tlvbuf_wps_ie) + |
| wps_serial_len; |
| tlv = (tlvbuf_wps_ie *)(buffer + |
| cmd_len_wifidirect |
| + |
| sizeof |
| (custom_ie) + |
| cmd_len_wps); |
| tlv->tag = SC_Serial_Number; |
| tlv->length = |
| tlv_len - 2 * sizeof(t_u16); |
| memcpy(tlv->data, WPS_serialnumber, |
| wps_serial_len); |
| endian_convert_tlv_wps_header_out(tlv); |
| cmd_len_wps += tlv_len; |
| |
| /* Append TLV for WPSVendorExtension */ |
| tlv_len = |
| sizeof(tlvbuf_wps_ie) + |
| wps_vendor_len; |
| tlv = (tlvbuf_wps_ie *)(buffer + |
| cmd_len_wifidirect |
| + |
| sizeof |
| (custom_ie) + |
| cmd_len_wps); |
| tlv->tag = SC_Vendor_Extension; |
| tlv->length = |
| tlv_len - 2 * sizeof(t_u16); |
| memcpy(tlv->data, WPS_VendorExt, |
| wps_vendor_len); |
| endian_convert_tlv_wps_header_out(tlv); |
| cmd_len_wps += tlv_len; |
| #ifdef DEBUG |
| /* Debug print */ |
| hexdump(buffer + sizeof(custom_ie) + |
| cmd_len_wifidirect, cmd_len_wps, |
| ' '); |
| #endif |
| break; |
| } |
| case WIFIDIRECT_EXTRA: |
| { |
| memcpy(buffer + cmd_len_wifidirect, |
| extra, extra_len); |
| cmd_len_wifidirect += extra_len; |
| break; |
| } |
| default: |
| *ie_len_wifidirect = cmd_len_wifidirect; |
| if (ie_len_wps) |
| *ie_len_wps = cmd_len_wps; |
| break; |
| } |
| memset(country, 0, sizeof(country)); |
| if (wifidirect_level == 0) |
| cmd_found = 0; |
| if (flag) |
| wifidirect_level = 0; |
| } |
| } |
| |
| done: |
| fclose(config_file); |
| if (chan_entry_list) |
| free(chan_entry_list); |
| if (line) |
| free(line); |
| if (extra) |
| free(extra); |
| if (args) |
| free(args); |
| return; |
| } |
| |
| /** |
| * @brief Process and send ie config command |
| * @param ie_index A pointer to the IE buffer index |
| * @param data_len_wifidirect Length of WIFIDIRECT data, 0 to get, else set. |
| * @param data_len_wps Length of WPS data, 0 to get, else set. |
| * @param buf Pointer to buffer to set. |
| * @return SUCCESS--success, FAILURE--fail |
| */ |
| static int |
| wifidirect_ie_config(t_u16 *ie_index, t_u16 data_len_wifidirect, |
| t_u16 data_len_wps, t_u8 *buf) |
| { |
| struct iwreq iwr; |
| t_s32 sockfd; |
| int i, ret = SUCCESS; |
| tlvbuf_custom_ie *tlv = NULL; |
| custom_ie *ie_ptr = NULL; |
| |
| tlv = (tlvbuf_custom_ie *)buf; |
| tlv->tag = MRVL_MGMT_IE_LIST_TLV_ID; |
| /* Locate headers */ |
| ie_ptr = (custom_ie *)(tlv->ie_data); |
| |
| /* Set TLV fields : WIFIDIRECT IE parameters */ |
| if (data_len_wifidirect) { |
| /* Set IE */ |
| #define MGMT_MASK_AUTO 0xffff |
| ie_ptr->mgmt_subtype_mask = MGMT_MASK_AUTO; |
| tlv->length = sizeof(custom_ie) + data_len_wifidirect; |
| ie_ptr->ie_length = data_len_wifidirect; |
| ie_ptr->ie_index = *ie_index; |
| } else { |
| /* Get WPS IE */ |
| tlv->length = 0; |
| } |
| |
| if (!wifidir_use_fixed_ie_indices()) { |
| if (*ie_index != 0xFFFF) { |
| (*ie_index)++; |
| } |
| } else { |
| (*ie_index)++; |
| } |
| /* Locate headers */ |
| ie_ptr = (custom_ie *)((t_u8 *)(tlv->ie_data) + sizeof(custom_ie) + |
| data_len_wifidirect); |
| |
| /* Set WPS IE parameters */ |
| if (data_len_wps) { |
| /* Set IE */ |
| /* Firmware Handled IE - mask should be set to -1 */ |
| ie_ptr->mgmt_subtype_mask = MGMT_MASK_AUTO; |
| tlv->length += sizeof(custom_ie) + data_len_wps; |
| ie_ptr->ie_length = data_len_wps; |
| ie_ptr->ie_index = *ie_index; |
| } |
| |
| memset(&iwr, 0, sizeof(iwr)); |
| strncpy(iwr.ifr_name, (char *)dev_name, IFNAMSIZ - 1); |
| |
| iwr.u.data.pointer = (void *)buf; |
| iwr.u.data.length = |
| ((2 * sizeof(custom_ie)) + sizeof(tlvbuf_custom_ie) + |
| data_len_wifidirect + data_len_wps); |
| iwr.u.data.flags = 0; |
| |
| /* |
| * create a socket |
| */ |
| if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { |
| printf("Cannot open socket.\n"); |
| ret = FAILURE; |
| goto _exit_; |
| } |
| |
| if (ioctl(sockfd, CUSTOM_IE, &iwr)) { |
| perror("ioctl[CUSTOM_IE]"); |
| printf("Failed to set/get/clear the IE buffer\n"); |
| ret = FAILURE; |
| close(sockfd); |
| goto _exit_; |
| } |
| close(sockfd); |
| |
| /** Max IE index */ |
| #define MAX_MGMT_IE_INDEX 12 |
| |
| if (!data_len_wifidirect) { |
| /* Get the IE buffer index number for MGMT_IE_LIST_TLV */ |
| tlv = (tlvbuf_custom_ie *)buf; |
| *ie_index = 0xFFFF; |
| if (tlv->tag == MRVL_MGMT_IE_LIST_TLV_ID) { |
| ie_ptr = (custom_ie *)(tlv->ie_data); |
| for (i = 0; i < MAX_MGMT_IE_INDEX; i++) { |
| /* zero mask indicates a wps IE, return previous index */ |
| if (ie_ptr->mgmt_subtype_mask == MGMT_MASK_AUTO |
| && ie_ptr->ie_length) { |
| *ie_index = ie_ptr->ie_index; |
| break; |
| } |
| if (i < (MAX_MGMT_IE_INDEX - 1)) |
| ie_ptr = (custom_ie *)((t_u8 *)ie_ptr + |
| sizeof(custom_ie) |
| + |
| ie_ptr-> |
| ie_length); |
| } |
| } |
| if (*ie_index == 0xFFFF) { |
| ret = FAILURE; |
| } |
| } |
| _exit_: |
| |
| return ret; |
| } |
| |
| /** |
| * @brief Creates a wifidirect_config request and sends to the driver |
| * |
| * Usage: "Usage : wifidirect_config [CONFIG_FILE]" |
| * |
| * @param argc Number of arguments |
| * @param argv Pointer to the arguments |
| * @return None |
| */ |
| static void |
| wifidirectcmd_config(int argc, char *argv[]) |
| { |
| t_u8 *buf = NULL, *ptr, *dev_ptr, *array_ptr; |
| t_u16 ie_len_wifidirect = 0, ie_len_wps = 0, ie_len; |
| t_u16 ie_index, temp; |
| int i, opt, ret = SUCCESS; |
| tlvbuf_custom_ie *tlv = NULL; |
| custom_ie *ie_ptr = NULL; |
| t_u16 len = 0, len_wifidirect = 0; |
| t_u8 type = 0; |
| t_u16 wps_len = 0, wps_type = 0; |
| |
| if (!wifidir_use_fixed_ie_indices()) { |
| ie_index = 0xFFFF; |
| } else { |
| ie_index = 0; |
| } |
| while ((opt = getopt_long(argc, argv, "+", cmd_options, NULL)) != -1) { |
| switch (opt) { |
| default: |
| print_wifidirect_config_usage(); |
| return; |
| } |
| } |
| argc -= optind; |
| argv += optind; |
| |
| /* Check arguments */ |
| if (argc < 2) { |
| printf("ERR:wrong number of arguments.\n"); |
| print_wifidirect_config_usage(); |
| return; |
| } |
| buf = (t_u8 *)malloc(MRVDRV_SIZE_OF_CMD_BUFFER); |
| if (!buf) { |
| printf("ERR:Cannot allocate memory!\n"); |
| return; |
| } |
| memset(buf, 0, MRVDRV_SIZE_OF_CMD_BUFFER); |
| |
| if (argc >= 3) { |
| /* Read parameters and send command to firmware */ |
| wifidirect_file_params_config(argv[2], argv[1], buf |
| + sizeof(tlvbuf_custom_ie) + |
| sizeof(custom_ie), |
| &ie_len_wifidirect, &ie_len_wps); |
| if (argc == 4) { |
| ie_index = atoi(argv[3]); |
| if (ie_index >= 4) { |
| printf("ERR:wrong argument %s.\n", argv[3]); |
| return; |
| } |
| } |
| if (ie_len_wifidirect > MAX_SIZE_IE_BUFFER || |
| ie_len_wps > MAX_SIZE_IE_BUFFER) { |
| printf("ERR:IE parameter size exceeds limit in %s.\n", |
| argv[2]); |
| free(buf); |
| return; |
| } |
| ie_len = ie_len_wifidirect + ie_len_wps + |
| sizeof(tlvbuf_custom_ie) + (2 * sizeof(custom_ie)); |
| if (ie_len >= MRVDRV_SIZE_OF_CMD_BUFFER) { |
| printf("ERR:Too much data in configuration file %s.\n", |
| argv[2]); |
| free(buf); |
| return; |
| } |
| #ifdef DEBUG |
| hexdump(buf, ie_len, ' '); |
| #endif |
| ret = wifidirect_ie_config(&ie_index, ie_len_wifidirect, |
| ie_len_wps, buf); |
| if (ret != SUCCESS) { |
| printf("ERR:Could not set wifidirect parameters\n"); |
| } |
| } else { |
| ret = wifidirect_ie_config(&ie_index, 0, 0, buf); |
| /* Print response */ |
| if (ret == SUCCESS && ie_index < 3) { |
| tlv = (tlvbuf_custom_ie *)buf; |
| if (tlv->tag == MRVL_MGMT_IE_LIST_TLV_ID) { |
| ie_ptr = (custom_ie *)(tlv->ie_data); |
| /* Goto appropriate Ie Index */ |
| for (i = 0; i < ie_index; i++) { |
| ie_ptr = (custom_ie *)((t_u8 *)ie_ptr + |
| sizeof(custom_ie) |
| + |
| ie_ptr-> |
| ie_length); |
| } |
| ie_len_wifidirect = ie_ptr->ie_length; |
| ptr = ie_ptr->ie_buffer; |
| /* Locate headers */ |
| printf("WIFIDIRECT settings:\n"); |
| if (!wifidir_use_fixed_ie_indices()) { |
| while (memcmp |
| (ptr, wifidirect_oui, |
| sizeof(wifidirect_oui))) { |
| ie_ptr = (custom_ie *)((t_u8 *) |
| ie_ptr + |
| sizeof |
| (custom_ie) |
| + |
| ie_ptr-> |
| ie_length); |
| ie_len_wifidirect = |
| ie_ptr->ie_length; |
| ptr = ie_ptr->ie_buffer; |
| } |
| ptr += sizeof(wifidirect_oui); |
| ie_len_wifidirect -= |
| sizeof(wifidirect_oui); |
| } |
| while (ie_len_wifidirect > |
| WIFIDIRECT_IE_HEADER_LEN) { |
| type = *ptr; |
| memcpy(&len, ptr + 1, sizeof(t_u16)); |
| len = le16_to_cpu(len); |
| switch (type) { |
| case TLV_TYPE_WIFIDIRECT_DEVICE_ID: |
| { |
| tlvbuf_wifidirect_device_id |
| *wifidirect_tlv |
| = |
| (tlvbuf_wifidirect_device_id |
| *)ptr; |
| printf("\t Device ID - "); |
| print_mac |
| (wifidirect_tlv-> |
| dev_mac_address); |
| printf("\n"); |
| } |
| break; |
| |
| case TLV_TYPE_WIFIDIRECT_CAPABILITY: |
| { |
| tlvbuf_wifidirect_capability |
| *wifidirect_tlv |
| = |
| (tlvbuf_wifidirect_capability |
| *)ptr; |
| printf("\t Device capability = %d\n", (int)wifidirect_tlv->dev_capability); |
| printf("\t Group capability = %d\n", (int)wifidirect_tlv->group_capability); |
| } |
| break; |
| case TLV_TYPE_WIFIDIRECT_GROUPOWNER_INTENT: |
| { |
| tlvbuf_wifidirect_group_owner_intent |
| *wifidirect_tlv |
| = |
| (tlvbuf_wifidirect_group_owner_intent |
| *)ptr; |
| printf("\t Group owner intent = %d\n", (int)wifidirect_tlv->dev_intent); |
| } |
| break; |
| case TLV_TYPE_WIFIDIRECT_MANAGEABILITY: |
| { |
| tlvbuf_wifidirect_manageability |
| *wifidirect_tlv |
| = |
| (tlvbuf_wifidirect_manageability |
| *)ptr; |
| printf("\t Manageability = %d\n", (int)wifidirect_tlv->manageability); |
| } |
| break; |
| case TLV_TYPE_WIFIDIRECT_CHANNEL_LIST: |
| { |
| tlvbuf_wifidirect_channel_list |
| *wifidirect_tlv |
| = |
| (tlvbuf_wifidirect_channel_list |
| *)ptr; |
| chan_entry *temp_ptr; |
| printf("\t Country String \"%c%c\"", wifidirect_tlv->country_string[0], wifidirect_tlv->country_string[1]); |
| if (isalpha |
| (wifidirect_tlv-> |
| country_string[2])) |
| printf("\"%c\"", |
| wifidirect_tlv-> |
| country_string |
| [2]); |
| printf("\n"); |
| temp_ptr = |
| (chan_entry *) |
| wifidirect_tlv-> |
| wifidirect_chan_entry_list; |
| len_wifidirect = |
| le16_to_cpu |
| (wifidirect_tlv-> |
| length) - |
| (sizeof |
| (tlvbuf_wifidirect_channel_list) |
| - |
| WIFIDIRECT_IE_HEADER_LEN); |
| if (len_wifidirect) |
| printf("\t Channel List :- \n"); |
| while (len_wifidirect) { |
| printf("\t\t Regulatory_class = %d\n", (int)(temp_ptr->regulatory_class)); |
| printf("\t\t No of channels = %d\n", (int)temp_ptr->num_of_channels); |
| printf("\t\t Channel list = "); |
| for (i = 0; |
| i < |
| temp_ptr-> |
| num_of_channels; |
| i++) { |
| printf("%d ", *(temp_ptr->chan_list + i)); |
| } |
| len_wifidirect |
| -= |
| sizeof |
| (chan_entry) |
| + |
| temp_ptr-> |
| num_of_channels; |
| temp_ptr = |
| (chan_entry |
| *)((t_u8 *)temp_ptr + sizeof(chan_entry) + temp_ptr->num_of_channels); |
| printf("\n"); |
| } |
| } |
| break; |
| case TLV_TYPE_WIFIDIRECT_NOTICE_OF_ABSENCE: |
| { |
| tlvbuf_wifidirect_notice_of_absence |
| *wifidirect_tlv |
| = |
| (tlvbuf_wifidirect_notice_of_absence |
| *)ptr; |
| noa_descriptor |
| *temp_ptr; |
| printf("\t Notice of Absence index = %d\n", (int)wifidirect_tlv->noa_index); |
| printf("\t CTWindow and opportunistic PS parameters = %d\n", (int)wifidirect_tlv->ctwindow_opp_ps); |
| temp_ptr = |
| (noa_descriptor |
| *) |
| wifidirect_tlv-> |
| wifidirect_noa_descriptor_list; |
| len_wifidirect = |
| le16_to_cpu |
| (wifidirect_tlv-> |
| length) - |
| (sizeof |
| (tlvbuf_wifidirect_notice_of_absence) |
| - |
| WIFIDIRECT_IE_HEADER_LEN); |
| while (len_wifidirect) { |
| printf("\t Count or Type = %d\n", (int)temp_ptr->count_type); |
| printf("\t Duration = %dms\n", le32_to_cpu(temp_ptr->duration)); |
| printf("\t Interval = %dms\n", le32_to_cpu(temp_ptr->interval)); |
| printf("\t Start Time = %d\n", le32_to_cpu(temp_ptr->start_time)); |
| printf("\n"); |
| temp_ptr += |
| sizeof |
| (noa_descriptor); |
| len_wifidirect |
| -= |
| sizeof |
| (noa_descriptor); |
| } |
| } |
| break; |
| case TLV_TYPE_WIFIDIRECT_DEVICE_INFO: |
| { |
| tlvbuf_wifidirect_device_info |
| *wifidirect_tlv |
| = |
| (tlvbuf_wifidirect_device_info |
| *)ptr; |
| printf("\t Device address - "); |
| print_mac |
| (wifidirect_tlv-> |
| dev_address); |
| printf("\n"); |
| /* display config_methods */ |
| printf("\t Config methods - 0x%02X\n", ntohs(wifidirect_tlv->config_methods)); |
| printf("\t Primary device type = %02d-%02X%02X%02X%02X-%02d\n", (int)ntohs(wifidirect_tlv->primary_category), (int)wifidirect_tlv->primary_oui[0], (int)wifidirect_tlv->primary_oui[1], (int)wifidirect_tlv->primary_oui[2], (int)wifidirect_tlv->primary_oui[3], (int)ntohs(wifidirect_tlv->primary_subcategory)); |
| printf("\t Secondary Device Count = %d\n", (int)wifidirect_tlv->secondary_dev_count); |
| array_ptr = |
| wifidirect_tlv-> |
| secondary_dev_info; |
| for (i = 0; |
| i < |
| wifidirect_tlv-> |
| secondary_dev_count; |
| i++) { |
| memcpy(&temp, |
| array_ptr, |
| sizeof |
| (t_u16)); |
| printf("\t\t Secondary device type = %02d-", ntohs(temp)); |
| array_ptr += |
| sizeof |
| (temp); |
| printf("%02X%02X%02X%02X", array_ptr[0], array_ptr[1], array_ptr[2], array_ptr[3]); |
| array_ptr += 4; |
| memcpy(&temp, |
| array_ptr, |
| sizeof |
| (t_u16)); |
| printf("-%02d\n", ntohs(temp)); |
| array_ptr += |
| sizeof |
| (temp); |
| } |
| array_ptr = |
| wifidirect_tlv-> |
| device_name + |
| wifidirect_tlv-> |
| secondary_dev_count |
| * |
| WPS_DEVICE_TYPE_LEN; |
| dev_ptr = |
| (((t_u8 |
| *) |
| (&wifidirect_tlv-> |
| device_name_len)) |
| + |
| wifidirect_tlv-> |
| secondary_dev_count |
| * |
| WPS_DEVICE_TYPE_LEN); |
| if (*(t_u16 *)dev_ptr) |
| printf("\t Device Name = "); |
| memcpy(&temp, dev_ptr, |
| sizeof(t_u16)); |
| for (i = 0; |
| i < ntohs(temp); |
| i++) |
| printf("%c", |
| *array_ptr++); |
| printf("\n"); |
| } |
| break; |
| case TLV_TYPE_WIFIDIRECT_GROUP_INFO: |
| { |
| tlvbuf_wifidirect_group_info |
| *wifidirect_tlv |
| = |
| (tlvbuf_wifidirect_group_info |
| *)ptr; |
| t_u8 no_of_wifidirect_clients = 0, wifidirect_client_dev_length = 0; |
| wifidirect_client_dev_info |
| *temp_ptr; |
| temp_ptr = |
| (wifidirect_client_dev_info |
| *) |
| wifidirect_tlv-> |
| wifidirect_client_dev_list; |
| if (temp_ptr == NULL) |
| break; |
| wifidirect_client_dev_length |
| = |
| temp_ptr-> |
| dev_length; |
| temp = le16_to_cpu |
| (wifidirect_tlv-> |
| length) - |
| wifidirect_client_dev_length; |
| while (temp) { |
| |
| printf("\t Group WifiDirect Client Device address - "); |
| print_mac |
| (temp_ptr-> |
| wifidirect_dev_address); |
| printf("\n"); |
| printf("\t Group WifiDirect Client Interface address - "); |
| print_mac |
| (temp_ptr-> |
| wifidirect_intf_address); |
| printf("\n"); |
| printf("\t Group WifiDirect Client Device capability = %d\n", (int)temp_ptr->wifidirect_dev_capability); |
| printf("\t Group WifiDirect Client Config methods - 0x%02X\n", ntohs(temp_ptr->config_methods)); |
| printf("\t Group WifiDirect Client Primay device type = %02d-%02X%02X%02X%02X-%02d\n", (int)ntohs(temp_ptr->primary_category), (int)temp_ptr->primary_oui[0], (int)temp_ptr->primary_oui[1], (int)temp_ptr->primary_oui[2], (int)temp_ptr->primary_oui[3], (int)ntohs(temp_ptr->primary_subcategory)); |
| printf("\t Group WifiDirect Client Secondary Device Count = %d\n", (int)temp_ptr->wifidirect_secondary_dev_count); |
| array_ptr = |
| temp_ptr-> |
| wifidirect_secondary_dev_info; |
| for (i = 0; |
| i < |
| temp_ptr-> |
| wifidirect_secondary_dev_count; |
| i++) { |
| memcpy(&temp, array_ptr, sizeof(t_u16)); |
| printf("\t Group WifiDirect Client Secondary device type = %02d-", ntohs(temp)); |
| array_ptr |
| += |
| sizeof |
| (temp); |
| printf("%02X%02X%02X%02X", array_ptr[0], array_ptr[1], array_ptr[2], array_ptr[3]); |
| array_ptr |
| += |
| 4; |
| memcpy(&temp, array_ptr, sizeof(t_u16)); |
| printf("-%02d\n", ntohs(temp)); |
| array_ptr |
| += |
| sizeof |
| (temp); |
| } |
| /* display device name */ |
| array_ptr = |
| temp_ptr-> |
| wifidirect_device_name |
| + |
| temp_ptr-> |
| wifidirect_secondary_dev_count |
| * |
| WPS_DEVICE_TYPE_LEN; |
| printf("\t Group WifiDirect Device Name = "); |
| memcpy(&temp, |
| (((t_u8 |
| *) |
| (&temp_ptr-> |
| wifidirect_device_name_len)) |
| + |
| temp_ptr-> |
| wifidirect_secondary_dev_count |
| * |
| WPS_DEVICE_TYPE_LEN), |
| sizeof |
| (t_u16)); |
| temp = ntohs |
| (temp); |
| for (i = 0; |
| i < temp; |
| i++) |
| printf("%c", *array_ptr++); |
| printf("\n"); |
| temp_ptr += |
| wifidirect_client_dev_length; |
| temp -= wifidirect_client_dev_length; |
| no_of_wifidirect_clients++; |
| if (temp_ptr) |
| wifidirect_client_dev_length |
| = |
| temp_ptr-> |
| dev_length; |
| } |
| printf("\n"); |
| printf("\t Group WifiDirect Client Devices count = %d\n", no_of_wifidirect_clients); |
| } |
| break; |
| case TLV_TYPE_WIFIDIRECT_GROUP_ID: |
| { |
| tlvbuf_wifidirect_group_id |
| *wifidirect_tlv |
| = |
| (tlvbuf_wifidirect_group_id |
| *)ptr; |
| printf("\t Group address - "); |
| print_mac |
| (wifidirect_tlv-> |
| group_address); |
| printf("\n"); |
| array_ptr = |
| wifidirect_tlv-> |
| group_ssid; |
| printf("\t Group ssid = "); |
| for (i = 0; |
| (unsigned int)i < |
| le16_to_cpu |
| (wifidirect_tlv-> |
| length) |
| - |
| (sizeof |
| (tlvbuf_wifidirect_group_id) |
| - |
| WIFIDIRECT_IE_HEADER_LEN); |
| i++) |
| printf("%c", |
| *array_ptr++); |
| printf("\n"); |
| } |
| break; |
| case TLV_TYPE_WIFIDIRECT_GROUP_BSS_ID: |
| { |
| tlvbuf_wifidirect_group_bss_id |
| *wifidirect_tlv |
| = |
| (tlvbuf_wifidirect_group_bss_id |
| *)ptr; |
| printf("\t Group BSS Id - "); |
| print_mac |
| (wifidirect_tlv-> |
| group_bssid); |
| printf("\n"); |
| } |
| break; |
| case TLV_TYPE_WIFIDIRECT_INTERFACE: |
| { |
| tlvbuf_wifidirect_interface |
| *wifidirect_tlv |
| = |
| (tlvbuf_wifidirect_interface |
| *)ptr; |
| printf("\t Interface Id - "); |
| print_mac |
| (wifidirect_tlv-> |
| interface_id); |
| printf("\t Interface count = %d", (int)wifidirect_tlv->interface_count); |
| for (i = 0; |
| i < |
| wifidirect_tlv-> |
| interface_count; |
| i++) { |
| printf("\n\t Interface address [%d]", i + 1); |
| print_mac |
| (&wifidirect_tlv-> |
| interface_idlist |
| [i * |
| ETH_ALEN]); |
| } |
| printf("\n"); |
| } |
| break; |
| case TLV_TYPE_WIFIDIRECT_CHANNEL: |
| { |
| tlvbuf_wifidirect_channel |
| *wifidirect_tlv |
| = |
| (tlvbuf_wifidirect_channel |
| *)ptr; |
| printf("\t Listen Channel Country String \"%c%c\"", wifidirect_tlv->country_string[0], wifidirect_tlv->country_string[1]); |
| if (isalpha |
| (wifidirect_tlv-> |
| country_string[2])) |
| printf("\"%c\"", |
| wifidirect_tlv-> |
| country_string |
| [2]); |
| printf("\n"); |
| printf("\t Listern Channel regulatory class = %d\n", (int)wifidirect_tlv->regulatory_class); |
| printf("\t Listen Channel number = %d\n", (int)wifidirect_tlv->channel_number); |
| } |
| break; |
| |
| case TLV_TYPE_WIFIDIRECT_OPCHANNEL: |
| { |
| tlvbuf_wifidirect_channel |
| *wifidirect_tlv |
| = |
| (tlvbuf_wifidirect_channel |
| *)ptr; |
| printf("\t Operating Channel Country String %c%c", wifidirect_tlv->country_string[0], wifidirect_tlv->country_string[1]); |
| if (isalpha |
| (wifidirect_tlv-> |
| country_string[2])) |
| printf("%c", |
| wifidirect_tlv-> |
| country_string |
| [2]); |
| printf("\n"); |
| printf("\t Operating Channel regulatory class = %d\n", (int)wifidirect_tlv->regulatory_class); |
| printf("\t Operating Channel number = %d\n", (int)wifidirect_tlv->channel_number); |
| } |
| break; |
| case TLV_TYPE_WIFIDIRECT_INVITATION_FLAG: |
| { |
| tlvbuf_wifidirect_invitation_flag |
| *wifidirect_tlv |
| = |
| (tlvbuf_wifidirect_invitation_flag |
| *)ptr; |
| printf("\t Invitation flag = %d\n", (int)wifidirect_tlv->invitation_flag & INVITATION_FLAG_MASK); |
| } |
| break; |
| case TLV_TYPE_WIFIDIRECT_CONFIG_TIMEOUT: |
| { |
| tlvbuf_wifidirect_config_timeout |
| *wifidirect_tlv |
| = |
| (tlvbuf_wifidirect_config_timeout |
| *)ptr; |
| printf("\t GO configuration timeout = %d msec\n", (int)wifidirect_tlv->group_config_timeout * 10); |
| printf("\t Client configuration timeout = %d msec\n", (int)wifidirect_tlv->device_config_timeout * 10); |
| } |
| break; |
| case TLV_TYPE_WIFIDIRECT_EXTENDED_LISTEN_TIME: |
| { |
| tlvbuf_wifidirect_ext_listen_time |
| *wifidirect_tlv |
| = |
| (tlvbuf_wifidirect_ext_listen_time |
| *)ptr; |
| printf("\t Availability Period = %d msec\n", (int)wifidirect_tlv->availability_period); |
| printf("\t Availability Interval = %d msec\n", (int)wifidirect_tlv->availability_interval); |
| } |
| break; |
| case TLV_TYPE_WIFIDIRECT_INTENDED_ADDRESS: |
| { |
| tlvbuf_wifidirect_intended_addr |
| *wifidirect_tlv |
| = |
| (tlvbuf_wifidirect_intended_addr |
| *)ptr; |
| printf("\t Intended Interface Address - "); |
| print_mac |
| (wifidirect_tlv-> |
| group_address); |
| printf("\n"); |
| } |
| break; |
| default: |
| printf("unknown ie=0x%x, len=%d\n", type, len); |
| break; |
| } |
| ptr += len + WIFIDIRECT_IE_HEADER_LEN; |
| ie_len_wifidirect -= |
| len + WIFIDIRECT_IE_HEADER_LEN; |
| } |
| |
| /* Goto next index, Locate headers */ |
| printf("WPS settings:\n"); |
| ie_ptr = (custom_ie *)((t_u8 *)ie_ptr + |
| sizeof(custom_ie) + |
| ie_ptr->ie_length); |
| ptr = ie_ptr->ie_buffer; |
| ie_len_wps = ie_ptr->ie_length; |
| if (!wifidir_use_fixed_ie_indices()) { |
| while (memcmp |
| (ptr, wps_oui, |
| sizeof(wps_oui))) { |
| ie_ptr = (custom_ie *)((t_u8 *) |
| ie_ptr + |
| sizeof |
| (custom_ie) |
| + |
| ie_ptr-> |
| ie_length); |
| ie_len_wps = ie_ptr->ie_length; |
| ptr = ie_ptr->ie_buffer; |
| } |
| ptr += sizeof(wps_oui); |
| ie_len_wifidirect -= sizeof(wps_oui); |
| } |
| while (ie_len_wps > sizeof(tlvbuf_wps_ie)) { |
| memcpy(&wps_type, ptr, sizeof(t_u16)); |
| memcpy(&wps_len, ptr + 2, |
| sizeof(t_u16)); |
| endian_convert_tlv_wps_header_in |
| (wps_type, wps_len); |
| switch (wps_type) { |
| case SC_Version: |
| { |
| tlvbuf_wps_ie *wps_tlv = |
| (tlvbuf_wps_ie |
| *)ptr; |
| printf("\t WPS Version = 0x%2x\n", *(wps_tlv->data)); |
| } |
| break; |
| case SC_Simple_Config_State: |
| { |
| tlvbuf_wps_ie *wps_tlv = |
| (tlvbuf_wps_ie |
| *)ptr; |
| printf("\t WPS setupstate = 0x%x\n", *(wps_tlv->data)); |
| } |
| break; |
| case SC_Request_Type: |
| { |
| tlvbuf_wps_ie *wps_tlv = |
| (tlvbuf_wps_ie |
| *)ptr; |
| printf("\t WPS RequestType = 0x%x\n", *(wps_tlv->data)); |
| } |
| break; |
| case SC_Response_Type: |
| { |
| tlvbuf_wps_ie *wps_tlv = |
| (tlvbuf_wps_ie |
| *)ptr; |
| printf("\t WPS ResponseType = 0x%x\n", *(wps_tlv->data)); |
| } |
| break; |
| case SC_Config_Methods: |
| { |
| t_u16 wps_config_methods |
| = 0; |
| tlvbuf_wps_ie *wps_tlv = |
| (tlvbuf_wps_ie |
| *)ptr; |
| memcpy(&wps_config_methods, wps_tlv->data, sizeof(t_u16)); |
| wps_config_methods = |
| ntohs |
| (wps_config_methods); |
| printf("\t WPS SpecConfigMethods = 0x%x\n", wps_config_methods); |
| } |
| break; |
| case SC_UUID_E: |
| { |
| tlvbuf_wps_ie *wps_tlv = |
| (tlvbuf_wps_ie |
| *)ptr; |
| array_ptr = |
| wps_tlv->data; |
| printf("\t WPS UUID = "); |
| for (i = 0; i < wps_len; |
| i++) |
| printf("%2X ", |
| *array_ptr++); |
| printf("\n"); |
| } |
| break; |
| case SC_Primary_Device_Type: |
| { |
| tlvbuf_wps_ie *wps_tlv = |
| (tlvbuf_wps_ie |
| *)ptr; |
| array_ptr = |
| wps_tlv->data; |
| printf("\t WPS Primary Device Type = "); |
| for (i = 0; i < wps_len; |
| i++) |
| printf("%02X ", |
| *array_ptr++); |
| printf("\n"); |
| } |
| break; |
| case SC_RF_Band: |
| { |
| tlvbuf_wps_ie *wps_tlv = |
| (tlvbuf_wps_ie |
| *)ptr; |
| printf("\t WPS RF Band = 0x%x\n", *(wps_tlv->data)); |
| } |
| break; |
| case SC_Association_State: |
| { |
| t_u16 wps_association_state = 0; |
| tlvbuf_wps_ie *wps_tlv = |
| (tlvbuf_wps_ie |
| *)ptr; |
| memcpy(&wps_association_state, wps_tlv->data, sizeof(t_u16)); |
| printf("\t WPS Association State = 0x%x\n", wps_association_state); |
| } |
| break; |
| case SC_Configuration_Error: |
| { |
| t_u16 wps_configuration_error = 0; |
| tlvbuf_wps_ie *wps_tlv = |
| (tlvbuf_wps_ie |
| *)ptr; |
| memcpy(&wps_configuration_error, wps_tlv->data, sizeof(t_u16)); |
| wps_configuration_error |
| = |
| ntohs |
| (wps_configuration_error); |
| printf("\t WPS Configuration Error = 0x%x\n", wps_configuration_error); |
| } |
| break; |
| case SC_Device_Password_ID: |
| { |
| t_u16 wps_device_password_id = 0; |
| tlvbuf_wps_ie *wps_tlv = |
| (tlvbuf_wps_ie |
| *)ptr; |
| memcpy(&wps_device_password_id, wps_tlv->data, sizeof(t_u16)); |
| wps_device_password_id = |
| ntohs |
| (wps_device_password_id); |
| printf("\t WPS Device Password ID = 0x%x\n", wps_device_password_id); |
| } |
| break; |
| case SC_Device_Name: |
| { |
| tlvbuf_wps_ie *wps_tlv = |
| (tlvbuf_wps_ie |
| *)ptr; |
| array_ptr = |
| wps_tlv->data; |
| printf("\t WPS Device Name = "); |
| for (i = 0; i < wps_len; |
| i++) |
| printf("%c", |
| *array_ptr++); |
| printf("\n"); |
| } |
| break; |
| case SC_Manufacturer: |
| { |
| tlvbuf_wps_ie *wps_tlv = |
| (tlvbuf_wps_ie |
| *)ptr; |
| array_ptr = |
| wps_tlv->data; |
| printf("\t WPS Manufacturer = "); |
| for (i = 0; i < wps_len; |
| i++) |
| printf("%c", |
| *array_ptr++); |
| printf("\n"); |
| } |
| break; |
| case SC_Model_Name: |
| { |
| tlvbuf_wps_ie *wps_tlv = |
| (tlvbuf_wps_ie |
| *)ptr; |
| array_ptr = |
| wps_tlv->data; |
| printf("\t WPS Model Name = "); |
| for (i = 0; i < wps_len; |
| i++) |
| printf("%c", |
| *array_ptr++); |
| printf("\n"); |
| } |
| break; |
| case SC_Model_Number: |
| { |
| tlvbuf_wps_ie *wps_tlv = |
| (tlvbuf_wps_ie |
| *)ptr; |
| array_ptr = |
| wps_tlv->data; |
| printf("\t WPS Model Number = "); |
| for (i = 0; i < wps_len; |
| i++) |
| printf("%c", |
| *array_ptr++); |
| printf("\n"); |
| } |
| break; |
| case SC_Serial_Number: |
| { |
| tlvbuf_wps_ie *wps_tlv = |
| (tlvbuf_wps_ie |
| *)ptr; |
| array_ptr = |
| wps_tlv->data; |
| printf("\t WPS Serial Number = "); |
| for (i = 0; i < wps_len; |
| i++) |
| printf("%c", |
| *array_ptr++); |
| printf("\n"); |
| } |
| break; |
| case SC_Vendor_Extension: |
| { |
| tlvbuf_wps_ie *wps_tlv = |
| (tlvbuf_wps_ie |
| *)ptr; |
| array_ptr = |
| wps_tlv->data; |
| printf("\t WPS Vendor Extension = "); |
| for (i = 0; i < wps_len; |
| i++) |
| printf("0x%02x ", *array_ptr++); |
| printf("\n"); |
| } |
| break; |
| default: |
| printf("unknown ie=0x%x, len=%d\n", wps_type, wps_len); |
| break; |
| } |
| ptr += wps_len + sizeof(tlvbuf_wps_ie); |
| ie_len_wps -= |
| wps_len + sizeof(tlvbuf_wps_ie); |
| } |
| } |
| } else { |
| printf("ERR:Could not retrieve wifidirect parameters\n"); |
| } |
| } |
| |
| free(buf); |
| return; |
| } |
| |
| /** |
| * @brief Show usage information for the wifidirect_params_config command |
| * |
| * $return N/A |
| */ |
| static void |
| print_wifidirect_params_config_usage(void) |
| { |
| printf("\nUsage : wifidirect_params_config <CONFIG_FILE>\n"); |
| printf("\nIssue set or get request using parameters in the CONFIG_FILE.\n"); |
| return; |
| } |
| |
| /** |
| * @brief Creates a wifidirect_params_config request and sends to the driver |
| * |
| * Usage: "Usage : wifidirect_params_config <CONFIG_FILE>" |
| * |
| * @param argc Number of arguments |
| * @param argv Pointer to the arguments |
| * @return None |
| */ |
| static void |
| wifidirectcmd_params_config(int argc, char *argv[]) |
| { |
| wifidirect_params_config *param_buf = NULL; |
| tlvbuf_wps_ie *new_tlv = NULL; |
| char *line = NULL, wifidirect_mac[20]; |
| FILE *config_file = NULL; |
| int i, opt, li = 0, arg_num = 0, ret = 0; |
| char *args[30], *pos = NULL; |
| t_u8 dev_address[ETH_ALEN], enable_scan; |
| t_u8 *buffer = NULL, WPS_primarydevicetype[WPS_DEVICE_TYPE_MAX_LEN]; |
| t_u16 device_state = 0, tlv_len = |
| 0, max_disc_int, min_disc_int, cmd_len = 0; |
| |
| while ((opt = getopt_long(argc, argv, "+", cmd_options, NULL)) != -1) { |
| switch (opt) { |
| default: |
| print_wifidirect_params_config_usage(); |
| return; |
| } |
| } |
| argc -= optind; |
| argv += optind; |
| |
| /* Check arguments */ |
| if (argc < 2) { |
| printf("ERR:wrong number of arguments.\n"); |
| print_wifidirect_params_config_usage(); |
| return; |
| } |
| |
| cmd_len = sizeof(wifidirect_params_config); |
| buffer = (t_u8 *)malloc(MRVDRV_SIZE_OF_CMD_BUFFER); |
| if (!buffer) { |
| printf("ERR:Cannot allocate memory!\n"); |
| goto done; |
| } |
| memset(buffer, 0, MRVDRV_SIZE_OF_CMD_BUFFER); |
| param_buf = (wifidirect_params_config *)buffer; |
| param_buf->cmd_code = HostCmd_CMD_WIFIDIRECT_PARAMS_CONFIG; |
| param_buf->seq_num = 0; |
| param_buf->result = 0; |
| |
| if (argc >= 3) { |
| /* Check if file exists */ |
| config_file = fopen(argv[2], "r"); |
| if (config_file == NULL) { |
| printf("\nERR:Config file can not open.\n"); |
| goto done; |
| } |
| line = (char *)malloc(MAX_CONFIG_LINE); |
| if (!line) { |
| printf("ERR:Cannot allocate memory for line\n"); |
| goto done; |
| } |
| memset(line, 0, MAX_CONFIG_LINE); |
| param_buf->action = cpu_to_le16(ACTION_SET); |
| |
| /* Parse file and process */ |
| while (config_get_line |
| (line, MAX_CONFIG_LINE, config_file, &li, &pos)) { |
| arg_num = parse_line(line, args); |
| |
| if (strcmp(args[0], "EnableScan") == 0) { |
| if (is_input_valid |
| (WIFIDIRECT_ENABLE_SCAN, arg_num - 1, |
| args + 1) |
| != SUCCESS) { |
| goto done; |
| |
| } |
| enable_scan = (t_u8)atoi(args[1]); |
| /* Append a new TLV */ |
| tlv_len = sizeof(tlvbuf_wps_ie) + sizeof(t_u8); |
| new_tlv = (tlvbuf_wps_ie *)(buffer + cmd_len); |
| cmd_len += tlv_len; |
| /* Set TLV fields */ |
| new_tlv->tag = |
| MRVL_WIFIDIRECT_SCAN_ENABLE_TLV_ID; |
| new_tlv->length = tlv_len - 2 * sizeof(t_u16); |
| memcpy(new_tlv->data, &enable_scan, |
| sizeof(t_u8)); |
| endian_convert_tlv_header_out(new_tlv); |
| |
| } else if (strcmp(args[0], "ScanPeerDeviceId") == 0) { |
| strncpy(wifidirect_mac, args[1], 20 - 1); |
| if ((ret = |
| mac2raw(wifidirect_mac, |
| dev_address)) != SUCCESS) { |
| printf("ERR: %s Address \n", |
| ret == |
| FAILURE ? "Invalid MAC" : ret == |
| WIFIDIRECT_RET_MAC_BROADCAST ? |
| "Broadcast" : "Multicast"); |
| goto done; |
| } |
| /* Append a new TLV */ |
| tlv_len = sizeof(tlvbuf_wps_ie) + ETH_ALEN; |
| new_tlv = (tlvbuf_wps_ie *)(buffer + cmd_len); |
| cmd_len += tlv_len; |
| /* Set TLV fields */ |
| new_tlv->tag = |
| MRVL_WIFIDIRECT_PEER_DEVICE_TLV_ID; |
| new_tlv->length = tlv_len - 2 * sizeof(t_u16); |
| memcpy(new_tlv->data, dev_address, ETH_ALEN); |
| endian_convert_tlv_header_out(new_tlv); |
| |
| } else if (strcmp(args[0], "MinDiscoveryInterval") == 0) { |
| if (is_input_valid |
| (WIFIDIRECT_MINDISCOVERYINT, arg_num - 1, |
| args + 1) != SUCCESS) { |
| goto done; |
| } |
| min_disc_int = cpu_to_le16(atoi(args[1])); |
| } else if (strcmp(args[0], "MaxDiscoveryInterval") == 0) { |
| if (is_input_valid |
| (WIFIDIRECT_MAXDISCOVERYINT, arg_num - 1, |
| args + 1) != SUCCESS) { |
| goto done; |
| } |
| max_disc_int = cpu_to_le16(atoi(args[1])); |
| |
| /* Append a new TLV */ |
| tlv_len = |
| sizeof(tlvbuf_wps_ie) + |
| 2 * sizeof(t_u16); |
| new_tlv = (tlvbuf_wps_ie *)(buffer + cmd_len); |
| cmd_len += tlv_len; |
| /* Set TLV fields */ |
| new_tlv->tag = |
| MRVL_WIFIDIRECT_DISC_PERIOD_TLV_ID; |
| new_tlv->length = tlv_len - 2 * sizeof(t_u16); |
| memcpy(&new_tlv->data, &min_disc_int, |
| sizeof(t_u16)); |
| memcpy((((t_u8 *)&new_tlv->data) + |
| sizeof(t_u16)), &max_disc_int, |
| sizeof(t_u16)); |
| endian_convert_tlv_header_out(new_tlv); |
| |
| } else if (strcmp(args[0], "ScanRequestDeviceType") == |
| 0) { |
| if (is_input_valid |
| (WIFIDIRECT_WPSPRIMARYDEVICETYPE, |
| arg_num - 1, args + 1) |
| != SUCCESS) { |
| goto done; |
| } |
| for (i = 0; i < WPS_DEVICE_TYPE_MAX_LEN; i++) |
| WPS_primarydevicetype[i] = |
| (t_u8)A2HEXDECIMAL(args[i + 1]); |
| |
| /* Append a new TLV */ |
| tlv_len = |
| sizeof(tlvbuf_wps_ie) + |
| WPS_DEVICE_TYPE_MAX_LEN; |
| new_tlv = (tlvbuf_wps_ie *)(buffer + cmd_len); |
| cmd_len += tlv_len; |
| /* Set TLV fields */ |
| new_tlv->tag = |
| MRVL_WIFIDIRECT_SCAN_REQ_DEVICE_TLV_ID; |
| new_tlv->length = tlv_len - 2 * sizeof(t_u16); |
| memcpy(&new_tlv->data, WPS_primarydevicetype, |
| WPS_DEVICE_TYPE_MAX_LEN); |
| endian_convert_tlv_header_out(new_tlv); |
| |
| } else if (strcmp(args[0], "DeviceState") == 0) { |
| if (is_input_valid |
| (WIFIDIRECT_DEVICE_STATE, arg_num - 1, |
| args + 1) |
| != SUCCESS) { |
| goto done; |
| } |
| device_state = |
| cpu_to_le16((t_u16)atoi(args[1])); |
| |
| /* Append a new TLV */ |
| tlv_len = sizeof(tlvbuf_wps_ie) + sizeof(t_u16); |
| new_tlv = (tlvbuf_wps_ie *)(buffer + cmd_len); |
| cmd_len += tlv_len; |
| /* Set TLV fields */ |
| new_tlv->tag = |
| MRVL_WIFIDIRECT_DEVICE_STATE_TLV_ID; |
| new_tlv->length = tlv_len - 2 * sizeof(t_u16); |
| memcpy(new_tlv->data, &device_state, |
| sizeof(t_u16)); |
| endian_convert_tlv_header_out(new_tlv); |
| } |
| } |
| } |
| |
| param_buf->size = cmd_len; |
| /* Send collective command */ |
| wifidirect_ioctl((t_u8 *)buffer, &cmd_len, MRVDRV_SIZE_OF_CMD_BUFFER); |
| |
| /* Process response */ |
| if (argc < 3) { |
| /* Verify response */ |
| if (param_buf->cmd_code != |
| (HostCmd_CMD_WIFIDIRECT_PARAMS_CONFIG | |
| WIFIDIRECTCMD_RESP_CHECK)) { |
| printf("ERR:Corrupted response!\n"); |
| goto done; |
| } |
| /* Print response */ |
| if (param_buf->result == CMD_SUCCESS) { |
| param_buf = (wifidirect_params_config *)buffer; |
| new_tlv = (tlvbuf_wps_ie *)param_buf->wifidirect_tlv; |
| tlv_len = |
| param_buf->size - |
| (sizeof(wifidirect_params_config) - |
| BUF_HEADER_SIZE); |
| if (tlv_len > sizeof(tlvbuf_wps_ie)) |
| printf("WifiDirect Parameter settings: \n"); |
| else |
| printf("WifiDirect Parameter settings are not received.\n"); |
| while (tlv_len > sizeof(tlvbuf_wps_ie)) { |
| endian_convert_tlv_header_in(new_tlv); |
| switch (new_tlv->tag) { |
| case MRVL_WIFIDIRECT_SCAN_ENABLE_TLV_ID: |
| { |
| enable_scan = |
| *((t_u8 *)&new_tlv-> |
| data); |
| printf("\t Scan %s\n", |
| (enable_scan == |
| 1) ? "enabled." : |
| "disabled."); |
| } |
| break; |
| case MRVL_WIFIDIRECT_PEER_DEVICE_TLV_ID: |
| { |
| memcpy(dev_address, |
| new_tlv->data, ETH_ALEN); |
| printf("\t Peer Device ID : "); |
| print_mac(dev_address); |
| printf("\n"); |
| } |
| break; |
| case MRVL_WIFIDIRECT_DISC_PERIOD_TLV_ID: |
| { |
| t_u16 temp; |
| memcpy(&temp, &new_tlv->data, |
| sizeof(t_u16)); |
| printf("\t Minimum Discovery Interval : %d\n", le16_to_cpu(temp)); |
| memcpy(&temp, |
| ((t_u8 *)&new_tlv-> |
| data) + sizeof(t_u16), |
| sizeof(t_u16)); |
| printf("\t Maximum Discovery Interval : %d\n", le16_to_cpu(temp)); |
| } |
| break; |
| case MRVL_WIFIDIRECT_SCAN_REQ_DEVICE_TLV_ID: |
| { |
| memcpy(WPS_primarydevicetype, |
| &new_tlv->data, |
| WPS_DEVICE_TYPE_MAX_LEN); |
| printf("\tType: %02x:%02x\n", |
| (unsigned int) |
| WPS_primarydevicetype[0], |
| (unsigned int) |
| WPS_primarydevicetype |
| [1]); |
| printf("\tOUI: %02x:%02x:%02x:%02x\n", (unsigned int)WPS_primarydevicetype[2], (unsigned int)WPS_primarydevicetype[3], (unsigned int)WPS_primarydevicetype[4], (unsigned int)WPS_primarydevicetype[5]); |
| printf("\tSubType: %02x:%02x\n", |
| (unsigned int) |
| WPS_primarydevicetype[6], |
| (unsigned int) |
| WPS_primarydevicetype |
| [7]); |
| } |
| break; |
| case MRVL_WIFIDIRECT_DEVICE_STATE_TLV_ID: |
| { |
| memcpy(&device_state, |
| &new_tlv->data, |
| sizeof(t_u16)); |
| printf("\t Device State %d\n", |
| le16_to_cpu |
| (device_state)); |
| } |
| break; |
| default: |
| printf("Unknown ie=0x%x, len=%d\n", |
| new_tlv->tag, new_tlv->length); |
| break; |
| } |
| tlv_len -= |
| new_tlv->length + sizeof(tlvbuf_wps_ie); |
| new_tlv = |
| (tlvbuf_wps_ie *)(((t_u8 *)new_tlv) + |
| new_tlv->length + |
| sizeof |
| (tlvbuf_wps_ie)); |
| } |
| } else { |
| printf("ERR:Could not retrieve wifidirect parameters.\n"); |
| } |
| } |
| |
| done: |
| if (config_file) |
| fclose(config_file); |
| if (line) |
| free(line); |
| if (buffer) |
| free(buffer); |
| return; |
| } |
| |
| /** |
| * @brief Show usage information for the wifidirect_action_frame command |
| * |
| * $return N/A |
| */ |
| static void |
| print_wifidirect_action_frame_usage(void) |
| { |
| printf("\nUsage : wifidirect_action_frame <CONFIG_FILE> |" |
| " [<PeerAddr> <Category> <OUISubtype> <DialogToken>]\n"); |
| printf("\nAction frame is sent using parameters in the CONFIG_FILE " |
| "or parameters specified on command line.\n"); |
| return; |
| } |
| |
| /** |
| * @brief Creates a wifidirect_action_frame request and sends to the driver |
| * |
| * Usage: "Usage : wifidirect_action_frame <CONFIG_FILE> | |
| * [<PeerAddr> <Category> <OUISubtype> <DialogToken>]" |
| * |
| * @param argc Number of arguments |
| * @param argv Pointer to the arguments |
| * @return None |
| */ |
| static void |
| wifidirectcmd_action_frame(int argc, char *argv[]) |
| { |
| wifidirect_action_frame *action_buf = NULL; |
| char *line = NULL, wifidirect_mac[20]; |
| FILE *config_file = NULL; |
| int i, opt, li = 0, arg_num = 0, ret = 0, cmd_found = 0; |
| char *args[30], *pos = NULL; |
| t_u8 dev_address[ETH_ALEN]; |
| t_u8 *buffer = NULL; |
| t_u16 ie_len = 0, cmd_len = 0; |
| |
| while ((opt = getopt_long(argc, argv, "+", cmd_options, NULL)) != -1) { |
| switch (opt) { |
| default: |
| print_wifidirect_action_frame_usage(); |
| return; |
| } |
| } |
| argc -= optind; |
| argv += optind; |
| |
| /* Check arguments */ |
| if ((argc != 3) && (argc != 6)) { |
| printf("ERR:wrong number of arguments.\n"); |
| print_wifidirect_action_frame_usage(); |
| return; |
| } |
| |
| cmd_len = sizeof(wifidirect_action_frame); |
| buffer = (t_u8 *)malloc(MRVDRV_SIZE_OF_CMD_BUFFER); |
| if (!buffer) { |
| printf("ERR:Cannot allocate memory!\n"); |
| goto done; |
| } |
| memset(buffer, 0, MRVDRV_SIZE_OF_CMD_BUFFER); |
| action_buf = (wifidirect_action_frame *)buffer; |
| action_buf->cmd_code = HostCmd_CMD_802_11_ACTION_FRAME; |
| action_buf->seq_num = 0; |
| action_buf->result = 0; |
| |
| /* Check if file exists */ |
| config_file = fopen(argv[2], "r"); |
| if (config_file && argc == 3) { |
| line = (char *)malloc(MAX_CONFIG_LINE); |
| if (!line) { |
| printf("ERR:Cannot allocate memory for line\n"); |
| goto done; |
| } |
| |
| /* Parse file and process */ |
| while (config_get_line |
| (line, MAX_CONFIG_LINE, config_file, &li, &pos)) { |
| arg_num = parse_line(line, args); |
| |
| if (strcmp(args[0], argv[1]) == 0) { |
| cmd_found = 1; |
| } |
| if (cmd_found == 0) |
| continue; |
| |
| if (strcmp(args[0], "}") == 0) { |
| cmd_found = 0; |
| } else if (strcmp(args[0], "Category") == 0) { |
| if (is_input_valid |
| (WIFIDIRECT_CATEGORY, arg_num - 1, args + 1) |
| != SUCCESS) { |
| goto done; |
| |
| } |
| action_buf->category = (t_u8)atoi(args[1]); |
| |
| } else if (strcmp(args[0], "PeerAddr") == 0) { |
| strncpy(wifidirect_mac, args[1], 20); |
| if ((ret = |
| mac2raw(wifidirect_mac, |
| dev_address)) != SUCCESS) { |
| printf("ERR: %s Address \n", |
| ret == |
| FAILURE ? "Invalid MAC" : ret == |
| WIFIDIRECT_RET_MAC_BROADCAST ? |
| "Broadcast" : "Multicast"); |
| goto done; |
| } |
| memcpy(action_buf->peer_mac_addr, dev_address, |
| ETH_ALEN); |
| } else if (strcmp(args[0], "Action") == 0) { |
| if (is_input_valid |
| (WIFIDIRECT_ACTION, arg_num - 1, args + 1) |
| != SUCCESS) { |
| goto done; |
| } |
| action_buf->action = |
| (t_u8)A2HEXDECIMAL(args[1]); |
| |
| } else if (strcmp(args[0], "DialogToken") == 0) { |
| if (is_input_valid |
| (WIFIDIRECT_DIALOGTOKEN, arg_num - 1, |
| args + 1) |
| != SUCCESS) { |
| goto done; |
| } |
| action_buf->dialog_taken = (t_u8)atoi(args[1]); |
| |
| } else if (strcmp(args[0], "OUI") == 0) { |
| if (is_input_valid |
| (WIFIDIRECT_OUI, arg_num - 1, args + 1) |
| != SUCCESS) { |
| goto done; |
| } |
| for (i = 0; i < arg_num - 1; i++) |
| action_buf->oui[i] = |
| A2HEXDECIMAL(args[i + 1]); |
| } else if (strcmp(args[0], "OUIType") == 0) { |
| if (is_input_valid |
| (WIFIDIRECT_OUITYPE, arg_num - 1, args + 1) |
| != SUCCESS) { |
| goto done; |
| } |
| action_buf->oui_type = (t_u8)atoi(args[1]); |
| } else if (strcmp(args[0], "OUISubType") == 0) { |
| if (is_input_valid |
| (WIFIDIRECT_OUISUBTYPE, arg_num - 1, |
| args + 1) |
| != SUCCESS) { |
| goto done; |
| } |
| action_buf->oui_sub_type = (t_u8)atoi(args[1]); |
| } |
| } |
| fclose(config_file); |
| config_file = NULL; |
| |
| /* Now, read IE parameters from file */ |
| wifidirect_file_params_config(argv[2], argv[1], |
| action_buf->ie_list, &ie_len, |
| NULL); |
| if (ie_len >= MRVDRV_SIZE_OF_CMD_BUFFER) { |
| printf("ERR:Too much data in configuration file %s.\n", |
| argv[2]); |
| free(buffer); |
| return; |
| } |
| cmd_len += ie_len; |
| } else { |
| if (argc == 3) { |
| printf("ERR:Can not open config file.\n"); |
| goto done; |
| } |
| strncpy(wifidirect_mac, argv[2], 20); |
| if ((ret = mac2raw(wifidirect_mac, dev_address)) != SUCCESS) { |
| printf("ERR: %s Address \n", |
| ret == FAILURE ? "Invalid MAC" : ret == |
| WIFIDIRECT_RET_MAC_BROADCAST ? "Broadcast" : |
| "Multicast"); |
| goto done; |
| } |
| memcpy(action_buf->peer_mac_addr, dev_address, ETH_ALEN); |
| |
| if (is_input_valid(WIFIDIRECT_CATEGORY, 1, &argv[3]) |
| != SUCCESS) { |
| goto done; |
| } |
| action_buf->category = (t_u8)atoi(argv[3]); |
| |
| if (is_input_valid(WIFIDIRECT_OUISUBTYPE, 1, &argv[4]) |
| != SUCCESS) { |
| goto done; |
| } |
| action_buf->oui_sub_type = (t_u8)atoi(argv[4]); |
| |
| if (is_input_valid(WIFIDIRECT_DIALOGTOKEN, 1, &argv[5]) |
| != SUCCESS) { |
| goto done; |
| } |
| action_buf->dialog_taken = (t_u8)atoi(argv[5]); |
| |
| action_buf->action = 0; |
| action_buf->oui[0] = 0x50; |
| action_buf->oui[1] = 0x6F; |
| action_buf->oui[2] = 0x9A; |
| action_buf->oui_type = OUI_TYPE_WFA_WIFIDIRECT; |
| } |
| action_buf->size = cmd_len; |
| #ifdef DEBUG |
| /* Debug print */ |
| hexdump(buffer, cmd_len, ' '); |
| #endif |
| /* Send collective command */ |
| wifidirect_ioctl((t_u8 *)buffer, &cmd_len, cmd_len); |
| |
| done: |
| if (config_file) |
| fclose(config_file); |
| if (line) |
| free(line); |
| if (buffer) |
| free(buffer); |
| return; |
| } |
| |
| /** |
| * @brief Show usage information for the wifidirect status command |
| * |
| * $return N/A |
| */ |
| static void |
| print_wifidirect_status_usage(void) |
| { |
| printf("\nUsage : wifidirect_mode [STATUS]"); |
| printf("\nOptions: STATUS : 0 - stop wifidirect status"); |
| printf("\n 1 - start wifidirect status"); |
| printf("\n 2 - start wifidirect group owner mode"); |
| printf("\n 3 - start wifidirect client mode"); |
| printf("\n 4 - start wifidirect find phase"); |
| printf("\n 5 - stop wifidirect find phase"); |
| printf("\n empty - get current wifidirect status\n"); |
| return; |
| } |
| |
| /** |
| * @brief Creates wifidirect mode start or stop request and send to driver |
| * |
| * Usage: "Usage : wifidirect_mode [STATUS]" |
| * |
| * Options: STATUS : 0 - start wifidirect status |
| * 1 - stop wifidirect status |
| * |
| * @param argc Number of arguments |
| * @param argv Pointer to the arguments |
| * @return N/A |
| */ |
| static void |
| wifidirectcmd_status(int argc, char *argv[]) |
| { |
| int opt, ret; |
| t_u16 data; |
| t_u16 cmd_len = 0; |
| t_u8 *buffer = NULL; |
| wifidirect_mode_config *cmd_buf = NULL; |
| while ((opt = getopt_long(argc, argv, "+", cmd_options, NULL)) != -1) { |
| switch (opt) { |
| default: |
| print_wifidirect_status_usage(); |
| return; |
| } |
| } |
| argc -= optind; |
| argv += optind; |
| /* Check arguments */ |
| if (argc < 2) { |
| printf("ERR:wrong arguments.\n"); |
| print_wifidirect_status_usage(); |
| return; |
| } |
| if (argc == 3) { |
| if ((ISDIGIT(argv[2]) == 0) || (atoi(argv[2]) < 0) || |
| (atoi(argv[2]) >= 0xFF)) { |
| printf("ERR:Illegal wifidirect mode %s. Must be in range from '0' to '5'.\n", argv[2]); |
| print_wifidirect_status_usage(); |
| return; |
| } |
| data = (t_u16)atoi(argv[2]); |
| } |
| |
| /* send hostcmd now */ |
| cmd_len = sizeof(wifidirect_mode_config); |
| buffer = (t_u8 *)malloc(MRVDRV_SIZE_OF_CMD_BUFFER); |
| if (!buffer) { |
| printf("ERR:Cannot allocate memory!\n"); |
| return; |
| } |
| |
| cmd_buf = (wifidirect_mode_config *)buffer; |
| cmd_buf->cmd_code = HostCmd_CMD_WIFIDIRECT_MODE_CONFIG; |
| cmd_buf->size = cmd_len - BUF_HEADER_SIZE; |
| cmd_buf->seq_num = 0; |
| cmd_buf->result = 0; |
| |
| if (argc == 2) { |
| cmd_buf->action = ACTION_GET; |
| } else { |
| cmd_buf->action = cpu_to_le16(ACTION_SET); |
| cmd_buf->mode = cpu_to_le16(data); |
| } |
| ret = wifidirect_ioctl((t_u8 *)buffer, &cmd_len, |
| MRVDRV_SIZE_OF_CMD_BUFFER); |
| if (ret != SUCCESS) { |
| printf("Error executing wifidirect mode command\n"); |
| return; |
| } |
| |
| data = le16_to_cpu(cmd_buf->mode); |
| switch (data) { |
| case 0: |
| printf("Wifidirect Device Mode = Not Configured\n"); |
| break; |
| case 1: |
| printf("Wifidirect Device Mode = Device\n"); |
| break; |
| case 2: |
| printf("Wifidirect Device Mode = Wifidirect Group Owner (GO)\n"); |
| break; |
| case 3: |
| printf("Wifidirect Device Mode = Wifidirect Group Client (GC)\n"); |
| break; |
| default: |
| printf("Wifidirect Device Mode = Not specified\n"); |
| break; |
| } |
| return; |
| } |
| |
| /** |
| * @brief Show usage information for the wifidirect discovery period command |
| * |
| * @return N/A |
| */ |
| static void |
| print_wifidirect_cfg_discovery_period_usage(void) |
| { |
| printf("Usage : wifidirect_cfg_discovery_period [<MinDiscPeriod> <MaxDiscPeriod>]\n"); |
| printf("For 'Set' both MinDiscPeriod and MaxDiscPeriod should be specified.\n"); |
| printf("If no parameter is given, 'get' is performed.\n"); |
| return; |
| } |
| |
| /** |
| * @brief Set/get wifidirect discovery period |
| * |
| * Usage: "Usage : wifidirect_cfg_discovery_period [<MinDiscPeriod> <MaxDiscPeriod>]" |
| * |
| * @param argc Number of arguments |
| * @param argv Pointer to the arguments |
| * @return None |
| */ |
| static void |
| wifidirect_cfg_cmd_discovery_period(int argc, char *argv[]) |
| { |
| wifidirect_params_config *cmd_buf = NULL; |
| tlvbuf_wifidirect_discovery_period *tlv = NULL; |
| t_u8 *buffer = NULL; |
| t_u16 cmd_len = 0; |
| int opt, ret = 0; |
| |
| while ((opt = getopt_long(argc, argv, "+", cmd_options, NULL)) != -1) { |
| switch (opt) { |
| default: |
| print_wifidirect_cfg_discovery_period_usage(); |
| return; |
| } |
| } |
| argc -= optind; |
| argv += optind; |
| |
| /* Check arguments */ |
| if ((argc != 2) && (argc != 4)) { |
| printf("ERR:wrong number of arguments.\n"); |
| print_wifidirect_cfg_discovery_period_usage(); |
| return; |
| } else if ((argc > 2) && |
| ((is_input_valid(WIFIDIRECT_MINDISCOVERYINT, 1, &argv[2]) != |
| SUCCESS) || |
| (is_input_valid(WIFIDIRECT_MAXDISCOVERYINT, 1, &argv[3]) != |
| SUCCESS))) { |
| print_wifidirect_cfg_discovery_period_usage(); |
| return; |
| } |
| |
| cmd_len = |
| sizeof(wifidirect_params_config) + |
| sizeof(tlvbuf_wifidirect_discovery_period); |
| |
| buffer = (t_u8 *)malloc(MRVDRV_SIZE_OF_CMD_BUFFER); |
| |
| if (!buffer) { |
| printf("ERR:Cannot allocate memory!\n"); |
| goto done; |
| } |
| |
| memset(buffer, 0, MRVDRV_SIZE_OF_CMD_BUFFER); |
| |
| cmd_buf = (wifidirect_params_config *)buffer; |
| tlv = (tlvbuf_wifidirect_discovery_period *)(buffer + |
| sizeof |
| (wifidirect_params_config)); |
| |
| cmd_buf->cmd_code = HostCmd_CMD_WIFIDIRECT_PARAMS_CONFIG; |
| cmd_buf->size = cmd_len - BUF_HEADER_SIZE; |
| cmd_buf->seq_num = 0; |
| cmd_buf->result = 0; |
| |
| tlv->tag = MRVL_WIFIDIRECT_DISC_PERIOD_TLV_ID; |
| tlv->length = |
| sizeof(tlvbuf_wifidirect_discovery_period) - |
| MRVL_TLV_HEADER_SIZE; |
| |
| if (argc == 2) { |
| cmd_buf->action = ACTION_GET; |
| } else { |
| cmd_buf->action = cpu_to_le16(ACTION_SET); |
| tlv->min_disc_interval = cpu_to_le16((t_u16)atoi(argv[2])); |
| tlv->max_disc_interval = cpu_to_le16((t_u16)atoi(argv[3])); |
| } |
| endian_convert_tlv_header_out(tlv); |
| |
| #ifdef DEBUG |
| hexdump(buffer, cmd_len, ' '); |
| #endif |
| |
| ret = wifidirect_ioctl((t_u8 *)buffer, &cmd_len, |
| MRVDRV_SIZE_OF_CMD_BUFFER); |
| endian_convert_tlv_header_in(tlv); |
| |
| #ifdef DEBUG |
| hexdump(buffer, cmd_len + BUF_HEADER_SIZE, ' '); |
| #endif |
| |
| /* Process Response */ |
| if (ret == SUCCESS) { |
| /* Verify response */ |
| if (cmd_buf->cmd_code != |
| (HostCmd_CMD_WIFIDIRECT_PARAMS_CONFIG | |
| WIFIDIRECTCMD_RESP_CHECK)) { |
| printf("ERR:Corrupted response!\n"); |
| goto done; |
| } |
| /* Print response */ |
| if (cmd_buf->result == CMD_SUCCESS) { |
| if (argc == 2) { |
| printf("Min Discovery period = %d\n", |
| le16_to_cpu(tlv->min_disc_interval)); |
| printf("Max discovery period = %d\n", |
| le16_to_cpu(tlv->max_disc_interval)); |
| } else { |
| printf("Discovery period setting successful!\n"); |
| } |
| } else { |
| if (argc == 2) { |
| printf("ERR:Couldn't get min and max discovery period!\n"); |
| } else { |
| printf("ERR:Couldn't set min and max discovery period!\n"); |
| } |
| } |
| } else { |
| printf("ERR:Command sending failed!\n"); |
| } |
| done: |
| if (buffer) |
| free(buffer); |
| return; |
| } |
| |
| /** |
| * @brief Show usage information for the wifidirect Intent command |
| * |
| * @return N/A |
| */ |
| static void |
| print_wifidirect_cfg_intent_usage(void) |
| { |
| printf("Usage : wifidirect_cfg_intent [IntentValue]\n"); |
| printf("If IntentValue parameter is provided, 'set' is performed otherwise 'get' is performed.\n"); |
| return; |
| } |
| |
| /** |
| * @brief Set/get wifidirect Intent |
| * |
| * Usage: "Usage : wifidirect_cfg_intent [IntentValue]" |
| * |
| * @param argc Number of arguments |
| * @param argv Pointer to the arguments |
| * @return None |
| */ |
| static void |
| wifidirect_cfg_cmd_intent(int argc, char *argv[]) |
| { |
| wifidirect_params_config *cmd_buf = NULL; |
| tlvbuf_wifidirect_intent *tlv = NULL; |
| t_u8 *buffer = NULL; |
| t_u16 cmd_len = 0; |
| int opt, ret = 0; |
| |
| while ((opt = getopt_long(argc, argv, "+", cmd_options, NULL)) != -1) { |
| switch (opt) { |
| default: |
| print_wifidirect_cfg_intent_usage(); |
| return; |
| } |
| } |
| argc -= optind; |
| argv += optind; |
| |
| /* Check arguments */ |
| if (argc < 2) { |
| printf("ERR: Wrong number of arguments!\n"); |
| print_wifidirect_cfg_intent_usage(); |
| return; |
| } else if ((argc > 2) && |
| (is_input_valid(WIFIDIRECT_INTENT, argc - 2, argv + 2) != |
| SUCCESS)) { |
| print_wifidirect_cfg_intent_usage(); |
| return; |
| } |
| cmd_len = |
| sizeof(wifidirect_params_config) + |
| sizeof(tlvbuf_wifidirect_intent); |
| |
| buffer = (t_u8 *)malloc(MRVDRV_SIZE_OF_CMD_BUFFER); |
| |
| if (!buffer) { |
| printf("ERR:Cannot allocate memory!\n"); |
| goto done; |
| } |
| |
| memset(buffer, 0, MRVDRV_SIZE_OF_CMD_BUFFER); |
| |
| cmd_buf = (wifidirect_params_config *)buffer; |
| tlv = (tlvbuf_wifidirect_intent *)(buffer + |
| sizeof(wifidirect_params_config)); |
| |
| cmd_buf->cmd_code = HostCmd_CMD_WIFIDIRECT_PARAMS_CONFIG; |
| cmd_buf->size = cmd_len - BUF_HEADER_SIZE; |
| cmd_buf->seq_num = 0; |
| cmd_buf->result = 0; |
| |
| tlv->tag = MRVL_WIFIDIRECT_INTENT_TLV_ID; |
| tlv->length = sizeof(tlvbuf_wifidirect_intent) - MRVL_TLV_HEADER_SIZE; |
| |
| if (argc == 2) { |
| cmd_buf->action = ACTION_GET; |
| } else { |
| cmd_buf->action = cpu_to_le16(ACTION_SET); |
| tlv->intent = (t_u8)atoi(argv[2]); |
| } |
| endian_convert_tlv_header_out(tlv); |
| #ifdef DEBUG |
| hexdump(buffer, cmd_len, ' '); |
| #endif |
| ret = wifidirect_ioctl((t_u8 *)buffer, &cmd_len, |
| MRVDRV_SIZE_OF_CMD_BUFFER); |
| endian_convert_tlv_header_in(tlv); |
| #ifdef DEBUG |
| hexdump(buffer, cmd_len + BUF_HEADER_SIZE, ' '); |
| #endif |
| /* Process Response */ |
| if (ret == SUCCESS) { |
| /* Verify response */ |
| if (cmd_buf->cmd_code != |
| (HostCmd_CMD_WIFIDIRECT_PARAMS_CONFIG | |
| WIFIDIRECTCMD_RESP_CHECK)) { |
| printf("ERR:Corrupted response!\n"); |
| goto done; |
| } |
| /* Print response */ |
| if (cmd_buf->result == CMD_SUCCESS) { |
| if (argc == 2) { |
| printf("Intent Value = %d\n", (int)tlv->intent); |
| } else { |
| printf("Intent value setting successful!\n"); |
| } |
| } else { |
| if (argc == 2) { |
| printf("ERR:Couldn't get Intent value!\n"); |
| } else { |
| printf("ERR:Couldn't set Intent value!\n"); |
| } |
| } |
| } else { |
| printf("ERR:Command sending failed!\n"); |
| } |
| done: |
| if (buffer) |
| free(buffer); |
| return; |
| } |
| |
| /** |
| * @brief Show usage information for the wifidirect Listen Channel command |
| * |
| * @return N/A |
| */ |
| static void |
| print_wifidirect_cfg_listen_channel_usage(void) |
| { |
| printf("Usage : wifidirect_cfg_listen_channel [ListenChannel]\n"); |
| printf("If ListenChannel parameter is provided, 'set' is performed otherwise 'get' is performed.\n"); |
| return; |
| } |
| |
| /** |
| * @brief Set/get wifidirect ListenChannel |
| * |
| * Usage: "Usage : wifidirect_cfg_listen_channel [ListenChannel]" |
| * |
| * @param argc Number of arguments |
| * @param argv Pointer to the arguments |
| * @return None |
| */ |
| static void |
| wifidirect_cfg_cmd_listen_channel(int argc, char *argv[]) |
| { |
| wifidirect_params_config *cmd_buf = NULL; |
| tlvbuf_wifidirect_listen_channel *tlv = NULL; |
| t_u8 *buffer = NULL; |
| t_u16 cmd_len = 0; |
| int opt, ret = 0; |
| |
| while ((opt = getopt_long(argc, argv, "+", cmd_options, NULL)) != -1) { |
| switch (opt) { |
| default: |
| print_wifidirect_cfg_listen_channel_usage(); |
| return; |
| } |
| } |
| argc -= optind; |
| argv += optind; |
| |
| /* Check arguments */ |
| if (argc < 2) { |
| printf("ERR: Wrong number of arguments!\n"); |
| print_wifidirect_cfg_listen_channel_usage(); |
| return; |
| } else if ((argc > 2) && |
| (is_input_valid(CHANNEL, argc - 2, argv + 2) != SUCCESS)) { |
| print_wifidirect_cfg_listen_channel_usage(); |
| return; |
| } |
| cmd_len = |
| sizeof(wifidirect_params_config) + |
| sizeof(tlvbuf_wifidirect_listen_channel); |
| |
| buffer = (t_u8 *)malloc(MRVDRV_SIZE_OF_CMD_BUFFER); |
| |
| if (!buffer) { |
| printf("ERR:Cannot allocate memory!\n"); |
| goto done; |
| } |
| |
| memset(buffer, 0, MRVDRV_SIZE_OF_CMD_BUFFER); |
| |
| cmd_buf = (wifidirect_params_config *)buffer; |
| tlv = (tlvbuf_wifidirect_listen_channel *)(buffer + |
| sizeof |
| (wifidirect_params_config)); |
| |
| cmd_buf->cmd_code = HostCmd_CMD_WIFIDIRECT_PARAMS_CONFIG; |
| cmd_buf->size = cmd_len - BUF_HEADER_SIZE; |
| cmd_buf->seq_num = 0; |
| cmd_buf->result = 0; |
| |
| tlv->tag = MRVL_WIFIDIRECT_LISTEN_CHANNEL_TLV_ID; |
| tlv->length = |
| sizeof(tlvbuf_wifidirect_listen_channel) - MRVL_TLV_HEADER_SIZE; |
| |
| if (argc == 2) { |
| cmd_buf->action = ACTION_GET; |
| } else { |
| cmd_buf->action = cpu_to_le16(ACTION_SET); |
| tlv->listen_channel = (t_u8)atoi(argv[2]); |
| } |
| endian_convert_tlv_header_out(tlv); |
| #ifdef DEBUG |
| hexdump(buffer, cmd_len, ' '); |
| #endif |
| ret = wifidirect_ioctl((t_u8 *)buffer, &cmd_len, |
| MRVDRV_SIZE_OF_CMD_BUFFER); |
| endian_convert_tlv_header_in(tlv); |
| #ifdef DEBUG |
| hexdump(buffer, cmd_len + BUF_HEADER_SIZE, ' '); |
| #endif |
| /* Process Response */ |
| if (ret == SUCCESS) { |
| /* Verify response */ |
| if (cmd_buf->cmd_code != |
| (HostCmd_CMD_WIFIDIRECT_PARAMS_CONFIG | |
| WIFIDIRECTCMD_RESP_CHECK)) { |
| printf("ERR:Corrupted response!\n"); |
| goto done; |
| } |
| /* Print response */ |
| if (cmd_buf->result == CMD_SUCCESS) { |
| if (argc == 2) { |
| printf("Listen Channel = %d\n", |
| (int)tlv->listen_channel); |
| } else { |
| printf("Listen Channel setting successful!\n"); |
| } |
| } else { |
| if (argc == 2) { |
| printf("ERR:Couldn't get Listen Channel!\n"); |
| } else { |
| printf("ERR:Couldn't set Listen Channel!\n"); |
| } |
| } |
| } else { |
| printf("ERR:Command sending failed!\n"); |
| } |
| done: |
| if (buffer) |
| free(buffer); |
| return; |
| } |
| |
| /** |
| * @brief Show usage information for the wifidirect Operating Channel command |
| * |
| * @return N/A |
| */ |
| static void |
| print_wifidirect_cfg_op_channel_usage(void) |
| { |
| printf("Usage : wifidirect_cfg_op_channel [OperatingChannel]\n"); |
| printf("If OperatingChannel parameter is provided, 'set' is performed otherwise 'get' is performed.\n"); |
| return; |
| } |
| |
| /** |
| * @brief Set/get wifidirect OperatingChannel |
| * |
| * Usage: "Usage : wifidirect_cfg_op_channel [OperatingChannel]" |
| * |
| * @param argc Number of arguments |
| * @param argv Pointer to the arguments |
| * @return None |
| */ |
| static void |
| wifidirect_cfg_cmd_op_channel(int argc, char *argv[]) |
| { |
| wifidirect_params_config *cmd_buf = NULL; |
| tlvbuf_wifidirect_operating_channel *tlv = NULL; |
| t_u8 *buffer = NULL; |
| t_u16 cmd_len = 0; |
| int opt, ret = 0; |
| |
| while ((opt = getopt_long(argc, argv, "+", cmd_options, NULL)) != -1) { |
| switch (opt) { |
| default: |
| print_wifidirect_cfg_op_channel_usage(); |
| return; |
| } |
| } |
| argc -= optind; |
| argv += optind; |
| |
| /* Check arguments */ |
| if (argc < 2) { |
| printf("ERR: Wrong number of arguments!\n"); |
| print_wifidirect_cfg_op_channel_usage(); |
| return; |
| } else if ((argc > 2) && |
| (is_input_valid(CHANNEL, argc - 2, argv + 2) != SUCCESS)) { |
| print_wifidirect_cfg_op_channel_usage(); |
| return; |
| } |
| cmd_len = |
| sizeof(wifidirect_params_config) + |
| sizeof(tlvbuf_wifidirect_operating_channel); |
| |
| buffer = (t_u8 *)malloc(MRVDRV_SIZE_OF_CMD_BUFFER); |
| |
| if (!buffer) { |
| printf("ERR:Cannot allocate memory!\n"); |
| goto done; |
| } |
| |
| memset(buffer, 0, MRVDRV_SIZE_OF_CMD_BUFFER); |
| |
| cmd_buf = (wifidirect_params_config *)buffer; |
| tlv = (tlvbuf_wifidirect_operating_channel *)(buffer + |
| sizeof |
| (wifidirect_params_config)); |
| |
| cmd_buf->cmd_code = HostCmd_CMD_WIFIDIRECT_PARAMS_CONFIG; |
| cmd_buf->size = cmd_len - BUF_HEADER_SIZE; |
| cmd_buf->seq_num = 0; |
| cmd_buf->result = 0; |
| |
| tlv->tag = MRVL_WIFIDIRECT_OPERATING_CHANNEL_TLV_ID; |
| tlv->length = |
| sizeof(tlvbuf_wifidirect_operating_channel) - |
| MRVL_TLV_HEADER_SIZE; |
| |
| if (argc == 2) { |
| cmd_buf->action = ACTION_GET; |
| } else { |
| cmd_buf->action = cpu_to_le16(ACTION_SET); |
| tlv->operating_channel = (t_u8)atoi(argv[2]); |
| } |
| endian_convert_tlv_header_out(tlv); |
| #ifdef DEBUG |
| hexdump(buffer, cmd_len, ' '); |
| #endif |
| ret = wifidirect_ioctl((t_u8 *)buffer, &cmd_len, |
| MRVDRV_SIZE_OF_CMD_BUFFER); |
| endian_convert_tlv_header_in(tlv); |
| #ifdef DEBUG |
| hexdump(buffer, cmd_len + BUF_HEADER_SIZE, ' '); |
| #endif |
| /* Process Response */ |
| if (ret == SUCCESS) { |
| /* Verify response */ |
| if (cmd_buf->cmd_code != |
| (HostCmd_CMD_WIFIDIRECT_PARAMS_CONFIG | |
| WIFIDIRECTCMD_RESP_CHECK)) { |
| printf("ERR:Corrupted response!\n"); |
| goto done; |
| } |
| /* Print response */ |
| if (cmd_buf->result == CMD_SUCCESS) { |
| if (argc == 2) { |
| printf("Operating Channel = %d\n", |
| (int)tlv->operating_channel); |
| } else { |
| printf("Operating Channel setting successful!\n"); |
| } |
| } else { |
| if (argc == 2) { |
| printf("ERR:Couldn't get Operating Channel!\n"); |
| } else { |
| printf("ERR:Couldn't set Operating Channel!\n"); |
| } |
| } |
| } else { |
| printf("ERR:Command sending failed!\n"); |
| } |
| done: |
| if (buffer) |
| free(buffer); |
| return; |
| } |
| |
| /** |
| * @brief Show usage information for the wifidirect Invitation List command |
| * |
| * @return N/A |
| */ |
| static void |
| print_wifidirect_cfg_invitation_list_usage(void) |
| { |
| printf("\nUsage : wifidirect_cfg_invitation_list [mac_addr]"); |
| printf("\nIf mac_addr parameter is provided, 'set' is performed otherwise 'get' is performed.\n"); |
| return; |
| } |
| |
| /** |
| * @brief Set/get wifidirect InvitationList |
| * |
| * Usage: "Usage : wifidirect_cfg_invitation_list [mac_addr]" |
| * |
| * @param argc Number of arguments |
| * @param argv Pointer to the arguments |
| * @return None |
| */ |
| static void |
| wifidirect_cfg_cmd_invitation_list(int argc, char *argv[]) |
| { |
| wifidirect_params_config *cmd_buf = NULL; |
| tlvbuf_wifidirect_invitation_list *tlv = NULL; |
| t_u8 *buffer = NULL; |
| t_u16 cmd_len = 0; |
| int opt, ret = 0, ctr = 1; |
| |
| while ((opt = getopt_long(argc, argv, "+", cmd_options, NULL)) != -1) { |
| switch (opt) { |
| default: |
| print_wifidirect_cfg_invitation_list_usage(); |
| return; |
| } |
| } |
| argc -= optind; |
| argv += optind; |
| |
| /* Check arguments */ |
| if ((argc < 2) || (argc > 3)) { |
| printf("ERR:Wrong number of arguments!\n"); |
| print_wifidirect_cfg_invitation_list_usage(); |
| return; |
| } |
| |
| cmd_len = |
| sizeof(wifidirect_params_config) + |
| sizeof(tlvbuf_wifidirect_invitation_list); |
| |
| buffer = (t_u8 *)malloc(MRVDRV_SIZE_OF_CMD_BUFFER); |
| |
| if (!buffer) { |
| printf("ERR:Cannot allocate memory!\n"); |
| goto done; |
| } |
| |
| memset(buffer, 0, MRVDRV_SIZE_OF_CMD_BUFFER); |
| |
| cmd_buf = (wifidirect_params_config *)buffer; |
| tlv = (tlvbuf_wifidirect_invitation_list *)(buffer + |
| sizeof |
| (wifidirect_params_config)); |
| |
| cmd_buf->cmd_code = HostCmd_CMD_WIFIDIRECT_PARAMS_CONFIG; |
| cmd_buf->size = cmd_len - BUF_HEADER_SIZE; |
| cmd_buf->seq_num = 0; |
| cmd_buf->result = 0; |
| |
| tlv->tag = MRVL_WIFIDIRECT_INVITATION_LIST_TLV_ID; |
| tlv->length = |
| sizeof(tlvbuf_wifidirect_invitation_list) - |
| MRVL_TLV_HEADER_SIZE; |
| |
| if (argc == 2) { |
| cmd_buf->action = ACTION_GET; |
| cmd_len += (WIFIDIRECT_INVITATION_LIST_MAX - 1) * ETH_ALEN; |
| } else { |
| cmd_buf->action = cpu_to_le16(ACTION_SET); |
| if ((ret = mac2raw(argv[2], tlv->inv_peer_addr)) != SUCCESS) { |
| printf("ERR:Invalid MAC address %s\n", argv[2]); |
| goto done; |
| } |
| } |
| endian_convert_tlv_header_out(tlv); |
| #ifdef DEBUG |
| hexdump(buffer, cmd_len, ' '); |
| #endif |
| ret = wifidirect_ioctl((t_u8 *)buffer, &cmd_len, |
| MRVDRV_SIZE_OF_CMD_BUFFER); |
| endian_convert_tlv_header_in(tlv); |
| #ifdef DEBUG |
| hexdump(buffer, cmd_len + BUF_HEADER_SIZE, ' '); |
| #endif |
| /* Process Response */ |
| if (ret == SUCCESS) { |
| /* Verify response */ |
| if (cmd_buf->cmd_code != |
| (HostCmd_CMD_WIFIDIRECT_PARAMS_CONFIG | |
| WIFIDIRECTCMD_RESP_CHECK)) { |
| printf("ERR:Corrupted response!\n"); |
| goto done; |
| } |
| /* Print response */ |
| if (cmd_buf->result == CMD_SUCCESS) { |
| if (argc == 2) { |
| /* reusing variable cmd_len */ |
| cmd_len = tlv->length; |
| if (cmd_len > 0) { |
| printf("Invitation List =>"); |
| while (cmd_len >= ETH_ALEN) { |
| if (memcmp |
| (tlv->inv_peer_addr, |
| "\x00\x00\x00\x00\x00\x00", |
| ETH_ALEN)) { |
| printf("\n\t [%d] ", |
| ctr++); |
| print_mac(tlv-> |
| inv_peer_addr); |
| } |
| cmd_len -= ETH_ALEN; |
| tlv = (tlvbuf_wifidirect_invitation_list *)(((t_u8 *)(tlv)) + ETH_ALEN); |
| } |
| if (ctr == 1) |
| printf(" empty."); |
| } else |
| printf("Invitation List is empty.\n"); |
| printf("\n"); |
| } else { |
| printf("Invitation List setting successful!\n"); |
| } |
| } else { |
| if (argc == 2) { |
| printf("ERR:Couldn't get Invitation List!\n"); |
| } else { |
| printf("ERR:Couldn't set Invitation List!\n"); |
| } |
| } |
| } else { |
| printf("ERR:Command sending failed!\n"); |
| } |
| done: |
| if (buffer) |
| free(buffer); |
| return; |
| } |
| |
| /** |
| * @brief Show usage information for the wifidirect noa config command |
| * |
| * @return N/A |
| */ |
| static void |
| print_wifidirect_cfg_noa_usage(void) |
| { |
| printf("Usage : wifidirect_cfg_noa <enable|disable> <index> [<counttype> <duration> <interval>]\n"); |
| printf("If NOA parameters are provided, 'set' is performed otherwise 'get' is performed.\n"); |
| return; |
| } |
| |
| /** |
| * @brief Set/get wifidirect NoA parameters |
| * |
| * Usage: "Usage : wifidirect_cfg_noa <enable|disable> <index> [<counttype> <duration> <interval>]" |
| * |
| * @param argc Number of arguments |
| * @param argv Pointer to the arguments |
| * @return None |
| */ |
| static void |
| wifidirect_cfg_cmd_noa(int argc, char *argv[]) |
| { |
| wifidirect_params_config *cmd_buf = NULL; |
| tlvbuf_wifidirect_noa_config *tlv = NULL; |
| t_u8 *buffer = NULL; |
| t_u16 cmd_len = 0; |
| int opt, ret = 0; |
| |
| while ((opt = getopt_long(argc, argv, "+", cmd_options, NULL)) != -1) { |
| switch (opt) { |
| default: |
| print_wifidirect_cfg_noa_usage(); |
| return; |
| } |
| } |
| argc -= optind; |
| argv += optind; |
| |
| /* Check arguments */ |
| if ((argc != 2) && (argc != 4) && (argc != 7)) { |
| printf("ERR: Wrong number of arguments!\n"); |
| print_wifidirect_cfg_noa_usage(); |
| return; |
| } |
| if (argc > 2) { |
| if (argc == 4) { |
| if (strcmp(argv[2], "enable") == 0) { |
| printf("ERR: index, count_type, duration and interval must be" " specified if noa is enabled!\n"); |
| print_wifidirect_cfg_noa_usage(); |
| return; |
| } else if (strcmp(argv[2], "disable")) { |
| print_wifidirect_cfg_noa_usage(); |
| return; |
| } |
| if (atoi(argv[3]) > WIFIDIRECT_NOA_DESC_MAX) { |
| print_wifidirect_cfg_noa_usage(); |
| return; |
| } |
| } else { |
| if (atoi(argv[3]) > WIFIDIRECT_NOA_DESC_MAX || |
| (is_input_valid(WIFIDIRECT_COUNT_TYPE, 1, &argv[4]) |
| != SUCCESS) || |
| (is_input_valid(WIFIDIRECT_DURATION, 1, &argv[5]) != |
| SUCCESS) || |
| (is_input_valid(WIFIDIRECT_INTERVAL, 1, &argv[6]) != |
| SUCCESS)) { |
| print_wifidirect_cfg_noa_usage(); |
| return; |
| } |
| } |
| } |
| cmd_len = |
| sizeof(wifidirect_params_config) + |
| sizeof(tlvbuf_wifidirect_noa_config); |
| |
| buffer = (t_u8 *)malloc(MRVDRV_SIZE_OF_CMD_BUFFER); |
| |
| if (!buffer) { |
| printf("ERR:Cannot allocate memory!\n"); |
| goto done; |
| } |
| |
| memset(buffer, 0, MRVDRV_SIZE_OF_CMD_BUFFER); |
| |
| cmd_buf = (wifidirect_params_config *)buffer; |
| tlv = (tlvbuf_wifidirect_noa_config *)(buffer + |
| sizeof |
| (wifidirect_params_config)); |
| |
| cmd_buf->cmd_code = HostCmd_CMD_WIFIDIRECT_PARAMS_CONFIG; |
| cmd_buf->size = cmd_len - BUF_HEADER_SIZE; |
| cmd_buf->seq_num = 0; |
| cmd_buf->result = 0; |
| |
| tlv->tag = MRVL_WIFIDIRECT_NOA_TLV_ID; |
| tlv->length = |
| sizeof(tlvbuf_wifidirect_noa_config) - MRVL_TLV_HEADER_SIZE; |
| |
| if (argc == 2) { |
| cmd_buf->action = ACTION_GET; |
| cmd_len += |
| (sizeof(tlvbuf_wifidirect_noa_config) - |
| MRVL_TLV_HEADER_SIZE) |
| * (WIFIDIRECT_NOA_DESC_MAX - 1); |
| } else { |
| cmd_buf->action = cpu_to_le16(ACTION_SET); |
| if (strcmp(argv[2], "disable")) { |
| /* enable case */ |
| tlv->enable_noa = 1; |
| tlv->enable_noa = cpu_to_le16(tlv->enable_noa); |
| } |
| tlv->noa_index = (t_u8)atoi(argv[3]); |
| |
| if (tlv->enable_noa) { |
| tlv->count_type = (t_u8)atoi(argv[4]); |
| tlv->duration = (t_u32)atoi(argv[5]); |
| tlv->duration = cpu_to_le32(tlv->duration); |
| tlv->interval = (t_u32)atoi(argv[6]); |
| tlv->interval = cpu_to_le32(tlv->interval); |
| } |
| } |
| endian_convert_tlv_header_out(tlv); |
| #ifdef DEBUG |
| hexdump(buffer, cmd_len, ' '); |
| #endif |
| ret = wifidirect_ioctl((t_u8 *)buffer, &cmd_len, |
| MRVDRV_SIZE_OF_CMD_BUFFER); |
| endian_convert_tlv_header_in(tlv); |
| #ifdef DEBUG |
| hexdump(buffer, cmd_len + BUF_HEADER_SIZE, ' '); |
| #endif |
| /* Process Response */ |
| if (ret == SUCCESS) { |
| /* Verify response */ |
| if (cmd_buf->cmd_code != |
| (HostCmd_CMD_WIFIDIRECT_PARAMS_CONFIG | |
| WIFIDIRECTCMD_RESP_CHECK)) { |
| printf("ERR:Corrupted response!\n"); |
| goto done; |
| } |
| /* Print response */ |
| if (cmd_buf->result == CMD_SUCCESS) { |
| if (argc == 2) { |
| if (tlv->length) |
| printf("NoA settings:\n"); |
| else |
| printf("NoA parameters are not configured.\n"); |
| if (tlv->length >= |
| sizeof(tlvbuf_wifidirect_noa_config) - |
| MRVL_TLV_HEADER_SIZE) { |
| tlv->enable_noa = |
| le16_to_cpu(tlv->enable_noa); |
| if (tlv->enable_noa) { |
| printf("[%d] NoA is enabled!\n", |
| (int)tlv->noa_index); |
| printf("CountType = %d\n", |
| (int)tlv->count_type); |
| printf("Duration = %dms\n", |
| le32_to_cpu(tlv-> |
| duration)); |
| printf("Interval = %dms\n", |
| le32_to_cpu(tlv-> |
| interval)); |
| } else { |
| printf("[%d] NoA is disabled!\n", (int)tlv->noa_index); |
| } |
| } |
| } else { |
| printf("NoA setting successful!\n"); |
| } |
| } else { |
| if (argc == 2) { |
| printf("ERR:Couldn't get NoA parameters!\n"); |
| } else { |
| printf("ERR:Couldn't set NoA parameters!\n"); |
| } |
| } |
| } else { |
| printf("ERR:Command sending failed!\n"); |
| } |
| done: |
| if (buffer) |
| free(buffer); |
| return; |
| } |
| |
| /** |
| * @brief Show usage information for the wifidirect opp_ps config command |
| * |
| * @return N/A |
| */ |
| static void |
| print_wifidirect_cfg_opp_ps_usage(void) |
| { |
| printf("Usage : wifidirect_cfg_opp_ps <enable|disable> [<CTWindow>]\n"); |
| printf("For 'set', both enable flag and CTWindow should be provided.\n"); |
| printf("If no parameter is specified,'get' is performed.\n"); |
| return; |
| } |
| |
| /** |
| * @brief Set/get wifidirect Opportunistic Power Save |
| * |
| * Usage: "Usage : wifidirect_cfg_opp_ps <enable|disable> [<CTWindow>]" |
| * |
| * @param argc Number of arguments |
| * @param argv Pointer to the arguments |
| * @return None |
| */ |
| static void |
| wifidirect_cfg_cmd_opp_ps(int argc, char *argv[]) |
| { |
| wifidirect_params_config *cmd_buf = NULL; |
| tlvbuf_wifidirect_opp_ps_config *tlv = NULL; |
| t_u8 *buffer = NULL; |
| t_u16 cmd_len = 0; |
| t_u8 opp_ps = 0, ctwindow = 0; |
| int opt, ret = 0; |
| |
| while ((opt = getopt_long(argc, argv, "+", cmd_options, NULL)) != -1) { |
| switch (opt) { |
| default: |
| print_wifidirect_cfg_opp_ps_usage(); |
| return; |
| } |
| } |
| argc -= optind; |
| argv += optind; |
| |
| /* Check arguments */ |
| if ((argc < 2) || (argc > 4)) { |
| printf("ERR: Wrong number of arguments!\n"); |
| print_wifidirect_cfg_opp_ps_usage(); |
| return; |
| } |
| if (argc == 3) { |
| if (strcmp(argv[2], "enable") == 0) { |
| printf("ERR: If Opp PS is enabled, CTWindow must be specified!\n"); |
| print_wifidirect_cfg_opp_ps_usage(); |
| return; |
| } else if (strcmp(argv[2], "disable")) { |
| print_wifidirect_cfg_opp_ps_usage(); |
| return; |
| } |
| } |
| if (argc == 4) { |
| if (strcmp(argv[2], "disable") == 0) { |
| printf("ERR: Extra parameter %s for disable command.\n", |
| argv[3]); |
| return; |
| } |
| if (is_input_valid(WIFIDIRECT_CTWINDOW, 1, &argv[3]) != SUCCESS) { |
| print_wifidirect_cfg_opp_ps_usage(); |
| return; |
| } |
| } |
| |
| cmd_len = |
| sizeof(wifidirect_params_config) + |
| sizeof(tlvbuf_wifidirect_opp_ps_config); |
| |
| buffer = (t_u8 *)malloc(MRVDRV_SIZE_OF_CMD_BUFFER); |
| |
| if (!buffer) { |
| printf("ERR:Cannot allocate memory!\n"); |
| goto done; |
| } |
| |
| memset(buffer, 0, MRVDRV_SIZE_OF_CMD_BUFFER); |
| |
| cmd_buf = (wifidirect_params_config *)buffer; |
| tlv = (tlvbuf_wifidirect_opp_ps_config *)(buffer + |
| sizeof |
| (wifidirect_params_config)); |
| |
| cmd_buf->cmd_code = HostCmd_CMD_WIFIDIRECT_PARAMS_CONFIG; |
| cmd_buf->size = cmd_len - BUF_HEADER_SIZE; |
| cmd_buf->seq_num = 0; |
| cmd_buf->result = 0; |
| |
| tlv->tag = MRVL_WIFIDIRECT_OPP_PS_TLV_ID; |
| tlv->length = |
| sizeof(tlvbuf_wifidirect_opp_ps_config) - MRVL_TLV_HEADER_SIZE; |
| |
| if (argc == 2) { |
| cmd_buf->action = ACTION_GET; |
| } else { |
| cmd_buf->action = cpu_to_le16(ACTION_SET); |
| if (strcmp(argv[2], "disable")) |
| opp_ps = 1; |
| if (argc == 4) |
| tlv->ctwindow_opp_ps = |
| (t_u8)atoi(argv[3]) | SET_OPP_PS(opp_ps);; |
| } |
| endian_convert_tlv_header_out(tlv); |
| #ifdef DEBUG |
| hexdump(buffer, cmd_len, ' '); |
| #endif |
| ret = wifidirect_ioctl((t_u8 *)buffer, &cmd_len, |
| MRVDRV_SIZE_OF_CMD_BUFFER); |
| endian_convert_tlv_header_in(tlv); |
| #ifdef DEBUG |
| hexdump(buffer, cmd_len + BUF_HEADER_SIZE, ' '); |
| #endif |
| /* Process Response */ |
| if (ret == SUCCESS) { |
| /* Verify response */ |
| if (cmd_buf->cmd_code != |
| (HostCmd_CMD_WIFIDIRECT_PARAMS_CONFIG | |
| WIFIDIRECTCMD_RESP_CHECK)) { |
| printf("ERR:Corrupted response!\n"); |
| goto done; |
| } |
| /* Print response */ |
| if (cmd_buf->result == CMD_SUCCESS) { |
| if (argc == 2) { |
| opp_ps = GET_OPP_PS(tlv->ctwindow_opp_ps); |
| if (opp_ps) { |
| ctwindow = |
| (tlv-> |
| ctwindow_opp_ps) & |
| CT_WINDOW_MASK; |
| printf("Opportunistic Power Save enabled!\n"); |
| printf("CTWindow = %d\n", ctwindow); |
| } else { |
| printf("Opportunistic Power Save disabled!\n"); |
| } |
| } else { |
| printf("Opportunistic power save setting successful!\n"); |
| } |
| } else { |
| if (argc == 2) { |
| printf("ERR:Couldn't get Opportunistic power save and CTWindow!\n"); |
| } else { |
| printf("ERR:Couldn't set Opportunistic power save and CTWindow!\n"); |
| } |
| } |
| } else { |
| printf("ERR:Command sending failed!\n"); |
| } |
| done: |
| if (buffer) |
| free(buffer); |
| return; |
| } |
| |
| /** |
| * @brief Show usage information for the wifidirect capability config command |
| * |
| * @return N/A |
| */ |
| static void |
| print_wifidirect_cfg_capability_usage(void) |
| { |
| printf("Usage : wifidirect_capability [<DeviceCapability> <GroupCapability>]\n"); |
| printf("For 'set' both DeviceCapability and GroupCapability should be provided.\n"); |
| printf("If no parameter is specified,'get' is performed.\n"); |
| return; |
| } |
| |
| /** |
| * @brief Set/get wifidirect Capability |
| * |
| * Usage: "Usage : wifidirect_cfg_capability [<DeviceCapability> <GroupCapability>]" |
| * |
| * @param argc Number of arguments |
| * @param argv Pointer to the arguments |
| * @return None |
| */ |
| static void |
| wifidirect_cfg_cmd_capability(int argc, char *argv[]) |
| { |
| wifidirect_params_config *cmd_buf = NULL; |
| tlvbuf_wifidirect_capability_config *tlv = NULL; |
| t_u8 *buffer = NULL; |
| t_u16 cmd_len = 0; |
| int opt, ret = 0; |
| |
| while ((opt = getopt_long(argc, argv, "+", cmd_options, NULL)) != -1) { |
| switch (opt) { |
| default: |
| print_wifidirect_cfg_capability_usage(); |
| return; |
| } |
| } |
| argc -= optind; |
| argv += optind; |
| |
| /* Check arguments */ |
| if ((argc < 2) || (argc > 4) || (argc == 3)) { |
| printf("ERR: Wrong number of arguments!\n"); |
| print_wifidirect_cfg_capability_usage(); |
| return; |
| } |
| if (argc == 4) { |
| if ((is_input_valid(WIFIDIRECT_DEVICECAPABILITY, 1, &argv[2]) != |
| SUCCESS) || |
| (is_input_valid(WIFIDIRECT_GROUPCAPABILITY, 1, &argv[3]) != |
| SUCCESS)) { |
| print_wifidirect_cfg_capability_usage(); |
| return; |
| } |
| } |
| cmd_len = |
| sizeof(wifidirect_params_config) + |
| sizeof(tlvbuf_wifidirect_capability_config); |
| |
| buffer = (t_u8 *)malloc(MRVDRV_SIZE_OF_CMD_BUFFER); |
| |
| if (!buffer) { |
| printf("ERR:Cannot allocate memory!\n"); |
| goto done; |
| } |
| |
| memset(buffer, 0, MRVDRV_SIZE_OF_CMD_BUFFER); |
| |
| cmd_buf = (wifidirect_params_config *)buffer; |
| tlv = (tlvbuf_wifidirect_capability_config *)(buffer + |
| sizeof |
| (wifidirect_params_config)); |
| |
| cmd_buf->cmd_code = HostCmd_CMD_WIFIDIRECT_PARAMS_CONFIG; |
| cmd_buf->size = cmd_len - BUF_HEADER_SIZE; |
| cmd_buf->seq_num = 0; |
| cmd_buf->result = 0; |
| |
| tlv->tag = MRVL_WIFIDIRECT_CAPABILITY_TLV_ID; |
| tlv->length = |
| sizeof(tlvbuf_wifidirect_capability_config) - |
| MRVL_TLV_HEADER_SIZE; |
| |
| if (argc == 2) { |
| cmd_buf->action = ACTION_GET; |
| } else { |
| cmd_buf->action = cpu_to_le16(ACTION_SET); |
| tlv->dev_capability = (t_u8)atoi(argv[2]); |
| tlv->group_capability = (t_u8)atoi(argv[3]); |
| } |
| endian_convert_tlv_header_out(tlv); |
| #ifdef DEBUG |
| hexdump(buffer, cmd_len, ' '); |
| #endif |
| ret = wifidirect_ioctl((t_u8 *)buffer, &cmd_len, |
| MRVDRV_SIZE_OF_CMD_BUFFER); |
| endian_convert_tlv_header_in(tlv); |
| #ifdef DEBUG |
| hexdump(buffer, cmd_len + BUF_HEADER_SIZE, ' '); |
| #endif |
| /* Process Response */ |
| if (ret == SUCCESS) { |
| /* Verify response */ |
| if (cmd_buf->cmd_code != |
| (HostCmd_CMD_WIFIDIRECT_PARAMS_CONFIG | |
| WIFIDIRECTCMD_RESP_CHECK)) { |
| printf("ERR:Corrupted response!\n"); |
| goto done; |
| } |
| /* Print response */ |
| if (cmd_buf->result == CMD_SUCCESS) { |
| if (argc == 2) { |
| printf("Device Capability = %d\n", |
| (int)tlv->dev_capability); |
| printf("Group Capability = %d\n", |
| (int)tlv->group_capability); |
| } else { |
| printf("Capability setting successful!\n"); |
| } |
| } else { |
| if (argc == 2) { |
| printf("ERR:Couldn't get Capability info!\n"); |
| } else { |
| printf("ERR:Couldn't set Capability!\n"); |
| } |
| } |
| } else { |
| printf("ERR:Command sending failed!\n"); |
| } |
| done: |
| if (buffer) |
| free(buffer); |
| return; |
| } |
| |
| /** |
| * @brief Show usage information for the wifidirect_cfg_persistent_group_record command |
| * |
| * $return N/A |
| */ |
| static void |
| print_wifidirect_peristent_group_usage(void) |
| { |
| printf("\nUsage : wifidirect_cfg_persistent_group_record [index] \ |
| <role> <bssid> <groupdevid> <ssid> <psk>> \ |
| [<peermac1> <peermac2> ]\n"); |
| printf("\nIssue set or get request using appropriate parameters.\n"); |
| return; |
| } |
| |
| /** |
| * @brief Creates a wifidirect_persistent group record request and |
| * sends to the driver |
| * |
| * Usage: "Usage : wifidirect_cfg_cmd_persistent_group_record [index] < |
| * <role> <bssid> <groupdevid> <ssid> <psk>> |
| * [<peermac1> <peermac2> ]" |
| * |
| * @param argc Number of arguments |
| * @param argv Pointer to the arguments |
| * @return SUCCESS or FAILURE |
| **/ |
| static void |
| wifidirect_cfg_cmd_persistent_group_record(int argc, char *argv[]) |
| { |
| wifidirect_params_config *cmd_buf = NULL; |
| tlvbuf_wifidirect_persistent_group *tlv = NULL; |
| t_u8 index = 0, role = 0, var_len = 0, psk_len = 0; |
| t_u8 *buffer = NULL; |
| int pi; |
| t_u16 cmd_len = 0, buf_len = 0; |
| int opt, ret; |
| |
| while ((opt = getopt_long(argc, argv, "+", cmd_options, NULL)) != -1) { |
| switch (opt) { |
| default: |
| print_wifidirect_peristent_group_usage(); |
| return; |
| } |
| } |
| argc -= optind; |
| argv += optind; |
| |
| /* Check arguments */ |
| if (argc != 2 && argc != 3 && argc != 8 && argc != 9 && argc != 10) { |
| printf("ERR:wrong number of arguments.\n"); |
| print_wifidirect_peristent_group_usage(); |
| return; |
| } |
| /* error checks */ |
| if (argc > 2) { |
| index = atoi(argv[2]); |
| if (index >= WIFIDIRECT_PERSISTENT_GROUP_MAX) { |
| printf("ERR:wrong index. Value values are [0-3]\n"); |
| return; |
| } |
| } |
| if (argc > 3) { |
| role = atoi(argv[3]); |
| if ((role != 1) && (role != 2)) { |
| printf("ERR:Incorrect Role. Use 2 for client, 1 for group owner.\n"); |
| return; |
| } |
| if (role == 1 && argc == 8) { |
| printf("ERR:Insufficient arguments. Please provide peer mac address(es) for group owner.\n"); |
| return; |
| } |
| } |
| |
| cmd_len = sizeof(wifidirect_params_config); |
| buffer = (t_u8 *)malloc(MRVDRV_SIZE_OF_CMD_BUFFER); |
| if (!buffer) { |
| printf("ERR:Cannot allocate memory!\n"); |
| goto done; |
| } |
| memset(buffer, 0, MRVDRV_SIZE_OF_CMD_BUFFER); |
| cmd_buf = (wifidirect_params_config *)buffer; |
| cmd_buf->cmd_code = HostCmd_CMD_WIFIDIRECT_PARAMS_CONFIG; |
| cmd_buf->seq_num = 0; |
| cmd_buf->result = 0; |
| tlv = (tlvbuf_wifidirect_persistent_group *)(buffer + |
| sizeof |
| (wifidirect_params_config)); |
| |
| tlv->tag = MRVL_WIFIDIRECT_PERSISTENT_GROUP_TLV_ID; |
| |
| /* parsing commands based on arguments */ |
| switch (argc) { |
| case 2: |
| cmd_buf->action = ACTION_GET; |
| tlv->length = 0; |
| cmd_len += MRVL_TLV_HEADER_SIZE + tlv->length; |
| cmd_buf->size = cmd_len - BUF_HEADER_SIZE; |
| buf_len = MRVDRV_SIZE_OF_CMD_BUFFER; |
| break; |
| |
| case 3: |
| cmd_buf->action = ACTION_GET; |
| tlv->rec_index = index; |
| tlv->length = sizeof(index); |
| cmd_len += MRVL_TLV_HEADER_SIZE + tlv->length; |
| cmd_buf->size = cmd_len - BUF_HEADER_SIZE; |
| buf_len = MRVDRV_SIZE_OF_CMD_BUFFER; |
| break; |
| |
| default: |
| cmd_buf->action = cpu_to_le16(ACTION_SET); |
| tlv->rec_index = index; |
| tlv->dev_role = role; |
| if ((ret = mac2raw(argv[4], tlv->group_bssid)) != SUCCESS) { |
| printf("ERR:Invalid MAC address %s\n", argv[4]); |
| goto done; |
| } |
| if ((ret = mac2raw(argv[5], tlv->dev_mac_address)) != SUCCESS) { |
| printf("ERR:Invalid MAC address %s\n", argv[5]); |
| goto done; |
| } |
| |
| /* ssid */ |
| tlv->group_ssid_len = strlen(argv[6]); |
| var_len += tlv->group_ssid_len; |
| memcpy(tlv->group_ssid, argv[6], tlv->group_ssid_len); |
| |
| /* adjust pointer from here */ |
| /* psk */ |
| if (!strncasecmp("0x", argv[7], 2)) { |
| argv[7] += 2; |
| if (strlen(argv[7]) / 2 != WIFIDIRECT_PSK_LEN_MAX) { |
| printf("ERR:Incorrect PSK length %d. It should be %d.\n", (t_u32)strlen(argv[7]) / 2, WIFIDIRECT_PSK_LEN_MAX); |
| goto done; |
| } |
| string2raw(argv[7], tlv->psk + var_len); |
| *(&tlv->psk_len + var_len) = WIFIDIRECT_PSK_LEN_MAX; |
| var_len += WIFIDIRECT_PSK_LEN_MAX; |
| } else { |
| /* ascii */ |
| psk_len = strlen(argv[7]); |
| if (psk_len < WIFIDIRECT_PASSPHRASE_LEN_MIN || |
| psk_len >= WIFIDIRECT_PSK_LEN_MAX) { |
| printf("ERR:Incorrect passphrase length %d. Valid range is [8-63]\n", psk_len); |
| goto done; |
| } |
| memcpy(tlv->psk + var_len, argv[7], psk_len); |
| *(&tlv->psk_len + var_len) = psk_len; |
| var_len += psk_len; |
| } |
| |
| tlv->length = |
| sizeof(tlvbuf_wifidirect_persistent_group) - |
| MRVL_TLV_HEADER_SIZE + var_len; |
| *(&tlv->num_peers + var_len) = 0; |
| |
| if (argc == 9 || argc == 10) { |
| if ((ret = |
| mac2raw(argv[8], tlv->peer_mac_addrs[0] + var_len)) |
| != SUCCESS) { |
| printf("ERR:Invalid MAC address %s\n", argv[8]); |
| goto done; |
| } |
| *(&tlv->num_peers + var_len) = 1; |
| } |
| if (argc == 10) { |
| if ((ret = |
| mac2raw(argv[9], tlv->peer_mac_addrs[1] + var_len)) |
| != SUCCESS) { |
| printf("ERR:Invalid MAC address %s\n", argv[8]); |
| goto done; |
| } |
| *(&tlv->num_peers + var_len) = 2; |
| } |
| |
| tlv->length += *(&tlv->num_peers + var_len) * ETH_ALEN; |
| cmd_len += MRVL_TLV_HEADER_SIZE + tlv->length; |
| buf_len = cmd_len; |
| cmd_buf->size = cmd_len - BUF_HEADER_SIZE; |
| break; |
| } |
| #ifdef DEBUG |
| hexdump(buffer, cmd_len, ' '); |
| #endif |
| endian_convert_tlv_header_out(tlv); |
| |
| /* Send collective command */ |
| wifidirect_ioctl((t_u8 *)buffer, &cmd_len, buf_len); |
| |
| endian_convert_tlv_header_in(tlv); |
| #ifdef DEBUG |
| hexdump(buffer, cmd_len, ' '); |
| #endif |
| |
| if (argc == 2 || argc == 3) { |
| if (tlv->length > 0) |
| printf("Persistent group information =>\n"); |
| else |
| printf("Persistent group information is empty.\n"); |
| buf_len = tlv->length; |
| while (buf_len > |
| (sizeof(tlvbuf_wifidirect_persistent_group) - |
| 2 * ETH_ALEN)) { |
| printf("\n\t Index = [%d]\n", tlv->rec_index); |
| if (tlv->dev_role == 1) |
| printf("\t Role = Group owner\n"); |
| else |
| printf("\t Role = Client\n"); |
| printf("\t GroupBssId - "); |
| print_mac(tlv->group_bssid); |
| printf("\n\t DeviceId - "); |
| print_mac(tlv->dev_mac_address); |
| printf("\n\t SSID = "); |
| for (index = 0; index < tlv->group_ssid_len; index++) |
| printf("%c", tlv->group_ssid[index]); |
| var_len = tlv->group_ssid_len; |
| printf("\n\t PSK = "); |
| for (index = 0; index < *(&tlv->psk_len + var_len); |
| index++) { |
| if (index == 16) |
| printf("\n\t "); |
| printf("%02x ", *(&tlv->psk[index] + var_len)); |
| } |
| var_len += *(&tlv->psk_len + var_len); |
| if (tlv->dev_role == 1) { |
| for (pi = 0; pi < *(&tlv->num_peers + var_len); |
| pi++) { |
| printf("\n\t Peer Mac address(%d) = ", |
| pi); |
| print_mac(tlv->peer_mac_addrs[pi] + |
| var_len); |
| } |
| var_len += |
| (*(&tlv->num_peers + var_len) * |
| ETH_ALEN); |
| } |
| if (argc == 2) |
| printf("\n\t -----------------------------------------"); |
| if (tlv->dev_role == 1) { |
| buf_len -= |
| sizeof |
| (tlvbuf_wifidirect_persistent_group) - |
| MRVL_TLV_HEADER_SIZE + var_len; |
| tlv = (tlvbuf_wifidirect_persistent_group |
| *)(((t_u8 *)(tlv)) + |
| (sizeof |
| (tlvbuf_wifidirect_persistent_group) |
| - MRVL_TLV_HEADER_SIZE + var_len)); |
| } else { |
| /* num_peer field willnt be present */ |
| buf_len -= |
| sizeof |
| (tlvbuf_wifidirect_persistent_group) - |
| MRVL_TLV_HEADER_SIZE - sizeof(t_u8) + |
| var_len; |
| tlv = (tlvbuf_wifidirect_persistent_group |
| *)(((t_u8 *)(tlv)) + |
| (sizeof |
| (tlvbuf_wifidirect_persistent_group) |
| - MRVL_TLV_HEADER_SIZE - |
| sizeof(t_u8) + var_len)); |
| } |
| } |
| printf("\n"); |
| } else { |
| printf("Setting persistent group information successful!\n"); |
| } |
| done: |
| if (buffer) |
| free(buffer); |
| return; |
| } |
| |
| /** |
| * @brief Show usage information for the wifidirect_cfg_persistent_group_invoke command |
| * |
| * $return N/A |
| */ |
| static void |
| print_wifidirect_peristent_group_invoke_usage(void) |
| { |
| printf("\nUsage : wifidirect_cfg_persistent_group_invoke [index] | <cancel>\n"); |
| return; |
| } |
| |
| /** |
| * @brief Creates a wifidirect_persistent group Invoke request and |
| * sends to the driver |
| * |
| * Usage: "Usage : wifidirect_cfg_cmd_persistent_group_invoke [index] | <cancel>" |
| * |
| * @param argc Number of arguments |
| * @param argv Pointer to the arguments |
| * @return SUCCESS or FAILURE |
| **/ |
| static void |
| wifidirect_cfg_cmd_persistent_group_invoke(int argc, char *argv[]) |
| { |
| wifidirect_params_config *cmd_buf = NULL; |
| tlvbuf_wifidirect_persistent_group *tlv = NULL; |
| t_u8 index; |
| t_u8 *buffer = NULL; |
| t_u16 cmd_len = 0; |
| int opt; |
| |
| while ((opt = getopt_long(argc, argv, "+", cmd_options, NULL)) != -1) { |
| switch (opt) { |
| default: |
| print_wifidirect_peristent_group_invoke_usage(); |
| return; |
| } |
| } |
| argc -= optind; |
| argv += optind; |
| |
| /* Check arguments */ |
| if (argc != 3) { |
| printf("ERR:wrong number of arguments.\n"); |
| print_wifidirect_peristent_group_invoke_usage(); |
| return; |
| } |
| |
| cmd_len = sizeof(wifidirect_params_config); |
| buffer = (t_u8 *)malloc(MRVDRV_SIZE_OF_CMD_BUFFER); |
| if (!buffer) { |
| printf("ERR:Cannot allocate memory!\n"); |
| goto done; |
| } |
| memset(buffer, 0, MRVDRV_SIZE_OF_CMD_BUFFER); |
| cmd_buf = (wifidirect_params_config *)buffer; |
| cmd_buf->cmd_code = HostCmd_CMD_WIFIDIRECT_PARAMS_CONFIG; |
| cmd_buf->seq_num = 0; |
| cmd_buf->result = 0; |
| cmd_buf->action = cpu_to_le16(ACTION_SET); |
| tlv = (tlvbuf_wifidirect_persistent_group *)(buffer + |
| sizeof |
| (wifidirect_params_config)); |
| |
| tlv->tag = MRVL_WIFIDIRECT_PERSISTENT_GROUP_TLV_ID; |
| tlv->length = sizeof(index); |
| |
| index = atoi(argv[2]); |
| if (index >= WIFIDIRECT_PERSISTENT_GROUP_MAX) { |
| printf("ERR:wrong index. Value values are [0-3]\n"); |
| goto done; |
| } |
| if (!isdigit(argv[2][0])) { |
| if (strcmp(argv[2], "cancel")) { |
| printf("ERR:Incorrect input. Use index [0-3] or \"cancel\" \n"); |
| goto done; |
| } else |
| index = WIFIDIRECT_PERSISTENT_RECORD_CANCEL; |
| } |
| tlv->rec_index = index; |
| |
| cmd_len += MRVL_TLV_HEADER_SIZE + tlv->length; |
| cmd_buf->size = cmd_len - BUF_HEADER_SIZE; |
| #ifdef DEBUG |
| hexdump(buffer, cmd_len, ' '); |
| #endif |
| endian_convert_tlv_header_out(tlv); |
| |
| /* Send collective command */ |
| wifidirect_ioctl((t_u8 *)buffer, &cmd_len, MRVDRV_SIZE_OF_CMD_BUFFER); |
| |
| #ifdef DEBUG |
| hexdump(buffer, cmd_len + BUF_HEADER_SIZE, ' '); |
| #endif |
| |
| printf("Persistent group %s successful!\n", |
| (index == |
| WIFIDIRECT_PERSISTENT_RECORD_CANCEL) ? "cancel" : "invoke"); |
| done: |
| if (buffer) |
| free(buffer); |
| return; |
| } |
| |
| /** |
| * @brief Show usage information for the wifidirect presence request parameters command |
| * |
| * @return N/A |
| */ |
| static void |
| print_wifidirect_cfg_presence_req_params_usage(void) |
| { |
| printf("Usage : wifidirect_cfg_presence_req_params [<type> <duration> <interval>]\n"); |
| printf(" : Type 1: preferred values, 2: acceptable values.\n"); |
| printf("If presence request parameters are provided, " |
| " 'set' is performed otherwise 'get' is performed.\n"); |
| return; |
| } |
| |
| /** |
| * @brief Set/get wifidirect presence request parameters |
| * |
| * Usage: "Usage : wifidirect_cfg_presence_req_params [<type> <duration> <interval>]" |
| * |
| * @param argc Number of arguments |
| * @param argv Pointer to the arguments |
| * @return None |
| */ |
| static void |
| wifidirect_cfg_cmd_presence_req_params(int argc, char *argv[]) |
| { |
| wifidirect_params_config *cmd_buf = NULL; |
| tlvbuf_wifidirect_presence_req_params *tlv = NULL; |
| t_u8 *buffer = NULL; |
| t_u16 cmd_len = 0; |
| int opt, ret = 0; |
| |
| while ((opt = getopt_long(argc, argv, "+", cmd_options, NULL)) != -1) { |
| switch (opt) { |
| default: |
| print_wifidirect_cfg_presence_req_params_usage(); |
| return; |
| } |
| } |
| argc -= optind; |
| argv += optind; |
| |
| /* Check arguments */ |
| if (argc < 2) { |
| printf("ERR: Wrong number of arguments!\n"); |
| print_wifidirect_cfg_presence_req_params_usage(); |
| return; |
| } else if ((argc > 2) && ((argc != 5) |
| || |
| (is_input_valid |
| (WIFIDIRECT_PRESENCE_REQ_TYPE, 1, |
| &argv[2]) != SUCCESS) |
| || |
| (is_input_valid |
| (WIFIDIRECT_DURATION, 1, |
| &argv[3]) != SUCCESS) |
| || |
| (is_input_valid |
| (WIFIDIRECT_INTERVAL, 1, |
| &argv[4]) != SUCCESS))) { |
| print_wifidirect_cfg_presence_req_params_usage(); |
| return; |
| } |
| cmd_len = |
| sizeof(wifidirect_params_config) + |
| sizeof(tlvbuf_wifidirect_presence_req_params); |
| |
| buffer = (t_u8 *)malloc(MRVDRV_SIZE_OF_CMD_BUFFER); |
| |
| if (!buffer) { |
| printf("ERR:Cannot allocate memory!\n"); |
| goto done; |
| } |
| |
| memset(buffer, 0, MRVDRV_SIZE_OF_CMD_BUFFER); |
| |
| cmd_buf = (wifidirect_params_config *)buffer; |
| tlv = (tlvbuf_wifidirect_presence_req_params *)(buffer + |
| sizeof |
| (wifidirect_params_config)); |
| |
| cmd_buf->cmd_code = HostCmd_CMD_WIFIDIRECT_PARAMS_CONFIG; |
| cmd_buf->size = cmd_len - BUF_HEADER_SIZE; |
| cmd_buf->seq_num = 0; |
| cmd_buf->result = 0; |
| |
| tlv->tag = MRVL_WIFIDIRECT_PRESENCE_REQ_PARAMS_TLV_ID; |
| tlv->length = |
| sizeof(tlvbuf_wifidirect_presence_req_params) - |
| MRVL_TLV_HEADER_SIZE; |
| |
| if (argc == 2) { |
| cmd_buf->action = ACTION_GET; |
| } else { |
| cmd_buf->action = cpu_to_le16(ACTION_SET); |
| tlv->presence_req_type = (t_u8)atoi(argv[2]); |
| tlv->duration = (t_u32)atoi(argv[3]); |
| tlv->duration = cpu_to_le32(tlv->duration); |
| tlv->interval = (t_u32)atoi(argv[4]); |
| tlv->interval = cpu_to_le32(tlv->interval); |
| } |
| endian_convert_tlv_header_out(tlv); |
| #ifdef DEBUG |
| hexdump(buffer, cmd_len, ' '); |
| #endif |
| ret = wifidirect_ioctl((t_u8 *)buffer, &cmd_len, |
| MRVDRV_SIZE_OF_CMD_BUFFER); |
| endian_convert_tlv_header_in(tlv); |
| #ifdef DEBUG |
| hexdump(buffer, cmd_len + BUF_HEADER_SIZE, ' '); |
| #endif |
| /* Process Response */ |
| if (ret == SUCCESS) { |
| /* Verify response */ |
| if (cmd_buf->cmd_code != |
| (HostCmd_CMD_WIFIDIRECT_PARAMS_CONFIG | |
| WIFIDIRECTCMD_RESP_CHECK)) { |
| printf("ERR:Corrupted response!\n"); |
| goto done; |
| } |
| /* Print response */ |
| if (cmd_buf->result == CMD_SUCCESS) { |
| if (argc == 2) { |
| printf("Presence request type = %d\n", |
| (int)tlv->presence_req_type); |
| printf("Duration of NoA descriptor = %d\n", |
| le32_to_cpu(tlv->duration)); |
| printf("Interval of NoA descriptor = %d\n", |
| le32_to_cpu(tlv->interval)); |
| } else { |
| printf("Presence request parameters setting successful!\n"); |
| } |
| } else { |
| if (argc == 2) { |
| printf("ERR:Couldn't get Presence request parameters!\n"); |
| } else { |
| printf("ERR:Couldn't set Presence request parameters!\n"); |
| } |
| } |
| } else { |
| printf("ERR:Command sending failed!\n"); |
| } |
| done: |
| if (buffer) |
| free(buffer); |
| return; |
| } |
| |
| /** |
| * @brief Show usage information for the wifidirect extended listen timing parameters command |
| * |
| * @return N/A |
| */ |
| static void |
| print_wifidirect_cfg_ext_listen_time_usage(void) |
| { |
| printf("Usage : wifidirect_cfg_ext_listen_time [<duration> <interval>]\n"); |
| printf("If extended listen timing parameters are provided, " |
| "'set' is performed otherwise 'get' is performed.\n"); |
| return; |
| } |
| |
| /** |
| * @brief Set/get wifidirect extended listen time parameters |
| * |
| * Usage: "Usage : wifidirect_cfg_ext_listen_time [<duration> <interval>]" |
| * |
| * @param argc Number of arguments |
| * @param argv Pointer to the arguments |
| * @return None |
| */ |
| static void |
| wifidirect_cfg_cmd_ext_listen_time(int argc, char *argv[]) |
| { |
| wifidirect_params_config *cmd_buf = NULL; |
| tlvbuf_wifidirect_mrvl_ext_listen_time *tlv = NULL; |
| t_u8 *buffer = NULL; |
| t_u16 cmd_len = 0; |
| int opt, ret = 0; |
| |
| while ((opt = getopt_long(argc, argv, "+", cmd_options, NULL)) != -1) { |
| switch (opt) { |
| default: |
| print_wifidirect_cfg_ext_listen_time_usage(); |
| return; |
| } |
| } |
| argc -= optind; |
| argv += optind; |
| |
| /* Check arguments */ |
| if (argc < 2) { |
| printf("ERR: Wrong number of arguments!\n"); |
| print_wifidirect_cfg_ext_listen_time_usage(); |
| return; |
| } else if ((argc > 2) && ((argc != 4) |
| || |
| (is_input_valid |
| (WIFIDIRECT_ATTR_EXTENDED_TIME, 1, |
| &argv[2]) != SUCCESS) |
| || |
| (is_input_valid |
| (WIFIDIRECT_ATTR_EXTENDED_TIME, 1, |
| &argv[3]) != SUCCESS))) { |
| print_wifidirect_cfg_ext_listen_time_usage(); |
| return; |
| } |
| cmd_len = |
| sizeof(wifidirect_params_config) + |
| sizeof(tlvbuf_wifidirect_mrvl_ext_listen_time); |
| |
| buffer = (t_u8 *)malloc(MRVDRV_SIZE_OF_CMD_BUFFER); |
| |
| if (!buffer) { |
| printf("ERR:Cannot allocate memory!\n"); |
| goto done; |
| } |
| |
| memset(buffer, 0, MRVDRV_SIZE_OF_CMD_BUFFER); |
| |
| cmd_buf = (wifidirect_params_config *)buffer; |
| tlv = (tlvbuf_wifidirect_mrvl_ext_listen_time *)(buffer + |
| sizeof |
| (wifidirect_params_config)); |
| |
| cmd_buf->cmd_code = HostCmd_CMD_WIFIDIRECT_PARAMS_CONFIG; |
| cmd_buf->size = cmd_len - BUF_HEADER_SIZE; |
| cmd_buf->seq_num = 0; |
| cmd_buf->result = 0; |
| |
| tlv->tag = MRVL_WIFIDIRECT_EXTENDED_LISTEN_TIME_TLV_ID; |
| tlv->length = |
| sizeof(tlvbuf_wifidirect_mrvl_ext_listen_time) - |
| MRVL_TLV_HEADER_SIZE; |
| if (argc == 2) { |
| cmd_buf->action = ACTION_GET; |
| } else { |
| cmd_buf->action = cpu_to_le16(ACTION_SET); |
| tlv->duration = cpu_to_le16((t_u16)atoi(argv[2])); |
| tlv->interval = cpu_to_le16((t_u16)atoi(argv[3])); |
| } |
| endian_convert_tlv_header_out(tlv); |
| #ifdef DEBUG |
| hexdump(buffer, cmd_len, ' '); |
| #endif |
| ret = wifidirect_ioctl((t_u8 *)buffer, &cmd_len, |
| MRVDRV_SIZE_OF_CMD_BUFFER); |
| endian_convert_tlv_header_in(tlv); |
| #ifdef DEBUG |
| hexdump(buffer, cmd_len + BUF_HEADER_SIZE, ' '); |
| #endif |
| /* Process Response */ |
| if (ret == SUCCESS) { |
| /* Verify response */ |
| if (cmd_buf->cmd_code != |
| (HostCmd_CMD_WIFIDIRECT_PARAMS_CONFIG | |
| WIFIDIRECTCMD_RESP_CHECK)) { |
| printf("ERR:Corrupted response!\n"); |
| goto done; |
| } |
| /* Print response */ |
| if (cmd_buf->result == CMD_SUCCESS) { |
| if (argc == 2) { |
| printf("Availability Period = %d\n", |
| le16_to_cpu(tlv->duration)); |
| printf("Availability Interval = %d\n", |
| le16_to_cpu(tlv->interval)); |
| } else { |
| printf("Extended listen timing parameters setting successful!\n"); |
| } |
| } else { |
| if (argc == 2) |
| printf("ERR:Couldn't get Extended listen time!\n"); |
| else |
| printf("ERR:Couldn't set Extended listen time!\n"); |
| } |
| } else { |
| printf("ERR:Command sending failed!\n"); |
| } |
| done: |
| if (buffer) |
| free(buffer); |
| return; |
| } |
| |
| /** |
| * @brief Show usage information for the wifidirect provisioing parameters command |
| * |
| * @return N/A |
| */ |
| static void |
| print_wifidirect_cfg_provisioning_params_usage(void) |
| { |
| printf("Usage : wifidirect_cfg_provisioning_params [<action> <configMethod> <devPassword>]\n"); |
| printf(" : Action 1: Request parameters 2: Response parameters.\n"); |
| printf("If provisioning protocol parameters are provided, " |
| "'set' is performed otherwise 'get' is performed.\n"); |
| return; |
| } |
| |
| /** |
| * @brief Set/get wifidirect provisioning protocol related parameters |
| * |
| * Usage: "Usage : wifidirect_cfg_provisioning_params [<action> <configMethod> |
| * <devPassword>]" |
| * |
| * @param argc Number of arguments |
| * @param argv Pointer to the arguments |
| * @return None |
| */ |
| static void |
| wifidirect_cfg_cmd_provisioning_params(int argc, char *argv[]) |
| { |
| wifidirect_params_config *cmd_buf = NULL; |
| tlvbuf_wifidirect_provisioning_params *tlv = NULL; |
| t_u8 *buffer = NULL; |
| t_u16 cmd_len = 0; |
| int opt, ret = 0; |
| |
| while ((opt = getopt_long(argc, argv, "+", cmd_options, NULL)) != -1) { |
| switch (opt) { |
| default: |
| print_wifidirect_cfg_provisioning_params_usage(); |
| return; |
| } |
| } |
| argc -= optind; |
| argv += optind; |
| |
| /* Check arguments */ |
| if (argc < 2) { |
| printf("ERR: Wrong number of arguments!\n"); |
| print_wifidirect_cfg_provisioning_params_usage(); |
| return; |
| } else if ((argc > 2) && (argc != 5)) { |
| print_wifidirect_cfg_provisioning_params_usage(); |
| return; |
| } |
| cmd_len = |
| sizeof(wifidirect_params_config) + |
| sizeof(tlvbuf_wifidirect_provisioning_params); |
| |
| buffer = (t_u8 *)malloc(MRVDRV_SIZE_OF_CMD_BUFFER); |
| |
| if (!buffer) { |
| printf("ERR:Cannot allocate memory!\n"); |
| goto done; |
| } |
| |
| memset(buffer, 0, MRVDRV_SIZE_OF_CMD_BUFFER); |
| |
| cmd_buf = (wifidirect_params_config *)buffer; |
| tlv = (tlvbuf_wifidirect_provisioning_params *)(buffer + |
| sizeof |
| (wifidirect_params_config)); |
| |
| cmd_buf->cmd_code = HostCmd_CMD_WIFIDIRECT_PARAMS_CONFIG; |
| cmd_buf->size = cmd_len - BUF_HEADER_SIZE; |
| cmd_buf->seq_num = 0; |
| cmd_buf->result = 0; |
| |
| tlv->tag = MRVL_WIFIDIRECT_PROVISIONING_PARAMS_TLV_ID; |
| tlv->length = |
| sizeof(tlvbuf_wifidirect_provisioning_params) - |
| MRVL_TLV_HEADER_SIZE; |
| if (argc == 2) { |
| cmd_buf->action = ACTION_GET; |
| } else { |
| cmd_buf->action = cpu_to_le16(ACTION_SET); |
| tlv->action = cpu_to_le16((t_u16)A2HEXDECIMAL(argv[2])); |
| tlv->config_methods = cpu_to_le16((t_u16)A2HEXDECIMAL(argv[3])); |
| tlv->dev_password = cpu_to_le16((t_u16)A2HEXDECIMAL(argv[4])); |
| } |
| endian_convert_tlv_header_out(tlv); |
| #ifdef DEBUG |
| hexdump(buffer, cmd_len, ' '); |
| #endif |
| ret = wifidirect_ioctl((t_u8 *)buffer, &cmd_len, |
| MRVDRV_SIZE_OF_CMD_BUFFER); |
| endian_convert_tlv_header_in(tlv); |
| #ifdef DEBUG |
| hexdump(buffer, cmd_len + BUF_HEADER_SIZE, ' '); |
| #endif |
| /* Process Response */ |
| if (ret == SUCCESS) { |
| /* Verify response */ |
| if (cmd_buf->cmd_code != |
| (HostCmd_CMD_WIFIDIRECT_PARAMS_CONFIG | |
| WIFIDIRECTCMD_RESP_CHECK)) { |
| printf("ERR:Corrupted response!\n"); |
| goto done; |
| } |
| /* Print response */ |
| if (cmd_buf->result == CMD_SUCCESS) { |
| if (argc == 2) { |
| printf("Action = %s %s\n", |
| (le16_to_cpu(tlv->action)) == |
| 1 ? "Request" : "Response", |
| "parameters"); |
| printf("Config Methods = %02X\n", |
| le16_to_cpu(tlv->config_methods)); |
| printf("Device Password ID = %02X\n", |
| le16_to_cpu(tlv->dev_password)); |
| } else { |
| printf("Provisioning protocol parameters setting successful!\n"); |
| } |
| } else { |
| if (argc == 2) |
| printf("ERR:Couldn't get provisioing parameters!\n"); |
| else |
| printf("ERR:Couldn't set provisioing parameters!\n"); |
| } |
| } else { |
| printf("ERR:Command sending failed!\n"); |
| } |
| done: |
| if (buffer) |
| free(buffer); |
| return; |
| } |
| |
| /** |
| * @brief Show usage information for the wifidirect WPS params command |
| * |
| * @return N/A |
| */ |
| static void |
| print_wifidirect_cfg_wps_params_usage(void) |
| { |
| printf("\nUsage : wifidirect_cfg_wps_params [pin/pbc/none]"); |
| printf("\nIf pin/pbc/none is provided, 'set' is performed" |
| " otherwise 'get' is performed.\n"); |
| return; |
| } |
| |
| /** |
| * @brief Set/get wifidirect WPS parametters |
| * |
| * Usage: "Usage : wifidirect_cfg_wps_params [pin/pbc/none]" |
| * |
| * @param argc Number of arguments |
| * @param argv Pointer to the arguments |
| * @return None |
| */ |
| static void |
| wifidirect_cfg_cmd_wps_params(int argc, char *argv[]) |
| { |
| wifidirect_params_config *cmd_buf = NULL; |
| tlvbuf_wifidirect_wps_params *tlv = NULL; |
| t_u8 *buffer = NULL; |
| t_u16 cmd_len = 0; |
| int opt, ret = 0, param = 0; |
| |
| while ((opt = getopt_long(argc, argv, "+", cmd_options, NULL)) != -1) { |
| switch (opt) { |
| default: |
| print_wifidirect_cfg_wps_params_usage(); |
| return; |
| } |
| } |
| argc -= optind; |
| argv += optind; |
| |
| /* Check arguments */ |
| if ((argc < 2) || (argc > 3)) { |
| printf("ERR:Wrong number of arguments!\n"); |
| print_wifidirect_cfg_wps_params_usage(); |
| return; |
| } |
| |
| cmd_len = |
| sizeof(wifidirect_params_config) + |
| sizeof(tlvbuf_wifidirect_wps_params); |
| |
| buffer = (t_u8 *)malloc(MRVDRV_SIZE_OF_CMD_BUFFER); |
| |
| if (!buffer) { |
| printf("ERR:Cannot allocate memory!\n"); |
| goto done; |
| } |
| |
| memset(buffer, 0, MRVDRV_SIZE_OF_CMD_BUFFER); |
| |
| cmd_buf = (wifidirect_params_config *)buffer; |
| tlv = (tlvbuf_wifidirect_wps_params *)(buffer + |
| sizeof |
| (wifidirect_params_config)); |
| |
| cmd_buf->cmd_code = HostCmd_CMD_WIFIDIRECT_PARAMS_CONFIG; |
| cmd_buf->size = cmd_len - BUF_HEADER_SIZE; |
| cmd_buf->seq_num = 0; |
| cmd_buf->result = 0; |
| |
| tlv->tag = MRVL_WIFIDIRECT_WPS_PARAMS_TLV_ID; |
| tlv->length = |
| sizeof(tlvbuf_wifidirect_wps_params) - MRVL_TLV_HEADER_SIZE; |
| |
| if (argc == 2) { |
| cmd_buf->action = ACTION_GET; |
| } else { |
| if (strncmp(argv[2], "pin", 3) == 0) |
| param = 1; |
| else if (strncmp(argv[2], "pbc", 3) == 0) |
| param = 2; |
| else if (strncmp(argv[2], "none", 4)) { |
| printf("Invalid input, should be pin/pbc or none.\n"); |
| goto done; |
| } |
| cmd_buf->action = cpu_to_le16(ACTION_SET); |
| tlv->action = cpu_to_le16(param); |
| } |
| endian_convert_tlv_header_out(tlv); |
| #ifdef DEBUG |
| hexdump(buffer, cmd_len, ' '); |
| #endif |
| ret = wifidirect_ioctl((t_u8 *)buffer, &cmd_len, |
| MRVDRV_SIZE_OF_CMD_BUFFER); |
| endian_convert_tlv_header_in(tlv); |
| #ifdef DEBUG |
| hexdump(buffer, cmd_len + BUF_HEADER_SIZE, ' '); |
| #endif |
| /* Process Response */ |
| if (ret == SUCCESS) { |
| /* Verify response */ |
| if (cmd_buf->cmd_code != |
| (HostCmd_CMD_WIFIDIRECT_PARAMS_CONFIG | |
| WIFIDIRECTCMD_RESP_CHECK)) { |
| printf("ERR:Corrupted response!\n"); |
| goto done; |
| } |
| /* Print response */ |
| if (cmd_buf->result == CMD_SUCCESS) { |
| if (argc == 2) { |
| printf("WPS password parameter =>"); |
| switch (le16_to_cpu(tlv->action)) { |
| case 1: |
| printf("Pin\n"); |
| break; |
| case 2: |
| printf("PBC\n"); |
| break; |
| default: |
| printf("None\n"); |
| break; |
| } |
| } else { |
| printf("WPS parameter setting successful!\n"); |
| } |
| } else { |
| if (argc == 2) { |
| printf("ERR:Couldn't get WPS parameters !\n"); |
| } else { |
| printf("ERR:Couldn't set WPS parameters !\n"); |
| } |
| } |
| } else { |
| printf("ERR:Command sending failed!\n"); |
| } |
| done: |
| if (buffer) |
| free(buffer); |
| return; |
| } |
| |
| /** |
| * @brief Checkes a particular input for validatation. |
| * |
| * @param cmd Type of input |
| * @param argc Number of arguments |
| * @param argv Pointer to the arguments |
| * @return SUCCESS or FAILURE |
| */ |
| int |
| is_input_valid(valid_inputs cmd, int argc, char *argv[]) |
| { |
| int i; |
| int ret = SUCCESS; |
| char country[6] = { ' ', ' ', 0, 0, 0, 0 }; |
| char wifidirect_dev_name[34]; |
| if (argc == 0) |
| return FAILURE; |
| switch (cmd) { |
| case WIFIDIRECT_MINDISCOVERYINT: |
| if (argc != 1) { |
| printf("ERR:Incorrect number of arguments for MinDiscoveryInterval\n"); |
| ret = FAILURE; |
| } else { |
| if ((ISDIGIT(argv[0]) == 0) || |
| (atoi(argv[0]) >= (1 << 16))) { |
| printf("ERR:MinDiscoveryInterval must be 2 bytes\n"); |
| ret = FAILURE; |
| } |
| } |
| break; |
| case WIFIDIRECT_MAXDISCOVERYINT: |
| if (argc != 1) { |
| printf("ERR:Incorrect number of arguments for MaxDiscoveryInterval\n"); |
| ret = FAILURE; |
| } else { |
| if ((ISDIGIT(argv[0]) == 0) || |
| (atoi(argv[0]) >= (1 << 16))) { |
| printf("ERR:MaxDiscoveryInterval must be 2 bytes\n"); |
| ret = FAILURE; |
| } |
| } |
| break; |
| case WIFIDIRECT_DEVICECAPABILITY: |
| if (argc != 1) { |
| printf("ERR:Incorrect number of arguments for DeviceCapability\n"); |
| ret = FAILURE; |
| } else { |
| if ((ISDIGIT(argv[0]) == 0) || |
| (atoi(argv[0]) > MAX_DEV_CAPABILITY) || |
| (atoi(argv[0]) < 0)) { |
| printf("ERR:DeviceCapability must be in the range [0:%d]\n", MAX_DEV_CAPABILITY); |
| ret = FAILURE; |
| } |
| } |
| break; |
| case WIFIDIRECT_GROUPCAPABILITY: |
| if (argc != 1) { |
| printf("ERR:Incorrect number of arguments for GroupCapability\n"); |
| ret = FAILURE; |
| } else { |
| if ((ISDIGIT(argv[0]) == 0) || |
| (atoi(argv[0]) > MAX_GRP_CAPABILITY) || |
| (atoi(argv[0]) < 0)) { |
| printf("ERR:GroupCapability must be in the range [0:%d]\n", MAX_GRP_CAPABILITY); |
| ret = FAILURE; |
| } |
| } |
| break; |
| case CHANNEL: |
| if ((argc != 1) && (argc != 2)) { |
| printf("ERR: Incorrect arguments for channel.\n"); |
| ret = FAILURE; |
| } else { |
| if (argc == 2) { |
| if ((ISDIGIT(argv[1]) == 0) || |
| (atoi(argv[1]) < 0) || |
| (atoi(argv[1]) > 1)) { |
| printf("ERR: MODE must be either 0 or 1\n"); |
| ret = FAILURE; |
| } |
| if ((atoi(argv[1]) == 1) && |
| (atoi(argv[0]) != 0)) { |
| printf("ERR: Channel must be 0 for ACS; MODE = 1.\n"); |
| ret = FAILURE; |
| } |
| } |
| if ((argc == 1) || (atoi(argv[1]) == 0)) { |
| if ((ISDIGIT(argv[0]) == 0) || |
| (atoi(argv[0]) < 1) || |
| (atoi(argv[0]) > MAX_CHANNELS)) { |
| printf("ERR: Channel must be in the range of 1 to %d, configured - %d\n", MAX_CHANNELS, atoi(argv[0])); |
| ret = FAILURE; |
| } |
| } |
| } |
| break; |
| case SCANCHANNELS: |
| if (argc > MAX_CHANNELS) { |
| printf("ERR: Invalid List of Channels\n"); |
| ret = FAILURE; |
| } else { |
| for (i = 0; i < argc; i++) { |
| if ((ISDIGIT(argv[i]) == 0) || |
| (atoi(argv[i]) < 1) || |
| (atoi(argv[i]) > MAX_CHANNELS)) { |
| printf("ERR: Channel must be in the range of 1 to %d, configured - %d\n", MAX_CHANNELS, atoi(argv[i])); |
| ret = FAILURE; |
| break; |
| } |
| } |
| if ((ret != FAILURE) && |
| (has_dup_channel(argc, argv) != SUCCESS)) { |
| printf("ERR: Duplicate channel values entered\n"); |
| ret = FAILURE; |
| } |
| } |
| break; |
| case WIFIDIRECT_INTENT: |
| if (argc != 1) { |
| printf("ERR:Incorrect number of arguments for intent\n"); |
| ret = FAILURE; |
| } else { |
| if ((ISDIGIT(argv[0]) == 0) || |
| (atoi(argv[0]) > MAX_INTENT) || |
| (atoi(argv[0]) < 0)) { |
| printf("ERR:Intent must be in the range [0:%d]\n", MAX_INTENT); |
| ret = FAILURE; |
| } |
| } |
| break; |
| case WIFIDIRECT_MANAGEABILITY: |
| if (argc != 1) { |
| printf("ERR:Incorrect number of arguments for manageability\n"); |
| ret = FAILURE; |
| } else { |
| if ((ISDIGIT(argv[0]) == 0) || (atoi(argv[0]) < 0) || |
| (atoi(argv[0]) > 1)) { |
| printf("ERR:Manageability must be either 0 or 1\n"); |
| ret = FAILURE; |
| } |
| } |
| break; |
| case WIFIDIRECT_GROUP_WIFIDIRECT_DEVICE_NAME: |
| /* 2 extra characters for quotes around device name */ |
| if ((strlen(argv[0]) > 34)) { |
| printf("ERR:WIFIDIRECT Device name string length must not be more than 32\n"); |
| ret = FAILURE; |
| } else { |
| strncpy(wifidirect_dev_name, argv[0], |
| sizeof(wifidirect_dev_name) - 1); |
| if ((wifidirect_dev_name[0] != '"') || |
| (wifidirect_dev_name |
| [strlen(wifidirect_dev_name) - 1] != '"')) { |
| printf("ERR:WIFIDIRECT Device name must be within double quotes!\n"); |
| ret = FAILURE; |
| } |
| } |
| break; |
| case WIFIDIRECT_COUNTRY: |
| /* 2 extra characters for quotes around country */ |
| if ((strlen(argv[0]) > 5) || (strlen(argv[0]) < 4)) { |
| printf("ERR:Country string must have length 2 or 3\n"); |
| ret = FAILURE; |
| } else { |
| strncpy(country, argv[0], sizeof(country) - 1); |
| if ((country[0] != '"') || |
| (country[strlen(country) - 1] != '"')) { |
| printf("ERR:country code must be within double quotes!\n"); |
| ret = FAILURE; |
| } else { |
| for (i = 1; i < strlen(country) - 2; i++) { |
| if ((toupper(country[i]) < 'A') || |
| (toupper(country[i]) > 'Z')) { |
| printf("ERR:Invalid Country Code\n"); |
| ret = FAILURE; |
| } |
| } |
| } |
| } |
| break; |
| case WIFIDIRECT_NO_OF_CHANNELS: |
| if (argc != 1) { |
| printf("ERR:Incorrect number of arguments for num of channels\n"); |
| ret = FAILURE; |
| } else { |
| if ((ISDIGIT(argv[0]) == 0) || |
| (atoi(argv[0]) > MAX_CHANNELS)) { |
| printf("ERR:Number of channels should be less than %d\n", MAX_CHANNELS); |
| ret = FAILURE; |
| } |
| } |
| break; |
| case WIFIDIRECT_NOA_INDEX: |
| if (argc != 1) { |
| printf("ERR:Incorrect number of arguments for NoA Index\n"); |
| ret = FAILURE; |
| } else { |
| if ((ISDIGIT(argv[0]) == 0) || |
| (atoi(argv[0]) < MIN_NOA_INDEX) || |
| (atoi(argv[0]) > MAX_NOA_INDEX)) { |
| printf("ERR:NoA index should be in the range [%d:%d]\n", MIN_NOA_INDEX, MAX_NOA_INDEX); |
| ret = FAILURE; |
| } |
| } |
| break; |
| case WIFIDIRECT_OPP_PS: |
| if (argc != 1) { |
| printf("ERR:Incorrect number of arguments for Opp PS\n"); |
| ret = FAILURE; |
| } else { |
| if ((ISDIGIT(argv[0]) == 0) || ((atoi(argv[0]) != 0) && |
| (atoi(argv[0]) != 1))) { |
| printf("ERR:Opp PS must be either 0 or 1\n"); |
| ret = FAILURE; |
| } |
| } |
| break; |
| case WIFIDIRECT_CTWINDOW: |
| if (argc != 1) { |
| printf("ERR:Incorrect number of arguments for CTWindow\n"); |
| ret = FAILURE; |
| } else { |
| if ((ISDIGIT(argv[0]) == 0) || |
| (atoi(argv[0]) > MAX_CTWINDOW) || |
| (atoi(argv[0]) < MIN_CTWINDOW)) { |
| printf("ERR:CT Window must be in the range [%d:%d]\n", MIN_CTWINDOW, MAX_CTWINDOW); |
| ret = FAILURE; |
| } |
| } |
| break; |
| case WIFIDIRECT_COUNT_TYPE: |
| if (argc != 1) { |
| printf("ERR:Incorrect number of arguments for Count/Type\n"); |
| ret = FAILURE; |
| } else { |
| if ((ISDIGIT(argv[0]) == 0) || (atoi(argv[0]) == 0) || |
| (atoi(argv[0]) > MAX_COUNT_TYPE) || |
| (atoi(argv[0]) < MIN_COUNT_TYPE)) { |
| printf("ERR:Count/Type must be in the range [%d:%d] or 255\n", MIN_COUNT_TYPE, MAX_COUNT_TYPE); |
| ret = FAILURE; |
| } |
| } |
| break; |
| case WIFIDIRECT_PRESENCE_REQ_TYPE: |
| if (argc != 1) { |
| printf("ERR:Incorrect number of arguments for Presence request type\n"); |
| ret = FAILURE; |
| } else { |
| if ((ISDIGIT(argv[0]) == 0) || ((atoi(argv[0]) != 1) |
| && (atoi(argv[0]) != |
| 2))) { |
| printf("ERR:Presence Type must be 1 or 2.\n"); |
| ret = FAILURE; |
| } |
| } |
| break; |
| case WIFIDIRECT_DURATION: |
| if (argc != 1) { |
| printf("ERR:Incorrect number of arguments for Duration\n"); |
| ret = FAILURE; |
| } |
| break; |
| case WIFIDIRECT_INTERVAL: |
| if (argc != 1) { |
| printf("ERR:Incorrect number of arguments for Interval\n"); |
| ret = FAILURE; |
| } |
| break; |
| case WIFIDIRECT_START_TIME: |
| if (argc != 1) { |
| printf("ERR:Incorrect number of arguments for Start Time\n"); |
| ret = FAILURE; |
| } |
| break; |
| case WIFIDIRECT_PRIDEVTYPEOUI: |
| if (argc > MAX_PRIMARY_OUI_LEN) { |
| printf("ERR: Incorrect number of PrimaryDeviceTypeOUI arguments.\n"); |
| ret = FAILURE; |
| break; |
| } |
| for (i = 0; i < argc; i++) { |
| if (IS_HEX_OR_DIGIT(argv[i]) == FAILURE) { |
| printf("ERR:Unsupported OUI\n"); |
| ret = FAILURE; |
| break; |
| } |
| } |
| if (! |
| ((A2HEXDECIMAL(argv[0]) == 0x00) && |
| (A2HEXDECIMAL(argv[1]) == 0x50) |
| && (A2HEXDECIMAL(argv[2]) == 0xF2) && |
| (A2HEXDECIMAL(argv[3]) == 0x04))) { |
| printf("ERR:Unsupported OUI\n"); |
| ret = FAILURE; |
| break; |
| } |
| break; |
| case WIFIDIRECT_REGULATORYCLASS: |
| if (argc != 1) { |
| printf("ERR:Incorrect number of arguments for RegulatoryClass\n"); |
| ret = FAILURE; |
| } else { |
| if ((ISDIGIT(argv[0]) == 0) || |
| (atoi(argv[0]) > MAX_REG_CLASS) || |
| (atoi(argv[0]) < MIN_REG_CLASS)) { |
| printf("ERR:RegulatoryClass must be in the range [%d:%d] or 255\n", MIN_REG_CLASS, MAX_REG_CLASS); |
| ret = FAILURE; |
| } |
| } |
| break; |
| case WIFIDIRECT_PRIDEVTYPECATEGORY: |
| if (argc != 1) { |
| printf("ERR:Incorrect number of arguments for PrimaryDeviceTypeCategory\n"); |
| ret = FAILURE; |
| } else { |
| if ((ISDIGIT(argv[0]) == 0) || |
| (atoi(argv[0]) > MAX_PRIDEV_TYPE_CAT) || |
| (atoi(argv[0]) < MIN_PRIDEV_TYPE_CAT)) { |
| printf("ERR:PrimaryDeviceTypeCategory must be in the range [%d:%d]\n", MIN_PRIDEV_TYPE_CAT, MAX_PRIDEV_TYPE_CAT); |
| ret = FAILURE; |
| } |
| } |
| break; |
| case WIFIDIRECT_SECONDARYDEVCOUNT: |
| if (argc != 1) { |
| printf("ERR:Incorrect number of arguments for SecondaryDeviceCount\n"); |
| ret = FAILURE; |
| } else { |
| if ((ISDIGIT(argv[0]) == 0) || |
| (atoi(argv[0]) > MAX_SECONDARY_DEVICE_COUNT)) { |
| printf("ERR:SecondaryDeviceCount must be less than 15.\n"); |
| ret = FAILURE; |
| } |
| } |
| break; |
| case WIFIDIRECT_INTERFACECOUNT: |
| if (argc != 1) { |
| printf("ERR:Incorrect number of arguments for InterfaceCount\n"); |
| ret = FAILURE; |
| } else { |
| if ((ISDIGIT(argv[0]) == 0) || |
| (atoi(argv[0]) > MAX_INTERFACE_ADDR_COUNT)) { |
| printf("ERR:IntefaceCount must be in range.[0-41]\n"); |
| ret = FAILURE; |
| } |
| } |
| break; |
| case WIFIDIRECT_GROUP_SECONDARYDEVCOUNT: |
| if (argc != 1) { |
| printf("ERR:Incorrect number of arguments for SecondaryDeviceCount\n"); |
| ret = FAILURE; |
| } else { |
| if ((ISDIGIT(argv[0]) == 0) || |
| (atoi(argv[0]) > |
| MAX_GROUP_SECONDARY_DEVICE_COUNT)) { |
| printf("ERR:SecondaryDeviceCount must be less than 2.\n"); |
| ret = FAILURE; |
| } |
| } |
| break; |
| case WIFIDIRECT_ATTR_CONFIG_TIMEOUT: |
| if (argc != 1) { |
| printf("ERR:Incorrect number of arguments for Timeout Configuration\n"); |
| ret = FAILURE; |
| } else { |
| if ((ISDIGIT(argv[0]) == 0) || (atoi(argv[0]) > 255)) { |
| printf("ERR:TimeoutConfig must be in the range [0:255]\n"); |
| ret = FAILURE; |
| } |
| } |
| break; |
| case WIFIDIRECT_ATTR_EXTENDED_TIME: |
| if (argc != 1) { |
| printf("ERR:Incorrect number of arguments for Extended time.\n"); |
| ret = FAILURE; |
| } else { |
| if ((ISDIGIT(argv[0]) == 0) || (atoi(argv[0]) > 65535) |
| || (atoi(argv[0]) < 1)) { |
| printf("ERR:Extended Time must be in the range [1:65535]\n"); |
| ret = FAILURE; |
| } |
| } |
| break; |
| |
| case WIFIDIRECT_PRIDEVTYPESUBCATEGORY: |
| if (argc != 1) { |
| printf("ERR:Incorrect number of arguments for PrimaryDeviceTypeSubCategory\n"); |
| ret = FAILURE; |
| } else { |
| if ((ISDIGIT(argv[0]) == 0) || |
| (atoi(argv[0]) > MAX_PRIDEV_TYPE_SUBCATEGORY) || |
| (atoi(argv[0]) < MIN_PRIDEV_TYPE_SUBCATEGORY)) { |
| printf("ERR:PrimaryDeviceTypeSubCategory must be in the range [%d:%d]\n", MIN_PRIDEV_TYPE_SUBCATEGORY, MAX_PRIDEV_TYPE_SUBCATEGORY); |
| ret = FAILURE; |
| } |
| } |
| break; |
| case WIFIDIRECT_INVITATIONFLAG: |
| if (argc != 1) { |
| printf("ERR:Incorrect number of arguments for InvitationFlag\n"); |
| ret = FAILURE; |
| } else { |
| if ((ISDIGIT(argv[0]) == 0) || (atoi(argv[0]) < 0) || |
| (atoi(argv[0]) > 1)) { |
| printf("ERR:Invitation flag must be either 0 or 1\n"); |
| ret = FAILURE; |
| } |
| } |
| break; |
| case WIFIDIRECT_WPSCONFMETHODS: |
| if (argc != 1) { |
| printf("ERR:Incorrect number of arguments for WPSConfigMethods\n"); |
| ret = FAILURE; |
| } else { |
| if ((IS_HEX_OR_DIGIT(argv[0]) == 0) || |
| (A2HEXDECIMAL(argv[0]) > MAX_WPS_CONF_METHODS) || |
| (A2HEXDECIMAL(argv[0]) < MIN_WPS_CONF_METHODS)) { |
| printf("ERR:WPSConfigMethods must be in the range [%d:%d]\n", MIN_WPS_CONF_METHODS, MAX_WPS_CONF_METHODS); |
| ret = FAILURE; |
| } |
| } |
| break; |
| case WIFIDIRECT_WPSVERSION: |
| if (argc != 1) { |
| printf("ERR:Incorrect number of arguments for WPSVersion\n"); |
| ret = FAILURE; |
| } else { |
| if ((A2HEXDECIMAL(argv[0]) < 0x10) && |
| (A2HEXDECIMAL(argv[0]) > 0x20)) { |
| printf("ERR:Incorrect WPS Version %s\n", |
| argv[0]); |
| ret = FAILURE; |
| } |
| } |
| break; |
| case WIFIDIRECT_WPSSETUPSTATE: |
| if (argc != 1) { |
| printf("ERR:Incorrect number of arguments for WPSSetupState\n"); |
| ret = FAILURE; |
| } else { |
| if ((IS_HEX_OR_DIGIT(argv[0]) == 0) || |
| ((A2HEXDECIMAL(argv[0]) != 0x01) |
| && (A2HEXDECIMAL(argv[0]) != 0x02))) { |
| printf("ERR:Incorrect WPSSetupState %s\n", |
| argv[0]); |
| ret = FAILURE; |
| } |
| } |
| break; |
| case WIFIDIRECT_WPSREQRESPTYPE: |
| if (argc != 1) { |
| printf("ERR:Incorrect number of arguments for WPSRequestType\n"); |
| ret = FAILURE; |
| } else { |
| if ((IS_HEX_OR_DIGIT(argv[0]) == 0) || |
| (A2HEXDECIMAL(argv[0]) > WPS_MAX_REQUESTTYPE)) { |
| printf("ERR:Incorrect WPSRequestType %s\n", |
| argv[0]); |
| ret = FAILURE; |
| } |
| } |
| break; |
| case WIFIDIRECT_WPSSPECCONFMETHODS: |
| if (argc != 1) { |
| printf("ERR:Incorrect number of arguments for WPSSpecConfigMethods\n"); |
| ret = FAILURE; |
| } else { |
| if ((IS_HEX_OR_DIGIT(argv[0]) == 0) || |
| ((t_u16)A2HEXDECIMAL(argv[0]) > |
| WPS_MAX_SPECCONFMETHODS) || |
| ((t_u16)A2HEXDECIMAL(argv[0]) < |
| WPS_MIN_SPECCONFMETHODS)) { |
| printf("ERR:WPSSpecConfigMethods must be in the range [%d:%d]\n", WPS_MIN_SPECCONFMETHODS, WPS_MAX_SPECCONFMETHODS); |
| ret = FAILURE; |
| } |
| } |
| break; |
| case WIFIDIRECT_WPSDEVICENAME: |
| if (argc != 1) { |
| printf("ERR:Incorrect number of arguments\n"); |
| ret = FAILURE; |
| } else { |
| if (argv[0][0] == '"') { |
| argv[0]++; |
| } |
| if (argv[0][strlen(argv[0]) - 1] == '"') { |
| argv[0][strlen(argv[0]) - 1] = '\0'; |
| } |
| if (strlen(argv[0]) > WPS_DEVICE_NAME_MAX_LEN) { |
| printf("ERR:Device name should contain" |
| " less than 32 charactors.\n"); |
| ret = FAILURE; |
| } |
| } |
| break; |
| case WIFIDIRECT_WPSMANUFACTURER: |
| if (argc != 1) { |
| printf("ERR:Incorrect number of arguments\n"); |
| ret = FAILURE; |
| } else { |
| if (strlen(argv[0]) > WPS_MANUFACT_MAX_LEN) { |
| printf("ERR:Manufacturer name should contain" |
| "less than 64 charactors.\n"); |
| ret = FAILURE; |
| } |
| } |
| break; |
| case WIFIDIRECT_WPSMODELNAME: |
| if (argc != 1) { |
| printf("ERR:Incorrect number of arguments\n"); |
| ret = FAILURE; |
| } else { |
| if (strlen(argv[0]) > WPS_MODEL_MAX_LEN) { |
| printf("ERR:Model name should contain" |
| " less than 64 charactors.\n"); |
| ret = FAILURE; |
| } |
| } |
| break; |
| case WIFIDIRECT_WPSUUID: |
| if (argc > WPS_UUID_MAX_LEN) { |
| printf("ERR: Incorrect number of WPSUUID arguments.\n"); |
| ret = FAILURE; |
| } else { |
| for (i = 0; i < argc; i++) { |
| if (IS_HEX_OR_DIGIT(argv[i]) == FAILURE) { |
| printf("ERR:Unsupported UUID\n"); |
| ret = FAILURE; |
| break; |
| } |
| } |
| } |
| break; |
| case WIFIDIRECT_WPSPRIMARYDEVICETYPE: |
| if (argc > WPS_DEVICE_TYPE_MAX_LEN) { |
| printf("ERR: Incorrect number of WPSPrimaryDeviceType arguments.\n"); |
| ret = FAILURE; |
| break; |
| } |
| for (i = 0; i < argc; i++) { |
| if (IS_HEX_OR_DIGIT(argv[i]) == FAILURE) { |
| printf("ERR:Unsupported primary device type\n"); |
| ret = FAILURE; |
| break; |
| } |
| } |
| if (! |
| ((A2HEXDECIMAL(argv[2]) == 0x00) && |
| (A2HEXDECIMAL(argv[3]) == 0x50) |
| && (A2HEXDECIMAL(argv[4]) == 0xF2) && |
| (A2HEXDECIMAL(argv[5]) == 0x04))) { |
| printf("ERR:Unsupported OUI\n"); |
| ret = FAILURE; |
| break; |
| } |
| break; |
| case WIFIDIRECT_WPSRFBAND: |
| if (argc != 1) { |
| printf("ERR:Incorrect number of arguments for WPSRFBand\n"); |
| ret = FAILURE; |
| } else { |
| if ((IS_HEX_OR_DIGIT(argv[0]) == 0) || |
| ((A2HEXDECIMAL(argv[0]) != 0x01) |
| && (A2HEXDECIMAL(argv[0]) != 0x02))) { |
| printf("ERR:Incorrect WPSRFBand %s\n", argv[0]); |
| ret = FAILURE; |
| } |
| } |
| break; |
| case WIFIDIRECT_WPSASSOCIATIONSTATE: |
| if (argc != 1) { |
| printf("ERR:Incorrect number of arguments for WPSAssociationState\n"); |
| ret = FAILURE; |
| } else { |
| if ((IS_HEX_OR_DIGIT(argv[0]) == 0) || |
| ((t_u16)A2HEXDECIMAL(argv[0]) > |
| WPS_MAX_ASSOCIATIONSTATE) || |
| ((t_u16)A2HEXDECIMAL(argv[0]) < |
| WPS_MIN_ASSOCIATIONSTATE)) { |
| printf("ERR:WPSAssociationState must be in the range [%d:%d]\n", WPS_MIN_ASSOCIATIONSTATE, WPS_MAX_ASSOCIATIONSTATE); |
| ret = FAILURE; |
| } |
| } |
| break; |
| case WIFIDIRECT_WPSCONFIGURATIONERROR: |
| if (argc != 1) { |
| printf("ERR:Incorrect number of arguments for WPSConfigurationError\n"); |
| ret = FAILURE; |
| } else { |
| if ((IS_HEX_OR_DIGIT(argv[0]) == 0) || |
| ((t_u16)A2HEXDECIMAL(argv[0]) > |
| WPS_MAX_CONFIGURATIONERROR) || |
| ((t_u16)A2HEXDECIMAL(argv[0]) < |
| WPS_MIN_CONFIGURATIONERROR)) { |
| printf("ERR:WPSConfigurationError must be in the range [%d:%d]\n", WPS_MIN_CONFIGURATIONERROR, WPS_MAX_CONFIGURATIONERROR); |
| ret = FAILURE; |
| } |
| } |
| break; |
| case WIFIDIRECT_WPSDEVICEPASSWORD: |
| if (argc != 1) { |
| printf("ERR:Incorrect number of arguments for WPSDevicePassword\n"); |
| ret = FAILURE; |
| } else { |
| if ((IS_HEX_OR_DIGIT(argv[0]) == 0) || |
| ((t_u16)A2HEXDECIMAL(argv[0]) > |
| WPS_MAX_DEVICEPASSWORD) || |
| ((t_u16)A2HEXDECIMAL(argv[0]) < |
| WPS_MIN_DEVICEPASSWORD)) { |
| printf("ERR:WPSDevicePassword must be in the range [%d:%d]\n", WPS_MIN_DEVICEPASSWORD, WPS_MAX_DEVICEPASSWORD); |
| ret = FAILURE; |
| } |
| } |
| break; |
| case WIFIDIRECT_WPSMODELNUMBER: |
| if (argc > WPS_MODEL_MAX_LEN) { |
| printf("ERR: Incorrect number of WPSModelNumber arguments.\n"); |
| ret = FAILURE; |
| } else { |
| for (i = 0; i < argc; i++) { |
| if (IS_HEX_OR_DIGIT(argv[i]) == FAILURE) { |
| printf("ERR:Unsupported WPSModelNumber\n"); |
| ret = FAILURE; |
| break; |
| } |
| } |
| } |
| break; |
| case WIFIDIRECT_WPSSERIALNUMBER: |
| if (argc > WPS_SERIAL_MAX_LEN) { |
| printf("ERR: Incorrect number of WPSSerialNumber arguments.\n"); |
| ret = FAILURE; |
| } else { |
| for (i = 0; i < argc; i++) { |
| if (IS_HEX_OR_DIGIT(argv[i]) == FAILURE) { |
| printf("ERR:Unsupported WPSSerialNumber\n"); |
| ret = FAILURE; |
| break; |
| } |
| } |
| } |
| break; |
| case WIFIDIRECT_CATEGORY: |
| if (argc != 1) { |
| printf("ERR:Incorrect number of arguments for Category\n"); |
| ret = FAILURE; |
| } else { |
| if (ISDIGIT(argv[0]) == 0) { |
| printf("ERR:Category incorrect value\n"); |
| ret = FAILURE; |
| } |
| } |
| break; |
| case WIFIDIRECT_ACTION: |
| if (argc != 1) { |
| printf("ERR:Incorrect number of arguments for Action\n"); |
| ret = FAILURE; |
| } else { |
| if ((ISDIGIT(argv[0]) == 0) || |
| ((atoi(argv[0]) > 0x10) && |
| (atoi(argv[0]) != 0xDD))) { |
| printf("ERR:Action must be less than 0x10 or 0xDD\n"); |
| ret = FAILURE; |
| } |
| } |
| break; |
| case WIFIDIRECT_DIALOGTOKEN: |
| if (argc != 1) { |
| printf("ERR:Incorrect number of arguments for DialogToken\n"); |
| ret = FAILURE; |
| } else { |
| if (ISDIGIT(argv[0]) == 0) { |
| printf("ERR:DialogToken incorrect value\n"); |
| ret = FAILURE; |
| } |
| } |
| break; |
| case WIFIDIRECT_GAS_COMEBACK_DELAY: |
| if (argc != 1) { |
| printf("ERR:Incorrect number of arguments for GAS Comeback Delay\n"); |
| ret = FAILURE; |
| } |
| break; |
| case WIFIDIRECT_DISC_ADPROTOIE: |
| if (argc > MAX_ADPROTOIE_LEN) { |
| printf("ERR: Incorrect number of AdvertisementProtocolIE arguments.\n"); |
| ret = FAILURE; |
| break; |
| } |
| for (i = 0; i < argc; i++) { |
| if (IS_HEX_OR_DIGIT(argv[i]) == FAILURE) { |
| printf("ERR:Unsupported AdvertisementProtocolIE\n"); |
| ret = FAILURE; |
| break; |
| } |
| } |
| break; |
| case WIFIDIRECT_DISC_INFOID: |
| if (argc > MAX_INFOID_LEN) { |
| printf("ERR: Incorrect number of DiscoveryInformationID arguments.\n"); |
| ret = FAILURE; |
| break; |
| } |
| if (! |
| ((A2HEXDECIMAL(argv[0]) == 0xDD) && |
| (A2HEXDECIMAL(argv[1]) == 0xDD)) && |
| !((A2HEXDECIMAL(argv[0]) == 0xDE) && |
| (A2HEXDECIMAL(argv[1]) == 0x92))) { |
| printf("ERR:Unsupported DiscoveryInformationID\n"); |
| ret = FAILURE; |
| } |
| break; |
| case WIFIDIRECT_OUI: |
| if (argc > MAX_OUI_LEN) { |
| printf("ERR: Incorrect number of OUI arguments.\n"); |
| ret = FAILURE; |
| break; |
| } |
| for (i = 0; i < argc; i++) { |
| if (IS_HEX_OR_DIGIT(argv[i]) == FAILURE) { |
| printf("ERR:Unsupported OUI\n"); |
| ret = FAILURE; |
| break; |
| } |
| } |
| break; |
| case WIFIDIRECT_OUITYPE: |
| if (argc != 1) { |
| printf("ERR:Incorrect number of arguments for OUIType\n"); |
| ret = FAILURE; |
| } else { |
| if (ISDIGIT(argv[0]) == 0) { |
| printf("ERR:OUIType incorrect value\n"); |
| ret = FAILURE; |
| } |
| } |
| break; |
| case WIFIDIRECT_OUISUBTYPE: |
| if (argc != 1) { |
| printf("ERR:Incorrect number of arguments for OUISubtype\n"); |
| ret = FAILURE; |
| } else { |
| if (ISDIGIT(argv[0]) == 0) { |
| printf("ERR:OUISubtype incorrect value\n"); |
| ret = FAILURE; |
| } |
| } |
| break; |
| case WIFIDIRECT_DISC_SERVICEPROTO: |
| if (argc != 1) { |
| printf("ERR:Incorrect number of arguments for DiscoveryServiceProtocol\n"); |
| ret = FAILURE; |
| } else { |
| if ((ISDIGIT(argv[0]) == 0) || ((atoi(argv[0]) >= 4) && |
| (atoi(argv[0]) != |
| 0xFF))) { |
| printf("ERR:DiscoveryServiceProtocol incorrect value\n"); |
| ret = FAILURE; |
| } |
| } |
| break; |
| case WIFIDIRECT_SERVICEUPDATE_INDICATOR: |
| if (argc != 1) { |
| printf("ERR:Incorrect number of arguments for ServiceUpdateIndicator\n"); |
| ret = FAILURE; |
| } else { |
| if (ISDIGIT(argv[0]) == 0) { |
| printf("ERR:ServiceUpdateIndicator incorrect value\n"); |
| ret = FAILURE; |
| } |
| } |
| break; |
| case WIFIDIRECT_DISC_SERVICETRANSACID: |
| if (argc != 1) { |
| printf("ERR:Incorrect number of arguments for DiscoveryServiceTransactionID\n"); |
| ret = FAILURE; |
| } else { |
| if (ISDIGIT(argv[0]) == 0) { |
| printf("ERR:DiscoveryServiceTransactionID incorrect value\n"); |
| ret = FAILURE; |
| } |
| } |
| break; |
| case WIFIDIRECT_DISC_SERVICE_STATUS: |
| if (argc != 1) { |
| printf("ERR:Incorrect number of arguments for ServiceStatus\n"); |
| ret = FAILURE; |
| } else { |
| if ((ISDIGIT(argv[0]) == 0) || (atoi(argv[0]) >= 4)) { |
| printf("ERR:ServiceStatus incorrect value\n"); |
| ret = FAILURE; |
| } |
| } |
| break; |
| case WIFIDIRECT_DISC_DNSTYPE: |
| if (argc != 1) { |
| printf("ERR:Incorrect number of arguments for DiscoveryDNSType\n"); |
| ret = FAILURE; |
| } else { |
| if (ISDIGIT(argv[0]) == 0) { |
| printf("ERR:DiscoveryDNSType incorrect value\n"); |
| ret = FAILURE; |
| } |
| } |
| break; |
| case WIFIDIRECT_DISC_BONJOUR_VERSION: |
| if (argc != 1) { |
| printf("ERR:Incorrect number of arguments for Version\n"); |
| ret = FAILURE; |
| } else { |
| if (ISDIGIT(argv[0]) == 0) { |
| printf("ERR:Version incorrect value\n"); |
| ret = FAILURE; |
| } |
| } |
| break; |
| case WIFIDIRECT_DISC_UPNP_VERSION: |
| if (argc != 1) { |
| printf("ERR:Incorrect number of arguments for Version\n"); |
| ret = FAILURE; |
| } |
| break; |
| case WIFIDIRECT_ENABLE_SCAN: |
| if (argc != 1) { |
| printf("ERR:Incorrect number of arguments for EnableScan\n"); |
| ret = FAILURE; |
| } else { |
| if ((ISDIGIT(argv[0]) == 0) || ((atoi(argv[0]) != 0) && |
| (atoi(argv[0]) != 1))) { |
| printf("ERR:EnableScan must be 0 or 1.\n"); |
| ret = FAILURE; |
| } |
| } |
| break; |
| |
| case WIFIDIRECT_DEVICE_STATE: |
| if (argc != 1) { |
| printf("ERR:Incorrect number of arguments for DeviceState\n"); |
| ret = FAILURE; |
| } else { |
| if (ISDIGIT(argv[0]) == 0) { |
| printf("ERR:Incorrect DeviceState.\n"); |
| ret = FAILURE; |
| } |
| } |
| break; |
| |
| default: |
| printf("Parameter validity for %d ignored\n", cmd); |
| break; |
| } |
| return ret; |
| } |
| |
| /** Structure of command table*/ |
| typedef struct { |
| /** Command name */ |
| char *cmd; |
| /** Command function pointer */ |
| void (*func) (int argc, char *argv[]); |
| /** Command usuage */ |
| char *help; |
| } command_table; |
| |
| /** WiFiDisplay command table */ |
| static command_table wifidisplay_command[] = { |
| {"wifidisplay_config", wifidisplaycmd_config, |
| "\tSet/get wifidisplay configuration"}, |
| {"wifidisplay_mode", wifidisplay_cmd_status, |
| "\tSet/get WFD Display status"}, |
| {"wifidisplay_update_devinfo", wifidisplay_update_custom_ie, |
| "\tUpdate WFD device info bitmap"}, |
| {"wifidisplay_update_coupledsink_bitmap", |
| wifidisplay_update_coupledsink_bitmap, |
| "\tUpdate WFD coupled sink bitmap"}, |
| {"wifidisplay_discovery_request", wifidisplaycmd_service_discovery, |
| "Send wifidisplay service discovery request"}, |
| {"wifidisplay_discovery_response", wifidisplaycmd_service_discovery, |
| "Send wifidisplay service discovery response"}, |
| {NULL, NULL, 0}, |
| }; |
| |
| /** WIFIDIRECT command table */ |
| static command_table wifidirect_command[] = { |
| {"wifidirect_config", wifidirectcmd_config, |
| "\tSet/get wifidirect configuration"}, |
| {"wifidirect_params_config", wifidirectcmd_params_config, |
| "\tSet/get wifidirect parameter's configuration"}, |
| {"wifidirect_action_frame", wifidirectcmd_action_frame, |
| "\tSend wifidirect action frame."}, |
| {"wifidirect_mode", wifidirectcmd_status, |
| "\tSet/get WIFIDIRECT start/stop status"}, |
| {"wifidirect_discovery_request", wifidirectcmd_service_discovery, |
| "Send wifidirect service discovery request"}, |
| {"wifidirect_discovery_response", wifidirectcmd_service_discovery, |
| "Send wifidirect service discovery response"}, |
| {"wifidirect_gas_comeback_request", |
| wifidirectcmd_gas_comeback_discovery, |
| "Send wifidirect GAS comeback request frame"}, |
| {"wifidirect_gas_comeback_response", |
| wifidirectcmd_gas_comeback_discovery, |
| "Send wifidirect GAS comeback response frame"}, |
| {"wifidirect_cfg_persistent_group_record", |
| wifidirect_cfg_cmd_persistent_group_record, |
| "Set/get information about a persistent group"}, |
| {"wifidirect_cfg_persistent_group_invoke", |
| wifidirect_cfg_cmd_persistent_group_invoke, |
| "Invoke or disable a persistent group"}, |
| {"wifidirect_cfg_discovery_period", wifidirect_cfg_cmd_discovery_period, |
| "\tSet/get discovery period"}, |
| {"wifidirect_cfg_intent", wifidirect_cfg_cmd_intent, |
| "\tSet/get intent"}, |
| {"wifidirect_cfg_capability", wifidirect_cfg_cmd_capability, |
| "\tSet/get capability"}, |
| {"wifidirect_cfg_noa", wifidirect_cfg_cmd_noa, |
| "\tSet/get notice of absence"}, |
| {"wifidirect_cfg_opp_ps", wifidirect_cfg_cmd_opp_ps, |
| "\tSet/get Opportunistic PS"}, |
| {"wifidirect_cfg_invitation_list", wifidirect_cfg_cmd_invitation_list, |
| "\tSet/get invitation list"}, |
| {"wifidirect_cfg_listen_channel", wifidirect_cfg_cmd_listen_channel, |
| "\tSet/get listen channel"}, |
| {"wifidirect_cfg_op_channel", wifidirect_cfg_cmd_op_channel, |
| "\tSet/get operating channel"}, |
| {"wifidirect_cfg_presence_req_params", |
| wifidirect_cfg_cmd_presence_req_params, |
| "\tSet/get presence request parameters"}, |
| {"wifidirect_cfg_ext_listen_time", wifidirect_cfg_cmd_ext_listen_time, |
| "Set/get extended listen timing parameters"}, |
| {"wifidirect_cfg_provisioning_params", |
| wifidirect_cfg_cmd_provisioning_params, |
| "Set/get provisioning protocol related parameters"}, |
| {"wifidirect_cfg_wps_params", wifidirect_cfg_cmd_wps_params, |
| "Set/get WPS protocol related parameters"}, |
| {NULL, NULL, 0} |
| }; |
| |
| /** |
| * @brief Entry function for wifidirectutl |
| * @param argc number of arguments |
| * @param argv A pointer to arguments array |
| * @return SUCCESS or FAILURE |
| */ |
| int |
| main(int argc, char *argv[]) |
| { |
| int i; |
| |
| if (argc < 3) { |
| print_tool_usage(); |
| exit(1); |
| } |
| |
| strncpy(dev_name, argv[1], IFNAMSIZ); |
| /* Process command */ |
| for (i = 0; wifidirect_command[i].cmd; i++) { |
| if (strncmp |
| (wifidirect_command[i].cmd, argv[2], |
| strlen(wifidirect_command[i].cmd))) |
| continue; |
| if (strlen(wifidirect_command[i].cmd) != strlen(argv[2])) |
| continue; |
| wifidirect_command[i].func(argc, argv); |
| break; |
| } |
| for (i = 0; wifidisplay_command[i].cmd; i++) { |
| if (strncmp |
| (wifidisplay_command[i].cmd, argv[2], |
| strlen(wifidisplay_command[i].cmd))) |
| continue; |
| if (strlen(wifidisplay_command[i].cmd) != strlen(argv[2])) |
| continue; |
| wifidisplay_command[i].func(argc, argv); |
| break; |
| } |
| if ((!wifidirect_command[i].cmd) && (!wifidisplay_command[i].cmd)) { |
| printf("ERR: %s is not supported\n", argv[2]); |
| exit(1); |
| } |
| return 0; |
| |
| } |