/** @file wifidirectutl.c * * @brief Program to configure WifiDirect parameters. * * Copyright (C) 2008-2019, 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #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 /** * @brief wifidirect use fixed ie indices * * @return 1 or 0 */ 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 wifidirect_mode [mode]\n" "./wifidirectutl wifidirect_config [*.conf]\n" "./wifidirectutl wifidirect_params_config [*.conf]\n" "./wifidirectutl wifidirect_action_frame <*.conf>|" " \n" "./wifidirectutl wifidirect_discovery_request <*.conf>\n" "./wifidirectutl wifidirect_discovery_response <*.conf>\n" "./wifidirectutl wifidirect_gas_comeback_request <*.conf>\n" "./wifidirectutl wifidirect_gas_comeback_response <*.conf>\n" "./wifidirectutl wifidisplay_config [*.conf]\n" "./wifidirectutl wifidisplay_mode [enable/disable]\n" "./wifidirectutl wifidisplay_update_devinfo [value]\n" "./wifidirectutl wifidisplay_update_coupledsink_bitmap [value <= 255]\n" "./wifidirectutl wifidisplay_discovery_request [*.config]\n" "./wifidirectutl wifidisplay_discovery_response [*.config]\n"); printf("\nPlease see example configuration file config/wifidirect.conf\n\n"); printf("Configuration API:\n"); printf("./wifidirectutl wifidirect_cfg_discovery_period [ ]\n" "./wifidirectutl wifidirect_cfg_intent [IntentValue]\n" "./wifidirectutl wifidirect_cfg_capability [ ]\n" "./wifidirectutl wifidirect_cfg_noa [ ]\n" "./wifidirectutl wifidirect_cfg_opp_ps [ ]\n" "./wifidirectutl wifidirect_cfg_invitation_list [mac_address]\n" "./wifidirectutl wifidirect_cfg_listen_channel [listenChannel]\n" "./wifidirectutl wifidirect_cfg_op_channel [operatingChannel]\n" "./wifidirecttul wifidirect_cfg_persistent_group_record [index] [role]\n" " [ ] [peermac1] [peermac2]\n" "./wifidirecttul wifidirect_cfg_persistent_group_invoke [index] | \n" "./wifidirectutl wifidirect_cfg_presence_req_params [ ]\n" "./wifidirectutl wifidirect_cfg_ext_listen_time [ ]\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 \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 " * * @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 |" " [ ]\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 | * [ ]" * * @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 = 0; 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 [ ]\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 [ ]" * * @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 [ ]\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 [ ]" * * @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 []\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 []" * * @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 [ ]\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 [ ]" * * @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] \ > \ [ ]\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] < * > * [ ]" * * @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] | \n"); return; } /** * @brief Creates a wifidirect_persistent group Invoke request and * sends to the driver * * Usage: "Usage : wifidirect_cfg_cmd_persistent_group_invoke [index] | " * * @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 [ ]\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 [ ]" * * @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 [ ]\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 [ ]" * * @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 [ ]\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 [ * ]" * * @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; }