From: Johnny Kim Date: Mon, 11 May 2015 05:30:56 +0000 (+0900) Subject: staging: wilc1000: Add SDIO/SPI 802.11 driver X-Git-Tag: omap-for-v4.3/legacy-v2-signed~121^2~586 X-Git-Url: http://git.openpandora.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c5c77ba18ea66aa05441c71e38473efb787705a4;p=pandora-kernel.git staging: wilc1000: Add SDIO/SPI 802.11 driver This driver is for the wilc1000 which is a single chip IEEE 802.11 b/g/n device. The driver works together with cfg80211, which is the kernel side of configuration management for wireless devices because the wilc1000 chipset is fullmac where the MLME is managed in hardware. The driver worked from kernel version 2.6.38 and being now ported to several others since then. A TODO file is included as well in this commit. Signed-off-by: Johnny Kim Signed-off-by: Rachel Kim Signed-off-by: Dean Lee Signed-off-by: Chris Park Acked-by: Nicolas Ferre Signed-off-by: Greg Kroah-Hartman --- diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index c204ab2693c1..7f6cae5beb90 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -110,4 +110,6 @@ source "drivers/staging/fbtft/Kconfig" source "drivers/staging/fsl-mc/Kconfig" +source "drivers/staging/wilc1000/Kconfig" + endif # STAGING diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index 9b9151758bbd..347f6477aa3e 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -47,3 +47,4 @@ obj-$(CONFIG_UNISYSSPAR) += unisys/ obj-$(CONFIG_COMMON_CLK_XLNX_CLKWZRD) += clocking-wizard/ obj-$(CONFIG_FB_TFT) += fbtft/ obj-$(CONFIG_FSL_MC_BUS) += fsl-mc/ +obj-$(CONFIG_WILC1000) += wilc1000/ diff --git a/drivers/staging/wilc1000/Kconfig b/drivers/staging/wilc1000/Kconfig new file mode 100644 index 000000000000..101f908bc9ed --- /dev/null +++ b/drivers/staging/wilc1000/Kconfig @@ -0,0 +1,55 @@ +config WILC1000 + tristate "WILC1000 support (WiFi only)" + ---help--- + This module only support IEEE 802.11n WiFi. + +choice + prompt "Memory Allocation" + depends on WILC1000 + default WILC1000_PREALLOCATE_AT_LOADING_DRIVER + + config WILC1000_PREALLOCATE_AT_LOADING_DRIVER + bool "Preallocate memory at loading driver" + ---help--- + This choice supports static allocation of the memory + for the receive buffer. The driver will allocate the RX buffer + during initial time. The driver will also free the buffer + by calling network device stop. + + config WILC1000_DYNAMICALLY_ALLOCATE_MEMROY + bool "Dynamically allocate memory in real time" + ---help--- + This choice supports dynamic allocation of the memory + for the receive buffer. The driver will allocate the RX buffer + when it is required. +endchoice + + +choice + prompt "Bus Type" + depends on WILC1000 + default WILC1000_SDIO + + config WILC1000_SDIO + bool "SDIO support" + depends on MMC + ---help--- + This module adds support for the SDIO interface of adapters using + WILC chipset. Select this if your platform is using the SDIO bus. + + config WILC1000_SPI + bool "SPI support" + ---help--- + This module adds support for the SPI interface of adapters using + WILC chipset. Select this if your platform is using the SPI bus. +endchoice + + +config WILC1000_HW_OOB_INTR + bool "Use out of band interrupt" + depends on WILC1000 && WILC1000_SDIO + default n + ---help--- + If your platform don't recognize SDIO IRQ, connect chipset external IRQ pin + and check this option. Or, Use this to get all interrupts including SDIO interrupts. + diff --git a/drivers/staging/wilc1000/Makefile b/drivers/staging/wilc1000/Makefile new file mode 100644 index 000000000000..84bd975ff3be --- /dev/null +++ b/drivers/staging/wilc1000/Makefile @@ -0,0 +1,41 @@ +obj-$(CONFIG_WILC1000) += wilc1000.o +obj-$(CONFIG_WILC1000_PREALLOCATE_DURING_SYSTEM_BOOT) += wilc_exported_buf.o + + +ccflags-$(CONFIG_WILC1000_SDIO) += -DWILC_SDIO -DCOMPLEMENT_BOOT +ccflags-$(CONFIG_WILC1000_HW_OOB_INTR) += -DWILC_SDIO_IRQ_GPIO +ccflags-$(CONFIG_WILC1000_SPI) += -DWILC_SPI + +ccflags-y += -DSTA_FIRMWARE=\"atmel/wilc1000_fw.bin\" \ + -DAP_FIRMWARE=\"atmel/wilc1000_ap_fw.bin\" \ + -DP2P_CONCURRENCY_FIRMWARE=\"atmel/wilc1000_p2p_fw.bin\" + +ccflags-y += -I$(src)/ -DEXPORT_SYMTAB -D__CHECK_ENDIAN__ -DWILC_ASIC_A0 \ + -DPLL_WORKAROUND -DCONNECT_DIRECT -DAGING_ALG \ + -DWILC_PARSE_SCAN_IN_HOST -DDISABLE_PWRSAVE_AND_SCAN_DURING_IP \ + -DWILC_PLATFORM=WILC_LINUXKERNEL -Wno-unused-function -DUSE_WIRELESS \ + -DWILC_DEBUGFS +#ccflags-y += -DTCP_ACK_FILTER + +ccflags-$(CONFIG_WILC1000_PREALLOCATE_DURING_SYSTEM_BOOT) += -DMEMORY_STATIC \ + -DWILC_PREALLOC_AT_BOOT + +ccflags-$(CONFIG_WILC1000_PREALLOCATE_AT_LOADING_DRIVER) += -DMEMORY_STATIC \ + -DWILC_PREALLOC_AT_INSMOD + +ccflags-$(CONFIG_WILC1000_DYNAMICALLY_ALLOCATE_MEMROY) += -DWILC_NORMAL_ALLOC + + +wilc1000-objs := wilc_wfi_netdevice.o wilc_wfi_cfgoperations.o linux_wlan.o linux_mon.o \ + wilc_memory.o wilc_msgqueue.o wilc_semaphore.o wilc_sleep.o wilc_strutils.o \ + wilc_thread.o wilc_time.o wilc_timer.o coreconfigurator.o host_interface.o \ + fifo_buffer.o wilc_sdio.o wilc_spi.o wilc_wlan_cfg.o wilc_debugfs.o + +wilc1000-$(CONFIG_WILC1000_SDIO) += linux_wlan_sdio.o +wilc1000-$(CONFIG_WILC1000_SPI) += linux_wlan_spi.o + +WILC1000_SRC_VERSION = 10.0 +PATCHLEVEL = 2 +WILC1000_FW_VERSION = 0 + +ccflags-y += -D__DRIVER_VERSION__=\"$(WILC1000_SRC_VERSION).$(PATCHLEVEL)\" diff --git a/drivers/staging/wilc1000/TODO b/drivers/staging/wilc1000/TODO new file mode 100644 index 000000000000..5dfeb3eda599 --- /dev/null +++ b/drivers/staging/wilc1000/TODO @@ -0,0 +1,8 @@ +TODO: +- remove the defined feature as kernel versions +- remove OS wrapper functions +- remove custom debug and tracing functions +- rework comments and function headers(also coding style) +- remove build warnings +- support soft-ap and p2p mode +- support resume/suspend function diff --git a/drivers/staging/wilc1000/coreconfigsimulator.h b/drivers/staging/wilc1000/coreconfigsimulator.h new file mode 100644 index 000000000000..6c3f431314fa --- /dev/null +++ b/drivers/staging/wilc1000/coreconfigsimulator.h @@ -0,0 +1,20 @@ + +/*! + * @file coreconfigsimulator.h + * @brief + * @author + * @sa coreconfigsimulator.c + * @date 1 Mar 2012 + * @version 1.0 + */ + + +#ifndef CORECONFIGSIMULATOR_H +#define CORECONFIGSIMULATOR_H + + +extern WILC_Sint32 CoreConfigSimulatorInit (void); +extern WILC_Sint32 CoreConfigSimulatorDeInit (void); + + +#endif \ No newline at end of file diff --git a/drivers/staging/wilc1000/coreconfigurator.c b/drivers/staging/wilc1000/coreconfigurator.c new file mode 100644 index 000000000000..01625bdda454 --- /dev/null +++ b/drivers/staging/wilc1000/coreconfigurator.c @@ -0,0 +1,2201 @@ + +/*! + * @file coreconfigurator.c + * @brief + * @author + * @sa coreconfigurator.h + * @date 1 Mar 2012 + * @version 1.0 + */ + + +/*****************************************************************************/ +/* File Includes */ +/*****************************************************************************/ +#include "itypes.h" +#include "coreconfigurator.h" +/*****************************************************************************/ +/* Constants */ +/*****************************************************************************/ +#define INLINE static __inline +#define PHY_802_11n +#define MAX_CFG_PKTLEN 1450 +#define MSG_HEADER_LEN 4 +#define QUERY_MSG_TYPE 'Q' +#define WRITE_MSG_TYPE 'W' +#define RESP_MSG_TYPE 'R' +#define WRITE_RESP_SUCCESS 1 +#define INVALID 255 +#define MAC_ADDR_LEN 6 +#define TAG_PARAM_OFFSET (MAC_HDR_LEN + TIME_STAMP_LEN + \ + BEACON_INTERVAL_LEN + CAP_INFO_LEN) + +/*****************************************************************************/ +/* Function Macros */ +/*****************************************************************************/ + + +/*****************************************************************************/ +/* Type Definitions */ +/*****************************************************************************/ + +/* Basic Frame Type Codes (2-bit) */ +typedef enum {FRAME_TYPE_CONTROL = 0x04, + FRAME_TYPE_DATA = 0x08, + FRAME_TYPE_MANAGEMENT = 0x00, + FRAME_TYPE_RESERVED = 0x0C, + FRAME_TYPE_FORCE_32BIT = 0xFFFFFFFF +} tenuBasicFrmType; + +/* Frame Type and Subtype Codes (6-bit) */ +typedef enum { + ASSOC_REQ = 0x00, + ASSOC_RSP = 0x10, + REASSOC_REQ = 0x20, + REASSOC_RSP = 0x30, + PROBE_REQ = 0x40, + PROBE_RSP = 0x50, + BEACON = 0x80, + ATIM = 0x90, + DISASOC = 0xA0, + AUTH = 0xB0, + DEAUTH = 0xC0, + ACTION = 0xD0, + PS_POLL = 0xA4, + RTS = 0xB4, + CTS = 0xC4, + ACK = 0xD4, + CFEND = 0xE4, + CFEND_ACK = 0xF4, + DATA = 0x08, + DATA_ACK = 0x18, + DATA_POLL = 0x28, + DATA_POLL_ACK = 0x38, + NULL_FRAME = 0x48, + CFACK = 0x58, + CFPOLL = 0x68, + CFPOLL_ACK = 0x78, + QOS_DATA = 0x88, + QOS_DATA_ACK = 0x98, + QOS_DATA_POLL = 0xA8, + QOS_DATA_POLL_ACK = 0xB8, + QOS_NULL_FRAME = 0xC8, + QOS_CFPOLL = 0xE8, + QOS_CFPOLL_ACK = 0xF8, + BLOCKACK_REQ = 0x84, + BLOCKACK = 0x94, + FRAME_SUBTYPE_FORCE_32BIT = 0xFFFFFFFF +} tenuFrmSubtype; + +/* Basic Frame Classes */ +typedef enum { + CLASS1_FRAME_TYPE = 0x00, + CLASS2_FRAME_TYPE = 0x01, + CLASS3_FRAME_TYPE = 0x02, + FRAME_CLASS_FORCE_32BIT = 0xFFFFFFFF +} tenuFrameClass; + +/* Element ID of various Information Elements */ +typedef enum { + ISSID = 0, /* Service Set Identifier */ + ISUPRATES = 1, /* Supported Rates */ + IFHPARMS = 2, /* FH parameter set */ + IDSPARMS = 3, /* DS parameter set */ + ICFPARMS = 4, /* CF parameter set */ + ITIM = 5, /* Traffic Information Map */ + IIBPARMS = 6, /* IBSS parameter set */ + ICOUNTRY = 7, /* Country element */ + IEDCAPARAMS = 12, /* EDCA parameter set */ + ITSPEC = 13, /* Traffic Specification */ + ITCLAS = 14, /* Traffic Classification */ + ISCHED = 15, /* Schedule */ + ICTEXT = 16, /* Challenge Text */ + IPOWERCONSTRAINT = 32, /* Power Constraint */ + IPOWERCAPABILITY = 33, /* Power Capability */ + ITPCREQUEST = 34, /* TPC Request */ + ITPCREPORT = 35, /* TPC Report */ + ISUPCHANNEL = 36, /* Supported channel list */ + ICHSWANNOUNC = 37, /* Channel Switch Announcement */ + IMEASUREMENTREQUEST = 38, /* Measurement request */ + IMEASUREMENTREPORT = 39, /* Measurement report */ + IQUIET = 40, /* Quiet element Info */ + IIBSSDFS = 41, /* IBSS DFS */ + IERPINFO = 42, /* ERP Information */ + ITSDELAY = 43, /* TS Delay */ + ITCLASPROCESS = 44, /* TCLAS Processing */ + IHTCAP = 45, /* HT Capabilities */ + IQOSCAP = 46, /* QoS Capability */ + IRSNELEMENT = 48, /* RSN Information Element */ + IEXSUPRATES = 50, /* Extended Supported Rates */ + IEXCHSWANNOUNC = 60, /* Extended Ch Switch Announcement*/ + IHTOPERATION = 61, /* HT Information */ + ISECCHOFF = 62, /* Secondary Channel Offeset */ + I2040COEX = 72, /* 20/40 Coexistence IE */ + I2040INTOLCHREPORT = 73, /* 20/40 Intolerant channel report*/ + IOBSSSCAN = 74, /* OBSS Scan parameters */ + IEXTCAP = 127, /* Extended capability */ + IWMM = 221, /* WMM parameters */ + IWPAELEMENT = 221, /* WPA Information Element */ + INFOELEM_ID_FORCE_32BIT = 0xFFFFFFFF +} tenuInfoElemID; + + +typedef struct { + WILC_Char *pcRespBuffer; + WILC_Sint32 s32MaxRespBuffLen; + WILC_Sint32 s32BytesRead; + WILC_Bool bRespRequired; +} tstrConfigPktInfo; + + + +/*****************************************************************************/ +/* Extern Variable Declarations */ +/*****************************************************************************/ + + +/*****************************************************************************/ +/* Extern Function Declarations */ +/*****************************************************************************/ +extern WILC_Sint32 SendRawPacket(WILC_Sint8 *ps8Packet, WILC_Sint32 s32PacketLen); +extern void NetworkInfoReceived(WILC_Uint8 *pu8Buffer, WILC_Uint32 u32Length); +extern void GnrlAsyncInfoReceived(WILC_Uint8 *pu8Buffer, WILC_Uint32 u32Length); +extern void host_int_ScanCompleteReceived(WILC_Uint8 *pu8Buffer, WILC_Uint32 u32Length); +/*****************************************************************************/ +/* Global Variables */ +/*****************************************************************************/ +static WILC_SemaphoreHandle SemHandleSendPkt; +static WILC_SemaphoreHandle SemHandlePktResp; + +static WILC_Sint8 *gps8ConfigPacket; + +static tstrConfigPktInfo gstrConfigPktInfo; + +static WILC_Uint8 g_seqno; + +static WILC_Sint16 g_wid_num = -1; + +static WILC_Uint16 Res_Len; + +static WILC_Uint8 g_oper_mode = SET_CFG; + +/* WID Switches */ +static tstrWID gastrWIDs[] = { + {WID_FIRMWARE_VERSION, WID_STR}, + {WID_PHY_VERSION, WID_STR}, + {WID_HARDWARE_VERSION, WID_STR}, + {WID_BSS_TYPE, WID_CHAR}, + {WID_QOS_ENABLE, WID_CHAR}, + {WID_11I_MODE, WID_CHAR}, + {WID_CURRENT_TX_RATE, WID_CHAR}, + {WID_LINKSPEED, WID_CHAR}, + {WID_RTS_THRESHOLD, WID_SHORT}, + {WID_FRAG_THRESHOLD, WID_SHORT}, + {WID_SSID, WID_STR}, + {WID_BSSID, WID_ADR}, + {WID_BEACON_INTERVAL, WID_SHORT}, + {WID_POWER_MANAGEMENT, WID_CHAR}, + {WID_LISTEN_INTERVAL, WID_CHAR}, + {WID_DTIM_PERIOD, WID_CHAR}, + {WID_CURRENT_CHANNEL, WID_CHAR}, + {WID_TX_POWER_LEVEL_11A, WID_CHAR}, + {WID_TX_POWER_LEVEL_11B, WID_CHAR}, + {WID_PREAMBLE, WID_CHAR}, + {WID_11G_OPERATING_MODE, WID_CHAR}, + {WID_MAC_ADDR, WID_ADR}, + {WID_IP_ADDRESS, WID_ADR}, + {WID_ACK_POLICY, WID_CHAR}, + {WID_PHY_ACTIVE_REG, WID_CHAR}, + {WID_AUTH_TYPE, WID_CHAR}, + {WID_REKEY_POLICY, WID_CHAR}, + {WID_REKEY_PERIOD, WID_INT}, + {WID_REKEY_PACKET_COUNT, WID_INT}, +#if 0 + {WID_WEP_KEY_VALUE0, WID_STR}, +#endif + {WID_11I_PSK, WID_STR}, + {WID_1X_KEY, WID_STR}, + {WID_1X_SERV_ADDR, WID_IP}, + {WID_SUPP_USERNAME, WID_STR}, + {WID_SUPP_PASSWORD, WID_STR}, + {WID_USER_CONTROL_ON_TX_POWER, WID_CHAR}, + {WID_MEMORY_ADDRESS, WID_INT}, + {WID_MEMORY_ACCESS_32BIT, WID_INT}, + {WID_MEMORY_ACCESS_16BIT, WID_SHORT}, + {WID_MEMORY_ACCESS_8BIT, WID_CHAR}, + {WID_SITE_SURVEY_RESULTS, WID_STR}, + {WID_PMKID_INFO, WID_STR}, + {WID_ASSOC_RES_INFO, WID_STR}, + {WID_MANUFACTURER, WID_STR}, /* 4 Wids added for the CAPI tool*/ + {WID_MODEL_NAME, WID_STR}, + {WID_MODEL_NUM, WID_STR}, + {WID_DEVICE_NAME, WID_STR}, + {WID_SSID_PROBE_REQ, WID_STR}, + +#ifdef MAC_802_11N + {WID_11N_ENABLE, WID_CHAR}, + {WID_11N_CURRENT_TX_MCS, WID_CHAR}, + {WID_TX_POWER_LEVEL_11N, WID_CHAR}, + {WID_11N_OPERATING_MODE, WID_CHAR}, + {WID_11N_SMPS_MODE, WID_CHAR}, + {WID_11N_PROT_MECH, WID_CHAR}, + {WID_11N_ERP_PROT_TYPE, WID_CHAR}, + {WID_11N_HT_PROT_TYPE, WID_CHAR}, + {WID_11N_PHY_ACTIVE_REG_VAL, WID_INT}, + {WID_11N_PRINT_STATS, WID_CHAR}, + {WID_11N_AUTORATE_TABLE, WID_BIN_DATA}, + {WID_HOST_CONFIG_IF_TYPE, WID_CHAR}, + {WID_HOST_DATA_IF_TYPE, WID_CHAR}, + {WID_11N_SIG_QUAL_VAL, WID_SHORT}, + {WID_11N_IMMEDIATE_BA_ENABLED, WID_CHAR}, + {WID_11N_TXOP_PROT_DISABLE, WID_CHAR}, + {WID_11N_SHORT_GI_20MHZ_ENABLE, WID_CHAR}, + {WID_SHORT_SLOT_ALLOWED, WID_CHAR}, + {WID_11W_ENABLE, WID_CHAR}, + {WID_11W_MGMT_PROT_REQ, WID_CHAR}, + {WID_2040_ENABLE, WID_CHAR}, + {WID_2040_COEXISTENCE, WID_CHAR}, + {WID_USER_SEC_CHANNEL_OFFSET, WID_CHAR}, + {WID_2040_CURR_CHANNEL_OFFSET, WID_CHAR}, + {WID_2040_40MHZ_INTOLERANT, WID_CHAR}, + {WID_HUT_RESTART, WID_CHAR}, + {WID_HUT_NUM_TX_PKTS, WID_INT}, + {WID_HUT_FRAME_LEN, WID_SHORT}, + {WID_HUT_TX_FORMAT, WID_CHAR}, + {WID_HUT_BANDWIDTH, WID_CHAR}, + {WID_HUT_OP_BAND, WID_CHAR}, + {WID_HUT_STBC, WID_CHAR}, + {WID_HUT_ESS, WID_CHAR}, + {WID_HUT_ANTSET, WID_CHAR}, + {WID_HUT_HT_OP_MODE, WID_CHAR}, + {WID_HUT_RIFS_MODE, WID_CHAR}, + {WID_HUT_SMOOTHING_REC, WID_CHAR}, + {WID_HUT_SOUNDING_PKT, WID_CHAR}, + {WID_HUT_HT_CODING, WID_CHAR}, + {WID_HUT_TEST_DIR, WID_CHAR}, + {WID_HUT_TXOP_LIMIT, WID_SHORT}, + {WID_HUT_DEST_ADDR, WID_ADR}, + {WID_HUT_TX_PATTERN, WID_BIN_DATA}, + {WID_HUT_TX_TIME_TAKEN, WID_INT}, + {WID_HUT_PHY_TEST_MODE, WID_CHAR}, + {WID_HUT_PHY_TEST_RATE_HI, WID_CHAR}, + {WID_HUT_PHY_TEST_RATE_LO, WID_CHAR}, + {WID_HUT_TX_TEST_TIME, WID_INT}, + {WID_HUT_LOG_INTERVAL, WID_INT}, + {WID_HUT_DISABLE_RXQ_REPLENISH, WID_CHAR}, + {WID_HUT_TEST_ID, WID_STR}, + {WID_HUT_KEY_ORIGIN, WID_CHAR}, + {WID_HUT_BCST_PERCENT, WID_CHAR}, + {WID_HUT_GROUP_CIPHER_TYPE, WID_CHAR}, + {WID_HUT_STATS, WID_BIN_DATA}, + {WID_HUT_TSF_TEST_MODE, WID_CHAR}, + {WID_HUT_SIG_QUAL_AVG, WID_SHORT}, + {WID_HUT_SIG_QUAL_AVG_CNT, WID_SHORT}, + {WID_HUT_TSSI_VALUE, WID_CHAR}, + {WID_HUT_MGMT_PERCENT, WID_CHAR}, + {WID_HUT_MGMT_BCST_PERCENT, WID_CHAR}, + {WID_HUT_MGMT_ALLOW_HT, WID_CHAR}, + {WID_HUT_UC_MGMT_TYPE, WID_CHAR}, + {WID_HUT_BC_MGMT_TYPE, WID_CHAR}, + {WID_HUT_UC_MGMT_FRAME_LEN, WID_SHORT}, + {WID_HUT_BC_MGMT_FRAME_LEN, WID_SHORT}, + {WID_HUT_11W_MFP_REQUIRED_TX, WID_CHAR}, + {WID_HUT_11W_MFP_PEER_CAPABLE, WID_CHAR}, + {WID_HUT_11W_TX_IGTK_ID, WID_CHAR}, + {WID_HUT_FC_TXOP_MOD, WID_CHAR}, + {WID_HUT_FC_PROT_TYPE, WID_CHAR}, + {WID_HUT_SEC_CCA_ASSERT, WID_CHAR}, +#endif /* MAC_802_11N */ +}; + +WILC_Uint16 g_num_total_switches = (sizeof(gastrWIDs) / sizeof(tstrWID)); +/*****************************************************************************/ +/* Static Function Declarations */ +/*****************************************************************************/ + + + +/*****************************************************************************/ +/* Functions */ +/*****************************************************************************/ +INLINE WILC_Uint8 ascii_hex_to_dec(WILC_Uint8 num) +{ + if ((num >= '0') && (num <= '9')) + return (num - '0'); + else if ((num >= 'A') && (num <= 'F')) + return (10 + (num - 'A')); + else if ((num >= 'a') && (num <= 'f')) + return (10 + (num - 'a')); + + return INVALID; +} + +INLINE WILC_Uint8 get_hex_char(WILC_Uint8 inp) +{ + WILC_Uint8 *d2htab = "0123456789ABCDEF"; + + return d2htab[inp & 0xF]; +} + +/* This function extracts the MAC address held in a string in standard format */ +/* into another buffer as integers. */ +INLINE WILC_Uint16 extract_mac_addr(WILC_Char *str, WILC_Uint8 *buff) +{ + *buff = 0; + while (*str != '\0') { + if ((*str == ':') || (*str == '-')) + *(++buff) = 0; + else + *buff = (*buff << 4) + ascii_hex_to_dec(*str); + + str++; + } + + return MAC_ADDR_LEN; +} + +/* This function creates MAC address in standard format from a buffer of */ +/* integers. */ +INLINE void create_mac_addr(WILC_Uint8 *str, WILC_Uint8 *buff) +{ + WILC_Uint32 i = 0; + WILC_Uint32 j = 0; + + for (i = 0; i < MAC_ADDR_LEN; i++) { + str[j++] = get_hex_char((WILC_Uint8)((buff[i] >> 4) & 0x0F)); + str[j++] = get_hex_char((WILC_Uint8)(buff[i] & 0x0F)); + str[j++] = ':'; + } + str[--j] = '\0'; +} + +/* This function converts the IP address string in dotted decimal format to */ +/* unsigned integer. This functionality is similar to the library function */ +/* inet_addr() but is reimplemented here since I could not confirm that */ +/* inet_addr is platform independent. */ +/* ips=>IP Address String in dotted decimal format */ +/* ipn=>Pointer to IP Address in integer format */ +INLINE WILC_Uint8 conv_ip_to_int(WILC_Uint8 *ips, WILC_Uint32 *ipn) +{ + WILC_Uint8 i = 0; + WILC_Uint8 ipb = 0; + *ipn = 0; + /* Integer to string for each component */ + while (ips[i] != '\0') { + if (ips[i] == '.') { + *ipn = ((*ipn) << 8) | ipb; + ipb = 0; + } else { + ipb = ipb * 10 + ascii_hex_to_dec(ips[i]); + } + + i++; + } + + /* The last byte of the IP address is read in here */ + *ipn = ((*ipn) << 8) | ipb; + + return 0; +} + +/* This function converts the IP address from integer format to dotted */ +/* decimal string format. Alternative to std library fn inet_ntoa(). */ +/* ips=>Buffer to hold IP Address String dotted decimal format (Min 17B) */ +/* ipn=>IP Address in integer format */ +INLINE WILC_Uint8 conv_int_to_ip(WILC_Uint8 *ips, WILC_Uint32 ipn) +{ + WILC_Uint8 i = 0; + WILC_Uint8 ipb = 0; + WILC_Uint8 cnt = 0; + WILC_Uint8 ipbsize = 0; + + for (cnt = 4; cnt > 0; cnt--) { + ipb = (ipn >> (8 * (cnt - 1))) & 0xFF; + + if (ipb >= 100) + ipbsize = 2; + else if (ipb >= 10) + ipbsize = 1; + else + ipbsize = 0; + + switch (ipbsize) { + case 2: + ips[i++] = get_hex_char(ipb / 100); + ipb %= 100; + + case 1: + ips[i++] = get_hex_char(ipb / 10); + ipb %= 10; + + default: + ips[i++] = get_hex_char(ipb); + } + + if (cnt > 1) + ips[i++] = '.'; + } + + ips[i] = '\0'; + + return i; +} + +INLINE tenuWIDtype get_wid_type(WILC_Uint32 wid_num) +{ + /* Check for iconfig specific WID types first */ + if ((wid_num == WID_BSSID) || + (wid_num == WID_MAC_ADDR) || + (wid_num == WID_IP_ADDRESS) || + (wid_num == WID_HUT_DEST_ADDR)) { + return WID_ADR; + } + + if ((WID_1X_SERV_ADDR == wid_num) || + (WID_STACK_IP_ADDR == wid_num) || + (WID_STACK_NETMASK_ADDR == wid_num)) { + return WID_IP; + } + + /* Next check for standard WID types */ + if (wid_num < 0x1000) + return WID_CHAR; + else if (wid_num < 0x2000) + return WID_SHORT; + else if (wid_num < 0x3000) + return WID_INT; + else if (wid_num < 0x4000) + return WID_STR; + else if (wid_num < 0x5000) + return WID_BIN_DATA; + + return WID_UNDEF; +} + + +/* This function extracts the beacon period field from the beacon or probe */ +/* response frame. */ +INLINE WILC_Uint16 get_beacon_period(WILC_Uint8 *data) +{ + WILC_Uint16 bcn_per = 0; + + bcn_per = data[0]; + bcn_per |= (data[1] << 8); + + return bcn_per; +} + +INLINE WILC_Uint32 get_beacon_timestamp_lo(WILC_Uint8 *data) +{ + WILC_Uint32 time_stamp = 0; + WILC_Uint32 index = MAC_HDR_LEN; + + time_stamp |= data[index++]; + time_stamp |= (data[index++] << 8); + time_stamp |= (data[index++] << 16); + time_stamp |= (data[index] << 24); + + return time_stamp; +} + +INLINE UWORD32 get_beacon_timestamp_hi(UWORD8 *data) +{ + UWORD32 time_stamp = 0; + UWORD32 index = (MAC_HDR_LEN + 4); + + time_stamp |= data[index++]; + time_stamp |= (data[index++] << 8); + time_stamp |= (data[index++] << 16); + time_stamp |= (data[index] << 24); + + return time_stamp; +} + +/* This function extracts the 'frame type' bits from the MAC header of the */ +/* input frame. */ +/* Returns the value in the LSB of the returned value. */ +INLINE tenuBasicFrmType get_type(WILC_Uint8 *header) +{ + return ((tenuBasicFrmType)(header[0] & 0x0C)); +} + +/* This function extracts the 'frame type and sub type' bits from the MAC */ +/* header of the input frame. */ +/* Returns the value in the LSB of the returned value. */ +INLINE tenuFrmSubtype get_sub_type(WILC_Uint8 *header) +{ + return ((tenuFrmSubtype)(header[0] & 0xFC)); +} + +/* This function extracts the 'to ds' bit from the MAC header of the input */ +/* frame. */ +/* Returns the value in the LSB of the returned value. */ +INLINE WILC_Uint8 get_to_ds(WILC_Uint8 *header) +{ + return (header[1] & 0x01); +} + +/* This function extracts the 'from ds' bit from the MAC header of the input */ +/* frame. */ +/* Returns the value in the LSB of the returned value. */ +INLINE WILC_Uint8 get_from_ds(WILC_Uint8 *header) +{ + return ((header[1] & 0x02) >> 1); +} + +/* This function extracts the MAC Address in 'address1' field of the MAC */ +/* header and updates the MAC Address in the allocated 'addr' variable. */ +INLINE void get_address1(WILC_Uint8 *pu8msa, WILC_Uint8 *addr) +{ + WILC_memcpy(addr, pu8msa + 4, 6); +} + +/* This function extracts the MAC Address in 'address2' field of the MAC */ +/* header and updates the MAC Address in the allocated 'addr' variable. */ +INLINE void get_address2(WILC_Uint8 *pu8msa, WILC_Uint8 *addr) +{ + WILC_memcpy(addr, pu8msa + 10, 6); +} + +/* This function extracts the MAC Address in 'address3' field of the MAC */ +/* header and updates the MAC Address in the allocated 'addr' variable. */ +INLINE void get_address3(WILC_Uint8 *pu8msa, WILC_Uint8 *addr) +{ + WILC_memcpy(addr, pu8msa + 16, 6); +} + +/* This function extracts the BSSID from the incoming WLAN packet based on */ +/* the 'from ds' bit, and updates the MAC Address in the allocated 'addr' */ +/* variable. */ +INLINE void get_BSSID(WILC_Uint8 *data, WILC_Uint8 *bssid) +{ + if (get_from_ds(data) == 1) + get_address2(data, bssid); + else if (get_to_ds(data) == 1) + get_address1(data, bssid); + else + get_address3(data, bssid); +} + +/* This function extracts the SSID from a beacon/probe response frame */ +INLINE void get_ssid(WILC_Uint8 *data, WILC_Uint8 *ssid, WILC_Uint8 *p_ssid_len) +{ + WILC_Uint8 len = 0; + WILC_Uint8 i = 0; + WILC_Uint8 j = 0; + + len = data[MAC_HDR_LEN + TIME_STAMP_LEN + BEACON_INTERVAL_LEN + + CAP_INFO_LEN + 1]; + j = MAC_HDR_LEN + TIME_STAMP_LEN + BEACON_INTERVAL_LEN + + CAP_INFO_LEN + 2; + + /* If the SSID length field is set wrongly to a value greater than the */ + /* allowed maximum SSID length limit, reset the length to 0 */ + if (len >= MAX_SSID_LEN) + len = 0; + + for (i = 0; i < len; i++, j++) + ssid[i] = data[j]; + + ssid[len] = '\0'; + + *p_ssid_len = len; +} + +/* This function extracts the capability info field from the beacon or probe */ +/* response frame. */ +INLINE WILC_Uint16 get_cap_info(WILC_Uint8 *data) +{ + WILC_Uint16 cap_info = 0; + WILC_Uint16 index = MAC_HDR_LEN; + tenuFrmSubtype st = BEACON; + + st = get_sub_type(data); + + /* Location of the Capability field is different for Beacon and */ + /* Association frames. */ + if ((st == BEACON) || (st == PROBE_RSP)) + index += TIME_STAMP_LEN + BEACON_INTERVAL_LEN; + + cap_info = data[index]; + cap_info |= (data[index + 1] << 8); + + return cap_info; +} + +/* This function extracts the capability info field from the Association */ +/* response frame. */ +INLINE WILC_Uint16 get_assoc_resp_cap_info(WILC_Uint8 *data) +{ + WILC_Uint16 cap_info = 0; + + cap_info = data[0]; + cap_info |= (data[1] << 8); + + return cap_info; +} + +/* This funcion extracts the association status code from the incoming */ +/* association response frame and returns association status code */ +INLINE WILC_Uint16 get_asoc_status(WILC_Uint8 *data) +{ + WILC_Uint16 asoc_status = 0; + + asoc_status = data[3]; + asoc_status = (asoc_status << 8) | data[2]; + + return asoc_status; +} + +/* This function extracts association ID from the incoming association */ +/* response frame */ +INLINE WILC_Uint16 get_asoc_id(WILC_Uint8 *data) +{ + WILC_Uint16 asoc_id = 0; + + asoc_id = data[4]; + asoc_id |= (data[5] << 8); + + return asoc_id; +} + +/** + * @brief initializes the Core Configurator + * @details + * @return Error code indicating success/failure + * @note + * @author mabubakr + * @date 1 Mar 2012 + * @version 1.0 + */ + +WILC_Sint32 CoreConfiguratorInit(void) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_SemaphoreAttrs strSemSendPktAttrs; + tstrWILC_SemaphoreAttrs strSemPktRespAttrs; + + PRINT_D(CORECONFIG_DBG, "CoreConfiguratorInit() \n"); + + WILC_SemaphoreFillDefault(&strSemSendPktAttrs); + strSemSendPktAttrs.u32InitCount = 1; + WILC_SemaphoreCreate(&SemHandleSendPkt, &strSemSendPktAttrs); + + WILC_SemaphoreFillDefault(&strSemPktRespAttrs); + strSemPktRespAttrs.u32InitCount = 0; + WILC_SemaphoreCreate(&SemHandlePktResp, &strSemPktRespAttrs); + + gps8ConfigPacket = (WILC_Sint8 *)WILC_MALLOC(MAX_PACKET_BUFF_SIZE); + if (gps8ConfigPacket == NULL) { + PRINT_ER("failed in gps8ConfigPacket allocation \n"); + s32Error = WILC_NO_MEM; + goto _fail_; + } + + WILC_memset((void *)gps8ConfigPacket, 0, MAX_PACKET_BUFF_SIZE); + + WILC_memset((void *)(&gstrConfigPktInfo), 0, sizeof(tstrConfigPktInfo)); +_fail_: + return s32Error; +} + +WILC_Uint8 *get_tim_elm(WILC_Uint8 *pu8msa, WILC_Uint16 u16RxLen, WILC_Uint16 u16TagParamOffset) +{ + WILC_Uint16 u16index = 0; + + /*************************************************************************/ + /* Beacon Frame - Frame Body */ + /* --------------------------------------------------------------------- */ + /* |Timestamp |BeaconInt |CapInfo |SSID |SupRates |DSParSet |TIM elm | */ + /* --------------------------------------------------------------------- */ + /* |8 |2 |2 |2-34 |3-10 |3 |4-256 | */ + /* --------------------------------------------------------------------- */ + /* */ + /*************************************************************************/ + + u16index = u16TagParamOffset; + + /* Search for the TIM Element Field and return if the element is found */ + while (u16index < (u16RxLen - FCS_LEN)) { + if (pu8msa[u16index] == ITIM) { + return(&pu8msa[u16index]); + } else { + u16index += (IE_HDR_LEN + pu8msa[u16index + 1]); + } + } + + return(0); +} + +/* This function gets the current channel information from + * the 802.11n beacon/probe response frame */ +WILC_Uint8 get_current_channel_802_11n(WILC_Uint8 *pu8msa, WILC_Uint16 u16RxLen) +{ + WILC_Uint16 index; + + index = TAG_PARAM_OFFSET; + while (index < (u16RxLen - FCS_LEN)) { + if (pu8msa[index] == IDSPARMS) + return (pu8msa[index + 2]); + else + /* Increment index by length information and header */ + index += pu8msa[index + 1] + IE_HDR_LEN; + } + + /* Return current channel information from the MIB, if beacon/probe */ + /* response frame does not contain the DS parameter set IE */ + /* return (mget_CurrentChannel() + 1); */ + return 0; /* no MIB here */ +} + +WILC_Uint8 get_current_channel(WILC_Uint8 *pu8msa, WILC_Uint16 u16RxLen) +{ +#ifdef PHY_802_11n +#ifdef FIVE_GHZ_BAND + /* Get the current channel as its not set in */ + /* 802.11a beacons/probe response */ + return (get_rf_channel() + 1); +#else /* FIVE_GHZ_BAND */ + /* Extract current channel information from */ + /* the beacon/probe response frame */ + return (get_current_channel_802_11n(pu8msa, u16RxLen)); +#endif /* FIVE_GHZ_BAND */ +#else + return 0; +#endif /* PHY_802_11n */ +} + +/** + * @brief parses the received 'N' message + * @details + * @param[in] pu8MsgBuffer The message to be parsed + * @param[out] ppstrNetworkInfo pointer to pointer to the structure containing the parsed Network Info + * @return Error code indicating success/failure + * @note + * @author mabubakr + * @date 1 Mar 2012 + * @version 1.0 + */ +WILC_Sint32 ParseNetworkInfo(WILC_Uint8 *pu8MsgBuffer, tstrNetworkInfo **ppstrNetworkInfo) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrNetworkInfo *pstrNetworkInfo = WILC_NULL; + WILC_Uint8 u8MsgType = 0; + WILC_Uint8 u8MsgID = 0; + WILC_Uint16 u16MsgLen = 0; + + WILC_Uint16 u16WidID = (WILC_Uint16)WID_NIL; + WILC_Uint16 u16WidLen = 0; + WILC_Uint8 *pu8WidVal = 0; + + u8MsgType = pu8MsgBuffer[0]; + + /* Check whether the received message type is 'N' */ + if ('N' != u8MsgType) { + PRINT_ER("Received Message format incorrect.\n"); + WILC_ERRORREPORT(s32Error, WILC_FAIL); + } + + /* Extract message ID */ + u8MsgID = pu8MsgBuffer[1]; + + /* Extract message Length */ + u16MsgLen = MAKE_WORD16(pu8MsgBuffer[2], pu8MsgBuffer[3]); + + /* Extract WID ID */ + u16WidID = MAKE_WORD16(pu8MsgBuffer[4], pu8MsgBuffer[5]); + + /* Extract WID Length */ + u16WidLen = MAKE_WORD16(pu8MsgBuffer[6], pu8MsgBuffer[7]); + + /* Assign a pointer to the WID value */ + pu8WidVal = &pu8MsgBuffer[8]; + + /* parse the WID value of the WID "WID_NEWORK_INFO" */ + { + WILC_Uint8 *pu8msa = 0; + WILC_Uint16 u16RxLen = 0; + WILC_Uint8 *pu8TimElm = 0; + WILC_Uint8 *pu8IEs = 0; + WILC_Uint16 u16IEsLen = 0; + WILC_Uint8 u8index = 0; + WILC_Uint32 u32Tsf_Lo; + WILC_Uint32 u32Tsf_Hi; + + pstrNetworkInfo = (tstrNetworkInfo *)WILC_MALLOC(sizeof(tstrNetworkInfo)); + WILC_memset((void *)(pstrNetworkInfo), 0, sizeof(tstrNetworkInfo)); + + pstrNetworkInfo->s8rssi = pu8WidVal[0]; + + /* Assign a pointer to msa "Mac Header Start Address" */ + pu8msa = &pu8WidVal[1]; + + u16RxLen = u16WidLen - 1; + + /* parse msa*/ + + /* Get the cap_info */ + pstrNetworkInfo->u16CapInfo = get_cap_info(pu8msa); + #ifdef WILC_P2P + /* Get time-stamp [Low only 32 bit] */ + pstrNetworkInfo->u32Tsf = get_beacon_timestamp_lo(pu8msa); + PRINT_D(CORECONFIG_DBG, "TSF :%x\n", pstrNetworkInfo->u32Tsf); + #endif + + /* Get full time-stamp [Low and High 64 bit] */ + u32Tsf_Lo = get_beacon_timestamp_lo(pu8msa); + u32Tsf_Hi = get_beacon_timestamp_hi(pu8msa); + + pstrNetworkInfo->u64Tsf = u32Tsf_Lo | ((WILC_Uint64)u32Tsf_Hi << 32); + + /* Get SSID */ + get_ssid(pu8msa, pstrNetworkInfo->au8ssid, &(pstrNetworkInfo->u8SsidLen)); + + /* Get BSSID */ + get_BSSID(pu8msa, pstrNetworkInfo->au8bssid); + + /* Get the current channel */ + pstrNetworkInfo->u8channel = get_current_channel(pu8msa, (u16RxLen + FCS_LEN)); + + /* Get beacon period */ + u8index = (MAC_HDR_LEN + TIME_STAMP_LEN); + + pstrNetworkInfo->u16BeaconPeriod = get_beacon_period(pu8msa + u8index); + + u8index += BEACON_INTERVAL_LEN + CAP_INFO_LEN; + + /* Get DTIM Period */ + pu8TimElm = get_tim_elm(pu8msa, (u16RxLen + FCS_LEN), u8index); + if (pu8TimElm != 0) { + pstrNetworkInfo->u8DtimPeriod = pu8TimElm[3]; + } + pu8IEs = &pu8msa[MAC_HDR_LEN + TIME_STAMP_LEN + BEACON_INTERVAL_LEN + CAP_INFO_LEN]; + u16IEsLen = u16RxLen - (MAC_HDR_LEN + TIME_STAMP_LEN + BEACON_INTERVAL_LEN + CAP_INFO_LEN); + + if (u16IEsLen > 0) { + pstrNetworkInfo->pu8IEs = (WILC_Uint8 *)WILC_MALLOC(u16IEsLen); + WILC_memset((void *)(pstrNetworkInfo->pu8IEs), 0, u16IEsLen); + + WILC_memcpy(pstrNetworkInfo->pu8IEs, pu8IEs, u16IEsLen); + } + pstrNetworkInfo->u16IEsLen = u16IEsLen; + + } + + *ppstrNetworkInfo = pstrNetworkInfo; + +ERRORHANDLER: + return s32Error; +} + +/** + * @brief Deallocates the parsed Network Info + * @details + * @param[in] pstrNetworkInfo Network Info to be deallocated + * @return Error code indicating success/failure + * @note + * @author mabubakr + * @date 1 Mar 2012 + * @version 1.0 + */ +WILC_Sint32 DeallocateNetworkInfo(tstrNetworkInfo *pstrNetworkInfo) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + + if (pstrNetworkInfo != WILC_NULL) { + if (pstrNetworkInfo->pu8IEs != WILC_NULL) { + WILC_FREE(pstrNetworkInfo->pu8IEs); + pstrNetworkInfo->pu8IEs = WILC_NULL; + } else { + s32Error = WILC_FAIL; + } + + WILC_FREE(pstrNetworkInfo); + pstrNetworkInfo = WILC_NULL; + + } else { + s32Error = WILC_FAIL; + } + + return s32Error; +} + +/** + * @brief parses the received Association Response frame + * @details + * @param[in] pu8Buffer The Association Response frame to be parsed + * @param[out] ppstrConnectRespInfo pointer to pointer to the structure containing the parsed Association Response Info + * @return Error code indicating success/failure + * @note + * @author mabubakr + * @date 2 Apr 2012 + * @version 1.0 + */ +WILC_Sint32 ParseAssocRespInfo(WILC_Uint8 *pu8Buffer, WILC_Uint32 u32BufferLen, + tstrConnectRespInfo **ppstrConnectRespInfo) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrConnectRespInfo *pstrConnectRespInfo = WILC_NULL; + WILC_Uint16 u16AssocRespLen = 0; + WILC_Uint8 *pu8IEs = 0; + WILC_Uint16 u16IEsLen = 0; + + pstrConnectRespInfo = (tstrConnectRespInfo *)WILC_MALLOC(sizeof(tstrConnectRespInfo)); + WILC_memset((void *)(pstrConnectRespInfo), 0, sizeof(tstrConnectRespInfo)); + + /* u16AssocRespLen = pu8Buffer[0]; */ + u16AssocRespLen = (WILC_Uint16)u32BufferLen; + + /* get the status code */ + pstrConnectRespInfo->u16ConnectStatus = get_asoc_status(pu8Buffer); + if (pstrConnectRespInfo->u16ConnectStatus == SUCCESSFUL_STATUSCODE) { + + /* get the capability */ + pstrConnectRespInfo->u16capability = get_assoc_resp_cap_info(pu8Buffer); + + /* get the Association ID */ + pstrConnectRespInfo->u16AssocID = get_asoc_id(pu8Buffer); + + /* get the Information Elements */ + pu8IEs = &pu8Buffer[CAP_INFO_LEN + STATUS_CODE_LEN + AID_LEN]; + u16IEsLen = u16AssocRespLen - (CAP_INFO_LEN + STATUS_CODE_LEN + AID_LEN); + + pstrConnectRespInfo->pu8RespIEs = (WILC_Uint8 *)WILC_MALLOC(u16IEsLen); + WILC_memset((void *)(pstrConnectRespInfo->pu8RespIEs), 0, u16IEsLen); + + WILC_memcpy(pstrConnectRespInfo->pu8RespIEs, pu8IEs, u16IEsLen); + pstrConnectRespInfo->u16RespIEsLen = u16IEsLen; + } + + *ppstrConnectRespInfo = pstrConnectRespInfo; + + + return s32Error; +} + +/** + * @brief Deallocates the parsed Association Response Info + * @details + * @param[in] pstrNetworkInfo Network Info to be deallocated + * @return Error code indicating success/failure + * @note + * @author mabubakr + * @date 2 Apr 2012 + * @version 1.0 + */ +WILC_Sint32 DeallocateAssocRespInfo(tstrConnectRespInfo *pstrConnectRespInfo) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + + if (pstrConnectRespInfo != WILC_NULL) { + if (pstrConnectRespInfo->pu8RespIEs != WILC_NULL) { + WILC_FREE(pstrConnectRespInfo->pu8RespIEs); + pstrConnectRespInfo->pu8RespIEs = WILC_NULL; + } else { + s32Error = WILC_FAIL; + } + + WILC_FREE(pstrConnectRespInfo); + pstrConnectRespInfo = WILC_NULL; + + } else { + s32Error = WILC_FAIL; + } + + return s32Error; +} + +#ifndef CONNECT_DIRECT +WILC_Sint32 ParseSurveyResults(WILC_Uint8 ppu8RcvdSiteSurveyResults[][MAX_SURVEY_RESULT_FRAG_SIZE], + wid_site_survey_reslts_s **ppstrSurveyResults, + WILC_Uint32 *pu32SurveyResultsCount) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + wid_site_survey_reslts_s *pstrSurveyResults = NULL; + WILC_Uint32 u32SurveyResultsCount = 0; + WILC_Uint32 u32SurveyBytesLength = 0; + WILC_Uint8 *pu8BufferPtr; + WILC_Uint32 u32RcvdSurveyResultsNum = 2; + WILC_Uint8 u8ReadSurveyResFragNum; + WILC_Uint32 i; + WILC_Uint32 j; + + for (i = 0; i < u32RcvdSurveyResultsNum; i++) { + u32SurveyBytesLength = ppu8RcvdSiteSurveyResults[i][0]; + + + for (j = 0; j < u32SurveyBytesLength; j += SURVEY_RESULT_LENGTH) { + u32SurveyResultsCount++; + } + } + + pstrSurveyResults = (wid_site_survey_reslts_s *)WILC_MALLOC(u32SurveyResultsCount * sizeof(wid_site_survey_reslts_s)); + if (pstrSurveyResults == NULL) { + u32SurveyResultsCount = 0; + WILC_ERRORREPORT(s32Error, WILC_NO_MEM); + } + + WILC_memset((void *)(pstrSurveyResults), 0, u32SurveyResultsCount * sizeof(wid_site_survey_reslts_s)); + + u32SurveyResultsCount = 0; + + for (i = 0; i < u32RcvdSurveyResultsNum; i++) { + pu8BufferPtr = ppu8RcvdSiteSurveyResults[i]; + + u32SurveyBytesLength = pu8BufferPtr[0]; + + /* TODO: mostafa: pu8BufferPtr[1] contains the fragment num */ + u8ReadSurveyResFragNum = pu8BufferPtr[1]; + + pu8BufferPtr += 2; + + for (j = 0; j < u32SurveyBytesLength; j += SURVEY_RESULT_LENGTH) { + WILC_memcpy(&pstrSurveyResults[u32SurveyResultsCount], pu8BufferPtr, SURVEY_RESULT_LENGTH); + pu8BufferPtr += SURVEY_RESULT_LENGTH; + u32SurveyResultsCount++; + } + } + +ERRORHANDLER: + *ppstrSurveyResults = pstrSurveyResults; + *pu32SurveyResultsCount = u32SurveyResultsCount; + + return s32Error; +} + + +WILC_Sint32 DeallocateSurveyResults(wid_site_survey_reslts_s *pstrSurveyResults) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + + if (pstrSurveyResults != WILC_NULL) { + WILC_FREE(pstrSurveyResults); + } + + return s32Error; +} +#endif + +/*****************************************************************************/ +/* */ +/* Function Name : ProcessCharWid */ +/* */ +/* Description : This function processes a WID of type WID_CHAR and */ +/* updates the cfg packet with the supplied value. */ +/* */ +/* Inputs : 1) Pointer to WID cfg structure */ +/* 2) Value to set */ +/* */ +/* Globals : */ +/* */ +/* Processing : */ +/* */ +/* Outputs : None */ +/* */ +/* Returns : None */ +/* */ +/* Issues : None */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 08 01 2008 Ittiam Draft */ +/* */ +/*****************************************************************************/ + +void ProcessCharWid(WILC_Char *pcPacket, WILC_Sint32 *ps32PktLen, + tstrWID *pstrWID, WILC_Sint8 *ps8WidVal) +{ + WILC_Uint8 *pu8val = (WILC_Uint8 *)ps8WidVal; + WILC_Uint8 u8val = 0; + WILC_Sint32 s32PktLen = *ps32PktLen; + if (pstrWID == NULL) { + PRINT_WRN(CORECONFIG_DBG, "Can't set CHAR val 0x%x ,NULL structure\n", u8val); + return; + } + + /* WID */ + pcPacket[s32PktLen++] = (WILC_Uint8)(pstrWID->u16WIDid & 0xFF); + pcPacket[s32PktLen++] = (WILC_Uint8)(pstrWID->u16WIDid >> 8) & 0xFF; + if (g_oper_mode == SET_CFG) { + u8val = *pu8val; + + /* Length */ + pcPacket[s32PktLen++] = sizeof(WILC_Uint8); + + + /* Value */ + pcPacket[s32PktLen++] = u8val; + } + *ps32PktLen = s32PktLen; +} + +/*****************************************************************************/ +/* */ +/* Function Name : ProcessShortWid */ +/* */ +/* Description : This function processes a WID of type WID_SHORT and */ +/* updates the cfg packet with the supplied value. */ +/* */ +/* Inputs : 1) Pointer to WID cfg structure */ +/* 2) Value to set */ +/* */ +/* Globals : */ +/* */ +/* Processing : */ +/* */ +/* Outputs : None */ +/* */ +/* Returns : None */ +/* */ +/* Issues : None */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 08 01 2008 Ittiam Draft */ +/* */ +/*****************************************************************************/ + +void ProcessShortWid(WILC_Char *pcPacket, WILC_Sint32 *ps32PktLen, + tstrWID *pstrWID, WILC_Sint8 *ps8WidVal) +{ + WILC_Uint16 *pu16val = (WILC_Uint16 *)ps8WidVal; + WILC_Uint16 u16val = 0; + WILC_Sint32 s32PktLen = *ps32PktLen; + if (pstrWID == NULL) { + PRINT_WRN(CORECONFIG_DBG, "Can't set SHORT val 0x%x ,NULL structure\n", u16val); + return; + } + + /* WID */ + pcPacket[s32PktLen++] = (WILC_Uint8)(pstrWID->u16WIDid & 0xFF); + pcPacket[s32PktLen++] = (WILC_Uint8)((pstrWID->u16WIDid >> 8) & 0xFF); + + if (g_oper_mode == SET_CFG) { + u16val = *pu16val; + + /* Length */ + pcPacket[s32PktLen++] = sizeof(WILC_Uint16); + + /* Value */ + pcPacket[s32PktLen++] = (WILC_Uint8)(u16val & 0xFF); + pcPacket[s32PktLen++] = (WILC_Uint8)((u16val >> 8) & 0xFF); + } + *ps32PktLen = s32PktLen; +} + +/*****************************************************************************/ +/* */ +/* Function Name : ProcessIntWid */ +/* */ +/* Description : This function processes a WID of type WID_INT and */ +/* updates the cfg packet with the supplied value. */ +/* */ +/* Inputs : 1) Pointer to WID cfg structure */ +/* 2) Value to set */ +/* */ +/* Globals : */ +/* */ +/* Processing : */ +/* */ +/* Outputs : None */ +/* */ +/* Returns : None */ +/* */ +/* Issues : None */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 08 01 2008 Ittiam Draft */ +/* */ +/*****************************************************************************/ + +void ProcessIntWid(WILC_Char *pcPacket, WILC_Sint32 *ps32PktLen, + tstrWID *pstrWID, WILC_Sint8 *ps8WidVal) +{ + WILC_Uint32 *pu32val = (WILC_Uint32 *)ps8WidVal; + WILC_Uint32 u32val = 0; + WILC_Sint32 s32PktLen = *ps32PktLen; + if (pstrWID == NULL) { + PRINT_WRN(CORECONFIG_DBG, "Can't set INT val 0x%x , NULL structure\n", u32val); + return; + } + + /* WID */ + pcPacket[s32PktLen++] = (WILC_Uint8)(pstrWID->u16WIDid & 0xFF); + pcPacket[s32PktLen++] = (WILC_Uint8)((pstrWID->u16WIDid >> 8) & 0xFF); + + if (g_oper_mode == SET_CFG) { + u32val = *pu32val; + + /* Length */ + pcPacket[s32PktLen++] = sizeof(WILC_Uint32); + + /* Value */ + pcPacket[s32PktLen++] = (WILC_Uint8)(u32val & 0xFF); + pcPacket[s32PktLen++] = (WILC_Uint8)((u32val >> 8) & 0xFF); + pcPacket[s32PktLen++] = (WILC_Uint8)((u32val >> 16) & 0xFF); + pcPacket[s32PktLen++] = (WILC_Uint8)((u32val >> 24) & 0xFF); + } + *ps32PktLen = s32PktLen; +} + +/*****************************************************************************/ +/* */ +/* Function Name : ProcessIPwid */ +/* */ +/* Description : This function processes a WID of type WID_IP and */ +/* updates the cfg packet with the supplied value. */ +/* */ +/* Inputs : 1) Pointer to WID cfg structure */ +/* 2) Value to set */ +/* */ +/* Globals : */ +/* */ +/* */ +/* Processing : */ +/* */ +/* Outputs : None */ +/* */ +/* Returns : None */ +/* */ +/* Issues : None */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 08 01 2008 Ittiam Draft */ +/* */ +/*****************************************************************************/ + +void ProcessIPwid(WILC_Char *pcPacket, WILC_Sint32 *ps32PktLen, + tstrWID *pstrWID, WILC_Uint8 *pu8ip) +{ + WILC_Uint32 u32val = 0; + WILC_Sint32 s32PktLen = *ps32PktLen; + + if (pstrWID == NULL) { + PRINT_WRN(CORECONFIG_DBG, "Can't set IP Addr , NULL structure\n"); + return; + } + + /* WID */ + pcPacket[s32PktLen++] = (WILC_Uint8)(pstrWID->u16WIDid & 0xFF); + pcPacket[s32PktLen++] = (WILC_Uint8)((pstrWID->u16WIDid >> 8) & 0xFF); + + if (g_oper_mode == SET_CFG) { + /* Length */ + pcPacket[s32PktLen++] = sizeof(WILC_Uint32); + + /* Convert the IP Address String to Integer */ + conv_ip_to_int(pu8ip, &u32val); + + /* Value */ + pcPacket[s32PktLen++] = (WILC_Uint8)(u32val & 0xFF); + pcPacket[s32PktLen++] = (WILC_Uint8)((u32val >> 8) & 0xFF); + pcPacket[s32PktLen++] = (WILC_Uint8)((u32val >> 16) & 0xFF); + pcPacket[s32PktLen++] = (WILC_Uint8)((u32val >> 24) & 0xFF); + } + *ps32PktLen = s32PktLen; +} + +/*****************************************************************************/ +/* */ +/* Function Name : ProcessStrWid */ +/* */ +/* Description : This function processes a WID of type WID_STR and */ +/* updates the cfg packet with the supplied value. */ +/* */ +/* Inputs : 1) Pointer to WID cfg structure */ +/* 2) Value to set */ +/* */ +/* Globals : */ +/* */ +/* Processing : */ +/* */ +/* Outputs : None */ +/* */ +/* Returns : None */ +/* */ +/* Issues : None */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 08 01 2008 Ittiam Draft */ +/* */ +/*****************************************************************************/ + +void ProcessStrWid(WILC_Char *pcPacket, WILC_Sint32 *ps32PktLen, + tstrWID *pstrWID, WILC_Uint8 *pu8val, WILC_Sint32 s32ValueSize) +{ + WILC_Uint16 u16MsgLen = 0; + WILC_Uint16 idx = 0; + WILC_Sint32 s32PktLen = *ps32PktLen; + if (pstrWID == NULL) { + PRINT_WRN(CORECONFIG_DBG, "Can't set STR val, NULL structure\n"); + return; + } + + /* WID */ + pcPacket[s32PktLen++] = (WILC_Uint8)(pstrWID->u16WIDid & 0xFF); + pcPacket[s32PktLen++] = (WILC_Uint8)((pstrWID->u16WIDid >> 8) & 0xFF); + + if (g_oper_mode == SET_CFG) { + /* Message Length */ + /* u16MsgLen = WILC_strlen(pu8val); */ + u16MsgLen = (WILC_Uint16)s32ValueSize; + + /* Length */ + pcPacket[s32PktLen++] = (WILC_Uint8)u16MsgLen; + + /* Value */ + for (idx = 0; idx < u16MsgLen; idx++) + pcPacket[s32PktLen++] = pu8val[idx]; + } + *ps32PktLen = s32PktLen; +} + +/*****************************************************************************/ +/* */ +/* Function Name : ProcessAdrWid */ +/* */ +/* Description : This function processes a WID of type WID_ADR and */ +/* updates the cfg packet with the supplied value. */ +/* */ +/* Inputs : 1) Pointer to WID cfg structure */ +/* 2) Value to set */ +/* */ +/* Globals : */ +/* */ +/* Processing : */ +/* */ +/* Outputs : None */ +/* */ +/* Returns : None */ +/* */ +/* Issues : None */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 08 01 2008 Ittiam Draft */ +/* */ +/*****************************************************************************/ + +void ProcessAdrWid(WILC_Char *pcPacket, WILC_Sint32 *ps32PktLen, + tstrWID *pstrWID, WILC_Uint8 *pu8val) +{ + WILC_Uint16 u16MsgLen = 0; + WILC_Sint32 s32PktLen = *ps32PktLen; + + if (pstrWID == NULL) { + PRINT_WRN(CORECONFIG_DBG, "Can't set Addr WID, NULL structure\n"); + return; + } + + /* WID */ + pcPacket[s32PktLen++] = (WILC_Uint8)(pstrWID->u16WIDid & 0xFF); + pcPacket[s32PktLen++] = (WILC_Uint8)((pstrWID->u16WIDid >> 8) & 0xFF); + + if (g_oper_mode == SET_CFG) { + /* Message Length */ + u16MsgLen = MAC_ADDR_LEN; + + /* Length */ + pcPacket[s32PktLen++] = (WILC_Uint8)u16MsgLen; + + /* Value */ + extract_mac_addr(pu8val, pcPacket + s32PktLen); + s32PktLen += u16MsgLen; + } + *ps32PktLen = s32PktLen; +} + +/*****************************************************************************/ +/* */ +/* Function Name : ProcessBinWid */ +/* */ +/* Description : This function processes a WID of type WID_BIN_DATA and */ +/* updates the cfg packet with the supplied value. */ +/* */ +/* Inputs : 1) Pointer to WID cfg structure */ +/* 2) Name of file containing the binary data in text mode */ +/* */ +/* Globals : */ +/* */ +/* Processing : The binary data is expected to be supplied through a */ +/* file in text mode. This file is expected to be in the */ +/* finject format. It is parsed, converted to binary format */ +/* and copied into g_cfg_pkt for further processing. This */ +/* is obviously a round-about way of processing involving */ +/* multiple (re)conversions between bin & ascii formats. */ +/* But it is done nevertheless to retain uniformity and for */ +/* ease of debugging. */ +/* */ +/* Outputs : None */ +/* */ +/* Returns : None */ +/* */ + +/* Issues : None */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 08 01 2008 Ittiam Draft */ +/* */ +/*****************************************************************************/ + +void ProcessBinWid(WILC_Char *pcPacket, WILC_Sint32 *ps32PktLen, + tstrWID *pstrWID, WILC_Uint8 *pu8val, WILC_Sint32 s32ValueSize) +{ + /* WILC_ERROR("processing Binary WIDs is not supported \n"); */ + + WILC_Uint16 u16MsgLen = 0; + WILC_Uint16 idx = 0; + WILC_Sint32 s32PktLen = *ps32PktLen; + WILC_Uint8 u8checksum = 0; + + if (pstrWID == NULL) { + PRINT_WRN(CORECONFIG_DBG, "Can't set BIN val, NULL structure\n"); + return; + } + + /* WID */ + pcPacket[s32PktLen++] = (WILC_Uint8)(pstrWID->u16WIDid & 0xFF); + pcPacket[s32PktLen++] = (WILC_Uint8)((pstrWID->u16WIDid >> 8) & 0xFF); + + if (g_oper_mode == SET_CFG) { + /* Message Length */ + u16MsgLen = (WILC_Uint16)s32ValueSize; + + /* Length */ + /* pcPacket[s32PktLen++] = (WILC_Uint8)u16MsgLen; */ + pcPacket[s32PktLen++] = (WILC_Uint8)(u16MsgLen & 0xFF); + pcPacket[s32PktLen++] = (WILC_Uint8)((u16MsgLen >> 8) & 0xFF); + + /* Value */ + for (idx = 0; idx < u16MsgLen; idx++) + pcPacket[s32PktLen++] = pu8val[idx]; + + /* checksum */ + for (idx = 0; idx < u16MsgLen; idx++) + u8checksum += pcPacket[MSG_HEADER_LEN + idx + 4]; + + pcPacket[s32PktLen++] = u8checksum; + } + *ps32PktLen = s32PktLen; +} + + +/*****************************************************************************/ +/* */ +/* Function Name : further_process_response */ +/* */ +/* Description : This function parses the response frame got from the */ +/* device. */ +/* */ +/* Inputs : 1) The received response frame */ +/* 2) WID */ +/* 3) WID Length */ +/* 4) Output file handle */ +/* 5) Process Wid Number(i.e wid from --widn switch) */ +/* 6) Index the array in the Global Wid Structure. */ +/* */ +/* Globals : g_wid_num, gastrWIDs */ +/* */ +/* Processing : This function parses the response of the device depending*/ +/* WID type and writes it to the output file in Hex or */ +/* decimal notation depending on the --getx or --get switch.*/ +/* */ +/* Outputs : None */ +/* */ +/* Returns : 0 on Success & -2 on Failure */ +/* */ +/* Issues : None */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 08 01 2009 Ittiam Draft */ +/* */ +/*****************************************************************************/ + +WILC_Sint32 further_process_response(WILC_Uint8 *resp, + WILC_Uint16 u16WIDid, + WILC_Uint16 cfg_len, + WILC_Bool process_wid_num, + WILC_Uint32 cnt, + tstrWID *pstrWIDresult) +{ + WILC_Uint32 retval = 0; + WILC_Uint32 idx = 0; + WILC_Uint8 cfg_chr = 0; + WILC_Uint16 cfg_sht = 0; + WILC_Uint32 cfg_int = 0; + WILC_Uint8 cfg_str[256] = {0}; + tenuWIDtype enuWIDtype = WID_UNDEF; + + if (process_wid_num) { + enuWIDtype = get_wid_type(g_wid_num); + } else { + enuWIDtype = gastrWIDs[cnt].enuWIDtype; + } + + + switch (enuWIDtype) { + case WID_CHAR: + cfg_chr = resp[idx]; + /*Set local copy of WID*/ + *(pstrWIDresult->ps8WidVal) = cfg_chr; + break; + + case WID_SHORT: + { + WILC_Uint16 *pu16val = (WILC_Uint16 *)(pstrWIDresult->ps8WidVal); + cfg_sht = MAKE_WORD16(resp[idx], resp[idx + 1]); + /*Set local copy of WID*/ + /* pstrWIDresult->ps8WidVal = (WILC_Sint8*)(WILC_Sint32)cfg_sht; */ + *pu16val = cfg_sht; + break; + } + + case WID_INT: + { + WILC_Uint32 *pu32val = (WILC_Uint32 *)(pstrWIDresult->ps8WidVal); + cfg_int = MAKE_WORD32( + MAKE_WORD16(resp[idx], resp[idx + 1]), + MAKE_WORD16(resp[idx + 2], resp[idx + 3]) + ); + /*Set local copy of WID*/ + /* pstrWIDresult->ps8WidVal = (WILC_Sint8*)cfg_int; */ + *pu32val = cfg_int; + break; + } + + case WID_STR: + WILC_memcpy(cfg_str, resp + idx, cfg_len); + /* cfg_str[cfg_len] = '\0'; //mostafa: no need currently for NULL termination */ + if (process_wid_num) { + /*fprintf(out_file,"0x%4.4x = %s\n",g_wid_num, + * cfg_str);*/ + } else { + /*fprintf(out_file,"%s = %s\n",gastrWIDs[cnt].cfg_switch, + * cfg_str);*/ + } + + if (pstrWIDresult->s32ValueSize >= cfg_len) { + WILC_memcpy(pstrWIDresult->ps8WidVal, cfg_str, cfg_len); /* mostafa: no need currently for the extra NULL byte */ + pstrWIDresult->s32ValueSize = cfg_len; + } else { + PRINT_ER("allocated WID buffer length is smaller than the received WID Length \n"); + retval = -2; + } + + break; + + case WID_ADR: + create_mac_addr(cfg_str, resp + idx); + + WILC_strncpy(pstrWIDresult->ps8WidVal, cfg_str, WILC_strlen(cfg_str)); + pstrWIDresult->ps8WidVal[WILC_strlen(cfg_str)] = '\0'; + if (process_wid_num) { + /*fprintf(out_file,"0x%4.4x = %s\n",g_wid_num, + * cfg_str);*/ + } else { + /*fprintf(out_file,"%s = %s\n",gastrWIDs[cnt].cfg_switch, + * cfg_str);*/ + } + break; + + case WID_IP: + cfg_int = MAKE_WORD32( + MAKE_WORD16(resp[idx], resp[idx + 1]), + MAKE_WORD16(resp[idx + 2], resp[idx + 3]) + ); + conv_int_to_ip(cfg_str, cfg_int); + if (process_wid_num) { + /*fprintf(out_file,"0x%4.4x = %s\n",g_wid_num, + * cfg_str);*/ + } else { + /*fprintf(out_file,"%s = %s\n",gastrWIDs[cnt].cfg_switch, + * cfg_str);*/ + } + break; + + case WID_BIN_DATA: + #if 0 + /* FILE *fp_bin = NULL; */ + WILC_Uint8 first_bin_wid = 1; + if (first_bin_wid) { + /* fp_bin = fopen("wid_response.bin","wb"); */ + first_bin_wid = 0; + } else { + /* fp_bin = fopen("wid_response.bin","ab"); */ + } + + if (/*fp_bin == NULL*/ 0) { + PRINT_ER("Error: Could not open wid_response.bin for write\n"); + return -2; + } + + /* fwrite(resp + idx, cfg_len, 1, fp_bin); */ + + /* fclose(fp_bin); */ + #endif + + if (pstrWIDresult->s32ValueSize >= cfg_len) { + WILC_memcpy(pstrWIDresult->ps8WidVal, resp + idx, cfg_len); + pstrWIDresult->s32ValueSize = cfg_len; + } else { + PRINT_ER("Allocated WID buffer length is smaller than the received WID Length Err(%d)\n", retval); + retval = -2; + } + break; + + default: + PRINT_ER("ERROR: Check config database: Error(%d)\n", retval); + retval = -2; + break; + } + + return retval; +} + +/*****************************************************************************/ +/* */ +/* Function Name : ParseResponse */ +/* */ +/* Description : This function parses the command-line options and */ +/* creates the config packets which can be sent to the WLAN */ +/* station. */ +/* */ +/* Inputs : 1) The received response frame */ +/* */ +/* Globals : g_opt_list, gastrWIDs */ +/* */ +/* Processing : This function parses the options and creates different */ +/* types of packets depending upon the WID-type */ +/* corresponding to the option. */ +/* */ +/* Outputs : None */ +/* */ +/* Returns : 0 on Success & -1 on Failure */ +/* */ +/* Issues : None */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 08 01 2008 Ittiam Draft */ +/* */ +/*****************************************************************************/ + +WILC_Sint32 ParseResponse(WILC_Uint8 *resp, tstrWID *pstrWIDcfgResult) +{ + WILC_Uint16 u16RespLen = 0; + WILC_Uint16 u16WIDid = 0; + WILC_Uint16 cfg_len = 0; + tenuWIDtype enuWIDtype = WID_UNDEF; + WILC_Bool num_wid_processed = WILC_FALSE; + WILC_Uint32 cnt = 0; + WILC_Uint32 idx = 0; + WILC_Uint32 ResCnt = 0; + /* Check whether the received frame is a valid response */ + if (RESP_MSG_TYPE != resp[0]) { + PRINT_INFO(CORECONFIG_DBG, "Received Message format incorrect.\n"); + return -1; + } + + /* Extract Response Length */ + u16RespLen = MAKE_WORD16(resp[2], resp[3]); + Res_Len = u16RespLen; + + for (idx = MSG_HEADER_LEN; idx < u16RespLen; ) { + u16WIDid = MAKE_WORD16(resp[idx], resp[idx + 1]); + cfg_len = resp[idx + 2]; + /* Incase of Bin Type Wid, the length is given by two byte field */ + enuWIDtype = get_wid_type(u16WIDid); + if (WID_BIN_DATA == enuWIDtype) { + cfg_len |= ((WILC_Uint16)resp[idx + 3] << 8) & 0xFF00; + idx++; + } + idx += 3; + if ((u16WIDid == g_wid_num) && (num_wid_processed == WILC_FALSE)) { + num_wid_processed = WILC_TRUE; + + if (-2 == further_process_response(&resp[idx], u16WIDid, cfg_len, WILC_TRUE, 0, &pstrWIDcfgResult[ResCnt])) { + return -2; + } + ResCnt++; + } else { + for (cnt = 0; cnt < g_num_total_switches; cnt++) { + if (gastrWIDs[cnt].u16WIDid == u16WIDid) { + if (-2 == further_process_response(&resp[idx], u16WIDid, cfg_len, WILC_FALSE, cnt, + &pstrWIDcfgResult[ResCnt])) { + return -2; + } + ResCnt++; + } + } + } + idx += cfg_len; + /* In case if BIN type Wid, The last byte of the Cfg packet is the */ + /* Checksum. The WID Length field does not accounts for the checksum. */ + /* The Checksum is discarded. */ + if (WID_BIN_DATA == enuWIDtype) { + idx++; + } + } + + return 0; +} + +/** + * @brief parses the write response [just detects its status: success or failure] + * @details + * @param[in] pu8RespBuffer The Response to be parsed + * @return Error code indicating Write Operation status: + * WRITE_RESP_SUCCESS (1) => Write Success. + * WILC_FAIL (-100) => Write Failure. + * @note + * @author Ittiam + * @date 11 Aug 2009 + * @version 1.0 + */ + +WILC_Sint32 ParseWriteResponse(WILC_Uint8 *pu8RespBuffer) +{ + WILC_Sint32 s32Error = WILC_FAIL; + WILC_Uint16 u16RespLen = 0; + WILC_Uint16 u16WIDtype = (WILC_Uint16)WID_NIL; + + /* Check whether the received frame is a valid response */ + if (RESP_MSG_TYPE != pu8RespBuffer[0]) { + PRINT_ER("Received Message format incorrect.\n"); + return WILC_FAIL; + } + + /* Extract Response Length */ + u16RespLen = MAKE_WORD16(pu8RespBuffer[2], pu8RespBuffer[3]); + + u16WIDtype = MAKE_WORD16(pu8RespBuffer[4], pu8RespBuffer[5]); + + /* Check for WID_STATUS ID and then check the length and status value */ + if ((u16WIDtype == WID_STATUS) && + (pu8RespBuffer[6] == 1) && + (pu8RespBuffer[7] == WRITE_RESP_SUCCESS)) { + s32Error = WRITE_RESP_SUCCESS; + return s32Error; + } + + /* If the length or status are not as expected return failure */ + s32Error = WILC_FAIL; + return s32Error; + +} + +/** + * @brief creates the header of the Configuration Packet + * @details + * @param[in,out] pcpacket The Configuration Packet + * @param[in,out] ps32PacketLength Length of the Configuration Packet + * @return Error code indicating success/failure + * @note + * @author aismail + * @date 18 Feb 2012 + * @version 1.0 + */ + +WILC_Sint32 CreatePacketHeader(WILC_Char *pcpacket, WILC_Sint32 *ps32PacketLength) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + WILC_Uint16 u16MsgLen = (WILC_Uint16)(*ps32PacketLength); + WILC_Uint16 u16MsgInd = 0; + + /* The format of the message is: */ + /* +-------------------------------------------------------------------+ */ + /* | Message Type | Message ID | Message Length |Message body | */ + /* +-------------------------------------------------------------------+ */ + /* | 1 Byte | 1 Byte | 2 Bytes | Message Length - 4 | */ + /* +-------------------------------------------------------------------+ */ + + /* The format of a message body of a message type 'W' is: */ + /* +-------------------------------------------------------------------+ */ + /* | WID0 | WID0 Length | WID0 Value | ......................... | */ + /* +-------------------------------------------------------------------+ */ + /* | 2 Bytes | 1 Byte | WID0 Length | ......................... | */ + /* +-------------------------------------------------------------------+ */ + + + + /* Message Type */ + if (g_oper_mode == SET_CFG) + pcpacket[u16MsgInd++] = WRITE_MSG_TYPE; + else + pcpacket[u16MsgInd++] = QUERY_MSG_TYPE; + + /* Sequence Number */ + pcpacket[u16MsgInd++] = g_seqno++; + + /* Message Length */ + pcpacket[u16MsgInd++] = (WILC_Uint8)(u16MsgLen & 0xFF); + pcpacket[u16MsgInd++] = (WILC_Uint8)((u16MsgLen >> 8) & 0xFF); + + *ps32PacketLength = u16MsgLen; + + return s32Error; +} + +/** + * @brief creates Configuration packet based on the Input WIDs + * @details + * @param[in] pstrWIDs WIDs to be sent in the configuration packet + * @param[in] u32WIDsCount number of WIDs to be sent in the configuration packet + * @param[out] ps8packet The created Configuration Packet + * @param[out] ps32PacketLength Length of the created Configuration Packet + * @return Error code indicating success/failure + * @note + * @author + * @date 1 Mar 2012 + * @version 1.0 + */ + +WILC_Sint32 CreateConfigPacket(WILC_Sint8 *ps8packet, WILC_Sint32 *ps32PacketLength, + tstrWID *pstrWIDs, WILC_Uint32 u32WIDsCount) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + WILC_Uint32 u32idx = 0; + *ps32PacketLength = MSG_HEADER_LEN; + for (u32idx = 0; u32idx < u32WIDsCount; u32idx++) { + switch (pstrWIDs[u32idx].enuWIDtype) { + case WID_CHAR: + ProcessCharWid(ps8packet, ps32PacketLength, &pstrWIDs[u32idx], + pstrWIDs[u32idx].ps8WidVal); + break; + + case WID_SHORT: + ProcessShortWid(ps8packet, ps32PacketLength, &pstrWIDs[u32idx], + pstrWIDs[u32idx].ps8WidVal); + break; + + case WID_INT: + ProcessIntWid(ps8packet, ps32PacketLength, &pstrWIDs[u32idx], + pstrWIDs[u32idx].ps8WidVal); + break; + + case WID_STR: + ProcessStrWid(ps8packet, ps32PacketLength, &pstrWIDs[u32idx], + pstrWIDs[u32idx].ps8WidVal, pstrWIDs[u32idx].s32ValueSize); + break; + + #if 0 + case WID_ADR: + ProcessAdrWid(ps8packet, ps32PacketLength, &pstrWIDs[u32idx], + pstrWIDs[u32idx].ps8WidVal); + break; + + #endif + case WID_IP: + ProcessIPwid(ps8packet, ps32PacketLength, &pstrWIDs[u32idx], + pstrWIDs[u32idx].ps8WidVal); + break; + + case WID_BIN_DATA: + ProcessBinWid(ps8packet, ps32PacketLength, &pstrWIDs[u32idx], + pstrWIDs[u32idx].ps8WidVal, pstrWIDs[u32idx].s32ValueSize); + break; + + default: + PRINT_ER("ERROR: Check Config database\n"); + } + } + + CreatePacketHeader(ps8packet, ps32PacketLength); + + return s32Error; +} + +WILC_Sint32 ConfigWaitResponse(WILC_Char *pcRespBuffer, WILC_Sint32 s32MaxRespBuffLen, WILC_Sint32 *ps32BytesRead, + WILC_Bool bRespRequired) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + /*bug 3878*/ + /*removed to caller function*/ + /*gstrConfigPktInfo.pcRespBuffer = pcRespBuffer; + * gstrConfigPktInfo.s32MaxRespBuffLen = s32MaxRespBuffLen; + * gstrConfigPktInfo.bRespRequired = bRespRequired;*/ + + + if (gstrConfigPktInfo.bRespRequired == WILC_TRUE) { + WILC_SemaphoreAcquire(&SemHandlePktResp, WILC_NULL); + + *ps32BytesRead = gstrConfigPktInfo.s32BytesRead; + } + + WILC_memset((void *)(&gstrConfigPktInfo), 0, sizeof(tstrConfigPktInfo)); + + return s32Error; +} + +/** + * @brief sends certain Configuration Packet based on the input WIDs pstrWIDs + * and retrieves the packet response pu8RxResp + * @details + * @param[in] pstrWIDs WIDs to be sent in the configuration packet + * @param[in] u32WIDsCount number of WIDs to be sent in the configuration packet + * @param[out] pu8RxResp The received Packet Response + * @param[out] ps32RxRespLen Length of the received Packet Response + * @return Error code indicating success/failure + * @note + * @author mabubakr + * @date 1 Mar 2012 + * @version 1.0 + */ +#ifdef SIMULATION +WILC_Sint32 SendConfigPkt(WILC_Uint8 u8Mode, tstrWID *pstrWIDs, + WILC_Uint32 u32WIDsCount, WILC_Bool bRespRequired, WILC_Uint32 drvHandler) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + WILC_Sint32 err = WILC_SUCCESS; + WILC_Sint32 s32ConfigPacketLen = 0; + WILC_Sint32 s32RcvdRespLen = 0; + + WILC_SemaphoreAcquire(&SemHandleSendPkt, WILC_NULL); + + /*set the packet mode*/ + g_oper_mode = u8Mode; + + WILC_memset((void *)gps8ConfigPacket, 0, MAX_PACKET_BUFF_SIZE); + + if (CreateConfigPacket(gps8ConfigPacket, &s32ConfigPacketLen, pstrWIDs, u32WIDsCount) != WILC_SUCCESS) { + s32Error = WILC_FAIL; + goto End_ConfigPkt; + } + /*bug 3878*/ + gstrConfigPktInfo.pcRespBuffer = gps8ConfigPacket; + gstrConfigPktInfo.s32MaxRespBuffLen = MAX_PACKET_BUFF_SIZE; + PRINT_INFO(CORECONFIG_DBG, "GLOBAL =bRespRequired =%d\n", bRespRequired); + gstrConfigPktInfo.bRespRequired = bRespRequired; + + s32Error = SendRawPacket(gps8ConfigPacket, s32ConfigPacketLen); + if (s32Error != WILC_SUCCESS) { + goto End_ConfigPkt; + } + + WILC_memset((void *)gps8ConfigPacket, 0, MAX_PACKET_BUFF_SIZE); + + ConfigWaitResponse(gps8ConfigPacket, MAX_PACKET_BUFF_SIZE, &s32RcvdRespLen, bRespRequired); + + + if (bRespRequired == WILC_TRUE) { + /* If the operating Mode is GET, then we expect a response frame from */ + /* the driver. Hence start listening to the port for response */ + if (g_oper_mode == GET_CFG) { + #if 1 + err = ParseResponse(gps8ConfigPacket, pstrWIDs); + if (err != 0) { + s32Error = WILC_FAIL; + goto End_ConfigPkt; + } else { + s32Error = WILC_SUCCESS; + } + #endif + } else { + err = ParseWriteResponse(gps8ConfigPacket); + if (err != WRITE_RESP_SUCCESS) { + s32Error = WILC_FAIL; + goto End_ConfigPkt; + } else { + s32Error = WILC_SUCCESS; + } + } + + + } + + +End_ConfigPkt: + WILC_SemaphoreRelease(&SemHandleSendPkt, WILC_NULL); + + return s32Error; +} +#endif +WILC_Sint32 ConfigProvideResponse(WILC_Char *pcRespBuffer, WILC_Sint32 s32RespLen) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + + if (gstrConfigPktInfo.bRespRequired == WILC_TRUE) { + if (s32RespLen <= gstrConfigPktInfo.s32MaxRespBuffLen) { + WILC_memcpy(gstrConfigPktInfo.pcRespBuffer, pcRespBuffer, s32RespLen); + gstrConfigPktInfo.s32BytesRead = s32RespLen; + } else { + WILC_memcpy(gstrConfigPktInfo.pcRespBuffer, pcRespBuffer, gstrConfigPktInfo.s32MaxRespBuffLen); + gstrConfigPktInfo.s32BytesRead = gstrConfigPktInfo.s32MaxRespBuffLen; + PRINT_ER("BusProvideResponse() Response greater than the prepared Buffer Size \n"); + } + + WILC_SemaphoreRelease(&SemHandlePktResp, WILC_NULL); + } + + return s32Error; +} + +/** + * @brief writes the received packet pu8RxPacket in the global Rx FIFO buffer + * @details + * @param[in] pu8RxPacket The received packet + * @param[in] s32RxPacketLen Length of the received packet + * @return Error code indicating success/failure + * @note + * + * @author mabubakr + * @date 1 Mar 2012 + * @version 1.0 + */ + +WILC_Sint32 ConfigPktReceived(WILC_Uint8 *pu8RxPacket, WILC_Sint32 s32RxPacketLen) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + WILC_Uint8 u8MsgType = 0; + + u8MsgType = pu8RxPacket[0]; + + switch (u8MsgType) { + case 'R': + ConfigProvideResponse(pu8RxPacket, s32RxPacketLen); + + break; + + case 'N': + PRINT_INFO(CORECONFIG_DBG, "NetworkInfo packet received\n"); + NetworkInfoReceived(pu8RxPacket, s32RxPacketLen); + break; + + case 'I': + GnrlAsyncInfoReceived(pu8RxPacket, s32RxPacketLen); + break; + + case 'S': + host_int_ScanCompleteReceived(pu8RxPacket, s32RxPacketLen); + break; + + default: + PRINT_ER("ConfigPktReceived(): invalid received msg type at the Core Configurator \n"); + break; + } + + return s32Error; +} + +/** + * @brief Deinitializes the Core Configurator + * @details + * @return Error code indicating success/failure + * @note + * @author mabubakr + * @date 1 Mar 2012 + * @version 1.0 + */ + +WILC_Sint32 CoreConfiguratorDeInit(void) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + + PRINT_D(CORECONFIG_DBG, "CoreConfiguratorDeInit() \n"); + + + WILC_SemaphoreDestroy(&SemHandleSendPkt, WILC_NULL); + WILC_SemaphoreDestroy(&SemHandlePktResp, WILC_NULL); + + + if (gps8ConfigPacket != NULL) { + + WILC_FREE(gps8ConfigPacket); + gps8ConfigPacket = NULL; + } + + return s32Error; +} + + +#ifndef SIMULATION +#if WILC_PLATFORM != WILC_WIN32 +/*Using the global handle of the driver*/ +extern wilc_wlan_oup_t *gpstrWlanOps; +/** + * @brief sends certain Configuration Packet based on the input WIDs pstrWIDs + * using driver config layer + * + * @details + * @param[in] pstrWIDs WIDs to be sent in the configuration packet + * @param[in] u32WIDsCount number of WIDs to be sent in the configuration packet + * @param[out] pu8RxResp The received Packet Response + * @param[out] ps32RxRespLen Length of the received Packet Response + * @return Error code indicating success/failure + * @note + * @author mabubakr + * @date 1 Mar 2012 + * @version 1.0 + */ +WILC_Sint32 SendConfigPkt(WILC_Uint8 u8Mode, tstrWID *pstrWIDs, + WILC_Uint32 u32WIDsCount, WILC_Bool bRespRequired, WILC_Uint32 drvHandler) +{ + WILC_Sint32 counter = 0, ret = 0; + if (gpstrWlanOps == NULL) { + PRINT_D(CORECONFIG_DBG, "Net Dev is still not initialized\n"); + return 1; + } else { + PRINT_D(CORECONFIG_DBG, "Net Dev is initialized\n"); + } + if (gpstrWlanOps->wlan_cfg_set == NULL || + gpstrWlanOps->wlan_cfg_get == NULL) { + PRINT_D(CORECONFIG_DBG, "Set and Get is still not initialized\n"); + return 1; + } else { + PRINT_D(CORECONFIG_DBG, "SET is initialized\n"); + } + if (u8Mode == GET_CFG) { + for (counter = 0; counter < u32WIDsCount; counter++) { + PRINT_INFO(CORECONFIG_DBG, "Sending CFG packet [%d][%d]\n", !counter, + (counter == u32WIDsCount - 1)); + if (!gpstrWlanOps->wlan_cfg_get(!counter, + pstrWIDs[counter].u16WIDid, + (counter == u32WIDsCount - 1), drvHandler)) { + ret = -1; + printk("[Sendconfigpkt]Get Timed out\n"); + break; + } + } + /** + * get the value + **/ + /* WILC_Sleep(1000); */ + counter = 0; + for (counter = 0; counter < u32WIDsCount; counter++) { + pstrWIDs[counter].s32ValueSize = gpstrWlanOps->wlan_cfg_get_value( + pstrWIDs[counter].u16WIDid, + pstrWIDs[counter].ps8WidVal, pstrWIDs[counter].s32ValueSize); + + } + } else if (u8Mode == SET_CFG) { + for (counter = 0; counter < u32WIDsCount; counter++) { + PRINT_D(CORECONFIG_DBG, "Sending config SET PACKET WID:%x\n", pstrWIDs[counter].u16WIDid); + if (!gpstrWlanOps->wlan_cfg_set(!counter, + pstrWIDs[counter].u16WIDid, pstrWIDs[counter].ps8WidVal, + pstrWIDs[counter].s32ValueSize, + (counter == u32WIDsCount - 1), drvHandler)) { + ret = -1; + printk("[Sendconfigpkt]Set Timed out\n"); + break; + } + } + } + + return ret; +} +#endif +#endif diff --git a/drivers/staging/wilc1000/coreconfigurator.h b/drivers/staging/wilc1000/coreconfigurator.h new file mode 100644 index 000000000000..9cdfa2ac8fca --- /dev/null +++ b/drivers/staging/wilc1000/coreconfigurator.h @@ -0,0 +1,498 @@ + +/*! + * @file coreconfigurator.h + * @brief + * @author + * @sa coreconfigurator.c + * @date 1 Mar 2012 + * @version 1.0 + */ + + +#ifndef CORECONFIGURATOR_H +#define CORECONFIGURATOR_H + +#include "wilc_oswrapper.h" +#include "wilc_wlan_if.h" +/*****************************************************************************/ +/* Constants */ +/*****************************************************************************/ +/* Number of WID Options Supported */ +#define NUM_BASIC_SWITCHES 45 +#define NUM_FHSS_SWITCHES 0 + +#define NUM_RSSI 5 + +#ifdef MAC_802_11N +#define NUM_11N_BASIC_SWITCHES 25 +#define NUM_11N_HUT_SWITCHES 47 +#else /* MAC_802_11N */ +#define NUM_11N_BASIC_SWITCHES 0 +#define NUM_11N_HUT_SWITCHES 0 +#endif /* MAC_802_11N */ + +extern WILC_Uint16 g_num_total_switches; + +#define MAC_HDR_LEN 24 /* No Address4 - non-ESS */ +#define MAX_SSID_LEN 33 +#define FCS_LEN 4 +#define TIME_STAMP_LEN 8 +#define BEACON_INTERVAL_LEN 2 +#define CAP_INFO_LEN 2 +#define STATUS_CODE_LEN 2 +#define AID_LEN 2 +#define IE_HDR_LEN 2 + + +/* Operating Mode: SET */ +#define SET_CFG 0 +/* Operating Mode: GET */ +#define GET_CFG 1 + +#define MAX_PACKET_BUFF_SIZE 1596 + +#define MAX_STRING_LEN 256 +#define MAX_SURVEY_RESULT_FRAG_SIZE MAX_STRING_LEN +#define SURVEY_RESULT_LENGTH 44 +#define MAX_ASSOC_RESP_FRAME_SIZE MAX_STRING_LEN + +#define STATUS_MSG_LEN 12 +#define MAC_CONNECTED 1 +#define MAC_DISCONNECTED 0 + + + +/*****************************************************************************/ +/* Function Macros */ +/*****************************************************************************/ +#define MAKE_WORD16(lsb, msb) ((((WILC_Uint16)(msb) << 8) & 0xFF00) | (lsb)) +#define MAKE_WORD32(lsw, msw) ((((WILC_Uint32)(msw) << 16) & 0xFFFF0000) | (lsw)) + + +/*****************************************************************************/ +/* Type Definitions */ +/*****************************************************************************/ +/* WID Data Types */ +#if 0 +typedef enum { + WID_CHAR = 0, + WID_SHORT = 1, + WID_INT = 2, + WID_STR = 3, + WID_ADR = 4, + WID_BIN = 5, + WID_IP = 6, + WID_UNDEF = 7, + WID_TYPE_FORCE_32BIT = 0xFFFFFFFF +} tenuWIDtype; + +/* WLAN Identifiers */ +typedef enum { + WID_NIL = -1, + /* EMAC Character WID list */ + WID_BSS_TYPE = 0x0000, + WID_CURRENT_TX_RATE = 0x0001, + WID_CURRENT_CHANNEL = 0x0002, + WID_PREAMBLE = 0x0003, + WID_11G_OPERATING_MODE = 0x0004, + WID_STATUS = 0x0005, + WID_11G_PROT_MECH = 0x0006, + WID_SCAN_TYPE = 0x0007, + WID_PRIVACY_INVOKED = 0x0008, + WID_KEY_ID = 0x0009, + WID_QOS_ENABLE = 0x000A, + WID_POWER_MANAGEMENT = 0x000B, + WID_11I_MODE = 0x000C, + WID_AUTH_TYPE = 0x000D, + WID_SITE_SURVEY = 0x000E, + WID_LISTEN_INTERVAL = 0x000F, + WID_DTIM_PERIOD = 0x0010, + WID_ACK_POLICY = 0x0011, + WID_RESET = 0x0012, + WID_PCF_MODE = 0x0013, + WID_CFP_PERIOD = 0x0014, + WID_BCAST_SSID = 0x0015, + WID_PHY_TEST_PATTERN = 0x0016, + WID_DISCONNECT = 0x0016, + WID_READ_ADDR_SDRAM = 0x0017, + WID_TX_POWER_LEVEL_11A = 0x0018, + WID_REKEY_POLICY = 0x0019, + WID_SHORT_SLOT_ALLOWED = 0x001A, + WID_PHY_ACTIVE_REG = 0x001B, + WID_PHY_ACTIVE_REG_VAL = 0x001C, + WID_TX_POWER_LEVEL_11B = 0x001D, + WID_START_SCAN_REQ = 0x001E, + WID_RSSI = 0x001F, + WID_JOIN_REQ = 0x0020, + WID_ANTENNA_SELECTION = 0x0021, + WID_USER_CONTROL_ON_TX_POWER = 0x0027, + WID_MEMORY_ACCESS_8BIT = 0x0029, + WID_UAPSD_SUPPORT_AP = 0x002A, + WID_CURRENT_MAC_STATUS = 0x0031, + WID_AUTO_RX_SENSITIVITY = 0x0032, + WID_DATAFLOW_CONTROL = 0x0033, + WID_SCAN_FILTER = 0x0036, + WID_LINK_LOSS_THRESHOLD = 0x0037, + WID_AUTORATE_TYPE = 0x0038, + WID_CCA_THRESHOLD = 0x0039, + WID_802_11H_DFS_MODE = 0x003B, + WID_802_11H_TPC_MODE = 0x003C, + WID_DEVICE_READY = 0x003D, + WID_PM_NULL_FRAME_INTERVAL = 0x003E, + WID_PM_ACTIVITY_TIMER = 0x003F, + WID_PM_NULL_FRAME_WAIT_ENABLE = 0x0040, + WID_SCAN_WAIT_TIME = 0x0041, + WID_WSC_IE_EN = 0x0042, + WID_WPS_START = 0x0043, + WID_WPS_DEV_MODE = 0x0044, + WID_BT_COEXISTENCE = 0x0050, + WID_TRACKING_ROAMING = 0x0070, + WID_NUM_PKTS_FOR_RSSI_AVG = 0x0071, + WID_FHSS_SCAN_CHAN_INDEX = 0x0072, + WID_FHSS_SCAN_STEP_INDEX = 0x0073, + + /* NMAC Character WID list */ + WID_11N_PROT_MECH = 0x0080, + WID_11N_ERP_PROT_TYPE = 0x0081, + WID_11N_ENABLE = 0x0082, + WID_11N_OPERATING_MODE = 0x0083, + WID_11N_OBSS_NONHT_DETECTION = 0x0084, + WID_11N_HT_PROT_TYPE = 0x0085, + WID_11N_RIFS_PROT_ENABLE = 0x0086, + WID_11N_SMPS_MODE = 0x0087, + WID_11N_CURRENT_TX_MCS = 0x0088, + WID_11N_PRINT_STATS = 0x0089, + WID_HUT_FCS_CORRUPT_MODE = 0x008A, + WID_HUT_RESTART = 0x008B, + WID_HUT_TX_FORMAT = 0x008C, + WID_11N_SHORT_GI_20MHZ_ENABLE = 0x008D, + WID_HUT_BANDWIDTH = 0x008E, + WID_HUT_OP_BAND = 0x008F, + WID_HUT_STBC = 0x0090, + WID_HUT_ESS = 0x0091, + WID_HUT_ANTSET = 0x0092, + WID_HUT_HT_OP_MODE = 0x0093, + WID_HUT_RIFS_MODE = 0x0094, + WID_HUT_SMOOTHING_REC = 0x0095, + WID_HUT_SOUNDING_PKT = 0x0096, + WID_HUT_HT_CODING = 0x0097, + WID_HUT_TEST_DIR = 0x0098, + WID_HUT_CAPTURE_MODE = 0x0099, + WID_HUT_PHY_TEST_MODE = 0x009A, + WID_HUT_PHY_TEST_RATE_HI = 0x009B, + WID_HUT_PHY_TEST_RATE_LO = 0x009C, + WID_HUT_DISABLE_RXQ_REPLENISH = 0x009D, + WID_HUT_KEY_ORIGIN = 0x009E, + WID_HUT_BCST_PERCENT = 0x009F, + WID_HUT_GROUP_CIPHER_TYPE = 0x00A0, + WID_TX_ABORT_CONFIG = 0x00A1, + WID_HOST_DATA_IF_TYPE = 0x00A2, + WID_HOST_CONFIG_IF_TYPE = 0x00A3, + WID_HUT_TSF_TEST_MODE = 0x00A4, + WID_HUT_TSSI_VALUE = 0x00A5, + WID_HUT_PKT_TSSI_VALUE = 0x00A5, + WID_REG_TSSI_11B_VALUE = 0x00A6, + WID_REG_TSSI_11G_VALUE = 0x00A7, + WID_REG_TSSI_11N_VALUE = 0x00A8, + WID_TX_CALIBRATION = 0x00A9, + WID_DSCR_TSSI_11B_VALUE = 0x00AA, + WID_DSCR_TSSI_11G_VALUE = 0x00AB, + WID_DSCR_TSSI_11N_VALUE = 0x00AC, + WID_HUT_RSSI_EX = 0x00AD, + WID_HUT_ADJ_RSSI_EX = 0x00AE, + WID_11N_IMMEDIATE_BA_ENABLED = 0x00AF, + WID_11N_TXOP_PROT_DISABLE = 0x00B0, + WID_TX_POWER_LEVEL_11N = 0x00B1, + WID_HUT_MGMT_PERCENT = 0x00B3, + WID_HUT_MGMT_BCST_PERCENT = 0x00B4, + WID_HUT_MGMT_ALLOW_HT = 0x00B5, + WID_HUT_UC_MGMT_TYPE = 0x00B6, + WID_HUT_BC_MGMT_TYPE = 0x00B7, + WID_HUT_11W_MFP_REQUIRED_TX = 0x00B8, + WID_HUT_11W_MFP_PEER_CAPABLE = 0x00B9, + WID_HUT_11W_TX_IGTK_ID = 0x00BA, + WID_11W_ENABLE = 0x00BB, + WID_11W_MGMT_PROT_REQ = 0x00BC, + WID_USER_SEC_CHANNEL_OFFSET = 0x00C0, + WID_2040_COEXISTENCE = 0x00C1, + WID_HUT_FC_TXOP_MOD = 0x00C2, + WID_HUT_FC_PROT_TYPE = 0x00C3, + WID_HUT_SEC_CCA_ASSERT = 0x00C4, + WID_2040_ENABLE = 0x00C5, + WID_2040_CURR_CHANNEL_OFFSET = 0x00C6, + WID_2040_40MHZ_INTOLERANT = 0x00C7, + + + /* Custom Character WID list */ + WID_POWER_SAVE = 0x0100, + WID_WAKE_STATUS = 0x0101, + WID_WAKE_CONTROL = 0x0102, + WID_CCA_BUSY_START = 0x0103, + + /* EMAC Short WID list */ + WID_RTS_THRESHOLD = 0x1000, + WID_FRAG_THRESHOLD = 0x1001, + WID_SHORT_RETRY_LIMIT = 0x1002, + WID_LONG_RETRY_LIMIT = 0x1003, + WID_CFP_MAX_DUR = 0x1004, + WID_PHY_TEST_FRAME_LEN = 0x1005, + WID_BEACON_INTERVAL = 0x1006, + WID_MEMORY_ACCESS_16BIT = 0x1008, + WID_RX_SENSE = 0x100B, + WID_ACTIVE_SCAN_TIME = 0x100C, + WID_PASSIVE_SCAN_TIME = 0x100D, + WID_SITE_SURVEY_SCAN_TIME = 0x100E, + WID_JOIN_START_TIMEOUT = 0x100F, + WID_AUTH_TIMEOUT = 0x1010, + WID_ASOC_TIMEOUT = 0x1011, + WID_11I_PROTOCOL_TIMEOUT = 0x1012, + WID_EAPOL_RESPONSE_TIMEOUT = 0x1013, + WID_WPS_PASS_ID = 0x1017, + WID_WPS_CONFIG_METHOD = 0x1018, + WID_FHSS_INIT_SCAN_TIME = 0x1070, + WID_FHSS_ROAM_SCAN_TIME = 0x1071, + + /* NMAC Short WID list */ + WID_11N_RF_REG_VAL = 0x1080, + WID_HUT_FRAME_LEN = 0x1081, + WID_HUT_TXOP_LIMIT = 0x1082, + WID_HUT_SIG_QUAL_AVG = 0x1083, + WID_HUT_SIG_QUAL_AVG_CNT = 0x1084, + WID_11N_SIG_QUAL_VAL = 0x1085, + WID_HUT_RSSI_EX_COUNT = 0x1086, + WID_HUT_UC_MGMT_FRAME_LEN = 0x1088, + WID_HUT_BC_MGMT_FRAME_LEN = 0x1089, + + /* Custom Short WID list */ + + WID_CCA_BUSY_STATUS = 0x1100, + + /* EMAC Integer WID list */ + WID_FAILED_COUNT = 0x2000, + WID_RETRY_COUNT = 0x2001, + WID_MULTIPLE_RETRY_COUNT = 0x2002, + WID_FRAME_DUPLICATE_COUNT = 0x2003, + WID_ACK_FAILURE_COUNT = 0x2004, + WID_RECEIVED_FRAGMENT_COUNT = 0x2005, + WID_MCAST_RECEIVED_FRAME_COUNT = 0x2006, + WID_FCS_ERROR_COUNT = 0x2007, + WID_SUCCESS_FRAME_COUNT = 0x2008, + WID_PHY_TEST_PKT_CNT = 0x2009, + WID_HUT_TX_COUNT = 0x200A, + WID_TX_FRAGMENT_COUNT = 0x200B, + WID_TX_MULTICAST_FRAME_COUNT = 0x200C, + WID_RTS_SUCCESS_COUNT = 0x200D, + WID_RTS_FAILURE_COUNT = 0x200E, + WID_WEP_UNDECRYPTABLE_COUNT = 0x200F, + WID_REKEY_PERIOD = 0x2010, + WID_REKEY_PACKET_COUNT = 0x2011, + WID_1X_SERV_ADDR = 0x2012, + WID_STACK_IP_ADDR = 0x2013, + WID_STACK_NETMASK_ADDR = 0x2014, + WID_HW_RX_COUNT = 0x2015, + WID_MEMORY_ADDRESS = 0x201E, + WID_MEMORY_ACCESS_32BIT = 0x201F, + WID_RF_REG_VAL = 0x2021, + WID_FIRMWARE_INFO = 0x2023, + WID_DEV_OS_VERSION = 0x2025, + WID_ROAM_RSSI_THESHOLDS = 0x2070, + WID_TRACK_INTERVAL_SEC = 0x2071, + WID_FHSS_HOPPING_PARAMS = 0x2072, + WID_FHSS_HOP_DWELL_TIME = 0x2073, + + /* NMAC Integer WID list */ + WID_11N_PHY_ACTIVE_REG_VAL = 0x2080, + WID_HUT_NUM_TX_PKTS = 0x2081, + WID_HUT_TX_TIME_TAKEN = 0x2082, + WID_HUT_TX_TEST_TIME = 0x2083, + WID_HUT_LOG_INTERVAL = 0x2084, + + /* EMAC String WID list */ + WID_SSID = 0x3000, + WID_FIRMWARE_VERSION = 0x3001, + WID_OPERATIONAL_RATE_SET = 0x3002, + WID_BSSID = 0x3003, + #if 0 + WID_WEP_KEY_VALUE0 = 0x3004, + #endif + WID_11I_PSK = 0x3008, + WID_11E_P_ACTION_REQ = 0x3009, + WID_1X_KEY = 0x300A, + WID_HARDWARE_VERSION = 0x300B, + WID_MAC_ADDR = 0x300C, + WID_HUT_DEST_ADDR = 0x300D, + /*WID_HUT_STATS = 0x300E,*/ + WID_PHY_VERSION = 0x300F, + WID_SUPP_USERNAME = 0x3010, + WID_SUPP_PASSWORD = 0x3011, + WID_SITE_SURVEY_RESULTS = 0x3012, + WID_RX_POWER_LEVEL = 0x3013, + WID_MANUFACTURER = 0x3026, /*Added for CAPI tool */ + WID_MODEL_NAME = 0x3027, /*Added for CAPI tool */ + WID_MODEL_NUM = 0x3028, /*Added for CAPI tool */ + WID_DEVICE_NAME = 0x3029, /*Added for CAPI tool */ + + WID_ASSOC_RES_INFO = 0x3020, + + /* NMAC String WID list */ + WID_11N_P_ACTION_REQ = 0x3080, + WID_HUT_TEST_ID = 0x3081, + WID_PMKID_INFO = 0x3082, + + /* Custom String WID list */ + WID_FLASH_DATA = 0x3100, + WID_EEPROM_DATA = 0x3101, + WID_SERIAL_NUMBER = 0x3102, + + /* EMAC Binary WID list */ + WID_UAPSD_CONFIG = 0x4001, + WID_UAPSD_STATUS = 0x4002, + WID_AC_PARAMS_AP = 0x4003, + WID_AC_PARAMS_STA = 0x4004, + WID_NEWORK_INFO = 0x4005, + WID_WPS_CRED_LIST = 0x4006, + WID_PRIM_DEV_TYPE = 0x4007, + WID_STA_JOIN_INFO = 0x4008, + WID_CONNECTED_STA_LIST = 0x4009, + + /* NMAC Binary WID list */ + WID_11N_AUTORATE_TABLE = 0x4080, + WID_HUT_TX_PATTERN = 0x4081, + WID_HUT_STATS = 0x4082, + WID_HUT_LOG_STATS = 0x4083, + + /*BugID_3746 WID to add IE to be added in next probe request*/ + WID_INFO_ELEMENT_PROBE = 0x4085, + /*BugID_3746 WID to add IE to be added in next associate request*/ + WID_INFO_ELEMENT_ASSOCIATE = 0x4086, + + /* Miscellaneous WIDs */ + WID_ALL = 0x7FFE, + WID_MAX = 0xFFFF +} tenuWIDid; +#endif + +/* Status Codes for Authentication and Association Frames */ +typedef enum { + SUCCESSFUL_STATUSCODE = 0, + UNSPEC_FAIL = 1, + UNSUP_CAP = 10, + REASOC_NO_ASOC = 11, + FAIL_OTHER = 12, + UNSUPT_ALG = 13, + AUTH_SEQ_FAIL = 14, + CHLNG_FAIL = 15, + AUTH_TIMEOUT = 16, + AP_FULL = 17, + UNSUP_RATE = 18, + SHORT_PREAMBLE_UNSUP = 19, + PBCC_UNSUP = 20, + CHANNEL_AGIL_UNSUP = 21, + SHORT_SLOT_UNSUP = 25, + OFDM_DSSS_UNSUP = 26, + CONNECT_STS_FORCE_16_BIT = 0xFFFF +} tenuConnectSts; + +typedef struct { + WILC_Uint16 u16WIDid; + tenuWIDtype enuWIDtype; + WILC_Sint32 s32ValueSize; + WILC_Sint8 *ps8WidVal; + +} tstrWID; + +typedef struct { + WILC_Uint8 u8Full; + WILC_Uint8 u8Index; + WILC_Sint8 as8RSSI[NUM_RSSI]; +} tstrRSSI; +/* This structure is used to support parsing of the received 'N' message */ +typedef struct { + WILC_Sint8 s8rssi; + WILC_Uint16 u16CapInfo; + WILC_Uint8 au8ssid[MAX_SSID_LEN]; + WILC_Uint8 u8SsidLen; + WILC_Uint8 au8bssid[6]; + WILC_Uint16 u16BeaconPeriod; + WILC_Uint8 u8DtimPeriod; + WILC_Uint8 u8channel; + unsigned long u32TimeRcvdInScanCached; /* of type unsigned long to be accepted by the linux kernel macro time_after() */ + unsigned long u32TimeRcvdInScan; + WILC_Bool bNewNetwork; +#ifdef AGING_ALG + WILC_Uint8 u8Found; +#endif +#ifdef WILC_P2P + WILC_Uint32 u32Tsf; /* time-stamp [Low only 32 bit] */ +#endif + WILC_Uint8 *pu8IEs; + WILC_Uint16 u16IEsLen; + void *pJoinParams; + tstrRSSI strRssi; + WILC_Uint64 u64Tsf; /* time-stamp [Low and High 64 bit] */ +} tstrNetworkInfo; + +/* This structure is used to support parsing of the received Association Response frame */ +typedef struct { + WILC_Uint16 u16capability; + WILC_Uint16 u16ConnectStatus; + WILC_Uint16 u16AssocID; + WILC_Uint8 *pu8RespIEs; + WILC_Uint16 u16RespIEsLen; +} tstrConnectRespInfo; + + +typedef struct { + WILC_Uint8 au8bssid[6]; + WILC_Uint8 *pu8ReqIEs; + size_t ReqIEsLen; + WILC_Uint8 *pu8RespIEs; + WILC_Uint16 u16RespIEsLen; + WILC_Uint16 u16ConnectStatus; +} tstrConnectInfo; + + + +typedef struct { + WILC_Uint16 u16reason; + WILC_Uint8 *ie; + size_t ie_len; +} tstrDisconnectNotifInfo; + +#ifndef CONNECT_DIRECT +typedef struct wid_site_survey_reslts { + WILC_Char SSID[MAX_SSID_LEN]; + WILC_Uint8 BssType; + WILC_Uint8 Channel; + WILC_Uint8 SecurityStatus; + WILC_Uint8 BSSID[6]; + WILC_Char RxPower; + WILC_Uint8 Reserved; + +} wid_site_survey_reslts_s; +#endif + +extern WILC_Sint32 CoreConfiguratorInit(void); +extern WILC_Sint32 CoreConfiguratorDeInit(void); + +extern WILC_Sint32 SendConfigPkt(WILC_Uint8 u8Mode, tstrWID *pstrWIDs, + WILC_Uint32 u32WIDsCount, WILC_Bool bRespRequired, WILC_Uint32 drvHandler); +extern WILC_Sint32 ParseNetworkInfo(WILC_Uint8 *pu8MsgBuffer, tstrNetworkInfo **ppstrNetworkInfo); +extern WILC_Sint32 DeallocateNetworkInfo(tstrNetworkInfo *pstrNetworkInfo); + +extern WILC_Sint32 ParseAssocRespInfo(WILC_Uint8 *pu8Buffer, WILC_Uint32 u32BufferLen, + tstrConnectRespInfo **ppstrConnectRespInfo); +extern WILC_Sint32 DeallocateAssocRespInfo(tstrConnectRespInfo *pstrConnectRespInfo); + +#ifndef CONNECT_DIRECT +extern WILC_Sint32 ParseSurveyResults(WILC_Uint8 ppu8RcvdSiteSurveyResults[][MAX_SURVEY_RESULT_FRAG_SIZE], + wid_site_survey_reslts_s **ppstrSurveyResults, WILC_Uint32 *pu32SurveyResultsCount); +extern WILC_Sint32 DeallocateSurveyResults(wid_site_survey_reslts_s *pstrSurveyResults); +#endif + +extern WILC_Sint32 SendRawPacket(WILC_Sint8 *pspacket, WILC_Sint32 s32PacketLen); +extern void NetworkInfoReceived(WILC_Uint8 *pu8Buffer, WILC_Uint32 u32Length); +void GnrlAsyncInfoReceived(WILC_Uint8 *pu8Buffer, WILC_Uint32 u32Length); +void host_int_ScanCompleteReceived(WILC_Uint8 *pu8Buffer, WILC_Uint32 u32Length); + +#endif diff --git a/drivers/staging/wilc1000/fifo_buffer.c b/drivers/staging/wilc1000/fifo_buffer.c new file mode 100644 index 000000000000..733d81f2eeca --- /dev/null +++ b/drivers/staging/wilc1000/fifo_buffer.c @@ -0,0 +1,142 @@ + + +#include "wilc_oswrapper.h" +#include "fifo_buffer.h" + + + +WILC_Uint32 FIFO_InitBuffer(tHANDLE *hBuffer, WILC_Uint32 u32BufferLength) +{ + WILC_Uint32 u32Error = 0; + tstrFifoHandler *pstrFifoHandler = WILC_MALLOC (sizeof (tstrFifoHandler)); + if (pstrFifoHandler) { + WILC_memset (pstrFifoHandler, 0, sizeof (tstrFifoHandler)); + pstrFifoHandler->pu8Buffer = WILC_MALLOC (u32BufferLength); + if (pstrFifoHandler->pu8Buffer) { + tstrWILC_SemaphoreAttrs strSemBufferAttrs; + pstrFifoHandler->u32BufferLength = u32BufferLength; + WILC_memset (pstrFifoHandler->pu8Buffer, 0, u32BufferLength); + /* create semaphore */ + WILC_SemaphoreFillDefault (&strSemBufferAttrs); + strSemBufferAttrs.u32InitCount = 1; + WILC_SemaphoreCreate(&pstrFifoHandler->SemBuffer, &strSemBufferAttrs); + *hBuffer = pstrFifoHandler; + } else { + *hBuffer = NULL; + u32Error = 1; + } + } else { + u32Error = 1; + } + return u32Error; +} +WILC_Uint32 FIFO_DeInit(tHANDLE hFifo) +{ + WILC_Uint32 u32Error = 0; + tstrFifoHandler *pstrFifoHandler = (tstrFifoHandler *) hFifo; + if (pstrFifoHandler) { + if (pstrFifoHandler->pu8Buffer) { + WILC_FREE (pstrFifoHandler->pu8Buffer); + } else { + u32Error = 1; + } + + WILC_SemaphoreDestroy (&pstrFifoHandler->SemBuffer, WILC_NULL); + + WILC_FREE (pstrFifoHandler); + } else { + u32Error = 1; + } + return u32Error; +} + +WILC_Uint32 FIFO_ReadBytes(tHANDLE hFifo, WILC_Uint8 *pu8Buffer, WILC_Uint32 u32BytesToRead, WILC_Uint32 *pu32BytesRead) +{ + WILC_Uint32 u32Error = 0; + tstrFifoHandler *pstrFifoHandler = (tstrFifoHandler *) hFifo; + if (pstrFifoHandler && pu32BytesRead) { + if (pstrFifoHandler->u32TotalBytes) { + if (WILC_SemaphoreAcquire(&pstrFifoHandler->SemBuffer, WILC_NULL) == WILC_SUCCESS) { + if (u32BytesToRead > pstrFifoHandler->u32TotalBytes) { + *pu32BytesRead = pstrFifoHandler->u32TotalBytes; + } else { + *pu32BytesRead = u32BytesToRead; + } + if ((pstrFifoHandler->u32ReadOffset + u32BytesToRead) <= pstrFifoHandler->u32BufferLength) { + WILC_memcpy(pu8Buffer, pstrFifoHandler->pu8Buffer + pstrFifoHandler->u32ReadOffset, + *pu32BytesRead); + /* update read offset and total bytes */ + pstrFifoHandler->u32ReadOffset += u32BytesToRead; + pstrFifoHandler->u32TotalBytes -= u32BytesToRead; + + } else { + WILC_Uint32 u32FirstPart = + pstrFifoHandler->u32BufferLength - pstrFifoHandler->u32ReadOffset; + WILC_memcpy(pu8Buffer, pstrFifoHandler->pu8Buffer + pstrFifoHandler->u32ReadOffset, + u32FirstPart); + WILC_memcpy(pu8Buffer + u32FirstPart, pstrFifoHandler->pu8Buffer, + u32BytesToRead - u32FirstPart); + /* update read offset and total bytes */ + pstrFifoHandler->u32ReadOffset = u32BytesToRead - u32FirstPart; + pstrFifoHandler->u32TotalBytes -= u32BytesToRead; + } + WILC_SemaphoreRelease (&pstrFifoHandler->SemBuffer, WILC_NULL); + } else { + u32Error = 1; + } + } else { + u32Error = 1; + } + } else { + u32Error = 1; + } + return u32Error; +} + +WILC_Uint32 FIFO_WriteBytes(tHANDLE hFifo, WILC_Uint8 *pu8Buffer, WILC_Uint32 u32BytesToWrite, WILC_Bool bForceOverWrite) +{ + WILC_Uint32 u32Error = 0; + tstrFifoHandler *pstrFifoHandler = (tstrFifoHandler *) hFifo; + if (pstrFifoHandler) { + if (u32BytesToWrite < pstrFifoHandler->u32BufferLength) { + if ((pstrFifoHandler->u32TotalBytes + u32BytesToWrite) <= pstrFifoHandler->u32BufferLength || + bForceOverWrite) { + if (WILC_SemaphoreAcquire(&pstrFifoHandler->SemBuffer, WILC_NULL) == WILC_SUCCESS) { + if ((pstrFifoHandler->u32WriteOffset + u32BytesToWrite) <= pstrFifoHandler->u32BufferLength) { + WILC_memcpy(pstrFifoHandler->pu8Buffer + pstrFifoHandler->u32WriteOffset, pu8Buffer, + u32BytesToWrite); + /* update read offset and total bytes */ + pstrFifoHandler->u32WriteOffset += u32BytesToWrite; + pstrFifoHandler->u32TotalBytes += u32BytesToWrite; + + } else { + WILC_Uint32 u32FirstPart = + pstrFifoHandler->u32BufferLength - pstrFifoHandler->u32WriteOffset; + WILC_memcpy(pstrFifoHandler->pu8Buffer + pstrFifoHandler->u32WriteOffset, pu8Buffer, + u32FirstPart); + WILC_memcpy(pstrFifoHandler->pu8Buffer, pu8Buffer + u32FirstPart, + u32BytesToWrite - u32FirstPart); + /* update read offset and total bytes */ + pstrFifoHandler->u32WriteOffset = u32BytesToWrite - u32FirstPart; + pstrFifoHandler->u32TotalBytes += u32BytesToWrite; + } + /* if data overwriten */ + if (pstrFifoHandler->u32TotalBytes > pstrFifoHandler->u32BufferLength) { + /* adjust read offset to the oldest data available */ + pstrFifoHandler->u32ReadOffset = pstrFifoHandler->u32WriteOffset; + /* data availabe is the buffer length */ + pstrFifoHandler->u32TotalBytes = pstrFifoHandler->u32BufferLength; + } + WILC_SemaphoreRelease(&pstrFifoHandler->SemBuffer, WILC_NULL); + } + } else { + u32Error = 1; + } + } else { + u32Error = 1; + } + } else { + u32Error = 1; + } + return u32Error; +} \ No newline at end of file diff --git a/drivers/staging/wilc1000/fifo_buffer.h b/drivers/staging/wilc1000/fifo_buffer.h new file mode 100644 index 000000000000..0700e7929c00 --- /dev/null +++ b/drivers/staging/wilc1000/fifo_buffer.h @@ -0,0 +1,23 @@ + +#include "wilc_oswrapper.h" + + +#define tHANDLE void * + +typedef struct { + WILC_Uint8 *pu8Buffer; + WILC_Uint32 u32BufferLength; + WILC_Uint32 u32WriteOffset; + WILC_Uint32 u32ReadOffset; + WILC_Uint32 u32TotalBytes; + WILC_SemaphoreHandle SemBuffer; +} tstrFifoHandler; + + +extern WILC_Uint32 FIFO_InitBuffer(tHANDLE *hBuffer, + WILC_Uint32 u32BufferLength); +extern WILC_Uint32 FIFO_DeInit(tHANDLE hFifo); +extern WILC_Uint32 FIFO_ReadBytes(tHANDLE hFifo, WILC_Uint8 *pu8Buffer, + WILC_Uint32 u32BytesToRead, WILC_Uint32 *pu32BytesRead); +extern WILC_Uint32 FIFO_WriteBytes(tHANDLE hFifo, WILC_Uint8 *pu8Buffer, + WILC_Uint32 u32BytesToWrite, WILC_Bool bForceOverWrite); \ No newline at end of file diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c new file mode 100644 index 000000000000..fcbadd1885de --- /dev/null +++ b/drivers/staging/wilc1000/host_interface.c @@ -0,0 +1,8074 @@ +#include "host_interface.h" +#include "wilc_oswrapper.h" +#include "itypes.h" +#include "coreconfigurator.h" + +extern WILC_Sint32 TransportInit(void); +extern WILC_Sint32 TransportDeInit(void); +extern WILC_Uint8 connecting; + +#ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP +extern WILC_TimerHandle hDuringIpTimer; +#endif + +extern WILC_Bool bEnablePS; +/*BugID_5137*/ +extern WILC_Uint8 g_wilc_initialized; +/*****************************************************************************/ +/* Macros */ +/*****************************************************************************/ + +/* Message types of the Host IF Message Queue*/ +#define HOST_IF_MSG_SCAN ((WILC_Uint16)0) +#define HOST_IF_MSG_CONNECT ((WILC_Uint16)1) +#define HOST_IF_MSG_RCVD_GNRL_ASYNC_INFO ((WILC_Uint16)2) +#define HOST_IF_MSG_KEY ((WILC_Uint16)3) +#define HOST_IF_MSG_RCVD_NTWRK_INFO ((WILC_Uint16)4) +#define HOST_IF_MSG_RCVD_SCAN_COMPLETE ((WILC_Uint16)5) +#define HOST_IF_MSG_CFG_PARAMS ((WILC_Uint16)6) +#define HOST_IF_MSG_SET_CHANNEL ((WILC_Uint16)7) +#define HOST_IF_MSG_DISCONNECT ((WILC_Uint16)8) +#define HOST_IF_MSG_GET_RSSI ((WILC_Uint16)9) +#define HOST_IF_MSG_GET_CHNL ((WILC_Uint16)10) +#define HOST_IF_MSG_ADD_BEACON ((WILC_Uint16)11) +#define HOST_IF_MSG_DEL_BEACON ((WILC_Uint16)12) +#define HOST_IF_MSG_ADD_STATION ((WILC_Uint16)13) +#define HOST_IF_MSG_DEL_STATION ((WILC_Uint16)14) +#define HOST_IF_MSG_EDIT_STATION ((WILC_Uint16)15) +#define HOST_IF_MSG_SCAN_TIMER_FIRED ((WILC_Uint16)16) +#define HOST_IF_MSG_CONNECT_TIMER_FIRED ((WILC_Uint16)17) +#define HOST_IF_MSG_POWER_MGMT ((WILC_Uint16)18) +#define HOST_IF_MSG_GET_INACTIVETIME ((WILC_Uint16)19) +#define HOST_IF_MSG_REMAIN_ON_CHAN ((WILC_Uint16)20) +#define HOST_IF_MSG_REGISTER_FRAME ((WILC_Uint16)21) +#define HOST_IF_MSG_LISTEN_TIMER_FIRED ((WILC_Uint16)22) +#define HOST_IF_MSG_GET_LINKSPEED ((WILC_Uint16)23) +#define HOST_IF_MSG_SET_WFIDRV_HANDLER ((WILC_Uint16)24) +#define HOST_IF_MSG_SET_MAC_ADDRESS ((WILC_Uint16)25) +#define HOST_IF_MSG_GET_MAC_ADDRESS ((WILC_Uint16)26) +#define HOST_IF_MSG_SET_OPERATION_MODE ((WILC_Uint16)27) +#define HOST_IF_MSG_SET_IPADDRESS ((WILC_Uint16)28) +#define HOST_IF_MSG_GET_IPADDRESS ((WILC_Uint16)29) +#define HOST_IF_MSG_FLUSH_CONNECT ((WILC_Uint16)30) +#define HOST_IF_MSG_GET_STATISTICS ((WILC_Uint16)31) +#define HOST_IF_MSG_SET_MULTICAST_FILTER ((WILC_Uint16)32) +#define HOST_IF_MSG_ADD_BA_SESSION ((WILC_Uint16)33) +#define HOST_IF_MSG_DEL_BA_SESSION ((WILC_Uint16)34) +#define HOST_IF_MSG_Q_IDLE ((WILC_Uint16)35) +#define HOST_IF_MSG_DEL_ALL_STA ((WILC_Uint16)36) +#define HOST_IF_MSG_DEL_ALL_RX_BA_SESSIONS ((WILC_Uint16)34) + +#define HOST_IF_MSG_EXIT ((WILC_Uint16)100) + +#define HOST_IF_SCAN_TIMEOUT 4000 +#define HOST_IF_CONNECT_TIMEOUT 9500 + +#define BA_SESSION_DEFAULT_BUFFER_SIZE 16 +#define BA_SESSION_DEFAULT_TIMEOUT 1000 +#define BLOCK_ACK_REQ_SIZE 0x14 +/*****************************************************************************/ +/* Type Definitions */ +/*****************************************************************************/ + +/*! + * @struct tstrHostIFCfgParamAttr + * @brief Structure to hold Host IF CFG Params Attributes + * @details + * @todo + * @sa + * @author Mai Daftedar + * @date 02 April 2012 + * @version 1.0 + */ +typedef struct _tstrHostIFCfgParamAttr { + tstrCfgParamVal pstrCfgParamVal; + +} tstrHostIFCfgParamAttr; + +/*! + * @struct tstrHostIFwpaAttr + * @brief Structure to hold Host IF Scan Attributes + * @details + * @todo + * @sa + * @author Mai Daftedar + * @date 25 March 2012 + * @version 1.0 + */ +typedef struct _tstrHostIFwpaAttr { + WILC_Uint8 *pu8key; + const WILC_Uint8 *pu8macaddr; + WILC_Uint8 *pu8seq; + WILC_Uint8 u8seqlen; + WILC_Uint8 u8keyidx; + WILC_Uint8 u8Keylen; + WILC_Uint8 u8Ciphermode; +} tstrHostIFwpaAttr; + + +/*! + * @struct tstrHostIFwepAttr + * @brief Structure to hold Host IF Scan Attributes + * @details + * @todo + * @sa + * @author Mai Daftedar + * @date 25 March 2012 + * @version 1.0 + */ +typedef struct _tstrHostIFwepAttr { + WILC_Uint8 *pu8WepKey; + WILC_Uint8 u8WepKeylen; + WILC_Uint8 u8Wepidx; + WILC_Uint8 u8mode; + AUTHTYPE_T tenuAuth_type; + +} tstrHostIFwepAttr; + +/*! + * @struct tuniHostIFkeyAttr + * @brief Structure to hold Host IF Scan Attributes + * @details + * @todo + * @sa + * @author Mai Daftedar + * @date 25 March 2012 + * @version 1.0 + */ +typedef union _tuniHostIFkeyAttr { + tstrHostIFwepAttr strHostIFwepAttr; + tstrHostIFwpaAttr strHostIFwpaAttr; + tstrHostIFpmkidAttr strHostIFpmkidAttr; +} tuniHostIFkeyAttr; + +/*! + * @struct tstrHostIFkeyAttr + * @brief Structure to hold Host IF Scan Attributes + * @details + * @todo + * @sa + * @author Mai Daftedar + * @date 25 March 2012 + * @version 1.0 + */ +typedef struct _tstrHostIFkeyAttr { + tenuKeyType enuKeyType; + WILC_Uint8 u8KeyAction; + tuniHostIFkeyAttr uniHostIFkeyAttr; +} tstrHostIFkeyAttr; + + + + +/*! + * @struct tstrHostIFscanAttr + * @brief Structure to hold Host IF Scan Attributes + * @details + * @todo + * @sa + * @author Mostafa Abu Bakr + * @date 25 March 2012 + * @version 1.0 + */ +typedef struct _tstrHostIFscanAttr { + WILC_Uint8 u8ScanSource; + WILC_Uint8 u8ScanType; + WILC_Uint8 *pu8ChnlFreqList; + WILC_Uint8 u8ChnlListLen; + WILC_Uint8 *pu8IEs; + size_t IEsLen; + tWILCpfScanResult pfScanResult; + void *pvUserArg; + /*BugID_4189*/ + tstrHiddenNetwork strHiddenNetwork; + +} tstrHostIFscanAttr; + +/*! + * @struct tstrHostIFconnectAttr + * @brief Structure to hold Host IF Connect Attributes + * @details + * @todo + * @sa + * @author Mostafa Abu Bakr + * @date 25 March 2012 + * @version 1.0 + */ +typedef struct _tstrHostIFconnectAttr { + WILC_Uint8 *pu8bssid; + WILC_Uint8 *pu8ssid; + size_t ssidLen; + WILC_Uint8 *pu8IEs; + size_t IEsLen; + WILC_Uint8 u8security; + tWILCpfConnectResult pfConnectResult; + void *pvUserArg; + AUTHTYPE_T tenuAuth_type; + WILC_Uint8 u8channel; + void *pJoinParams; +} tstrHostIFconnectAttr; + +/*! + * @struct tstrRcvdGnrlAsyncInfo + * @brief Structure to hold Received General Asynchronous info + * @details + * @todo + * @sa + * @author Mostafa Abu Bakr + * @date 25 March 2012 + * @version 1.0 + */ +typedef struct _tstrRcvdGnrlAsyncInfo { + WILC_Uint8 *pu8Buffer; + WILC_Uint32 u32Length; +} tstrRcvdGnrlAsyncInfo; + +/*! + * @struct tstrHostIFSetChan + * @brief Set Channel message body + * @details + * @todo + * @sa + * @author Mai Daftedar + * @date 25 March 2012 + * @version 1.0 + */ +typedef struct _tstrHostIFSetChan { + WILC_Uint8 u8SetChan; +} tstrHostIFSetChan; + +/*! + * @struct tstrHostIFSetChan + * @brief Get Channel message body + * @details + * @todo + * @sa + * @author Mai Daftedar + * @date 01 Jule 2012 + * @version 1.0 + */ +typedef struct _tstrHostIFGetChan { + WILC_Uint8 u8GetChan; +} tstrHostIFGetChan; + +/*bug3819: Add Scan acomplete notification to host*/ +/*! + * @struct tstrScanComplete + * @brief hold received Async. Scan Complete message body + * @details + * @todo + * @sa + * @author zsalah + * @date 25 March 2012 + * @version 1.0 + */ +/*typedef struct _tstrScanComplete + * { + * WILC_Uint8* pu8Buffer; + * WILC_Uint32 u32Length; + * } tstrScanComplete;*/ + +/*! + * @struct tstrHostIFSetBeacon + * @brief Set Beacon message body + * @details + * @todo + * @sa + * @author Adham Abozaeid + * @date 10 July 2012 + * @version 1.0 + */ +typedef struct _tstrHostIFSetBeacon { + WILC_Uint32 u32Interval; /*!< Beacon Interval. Period between two successive beacons on air */ + WILC_Uint32 u32DTIMPeriod; /*!< DTIM Period. Indicates how many Beacon frames + * (including the current frame) appear before the next DTIM */ + WILC_Uint32 u32HeadLen; /*!< Length of the head buffer in bytes */ + WILC_Uint8 *pu8Head; /*!< Pointer to the beacon's head buffer. Beacon's head is the part + * from the beacon's start till the TIM element, NOT including the TIM */ + WILC_Uint32 u32TailLen; /*!< Length of the tail buffer in bytes */ + WILC_Uint8 *pu8Tail; /*!< Pointer to the beacon's tail buffer. Beacon's tail starts just + * after the TIM inormation element */ +} tstrHostIFSetBeacon; + + + +/*! + * @struct tstrHostIFDelBeacon + * @brief Del Beacon message body + * @details + * @todo + * @sa + * @author Adham Abozaeid + * @date 15 July 2012 + * @version 1.0 + */ +typedef struct _tstrHostIFDelBeacon { + WILC_Uint8 u8dummy; +} tstrHostIFDelBeacon; + +/*! + * @struct tstrHostIFSetMulti + * @brief set Multicast filter Address + * @details + * @todo + * @sa + * @author Abdelrahman Sobhy + * @date 30 August 2013 + * @version 1.0 Description + */ + +typedef struct { + WILC_Bool bIsEnabled; + WILC_Uint32 u32count; +} tstrHostIFSetMulti; + +/*! + * @struct tstrHostIFDelAllSta + * @brief Deauth station message body + * @details + * @todo + * @sa + * @author Mai Daftedar + * @date 09 April 2014 + * @version 1.0 Description + */ + +typedef struct { + WILC_Uint8 au8Sta_DelAllSta[MAX_NUM_STA][ETH_ALEN]; + WILC_Uint8 u8Num_AssocSta; +} tstrHostIFDelAllSta; + +/*! + * @struct tstrHostIFDelSta + * @brief Delete station message body + * @details + * @todo + * @sa + * @author Adham Abozaeid + * @date 15 July 2012 + * @version 1.0 Description + */ + +typedef struct { + WILC_Uint8 au8MacAddr[ETH_ALEN]; +} tstrHostIFDelSta; + +/*! + * @struct tstrTimerCb + * @brief Timer callback message body + * @details + * @todo + * @sa + * @author Mostafa Abu Bakr + * @date 25 March 2012 + * @version 1.0 + */ +typedef struct _tstrTimerCb { + void *pvUsrArg; /*!< Private data passed at timer start */ +} tstrTimerCb; + +/*! + * @struct tstrHostIfPowerMgmtParam + * @brief Power management message body + * @details + * @todo + * @sa + * @author Adham Abozaeid + * @date 24 November 2012 + * @version 1.0 + */ +typedef struct { + + WILC_Bool bIsEnabled; + WILC_Uint32 u32Timeout; +} tstrHostIfPowerMgmtParam; + +/*! + * @struct tstrHostIFSetIPAddr + * @brief set IP Address message body + * @details + * @todo + * @sa + * @author Abdelrahman Sobhy + * @date 30 August 2013 + * @version 1.0 Description + */ + +typedef struct { + WILC_Uint8 *au8IPAddr; + WILC_Uint8 idx; +} tstrHostIFSetIPAddr; + +/*! + * @struct tstrHostIfStaInactiveT + * @brief Get station message body + * @details + * @todo + * @sa + * @author Mai Daftedar + * @date 16 April 2013 + * @version 1.0 + */ +typedef struct { + WILC_Uint8 mac[6]; + +} tstrHostIfStaInactiveT; +/**/ +/*! + * @union tuniHostIFmsgBody + * @brief Message body for the Host Interface message_q + * @details + * @todo + * @sa + * @author Mostafa Abu Bakr + * @date 25 March 2012 + * @version 1.0 + */ +typedef union _tuniHostIFmsgBody { + tstrHostIFscanAttr strHostIFscanAttr; /*!< Host IF Scan Request Attributes message body */ + tstrHostIFconnectAttr strHostIFconnectAttr; /*!< Host IF Connect Request Attributes message body */ + tstrRcvdNetworkInfo strRcvdNetworkInfo; /*!< Received Asynchronous Network Info message body */ + tstrRcvdGnrlAsyncInfo strRcvdGnrlAsyncInfo; /*!< Received General Asynchronous Info message body */ + tstrHostIFkeyAttr strHostIFkeyAttr; /*!<>*/ + tstrHostIFCfgParamAttr strHostIFCfgParamAttr; /*! */ + tstrHostIFSetChan strHostIFSetChan; + tstrHostIFGetChan strHostIFGetChan; + tstrHostIFSetBeacon strHostIFSetBeacon; /*!< Set beacon message body */ + tstrHostIFDelBeacon strHostIFDelBeacon; /*!< Del beacon message body */ + tstrWILC_AddStaParam strAddStaParam; /*!< Add station message body */ + tstrHostIFDelSta strDelStaParam; /*!< Del Station message body */ + tstrWILC_AddStaParam strEditStaParam; /*!< Edit station message body */ + /* tstrScanComplete strScanComplete; / *Received Async. Scan Complete message body* / */ + tstrTimerCb strTimerCb; /*!< Timer callback message body */ + tstrHostIfPowerMgmtParam strPowerMgmtparam; /*!< Power Management message body */ + tstrHostIfStaInactiveT strHostIfStaInactiveT; + tstrHostIFSetIPAddr strHostIfSetIP; + tstrHostIfSetDrvHandler strHostIfSetDrvHandler; + tstrHostIFSetMulti strHostIfSetMulti; + tstrHostIfSetOperationMode strHostIfSetOperationMode; + tstrHostIfSetMacAddress strHostIfSetMacAddress; + tstrHostIfGetMacAddress strHostIfGetMacAddress; + tstrHostIfBASessionInfo strHostIfBASessionInfo; + #ifdef WILC_P2P + tstrHostIfRemainOnChan strHostIfRemainOnChan; + tstrHostIfRegisterFrame strHostIfRegisterFrame; + #endif + WILC_Char *pUserData; + tstrHostIFDelAllSta strHostIFDelAllSta; +} tuniHostIFmsgBody; + +/*! + * @struct tstrHostIFmsg + * @brief Host Interface message + * @details + * @todo + * @sa + * @author Mostafa Abu Bakr + * @date 25 March 2012 + * @version 1.0 + */ +typedef struct _tstrHostIFmsg { + WILC_Uint16 u16MsgId; /*!< Message ID */ + tuniHostIFmsgBody uniHostIFmsgBody; /*!< Message body */ + void *drvHandler; +} tstrHostIFmsg; + +#ifdef CONNECT_DIRECT +typedef struct _tstrWidJoinReqExt { + WILC_Char SSID[MAX_SSID_LEN]; + WILC_Uint8 u8channel; + WILC_Uint8 BSSID[6]; +} tstrWidJoinReqExt; +#endif + +/*Bug4218: Parsing Join Param*/ +#ifdef WILC_PARSE_SCAN_IN_HOST +/*Struct containg joinParam of each AP*/ +typedef struct _tstrJoinBssParam { + BSSTYPE_T bss_type; + WILC_Uint8 dtim_period; + WILC_Uint16 beacon_period; + WILC_Uint16 cap_info; + WILC_Uint8 au8bssid[6]; + WILC_Char ssid[MAX_SSID_LEN]; + WILC_Uint8 ssidLen; + WILC_Uint8 supp_rates[MAX_RATES_SUPPORTED + 1]; + WILC_Uint8 ht_capable; + WILC_Uint8 wmm_cap; + WILC_Uint8 uapsd_cap; + WILC_Bool rsn_found; + WILC_Uint8 rsn_grp_policy; + WILC_Uint8 mode_802_11i; + WILC_Uint8 rsn_pcip_policy[3]; + WILC_Uint8 rsn_auth_policy[3]; + WILC_Uint8 rsn_cap[2]; + struct _tstrJoinParam *nextJoinBss; + #ifdef WILC_P2P + WILC_Uint32 tsf; + WILC_Uint8 u8NoaEnbaled; + WILC_Uint8 u8OppEnable; + WILC_Uint8 u8CtWindow; + WILC_Uint8 u8Count; + WILC_Uint8 u8Index; + WILC_Uint8 au8Duration[4]; + WILC_Uint8 au8Interval[4]; + WILC_Uint8 au8StartTime[4]; + #endif +} tstrJoinBssParam; +/*Bug4218: Parsing Join Param*/ +/*a linked list table containing needed join parameters entries for each AP found in most recent scan*/ +typedef struct _tstrBssTable { + WILC_Uint8 u8noBssEntries; + tstrJoinBssParam *head; + tstrJoinBssParam *tail; +} tstrBssTable; +#endif /*WILC_PARSE_SCAN_IN_HOST*/ + +typedef enum { + SCAN_TIMER = 0, + CONNECT_TIMER = 1, + SCAN_CONNECT_TIMER_FORCE_32BIT = 0xFFFFFFFF +} tenuScanConnTimer; + +/*****************************************************************************/ +/* */ +/* Global Variabls */ +/* */ +/*****************************************************************************/ + + +tstrWILC_WFIDrv *terminated_handle = WILC_NULL; +tstrWILC_WFIDrv *gWFiDrvHandle = WILC_NULL; +#ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP +WILC_Bool g_obtainingIP = WILC_FALSE; +#endif +WILC_Uint8 P2P_LISTEN_STATE; +static WILC_ThreadHandle HostIFthreadHandler; +static WILC_MsgQueueHandle gMsgQHostIF; +static WILC_SemaphoreHandle hSemHostIFthrdEnd; + +WILC_SemaphoreHandle hSemDeinitDrvHandle; +static WILC_SemaphoreHandle hWaitResponse; +WILC_SemaphoreHandle hSemHostIntDeinit; +WILC_TimerHandle g_hPeriodicRSSI; + + + +WILC_Uint8 gau8MulticastMacAddrList[WILC_MULTICAST_TABLE_SIZE][ETH_ALEN]; + +#ifndef CONNECT_DIRECT +static WILC_Uint8 gapu8RcvdSurveyResults[2][MAX_SURVEY_RESULT_FRAG_SIZE]; +#endif + +static WILC_Uint8 gapu8RcvdAssocResp[MAX_ASSOC_RESP_FRAME_SIZE]; + +WILC_Bool gbScanWhileConnected = WILC_FALSE; + +static WILC_Sint8 gs8Rssi; +static WILC_Sint8 gs8lnkspd; +static WILC_Uint8 gu8Chnl; +static WILC_Uint8 gs8SetIP[2][4]; +static WILC_Uint8 gs8GetIP[2][4]; +#ifdef WILC_AP_EXTERNAL_MLME +static WILC_Uint32 gu32InactiveTime; +static WILC_Uint8 gu8DelBcn; +#endif +#ifndef SIMULATION +static WILC_Uint32 gu32WidConnRstHack; +#endif + +/*BugID_5137*/ +WILC_Uint8 *gu8FlushedJoinReq; +WILC_Uint8 *gu8FlushedInfoElemAsoc; +WILC_Uint8 gu8Flushed11iMode; +WILC_Uint8 gu8FlushedAuthType; +WILC_Uint32 gu32FlushedJoinReqSize; +WILC_Uint32 gu32FlushedInfoElemAsocSize; +WILC_Uint32 gu8FlushedJoinReqDrvHandler; +#define REAL_JOIN_REQ 0 +#define FLUSHED_JOIN_REQ 1 +#define FLUSHED_BYTE_POS 79 /* Position the byte indicating flushing in the flushed request */ + +/*Bug4218: Parsing Join Param*/ +#ifdef WILC_PARSE_SCAN_IN_HOST +/*Bug4218: Parsing Join Param*/ +static void *host_int_ParseJoinBssParam(tstrNetworkInfo *ptstrNetworkInfo); +#endif /*WILC_PARSE_SCAN_IN_HOST*/ + +extern void chip_sleep_manually(WILC_Uint32 u32SleepTime); +extern int linux_wlan_get_num_conn_ifcs(void); + +/** + * @brief Handle_SetChannel + * @details Sending config packet to firmware to set channel + * @param[in] tstrHostIFSetChan* pstrHostIFSetChan + * @return Error code. + * @author + * @date + * @version 1.0 + */ +static WILC_Sint32 Handle_SetChannel(void *drvHandler, tstrHostIFSetChan *pstrHostIFSetChan) +{ + + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler; + + /*prepare configuration packet*/ + strWID.u16WIDid = (WILC_Uint16)WID_CURRENT_CHANNEL; + strWID.enuWIDtype = WID_CHAR; + strWID.ps8WidVal = (WILC_Char *)&(pstrHostIFSetChan->u8SetChan); + strWID.s32ValueSize = sizeof(WILC_Char); + + PRINT_D(HOSTINF_DBG, "Setting channel\n"); + /*Sending Cfg*/ + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + if (s32Error) { + PRINT_ER("Failed to set channel\n"); + WILC_ERRORREPORT(s32Error, WILC_INVALID_STATE); + } + WILC_CATCH(s32Error) + { + + } + + return s32Error; +} +/** + * @brief Handle_SetWfiDrvHandler + * @details Sending config packet to firmware to set driver handler + * @param[in] void * drvHandler,tstrHostIfSetDrvHandler* pstrHostIfSetDrvHandler + * @return Error code. + * @author + * @date + * @version 1.0 + */ +static WILC_Sint32 Handle_SetWfiDrvHandler(tstrHostIfSetDrvHandler *pstrHostIfSetDrvHandler) +{ + + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)((pstrHostIfSetDrvHandler->u32Address)); + + + /*prepare configuration packet*/ + strWID.u16WIDid = (WILC_Uint16)WID_SET_DRV_HANDLER; + strWID.enuWIDtype = WID_INT; + strWID.ps8WidVal = (WILC_Sint8 *)&(pstrHostIfSetDrvHandler->u32Address); + strWID.s32ValueSize = sizeof(WILC_Uint32); + + /*Sending Cfg*/ + + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + + + if ((pstrHostIfSetDrvHandler->u32Address) == (WILC_Uint32)NULL) { + WILC_SemaphoreRelease(&hSemDeinitDrvHandle, WILC_NULL); + } + + + if (s32Error) { + PRINT_ER("Failed to set driver handler\n"); + WILC_ERRORREPORT(s32Error, WILC_INVALID_STATE); + } + WILC_CATCH(s32Error) + { + + } + + return s32Error; +} + +/** + * @brief Handle_SetWfiAPDrvHandler + * @details Sending config packet to firmware to set driver handler + * @param[in] void * drvHandler,tstrHostIfSetDrvHandler* pstrHostIfSetDrvHandler + * @return Error code. + * @author + * @date + * @version 1.0 + */ +static WILC_Sint32 Handle_SetOperationMode(void *drvHandler, tstrHostIfSetOperationMode *pstrHostIfSetOperationMode) +{ + + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler; + + + /*prepare configuration packet*/ + strWID.u16WIDid = (WILC_Uint16)WID_SET_OPERATION_MODE; + strWID.enuWIDtype = WID_INT; + strWID.ps8WidVal = (WILC_Sint8 *)&(pstrHostIfSetOperationMode->u32Mode); + strWID.s32ValueSize = sizeof(WILC_Uint32); + + /*Sending Cfg*/ + PRINT_INFO(HOSTINF_DBG, "(WILC_Uint32)pstrWFIDrv= %x \n", (WILC_Uint32)pstrWFIDrv); + + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + + + if ((pstrHostIfSetOperationMode->u32Mode) == (WILC_Uint32)NULL) { + WILC_SemaphoreRelease(&hSemDeinitDrvHandle, WILC_NULL); + } + + + if (s32Error) { + PRINT_ER("Failed to set driver handler\n"); + WILC_ERRORREPORT(s32Error, WILC_INVALID_STATE); + } + WILC_CATCH(s32Error) + { + + } + + return s32Error; +} + +/** + * @brief host_int_set_IPAddress + * @details Setting IP address params in message queue + * @param[in] WILC_WFIDrvHandle hWFIDrv, WILC_Uint8* pu8IPAddr + * @return Error code. + * @author + * @date + * @version 1.0 + */ +WILC_Sint32 Handle_set_IPAddress(void *drvHandler, WILC_Uint8 *pu8IPAddr, WILC_Uint8 idx) +{ + + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + char firmwareIPAddress[4] = {0}; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler; + + if (pu8IPAddr[0] < 192) + pu8IPAddr[0] = 0; + + PRINT_INFO(HOSTINF_DBG, "Indx = %d, Handling set IP = %d.%d.%d.%d \n", idx, pu8IPAddr[0], pu8IPAddr[1], pu8IPAddr[2], pu8IPAddr[3]); + + WILC_memcpy(gs8SetIP[idx], pu8IPAddr, IP_ALEN); + + /*prepare configuration packet*/ + strWID.u16WIDid = (WILC_Uint16)WID_IP_ADDRESS; + strWID.enuWIDtype = WID_STR; + strWID.ps8WidVal = (WILC_Uint8 *)pu8IPAddr; + strWID.s32ValueSize = IP_ALEN; + + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + + + + host_int_get_ipaddress((WILC_WFIDrvHandle)drvHandler, firmwareIPAddress, idx); + + if (s32Error) { + PRINT_D(HOSTINF_DBG, "Failed to set IP address\n"); + WILC_ERRORREPORT(s32Error, WILC_INVALID_STATE); + } else { + PRINT_INFO(HOSTINF_DBG, "IP address set\n"); + } + + WILC_CATCH(s32Error) + { + + } + + return s32Error; +} + + +/** + * @brief Handle_get_IPAddress + * @details Setting IP address params in message queue + * @param[in] WILC_WFIDrvHandle hWFIDrv, WILC_Uint8* pu8IPAddr + * @return Error code. + * @author + * @date + * @version 1.0 + */ +WILC_Sint32 Handle_get_IPAddress(void *drvHandler, WILC_Uint8 *pu8IPAddr, WILC_Uint8 idx) +{ + + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler; + + /*prepare configuration packet*/ + strWID.u16WIDid = (WILC_Uint16)WID_IP_ADDRESS; + strWID.enuWIDtype = WID_STR; + strWID.ps8WidVal = (WILC_Uint8 *)WILC_MALLOC(IP_ALEN); + strWID.s32ValueSize = IP_ALEN; + + s32Error = SendConfigPkt(GET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + + PRINT_INFO(HOSTINF_DBG, "%d.%d.%d.%d\n", (WILC_Uint8)(strWID.ps8WidVal[0]), (WILC_Uint8)(strWID.ps8WidVal[1]), (WILC_Uint8)(strWID.ps8WidVal[2]), (WILC_Uint8)(strWID.ps8WidVal[3])); + + WILC_memcpy(gs8GetIP[idx], strWID.ps8WidVal, IP_ALEN); + + /*get the value by searching the local copy*/ + WILC_FREE(strWID.ps8WidVal); + + if (WILC_memcmp(gs8GetIP[idx], gs8SetIP[idx], IP_ALEN) != 0) + host_int_setup_ipaddress((WILC_WFIDrvHandle)pstrWFIDrv, gs8SetIP[idx], idx); + + if (s32Error != WILC_SUCCESS) { + PRINT_ER("Failed to get IP address\n"); + WILC_ERRORREPORT(s32Error, WILC_INVALID_STATE); + } else { + PRINT_INFO(HOSTINF_DBG, "IP address retrieved:: u8IfIdx = %d \n", idx); + PRINT_INFO(HOSTINF_DBG, "%d.%d.%d.%d\n", gs8GetIP[idx][0], gs8GetIP[idx][1], gs8GetIP[idx][2], gs8GetIP[idx][3]); + PRINT_INFO(HOSTINF_DBG, "\n"); + } + + WILC_CATCH(s32Error) + { + + } + + return s32Error; +} + + +/*BugId_5077*/ +/** + * @brief Handle_SetMacAddress + * @details Setting mac address + * @param[in] void * drvHandler,tstrHostIfSetDrvHandler* pstrHostIfSetDrvHandler + * @return Error code. + * @author Amr Abdel-Moghny + * @date November 2013 + * @version 7.0 + */ +static WILC_Sint32 Handle_SetMacAddress(void *drvHandler, tstrHostIfSetMacAddress *pstrHostIfSetMacAddress) +{ + + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler; + WILC_Uint8 *mac_buf = (WILC_Uint8 *)WILC_MALLOC(ETH_ALEN); + if (mac_buf == NULL) { + PRINT_ER("No buffer to send mac address\n"); + return WILC_FAIL; + } + WILC_memcpy(mac_buf, pstrHostIfSetMacAddress->u8MacAddress, ETH_ALEN); + + /*prepare configuration packet*/ + strWID.u16WIDid = (WILC_Uint16)WID_MAC_ADDR; + strWID.enuWIDtype = WID_STR; + strWID.ps8WidVal = mac_buf; + strWID.s32ValueSize = ETH_ALEN; + PRINT_D(GENERIC_DBG, "mac addr = :%x:%x:%x:%x:%x:%x\n", strWID.ps8WidVal[0], strWID.ps8WidVal[1], strWID.ps8WidVal[2], strWID.ps8WidVal[3], strWID.ps8WidVal[4], strWID.ps8WidVal[5]); + /*Sending Cfg*/ + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + if (s32Error) { + PRINT_ER("Failed to set mac address\n"); + WILC_ERRORREPORT(s32Error, WILC_FAIL); + } + + WILC_CATCH(s32Error) + { + + } + WILC_FREE(mac_buf); + return s32Error; +} + + +/*BugID_5213*/ +/** + * @brief Handle_GetMacAddress + * @details Getting mac address + * @param[in] void * drvHandler,tstrHostIfSetDrvHandler* pstrHostIfSetDrvHandler + * @return Error code. + * @author Amr Abdel-Moghny + * @date JAN 2013 + * @version 8.0 + */ +static WILC_Sint32 Handle_GetMacAddress(void *drvHandler, tstrHostIfGetMacAddress *pstrHostIfGetMacAddress) +{ + + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + + /*prepare configuration packet*/ + strWID.u16WIDid = (WILC_Uint16)WID_MAC_ADDR; + strWID.enuWIDtype = WID_STR; + strWID.ps8WidVal = pstrHostIfGetMacAddress->u8MacAddress; + strWID.s32ValueSize = ETH_ALEN; + + /*Sending Cfg*/ + s32Error = SendConfigPkt(GET_CFG, &strWID, 1, WILC_FALSE, (WILC_Uint32)drvHandler); + if (s32Error) { + PRINT_ER("Failed to get mac address\n"); + WILC_ERRORREPORT(s32Error, WILC_FAIL); + } + WILC_CATCH(s32Error) + { + + } + WILC_SemaphoreRelease(&hWaitResponse, NULL); + + return s32Error; +} + + +/** + * @brief Handle_CfgParam + * @details Sending config packet to firmware to set CFG params + * @param[in] tstrHostIFCfgParamAttr* strHostIFCfgParamAttr + * @return Error code. + * @author + * @date + * @version 1.0 + */ +static WILC_Sint32 Handle_CfgParam(void *drvHandler, tstrHostIFCfgParamAttr *strHostIFCfgParamAttr) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWIDList[32]; + WILC_Uint8 u8WidCnt = 0; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler; + + + WILC_SemaphoreAcquire(&(pstrWFIDrv->gtOsCfgValuesSem), NULL); + + + PRINT_D(HOSTINF_DBG, "Setting CFG params\n"); + + if (strHostIFCfgParamAttr->pstrCfgParamVal.u32SetCfgFlag & BSS_TYPE) { + /*----------------------------------------------------------*/ + /*Input Value: INFRASTRUCTURE = 1, */ + /* INDEPENDENT= 2, */ + /* ANY_BSS= 3 */ + /*----------------------------------------------------------*/ + /* validate input then copy>> need to check value 4 and 5 */ + if (strHostIFCfgParamAttr->pstrCfgParamVal.bss_type < 6) { + strWIDList[u8WidCnt].u16WIDid = WID_BSS_TYPE; + strWIDList[u8WidCnt].ps8WidVal = (WILC_Sint8 *)&strHostIFCfgParamAttr->pstrCfgParamVal.bss_type; + strWIDList[u8WidCnt].enuWIDtype = WID_CHAR; + strWIDList[u8WidCnt].s32ValueSize = sizeof(WILC_Char); + pstrWFIDrv->strCfgValues.bss_type = (WILC_Uint8)strHostIFCfgParamAttr->pstrCfgParamVal.bss_type; + } else { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + u8WidCnt++; + } + if (strHostIFCfgParamAttr->pstrCfgParamVal.u32SetCfgFlag & AUTH_TYPE) { + /*------------------------------------------------------*/ + /*Input Values: OPEN_SYSTEM = 0, */ + /* SHARED_KEY = 1, */ + /* ANY = 2 */ + /*------------------------------------------------------*/ + /*validate Possible values*/ + if ((strHostIFCfgParamAttr->pstrCfgParamVal.auth_type) == 1 || (strHostIFCfgParamAttr->pstrCfgParamVal.auth_type) == 2 || (strHostIFCfgParamAttr->pstrCfgParamVal.auth_type) == 5) { + strWIDList[u8WidCnt].u16WIDid = WID_AUTH_TYPE; + strWIDList[u8WidCnt].ps8WidVal = (WILC_Sint8 *)&strHostIFCfgParamAttr->pstrCfgParamVal.auth_type; + strWIDList[u8WidCnt].enuWIDtype = WID_CHAR; + strWIDList[u8WidCnt].s32ValueSize = sizeof(WILC_Char); + pstrWFIDrv->strCfgValues.auth_type = (WILC_Uint8)strHostIFCfgParamAttr->pstrCfgParamVal.auth_type; + } else { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + u8WidCnt++; + } + if (strHostIFCfgParamAttr->pstrCfgParamVal.u32SetCfgFlag & AUTHEN_TIMEOUT) { + /* range is 1 to 65535. */ + if (strHostIFCfgParamAttr->pstrCfgParamVal.auth_timeout > 0 && strHostIFCfgParamAttr->pstrCfgParamVal.auth_timeout < 65536) { + strWIDList[u8WidCnt].u16WIDid = WID_AUTH_TIMEOUT; + strWIDList[u8WidCnt].ps8WidVal = (WILC_Sint8 *)&strHostIFCfgParamAttr->pstrCfgParamVal.auth_timeout; + strWIDList[u8WidCnt].enuWIDtype = WID_SHORT; + strWIDList[u8WidCnt].s32ValueSize = sizeof(WILC_Uint16); + pstrWFIDrv->strCfgValues.auth_timeout = strHostIFCfgParamAttr->pstrCfgParamVal.auth_timeout; + } else { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + u8WidCnt++; + } + if (strHostIFCfgParamAttr->pstrCfgParamVal.u32SetCfgFlag & POWER_MANAGEMENT) { + /*-----------------------------------------------------------*/ + /*Input Values: NO_POWERSAVE = 0, */ + /* MIN_FAST_PS = 1, */ + /* MAX_FAST_PS = 2, */ + /* MIN_PSPOLL_PS = 3, */ + /* MAX_PSPOLL_PS = 4 */ + /*----------------------------------------------------------*/ + if (strHostIFCfgParamAttr->pstrCfgParamVal.power_mgmt_mode < 5) { + strWIDList[u8WidCnt].u16WIDid = WID_POWER_MANAGEMENT; + strWIDList[u8WidCnt].ps8WidVal = (WILC_Sint8 *)&strHostIFCfgParamAttr->pstrCfgParamVal.power_mgmt_mode; + strWIDList[u8WidCnt].enuWIDtype = WID_CHAR; + strWIDList[u8WidCnt].s32ValueSize = sizeof(WILC_Char); + pstrWFIDrv->strCfgValues.power_mgmt_mode = (WILC_Uint8)strHostIFCfgParamAttr->pstrCfgParamVal.power_mgmt_mode; + } else { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + u8WidCnt++; + } + if (strHostIFCfgParamAttr->pstrCfgParamVal.u32SetCfgFlag & RETRY_SHORT) { + /* range from 1 to 256 */ + if ((strHostIFCfgParamAttr->pstrCfgParamVal.short_retry_limit > 0) && (strHostIFCfgParamAttr->pstrCfgParamVal.short_retry_limit < 256)) { + strWIDList[u8WidCnt].u16WIDid = WID_SHORT_RETRY_LIMIT; + strWIDList[u8WidCnt].ps8WidVal = (WILC_Sint8 *)&strHostIFCfgParamAttr->pstrCfgParamVal.short_retry_limit; + strWIDList[u8WidCnt].enuWIDtype = WID_SHORT; + strWIDList[u8WidCnt].s32ValueSize = sizeof(WILC_Uint16); + pstrWFIDrv->strCfgValues.short_retry_limit = strHostIFCfgParamAttr->pstrCfgParamVal.short_retry_limit; + } else { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + u8WidCnt++; + } + if (strHostIFCfgParamAttr->pstrCfgParamVal.u32SetCfgFlag & RETRY_LONG) { + /* range from 1 to 256 */ + if ((strHostIFCfgParamAttr->pstrCfgParamVal.long_retry_limit > 0) && (strHostIFCfgParamAttr->pstrCfgParamVal.long_retry_limit < 256)) { + strWIDList[u8WidCnt].u16WIDid = WID_LONG_RETRY_LIMIT; + strWIDList[u8WidCnt].ps8WidVal = (WILC_Sint8 *)&strHostIFCfgParamAttr->pstrCfgParamVal.long_retry_limit; + + strWIDList[u8WidCnt].enuWIDtype = WID_SHORT; + strWIDList[u8WidCnt].s32ValueSize = sizeof(WILC_Uint16); + pstrWFIDrv->strCfgValues.long_retry_limit = strHostIFCfgParamAttr->pstrCfgParamVal.long_retry_limit; + } else { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + u8WidCnt++; + } + if (strHostIFCfgParamAttr->pstrCfgParamVal.u32SetCfgFlag & FRAG_THRESHOLD) { + + if (strHostIFCfgParamAttr->pstrCfgParamVal.frag_threshold > 255 && strHostIFCfgParamAttr->pstrCfgParamVal.frag_threshold < 7937) { + strWIDList[u8WidCnt].u16WIDid = WID_FRAG_THRESHOLD; + strWIDList[u8WidCnt].ps8WidVal = (WILC_Sint8 *)&strHostIFCfgParamAttr->pstrCfgParamVal.frag_threshold; + strWIDList[u8WidCnt].enuWIDtype = WID_SHORT; + strWIDList[u8WidCnt].s32ValueSize = sizeof(WILC_Uint16); + pstrWFIDrv->strCfgValues.frag_threshold = strHostIFCfgParamAttr->pstrCfgParamVal.frag_threshold; + } else { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + u8WidCnt++; + } + if (strHostIFCfgParamAttr->pstrCfgParamVal.u32SetCfgFlag & RTS_THRESHOLD) { + /* range 256 to 65535 */ + if (strHostIFCfgParamAttr->pstrCfgParamVal.rts_threshold > 255 && strHostIFCfgParamAttr->pstrCfgParamVal.rts_threshold < 65536) { + strWIDList[u8WidCnt].u16WIDid = WID_RTS_THRESHOLD; + strWIDList[u8WidCnt].ps8WidVal = (WILC_Sint8 *)&strHostIFCfgParamAttr->pstrCfgParamVal.rts_threshold; + strWIDList[u8WidCnt].enuWIDtype = WID_SHORT; + strWIDList[u8WidCnt].s32ValueSize = sizeof(WILC_Uint16); + pstrWFIDrv->strCfgValues.rts_threshold = strHostIFCfgParamAttr->pstrCfgParamVal.rts_threshold; + } else { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + u8WidCnt++; + } + if (strHostIFCfgParamAttr->pstrCfgParamVal.u32SetCfgFlag & PREAMBLE) { + /*-----------------------------------------------------*/ + /*Input Values: Short= 0, */ + /* Long= 1, */ + /* Auto= 2 */ + /*------------------------------------------------------*/ + if (strHostIFCfgParamAttr->pstrCfgParamVal.preamble_type < 3) { + strWIDList[u8WidCnt].u16WIDid = WID_PREAMBLE; + strWIDList[u8WidCnt].ps8WidVal = (WILC_Sint8 *)&strHostIFCfgParamAttr->pstrCfgParamVal.preamble_type; + strWIDList[u8WidCnt].enuWIDtype = WID_CHAR; + strWIDList[u8WidCnt].s32ValueSize = sizeof(WILC_Char); + pstrWFIDrv->strCfgValues.preamble_type = strHostIFCfgParamAttr->pstrCfgParamVal.preamble_type; + } else { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + u8WidCnt++; + } + if (strHostIFCfgParamAttr->pstrCfgParamVal.u32SetCfgFlag & SHORT_SLOT_ALLOWED) { + if (strHostIFCfgParamAttr->pstrCfgParamVal.short_slot_allowed < 2) { + strWIDList[u8WidCnt].u16WIDid = WID_SHORT_SLOT_ALLOWED; + strWIDList[u8WidCnt].ps8WidVal = (WILC_Sint8 *)&strHostIFCfgParamAttr->pstrCfgParamVal.short_slot_allowed; + strWIDList[u8WidCnt].enuWIDtype = WID_CHAR; + strWIDList[u8WidCnt].s32ValueSize = sizeof(WILC_Char); + pstrWFIDrv->strCfgValues.short_slot_allowed = (WILC_Uint8)strHostIFCfgParamAttr->pstrCfgParamVal.short_slot_allowed; + } else { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + u8WidCnt++; + } + if (strHostIFCfgParamAttr->pstrCfgParamVal.u32SetCfgFlag & TXOP_PROT_DISABLE) { + /*Description: used to Disable RTS-CTS protection for TXOP burst*/ + /*transmission when the acknowledgement policy is No-Ack or Block-Ack */ + /* this information is useful for external supplicant */ + /*Input Values: 1 for enable and 0 for disable. */ + if (strHostIFCfgParamAttr->pstrCfgParamVal.txop_prot_disabled < 2) { + strWIDList[u8WidCnt].u16WIDid = WID_11N_TXOP_PROT_DISABLE; + strWIDList[u8WidCnt].ps8WidVal = (WILC_Sint8 *)&strHostIFCfgParamAttr->pstrCfgParamVal.txop_prot_disabled; + strWIDList[u8WidCnt].enuWIDtype = WID_CHAR; + strWIDList[u8WidCnt].s32ValueSize = sizeof(WILC_Char); + pstrWFIDrv->strCfgValues.txop_prot_disabled = (WILC_Uint8)strHostIFCfgParamAttr->pstrCfgParamVal.txop_prot_disabled; + } else { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + u8WidCnt++; + } + if (strHostIFCfgParamAttr->pstrCfgParamVal.u32SetCfgFlag & BEACON_INTERVAL) { + /* range is 1 to 65535. */ + if (strHostIFCfgParamAttr->pstrCfgParamVal.beacon_interval > 0 && strHostIFCfgParamAttr->pstrCfgParamVal.beacon_interval < 65536) { + strWIDList[u8WidCnt].u16WIDid = WID_BEACON_INTERVAL; + strWIDList[u8WidCnt].ps8WidVal = (WILC_Sint8 *)&strHostIFCfgParamAttr->pstrCfgParamVal.beacon_interval; + strWIDList[u8WidCnt].enuWIDtype = WID_SHORT; + strWIDList[u8WidCnt].s32ValueSize = sizeof(WILC_Uint16); + pstrWFIDrv->strCfgValues.beacon_interval = strHostIFCfgParamAttr->pstrCfgParamVal.beacon_interval; + } else { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + u8WidCnt++; + } + if (strHostIFCfgParamAttr->pstrCfgParamVal.u32SetCfgFlag & DTIM_PERIOD) { + /* range is 1 to 255. */ + if (strHostIFCfgParamAttr->pstrCfgParamVal.dtim_period > 0 && strHostIFCfgParamAttr->pstrCfgParamVal.dtim_period < 256) { + strWIDList[u8WidCnt].u16WIDid = WID_DTIM_PERIOD; + strWIDList[u8WidCnt].ps8WidVal = (WILC_Sint8 *)&strHostIFCfgParamAttr->pstrCfgParamVal.dtim_period; + strWIDList[u8WidCnt].enuWIDtype = WID_CHAR; + strWIDList[u8WidCnt].s32ValueSize = sizeof(WILC_Char); + pstrWFIDrv->strCfgValues.dtim_period = strHostIFCfgParamAttr->pstrCfgParamVal.dtim_period; + } else { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + u8WidCnt++; + } + if (strHostIFCfgParamAttr->pstrCfgParamVal.u32SetCfgFlag & SITE_SURVEY) { + /*----------------------------------------------------------------------*/ + /*Input Values: SITE_SURVEY_1CH = 0, i.e.: currently set channel */ + /* SITE_SURVEY_ALL_CH = 1, */ + /* SITE_SURVEY_OFF = 2 */ + /*----------------------------------------------------------------------*/ + if (strHostIFCfgParamAttr->pstrCfgParamVal.site_survey_enabled < 3) { + strWIDList[u8WidCnt].u16WIDid = WID_SITE_SURVEY; + strWIDList[u8WidCnt].ps8WidVal = (WILC_Sint8 *)&strHostIFCfgParamAttr->pstrCfgParamVal.site_survey_enabled; + strWIDList[u8WidCnt].enuWIDtype = WID_CHAR; + strWIDList[u8WidCnt].s32ValueSize = sizeof(WILC_Char); + pstrWFIDrv->strCfgValues.site_survey_enabled = (WILC_Uint8)strHostIFCfgParamAttr->pstrCfgParamVal.site_survey_enabled; + } else { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + u8WidCnt++; + } + if (strHostIFCfgParamAttr->pstrCfgParamVal.u32SetCfgFlag & SITE_SURVEY_SCAN_TIME) { + /* range is 1 to 65535. */ + if (strHostIFCfgParamAttr->pstrCfgParamVal.site_survey_scan_time > 0 && strHostIFCfgParamAttr->pstrCfgParamVal.site_survey_scan_time < 65536) { + strWIDList[u8WidCnt].u16WIDid = WID_SITE_SURVEY_SCAN_TIME; + strWIDList[u8WidCnt].ps8WidVal = (WILC_Sint8 *)&strHostIFCfgParamAttr->pstrCfgParamVal.site_survey_scan_time; + strWIDList[u8WidCnt].enuWIDtype = WID_SHORT; + strWIDList[u8WidCnt].s32ValueSize = sizeof(WILC_Uint16); + pstrWFIDrv->strCfgValues.site_survey_scan_time = strHostIFCfgParamAttr->pstrCfgParamVal.site_survey_scan_time; + } else { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + u8WidCnt++; + } + if (strHostIFCfgParamAttr->pstrCfgParamVal.u32SetCfgFlag & ACTIVE_SCANTIME) { + /* range is 1 to 65535. */ + if (strHostIFCfgParamAttr->pstrCfgParamVal.active_scan_time > 0 && strHostIFCfgParamAttr->pstrCfgParamVal.active_scan_time < 65536) { + strWIDList[u8WidCnt].u16WIDid = WID_ACTIVE_SCAN_TIME; + strWIDList[u8WidCnt].ps8WidVal = (WILC_Sint8 *)&strHostIFCfgParamAttr->pstrCfgParamVal.active_scan_time; + strWIDList[u8WidCnt].enuWIDtype = WID_SHORT; + strWIDList[u8WidCnt].s32ValueSize = sizeof(WILC_Uint16); + pstrWFIDrv->strCfgValues.active_scan_time = strHostIFCfgParamAttr->pstrCfgParamVal.active_scan_time; + } else { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + u8WidCnt++; + } + if (strHostIFCfgParamAttr->pstrCfgParamVal.u32SetCfgFlag & PASSIVE_SCANTIME) { + /* range is 1 to 65535. */ + if (strHostIFCfgParamAttr->pstrCfgParamVal.passive_scan_time > 0 && strHostIFCfgParamAttr->pstrCfgParamVal.passive_scan_time < 65536) { + strWIDList[u8WidCnt].u16WIDid = WID_PASSIVE_SCAN_TIME; + strWIDList[u8WidCnt].ps8WidVal = (WILC_Sint8 *)&strHostIFCfgParamAttr->pstrCfgParamVal.passive_scan_time; + strWIDList[u8WidCnt].enuWIDtype = WID_SHORT; + strWIDList[u8WidCnt].s32ValueSize = sizeof(WILC_Uint16); + pstrWFIDrv->strCfgValues.passive_scan_time = strHostIFCfgParamAttr->pstrCfgParamVal.passive_scan_time; + } else { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + u8WidCnt++; + } + if (strHostIFCfgParamAttr->pstrCfgParamVal.u32SetCfgFlag & CURRENT_TX_RATE) { + CURRENT_TX_RATE_T curr_tx_rate = strHostIFCfgParamAttr->pstrCfgParamVal.curr_tx_rate; + /*----------------------------------------------------------------------*/ + /*Rates: 1 2 5.5 11 6 9 12 18 24 36 48 54 Auto */ + /*InputValues: 1 2 3 4 5 6 7 8 9 10 11 12 0 */ + /*----------------------------------------------------------------------*/ + /* validate rate */ + if (curr_tx_rate == AUTORATE || curr_tx_rate == MBPS_1 + || curr_tx_rate == MBPS_2 || curr_tx_rate == MBPS_5_5 + || curr_tx_rate == MBPS_11 || curr_tx_rate == MBPS_6 + || curr_tx_rate == MBPS_9 || curr_tx_rate == MBPS_12 + || curr_tx_rate == MBPS_18 || curr_tx_rate == MBPS_24 + || curr_tx_rate == MBPS_36 || curr_tx_rate == MBPS_48 || curr_tx_rate == MBPS_54) { + strWIDList[u8WidCnt].u16WIDid = WID_CURRENT_TX_RATE; + strWIDList[u8WidCnt].ps8WidVal = (WILC_Sint8 *)&curr_tx_rate; + strWIDList[u8WidCnt].enuWIDtype = WID_SHORT; + strWIDList[u8WidCnt].s32ValueSize = sizeof(WILC_Uint16); + pstrWFIDrv->strCfgValues.curr_tx_rate = (WILC_Uint8)curr_tx_rate; + } else { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + u8WidCnt++; + } + s32Error = SendConfigPkt(SET_CFG, strWIDList, u8WidCnt, WILC_FALSE, (WILC_Uint32)pstrWFIDrv); + + if (s32Error) { + PRINT_ER("Error in setting CFG params\n"); + + } + WILC_CATCH(s32Error) + { + } + WILC_SemaphoreRelease(&(pstrWFIDrv->gtOsCfgValuesSem), NULL); + return s32Error; +} + + +/** + * @brief Handle_wait_msg_q_empty + * @details this should be the last msg and then the msg Q becomes idle + * @param[in] tstrHostIFscanAttr* pstrHostIFscanAttr + * @return Error code. + * @author + * @date + * @version 1.0 + */ +static WILC_Sint32 Handle_wait_msg_q_empty(void) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + g_wilc_initialized = 0; + WILC_SemaphoreRelease(&hWaitResponse, NULL); + return s32Error; +} + +/** + * @brief Handle_Scan + * @details Sending config packet to firmware to set the scan params + * @param[in] tstrHostIFscanAttr* pstrHostIFscanAttr + * @return Error code. + * @author + * @date + * @version 1.0 + */ +static WILC_Sint32 Handle_Scan(void *drvHandler, tstrHostIFscanAttr *pstrHostIFscanAttr) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWIDList[5]; + WILC_Uint32 u32WidsCount = 0; + WILC_Uint32 i; + WILC_Uint8 *pu8Buffer; + WILC_Uint8 valuesize = 0; + WILC_Uint8 *pu8HdnNtwrksWidVal = NULL; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *) drvHandler; + + PRINT_D(HOSTINF_DBG, "Setting SCAN params\n"); + PRINT_D(HOSTINF_DBG, "Scanning: In [%d] state \n", pstrWFIDrv->enuHostIFstate); + + pstrWFIDrv->strWILC_UsrScanReq.pfUserScanResult = pstrHostIFscanAttr->pfScanResult; + pstrWFIDrv->strWILC_UsrScanReq.u32UserScanPvoid = pstrHostIFscanAttr->pvUserArg; + + #ifdef WILC_P2P + #if 0 + if (pstrWFIDrv->enuHostIFstate == HOST_IF_P2P_LISTEN || (pstrWFIDrv->enuHostIFstate == HOST_IF_CONNECTED && pstrWFIDrv->u8P2PConnect)) { + PRINT_INFO(GENERIC_DBG, "Busy: State: %d\n", pstrWFIDrv->enuHostIFstate); + PRINT_INFO(GENERIC_DBG, "Current Jiffies: %lu Timeout:%llu\n", jiffies, pstrWFIDrv->u64P2p_MgmtTimeout); + WILC_ERRORREPORT(s32Error, WILC_BUSY); + } + #endif + #endif + + if ((pstrWFIDrv->enuHostIFstate >= HOST_IF_SCANNING) && (pstrWFIDrv->enuHostIFstate < HOST_IF_CONNECTED)) { + /* here we either in HOST_IF_SCANNING, HOST_IF_WAITING_CONN_REQ or HOST_IF_WAITING_CONN_RESP */ + PRINT_D(GENERIC_DBG, "Don't scan we are already in [%d] state\n", pstrWFIDrv->enuHostIFstate); + WILC_ERRORREPORT(s32Error, WILC_BUSY); + } + + #ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP + if (g_obtainingIP || connecting) { + PRINT_D(GENERIC_DBG, "[handle_scan]: Don't do obss scan until IP adresss is obtained\n"); + WILC_ERRORREPORT(s32Error, WILC_BUSY); + } + #endif + + PRINT_D(HOSTINF_DBG, "Setting SCAN params\n"); + + + pstrWFIDrv->strWILC_UsrScanReq.u32RcvdChCount = 0; + + /*BugID_4189*/ + strWIDList[u32WidsCount].u16WIDid = (WILC_Uint16)WID_SSID_PROBE_REQ; + strWIDList[u32WidsCount].enuWIDtype = WID_STR; + + for (i = 0; i < pstrHostIFscanAttr->strHiddenNetwork.u8ssidnum; i++) { + valuesize += ((pstrHostIFscanAttr->strHiddenNetwork.pstrHiddenNetworkInfo[i].u8ssidlen) + 1); + } + pu8HdnNtwrksWidVal = WILC_MALLOC(valuesize + 1); + strWIDList[u32WidsCount].ps8WidVal = pu8HdnNtwrksWidVal; + if (strWIDList[u32WidsCount].ps8WidVal != WILC_NULL) { + pu8Buffer = strWIDList[u32WidsCount].ps8WidVal; + + *pu8Buffer++ = pstrHostIFscanAttr->strHiddenNetwork.u8ssidnum; + + PRINT_D(HOSTINF_DBG, "In Handle_ProbeRequest number of ssid %d\n", pstrHostIFscanAttr->strHiddenNetwork.u8ssidnum); + + for (i = 0; i < pstrHostIFscanAttr->strHiddenNetwork.u8ssidnum; i++) { + *pu8Buffer++ = pstrHostIFscanAttr->strHiddenNetwork.pstrHiddenNetworkInfo[i].u8ssidlen; + WILC_memcpy(pu8Buffer, pstrHostIFscanAttr->strHiddenNetwork.pstrHiddenNetworkInfo[i].pu8ssid, pstrHostIFscanAttr->strHiddenNetwork.pstrHiddenNetworkInfo[i].u8ssidlen); + pu8Buffer += pstrHostIFscanAttr->strHiddenNetwork.pstrHiddenNetworkInfo[i].u8ssidlen; + } + + + + strWIDList[u32WidsCount].s32ValueSize = (WILC_Sint32)(valuesize + 1); + u32WidsCount++; + } + + /*filling cfg param array*/ + + /* if((pstrHostIFscanAttr->pu8IEs != NULL) && (pstrHostIFscanAttr->IEsLen != 0)) */ + { + /* IEs to be inserted in Probe Request */ + strWIDList[u32WidsCount].u16WIDid = WID_INFO_ELEMENT_PROBE; + strWIDList[u32WidsCount].enuWIDtype = WID_BIN_DATA; + strWIDList[u32WidsCount].ps8WidVal = pstrHostIFscanAttr->pu8IEs; + strWIDList[u32WidsCount].s32ValueSize = pstrHostIFscanAttr->IEsLen; + u32WidsCount++; + } + + /*Scan Type*/ + strWIDList[u32WidsCount].u16WIDid = WID_SCAN_TYPE; + strWIDList[u32WidsCount].enuWIDtype = WID_CHAR; + strWIDList[u32WidsCount].s32ValueSize = sizeof(WILC_Char); + strWIDList[u32WidsCount].ps8WidVal = (WILC_Sint8 *)(&(pstrHostIFscanAttr->u8ScanType)); + u32WidsCount++; + + /*list of channels to be scanned*/ + strWIDList[u32WidsCount].u16WIDid = WID_SCAN_CHANNEL_LIST; + strWIDList[u32WidsCount].enuWIDtype = WID_BIN_DATA; + + /* Bug 4648: Convert channel numbers to start from 0 not 1. */ + if (pstrHostIFscanAttr->pu8ChnlFreqList != NULL && pstrHostIFscanAttr->u8ChnlListLen > 0) { + int i; + + for (i = 0; i < pstrHostIFscanAttr->u8ChnlListLen; i++) { + if (pstrHostIFscanAttr->pu8ChnlFreqList[i] > 0) { + pstrHostIFscanAttr->pu8ChnlFreqList[i] = pstrHostIFscanAttr->pu8ChnlFreqList[i] - 1; + } + } + } + + strWIDList[u32WidsCount].ps8WidVal = pstrHostIFscanAttr->pu8ChnlFreqList; + strWIDList[u32WidsCount].s32ValueSize = pstrHostIFscanAttr->u8ChnlListLen; + u32WidsCount++; + + /*Scan Request*/ + strWIDList[u32WidsCount].u16WIDid = WID_START_SCAN_REQ; + strWIDList[u32WidsCount].enuWIDtype = WID_CHAR; + strWIDList[u32WidsCount].s32ValueSize = sizeof(WILC_Char); + strWIDList[u32WidsCount].ps8WidVal = (WILC_Sint8 *)(&(pstrHostIFscanAttr->u8ScanSource)); + u32WidsCount++; + + /*keep the state as is , no need to change it*/ + /* gWFiDrvHandle->enuHostIFstate = HOST_IF_SCANNING; */ + + if (pstrWFIDrv->enuHostIFstate == HOST_IF_CONNECTED) { + gbScanWhileConnected = WILC_TRUE; + } else if (pstrWFIDrv->enuHostIFstate == HOST_IF_IDLE) { + gbScanWhileConnected = WILC_FALSE; + } + + s32Error = SendConfigPkt(SET_CFG, strWIDList, u32WidsCount, WILC_FALSE, (WILC_Uint32)pstrWFIDrv); + + if (s32Error) { + PRINT_ER("Failed to send scan paramters config packet\n"); + WILC_ERRORREPORT(s32Error, s32Error); + } else { + PRINT_D(HOSTINF_DBG, "Successfully sent SCAN params config packet\n"); + } + + WILC_CATCH(s32Error) + { + WILC_TimerStop(&(pstrWFIDrv->hScanTimer), WILC_NULL); + /*if there is an ongoing scan request*/ + Handle_ScanDone(drvHandler, SCAN_EVENT_ABORTED); + } + + /* Deallocate pstrHostIFscanAttr->u8ChnlListLen which was prevoisuly allocated by the sending thread */ + if (pstrHostIFscanAttr->pu8ChnlFreqList != NULL) { + WILC_FREE(pstrHostIFscanAttr->pu8ChnlFreqList); + pstrHostIFscanAttr->pu8ChnlFreqList = NULL; + } + + /* Deallocate pstrHostIFscanAttr->pu8IEs which was previously allocated by the sending thread */ + if (pstrHostIFscanAttr->pu8IEs != NULL) { + WILC_FREE(pstrHostIFscanAttr->pu8IEs); + pstrHostIFscanAttr->pu8IEs = NULL; + } + if (pstrHostIFscanAttr->strHiddenNetwork.pstrHiddenNetworkInfo != NULL) { + WILC_FREE(pstrHostIFscanAttr->strHiddenNetwork.pstrHiddenNetworkInfo); + pstrHostIFscanAttr->strHiddenNetwork.pstrHiddenNetworkInfo = NULL; + } + + /* Deallocate pstrHostIFscanAttr->u8ChnlListLen which was prevoisuly allocated by the sending thread */ + if (pstrHostIFscanAttr->pu8ChnlFreqList != NULL) { + WILC_FREE(pstrHostIFscanAttr->pu8ChnlFreqList); + pstrHostIFscanAttr->pu8ChnlFreqList = NULL; + } + + if (pu8HdnNtwrksWidVal != NULL) { + WILC_FREE(pu8HdnNtwrksWidVal); + } + + return s32Error; +} + +/** + * @brief Handle_ScanDone + * @details Call scan notification callback function + * @param[in] NONE + * @return Error code. + * @author + * @date + * @version 1.0 + */ +static WILC_Sint32 Handle_ScanDone(void *drvHandler, tenuScanEvent enuEvent) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler; + + + WILC_Uint8 u8abort_running_scan; + tstrWID strWID; + + + PRINT_D(HOSTINF_DBG, "in Handle_ScanDone()\n"); + + /*BugID_4978*/ + /*Ask FW to abort the running scan, if any*/ + if (enuEvent == SCAN_EVENT_ABORTED) { + PRINT_D(GENERIC_DBG, "Abort running scan\n"); + u8abort_running_scan = 1; + strWID.u16WIDid = (WILC_Uint16)WID_ABORT_RUNNING_SCAN; + strWID.enuWIDtype = WID_CHAR; + strWID.ps8WidVal = (WILC_Sint8 *)&u8abort_running_scan; + strWID.s32ValueSize = sizeof(WILC_Char); + + /*Sending Cfg*/ + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + if (s32Error != WILC_SUCCESS) { + PRINT_ER("Failed to set abort running scan\n"); + WILC_ERRORREPORT(s32Error, WILC_FAIL); + } + WILC_CATCH(s32Error) + { + } + } + + if (pstrWFIDrv == NULL) { + PRINT_ER("Driver handler is NULL\n"); + return s32Error; + } + + /*if there is an ongoing scan request*/ + if (pstrWFIDrv->strWILC_UsrScanReq.pfUserScanResult) { + pstrWFIDrv->strWILC_UsrScanReq.pfUserScanResult(enuEvent, WILC_NULL, + pstrWFIDrv->strWILC_UsrScanReq.u32UserScanPvoid, NULL); + /*delete current scan request*/ + pstrWFIDrv->strWILC_UsrScanReq.pfUserScanResult = NULL; + } + + return s32Error; +} + +/** + * @brief Handle_Connect + * @details Sending config packet to firmware to starting connection + * @param[in] tstrHostIFconnectAttr* pstrHostIFconnectAttr + * @return Error code. + * @author + * @date + * @version 1.0 + */ +WILC_Uint8 u8ConnectedSSID[6] = {0}; +static WILC_Sint32 Handle_Connect(void *drvHandler, tstrHostIFconnectAttr *pstrHostIFconnectAttr) +{ + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *) drvHandler; + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWIDList[8]; + WILC_Uint32 u32WidsCount = 0, dummyval = 0; + /* char passphrase[] = "12345678"; */ + #ifndef CONNECT_DIRECT + WILC_Sint32 s32Err = WILC_SUCCESS; + WILC_Uint32 i; + WILC_Uint8 u8bssDscListIndex; + wid_site_survey_reslts_s *pstrSurveyResults = WILC_NULL; + #else + WILC_Uint8 *pu8CurrByte = WILC_NULL; + /*Bug4218: Parsing Join Param*/ + #ifdef WILC_PARSE_SCAN_IN_HOST + tstrJoinBssParam *ptstrJoinBssParam; + #endif /*WILC_PARSE_SCAN_IN_HOST*/ + + #endif + + PRINT_D(GENERIC_DBG, "Handling connect request\n"); + + #ifndef CONNECT_DIRECT + WILC_memset(gapu8RcvdSurveyResults[0], 0, MAX_SURVEY_RESULT_FRAG_SIZE); + WILC_memset(gapu8RcvdSurveyResults[1], 0, MAX_SURVEY_RESULT_FRAG_SIZE); + + + PRINT_D(HOSTINF_DBG, "Getting site survey results\n"); + s32Err = host_int_get_site_survey_results((WILC_WFIDrvHandle)pstrWFIDrv, + gapu8RcvdSurveyResults, + MAX_SURVEY_RESULT_FRAG_SIZE); + if (s32Err) { + PRINT_ER("Failed to get site survey results\n"); + WILC_ERRORREPORT(s32Error, WILC_FAIL); + + } + s32Err = ParseSurveyResults(gapu8RcvdSurveyResults, &pstrSurveyResults, + &pstrWFIDrv->u32SurveyResultsCount); + + + if (s32Err == WILC_SUCCESS) { + /* use the parsed info in pstrSurveyResults, then deallocate it */ + PRINT_D(HOSTINF_DBG, "Copying site survey results in global structure, then deallocate\n"); + for (i = 0; i < pstrWFIDrv->u32SurveyResultsCount; i++) { + WILC_memcpy(&pstrWFIDrv->astrSurveyResults[i], &pstrSurveyResults[i], + sizeof(wid_site_survey_reslts_s)); + } + + DeallocateSurveyResults(pstrSurveyResults); + } else { + WILC_ERRORREPORT(s32Error, WILC_FAIL); + PRINT_ER("ParseSurveyResults() Error(%d) \n", s32Err); + } + + + for (i = 0; i < pstrWFIDrv->u32SurveyResultsCount; i++) { + if (WILC_memcmp(pstrWFIDrv->astrSurveyResults[i].SSID, + pstrHostIFconnectAttr->pu8ssid, + pstrHostIFconnectAttr->ssidLen) == 0) { + PRINT_INFO(HOSTINF_DBG, "Network with required SSID is found %s\n", pstrHostIFconnectAttr->pu8ssid); + if (pstrHostIFconnectAttr->pu8bssid == NULL) { + /* BSSID is not passed from the user, so decision of matching + * is done by SSID only */ + PRINT_INFO(HOSTINF_DBG, "BSSID is not passed from the user\n"); + break; + } else { + /* BSSID is also passed from the user, so decision of matching + * should consider also this passed BSSID */ + + if (WILC_memcmp(pstrWFIDrv->astrSurveyResults[i].BSSID, + pstrHostIFconnectAttr->pu8bssid, + 6) == 0) { + PRINT_INFO(HOSTINF_DBG, "BSSID is passed from the user and matched\n"); + break; + } + } + } + } + + if (i < pstrWFIDrv->u32SurveyResultsCount) { + u8bssDscListIndex = i; + + PRINT_INFO(HOSTINF_DBG, "Connecting to network of Bss Idx %d and SSID %s and channel %d \n", + u8bssDscListIndex, pstrWFIDrv->astrSurveyResults[u8bssDscListIndex].SSID, + pstrWFIDrv->astrSurveyResults[u8bssDscListIndex].Channel); + + PRINT_INFO(HOSTINF_DBG, "Saving connection parameters in global structure\n"); + + if (pstrHostIFconnectAttr->pu8bssid != NULL) { + pstrWFIDrv->strWILC_UsrConnReq.pu8bssid = (WILC_Uint8 *)WILC_MALLOC(6); + WILC_memcpy(pstrWFIDrv->strWILC_UsrConnReq.pu8bssid, pstrHostIFconnectAttr->pu8bssid, 6); + } + + pstrWFIDrv->strWILC_UsrConnReq.ssidLen = pstrHostIFconnectAttr->ssidLen; + if (pstrHostIFconnectAttr->pu8ssid != NULL) { + pstrWFIDrv->strWILC_UsrConnReq.pu8ssid = (WILC_Uint8 *)WILC_MALLOC(pstrHostIFconnectAttr->ssidLen + 1); + WILC_memcpy(pstrWFIDrv->strWILC_UsrConnReq.pu8ssid, pstrHostIFconnectAttr->pu8ssid, + pstrHostIFconnectAttr->ssidLen); + pstrWFIDrv->strWILC_UsrConnReq.pu8ssid[pstrHostIFconnectAttr->ssidLen] = '\0'; + } + + pstrWFIDrv->strWILC_UsrConnReq.ConnReqIEsLen = pstrHostIFconnectAttr->IEsLen; + if (pstrHostIFconnectAttr->pu8IEs != NULL) { + pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs = (WILC_Uint8 *)WILC_MALLOC(pstrHostIFconnectAttr->IEsLen); + WILC_memcpy(pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs, pstrHostIFconnectAttr->pu8IEs, + pstrHostIFconnectAttr->IEsLen); + } + + pstrWFIDrv->strWILC_UsrConnReq.u8security = pstrHostIFconnectAttr->u8security; + pstrWFIDrv->strWILC_UsrConnReq.tenuAuth_type = pstrHostIFconnectAttr->tenuAuth_type; + pstrWFIDrv->strWILC_UsrConnReq.pfUserConnectResult = pstrHostIFconnectAttr->pfConnectResult; + pstrWFIDrv->strWILC_UsrConnReq.u32UserConnectPvoid = pstrHostIFconnectAttr->pvUserArg; + + + /* if((gWFiDrvHandle->strWILC_UsrConnReq.pu8ConnReqIEs != NULL) && */ + /* (gWFiDrvHandle->strWILC_UsrConnReq.ConnReqIEsLen != 0)) */ + { + /* IEs to be inserted in Association Request */ + strWIDList[u32WidsCount].u16WIDid = WID_INFO_ELEMENT_ASSOCIATE; + strWIDList[u32WidsCount].enuWIDtype = WID_BIN_DATA; + strWIDList[u32WidsCount].ps8WidVal = pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs; + strWIDList[u32WidsCount].s32ValueSize = pstrWFIDrv->strWILC_UsrConnReq.ConnReqIEsLen; + u32WidsCount++; + } + strWIDList[u32WidsCount].u16WIDid = (WILC_Uint16)WID_11I_MODE; + strWIDList[u32WidsCount].enuWIDtype = WID_CHAR; + strWIDList[u32WidsCount].s32ValueSize = sizeof(WILC_Char); + strWIDList[u32WidsCount].ps8WidVal = (WILC_Sint8 *)(&(pstrWFIDrv->strWILC_UsrConnReq.u8security)); + u32WidsCount++; + + PRINT_INFO(HOSTINF_DBG, "Encrypt Mode = %x\n", pstrWFIDrv->strWILC_UsrConnReq.u8security); + + strWIDList[u32WidsCount].u16WIDid = (WILC_Uint16)WID_AUTH_TYPE; + strWIDList[u32WidsCount].enuWIDtype = WID_CHAR; + strWIDList[u32WidsCount].s32ValueSize = sizeof(WILC_Char); + strWIDList[u32WidsCount].ps8WidVal = (WILC_Sint8 *)(&pstrWFIDrv->strWILC_UsrConnReq.tenuAuth_type); + u32WidsCount++; + + PRINT_INFO(HOSTINF_DBG, "Authentication Type = %x\n", pstrWFIDrv->strWILC_UsrConnReq.tenuAuth_type); + /* + * strWIDList[u32WidsCount].u16WIDid = (WILC_Uint16)WID_11I_PSK; + * strWIDList[u32WidsCount].enuWIDtype = WID_STR; + * strWIDList[u32WidsCount].s32ValueSize = sizeof(passphrase); + * strWIDList[u32WidsCount].ps8WidVal = (WILC_Sint8*)(passphrase); + * u32WidsCount++; + */ + + strWIDList[u32WidsCount].u16WIDid = (WILC_Uint16)WID_JOIN_REQ; + strWIDList[u32WidsCount].enuWIDtype = WID_CHAR; + strWIDList[u32WidsCount].s32ValueSize = sizeof(WILC_Char); + strWIDList[u32WidsCount].ps8WidVal = (WILC_Sint8 *)&u8bssDscListIndex; + u32WidsCount++; + + #ifndef SIMULATION + /* A temporary workaround to avoid handling the misleading MAC_DISCONNECTED raised from the + * firmware at chip reset when processing the WIDs of the Connect Request. + * (This workaround should be removed in the future when the Chip reset of the Connect WIDs is disabled) */ + /* ////////////////////// */ + gu32WidConnRstHack = 0; + /* ////////////////////// */ + #endif + + s32Error = SendConfigPkt(SET_CFG, strWIDList, u32WidsCount, WILC_FALSE, (WILC_Uint32)pstrWFIDrv); + if (s32Error) { + PRINT_ER("Handle_Connect()] failed to send config packet\n"); + WILC_ERRORREPORT(s32Error, WILC_INVALID_STATE); + } else { + pstrWFIDrv->enuHostIFstate = HOST_IF_WAITING_CONN_RESP; + } + + } else { + PRINT_ER("Required BSSID not found\n"); + WILC_ERRORREPORT(s32Error, WILC_NOT_FOUND); + } + + #else + + /* if we try to connect to an already connected AP then discard the request */ + + if (WILC_memcmp(pstrHostIFconnectAttr->pu8bssid, u8ConnectedSSID, ETH_ALEN) == 0) { + + s32Error = WILC_SUCCESS; + PRINT_ER("Trying to connect to an already connected AP, Discard connect request\n"); + return s32Error; + } + + PRINT_INFO(HOSTINF_DBG, "Saving connection parameters in global structure\n"); + + /*Bug4218: Parsing Join Param*/ + #ifdef WILC_PARSE_SCAN_IN_HOST + ptstrJoinBssParam = (tstrJoinBssParam *)pstrHostIFconnectAttr->pJoinParams; + if (ptstrJoinBssParam == NULL) { + PRINT_ER("Required BSSID not found\n"); + WILC_ERRORREPORT(s32Error, WILC_NOT_FOUND); + } + #endif /*WILC_PARSE_SCAN_IN_HOST*/ + +#if 0 + /* if we try to connect to an already connected AP then discard the request */ + PRINT_D(GENERIC_DBG, "Bssid = %x:%x:%x:%x:%x:%x\n", (pstrHostIFconnectAttr->pu8bssid[0]), (pstrHostIFconnectAttr->pu8bssid[1]), (pstrHostIFconnectAttr->pu8bssid[2]), (pstrHostIFconnectAttr->pu8bssid[3]), (pstrHostIFconnectAttr->pu8bssid[4]), (pstrHostIFconnectAttr->pu8bssid[5])); + PRINT_D(GENERIC_DBG, "bssid = %x:%x:%x:%x:%x:%x\n", (u8ConnectedSSID[0]), (u8ConnectedSSID[1]), (u8ConnectedSSID[2]), (u8ConnectedSSID[3]), (u8ConnectedSSID[4]), (u8ConnectedSSID[5])); + if (WILC_memcmp(pstrHostIFconnectAttr->pu8bssid, u8ConnectedSSID, ETH_ALEN) == 0) { + PRINT_ER("Discard connect request\n"); + s32Error = WILC_FAIL; + return s32Error; + } +#endif + + if (pstrHostIFconnectAttr->pu8bssid != NULL) { + pstrWFIDrv->strWILC_UsrConnReq.pu8bssid = (WILC_Uint8 *)WILC_MALLOC(6); + WILC_memcpy(pstrWFIDrv->strWILC_UsrConnReq.pu8bssid, pstrHostIFconnectAttr->pu8bssid, 6); + } + + pstrWFIDrv->strWILC_UsrConnReq.ssidLen = pstrHostIFconnectAttr->ssidLen; + if (pstrHostIFconnectAttr->pu8ssid != NULL) { + pstrWFIDrv->strWILC_UsrConnReq.pu8ssid = (WILC_Uint8 *)WILC_MALLOC(pstrHostIFconnectAttr->ssidLen + 1); + WILC_memcpy(pstrWFIDrv->strWILC_UsrConnReq.pu8ssid, pstrHostIFconnectAttr->pu8ssid, + pstrHostIFconnectAttr->ssidLen); + pstrWFIDrv->strWILC_UsrConnReq.pu8ssid[pstrHostIFconnectAttr->ssidLen] = '\0'; + } + + pstrWFIDrv->strWILC_UsrConnReq.ConnReqIEsLen = pstrHostIFconnectAttr->IEsLen; + if (pstrHostIFconnectAttr->pu8IEs != NULL) { + pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs = (WILC_Uint8 *)WILC_MALLOC(pstrHostIFconnectAttr->IEsLen); + WILC_memcpy(pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs, pstrHostIFconnectAttr->pu8IEs, + pstrHostIFconnectAttr->IEsLen); + } + + pstrWFIDrv->strWILC_UsrConnReq.u8security = pstrHostIFconnectAttr->u8security; + pstrWFIDrv->strWILC_UsrConnReq.tenuAuth_type = pstrHostIFconnectAttr->tenuAuth_type; + pstrWFIDrv->strWILC_UsrConnReq.pfUserConnectResult = pstrHostIFconnectAttr->pfConnectResult; + pstrWFIDrv->strWILC_UsrConnReq.u32UserConnectPvoid = pstrHostIFconnectAttr->pvUserArg; + + strWIDList[u32WidsCount].u16WIDid = WID_SUCCESS_FRAME_COUNT; + strWIDList[u32WidsCount].enuWIDtype = WID_INT; + strWIDList[u32WidsCount].s32ValueSize = sizeof(WILC_Uint32); + strWIDList[u32WidsCount].ps8WidVal = (WILC_Sint8 *)(&(dummyval)); + u32WidsCount++; + + strWIDList[u32WidsCount].u16WIDid = WID_RECEIVED_FRAGMENT_COUNT; + strWIDList[u32WidsCount].enuWIDtype = WID_INT; + strWIDList[u32WidsCount].s32ValueSize = sizeof(WILC_Uint32); + strWIDList[u32WidsCount].ps8WidVal = (WILC_Sint8 *)(&(dummyval)); + u32WidsCount++; + + strWIDList[u32WidsCount].u16WIDid = WID_FAILED_COUNT; + strWIDList[u32WidsCount].enuWIDtype = WID_INT; + strWIDList[u32WidsCount].s32ValueSize = sizeof(WILC_Uint32); + strWIDList[u32WidsCount].ps8WidVal = (WILC_Sint8 *)(&(dummyval)); + u32WidsCount++; + + /* if((gWFiDrvHandle->strWILC_UsrConnReq.pu8ConnReqIEs != NULL) && */ + /* (gWFiDrvHandle->strWILC_UsrConnReq.ConnReqIEsLen != 0)) */ + { + /* IEs to be inserted in Association Request */ + strWIDList[u32WidsCount].u16WIDid = WID_INFO_ELEMENT_ASSOCIATE; + strWIDList[u32WidsCount].enuWIDtype = WID_BIN_DATA; + strWIDList[u32WidsCount].ps8WidVal = pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs; + strWIDList[u32WidsCount].s32ValueSize = pstrWFIDrv->strWILC_UsrConnReq.ConnReqIEsLen; + u32WidsCount++; + + /*BugID_5137*/ + if (WILC_memcmp("DIRECT-", pstrHostIFconnectAttr->pu8ssid, 7)) { + + gu32FlushedInfoElemAsocSize = pstrWFIDrv->strWILC_UsrConnReq.ConnReqIEsLen; + gu8FlushedInfoElemAsoc = WILC_MALLOC(gu32FlushedInfoElemAsocSize); + memcpy(gu8FlushedInfoElemAsoc, pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs, + gu32FlushedInfoElemAsocSize); + } + } + strWIDList[u32WidsCount].u16WIDid = (WILC_Uint16)WID_11I_MODE; + strWIDList[u32WidsCount].enuWIDtype = WID_CHAR; + strWIDList[u32WidsCount].s32ValueSize = sizeof(WILC_Char); + strWIDList[u32WidsCount].ps8WidVal = (WILC_Sint8 *)(&(pstrWFIDrv->strWILC_UsrConnReq.u8security)); + u32WidsCount++; + + /*BugID_5137*/ + if (WILC_memcmp("DIRECT-", pstrHostIFconnectAttr->pu8ssid, 7)) + gu8Flushed11iMode = pstrWFIDrv->strWILC_UsrConnReq.u8security; + + PRINT_INFO(HOSTINF_DBG, "Encrypt Mode = %x\n", pstrWFIDrv->strWILC_UsrConnReq.u8security); + + + strWIDList[u32WidsCount].u16WIDid = (WILC_Uint16)WID_AUTH_TYPE; + strWIDList[u32WidsCount].enuWIDtype = WID_CHAR; + strWIDList[u32WidsCount].s32ValueSize = sizeof(WILC_Char); + strWIDList[u32WidsCount].ps8WidVal = (WILC_Sint8 *)(&pstrWFIDrv->strWILC_UsrConnReq.tenuAuth_type); + u32WidsCount++; + + /*BugID_5137*/ + if (WILC_memcmp("DIRECT-", pstrHostIFconnectAttr->pu8ssid, 7)) + gu8FlushedAuthType = (WILC_Uint8)pstrWFIDrv->strWILC_UsrConnReq.tenuAuth_type; + + PRINT_INFO(HOSTINF_DBG, "Authentication Type = %x\n", pstrWFIDrv->strWILC_UsrConnReq.tenuAuth_type); + /* + * strWIDList[u32WidsCount].u16WIDid = (WILC_Uint16)WID_11I_PSK; + * strWIDList[u32WidsCount].enuWIDtype = WID_STR; + * strWIDList[u32WidsCount].s32ValueSize = sizeof(passphrase); + * strWIDList[u32WidsCount].ps8WidVal = (WILC_Sint8*)(passphrase); + * u32WidsCount++; + */ + + PRINT_D(HOSTINF_DBG, "Connecting to network of SSID %s on channel %d\n", + pstrWFIDrv->strWILC_UsrConnReq.pu8ssid, pstrHostIFconnectAttr->u8channel); + + +#ifndef WILC_PARSE_SCAN_IN_HOST + strWIDList[u32WidsCount].u16WIDid = (WILC_Uint16)WID_JOIN_REQ_EXTENDED; + strWIDList[u32WidsCount].enuWIDtype = WID_STR; + strWIDList[u32WidsCount].s32ValueSize = MAX_SSID_LEN + 7; + strWIDList[u32WidsCount].ps8WidVal = WILC_MALLOC(strWIDList[u32WidsCount].s32ValueSize); + + if (strWIDList[u32WidsCount].ps8WidVal == WILC_NULL) { + WILC_ERRORREPORT(s32Error, WILC_NO_MEM); + } + + pu8CurrByte = strWIDList[u32WidsCount].ps8WidVal; + + if (pstrHostIFconnectAttr->pu8ssid != NULL) { + WILC_memcpy(pu8CurrByte, pstrHostIFconnectAttr->pu8ssid, pstrHostIFconnectAttr->ssidLen); + pu8CurrByte[pstrHostIFconnectAttr->ssidLen] = '\0'; + } + pu8CurrByte += MAX_SSID_LEN; + if ((pstrHostIFconnectAttr->u8channel >= 1) && (pstrHostIFconnectAttr->u8channel <= 14)) { + *(pu8CurrByte++) = pstrHostIFconnectAttr->u8channel; + } else { + PRINT_ER("Channel out of range\n"); + *(pu8CurrByte++) = 0xFF; + } + if (pstrHostIFconnectAttr->pu8bssid != NULL) { + WILC_memcpy(pu8CurrByte, pstrHostIFconnectAttr->pu8bssid, 6); + } + pu8CurrByte += 6; + + /* keep the buffer at the start of the allocated pointer to use it with the free*/ + pu8CurrByte = strWIDList[u32WidsCount].ps8WidVal; + + #else + + strWIDList[u32WidsCount].u16WIDid = (WILC_Uint16)WID_JOIN_REQ_EXTENDED; + strWIDList[u32WidsCount].enuWIDtype = WID_STR; + + /*Sending NoA attributes during connection*/ + strWIDList[u32WidsCount].s32ValueSize = 112; /* 79; */ + strWIDList[u32WidsCount].ps8WidVal = WILC_MALLOC(strWIDList[u32WidsCount].s32ValueSize); + + /*BugID_5137*/ + if (WILC_memcmp("DIRECT-", pstrHostIFconnectAttr->pu8ssid, 7)) { + gu32FlushedJoinReqSize = strWIDList[u32WidsCount].s32ValueSize; + gu8FlushedJoinReq = WILC_MALLOC(gu32FlushedJoinReqSize); + } + if (strWIDList[u32WidsCount].ps8WidVal == WILC_NULL) { + WILC_ERRORREPORT(s32Error, WILC_NO_MEM); + } + + pu8CurrByte = strWIDList[u32WidsCount].ps8WidVal; + + + if (pstrHostIFconnectAttr->pu8ssid != NULL) { + WILC_memcpy(pu8CurrByte, pstrHostIFconnectAttr->pu8ssid, pstrHostIFconnectAttr->ssidLen); + pu8CurrByte[pstrHostIFconnectAttr->ssidLen] = '\0'; + } + pu8CurrByte += MAX_SSID_LEN; + + /* BSS type*/ + *(pu8CurrByte++) = INFRASTRUCTURE; + /* Channel*/ + if ((pstrHostIFconnectAttr->u8channel >= 1) && (pstrHostIFconnectAttr->u8channel <= 14)) { + *(pu8CurrByte++) = pstrHostIFconnectAttr->u8channel; + } else { + PRINT_ER("Channel out of range\n"); + *(pu8CurrByte++) = 0xFF; + } + /* Cap Info*/ + *(pu8CurrByte++) = (ptstrJoinBssParam->cap_info) & 0xFF; + *(pu8CurrByte++) = ((ptstrJoinBssParam->cap_info) >> 8) & 0xFF; + PRINT_D(HOSTINF_DBG, "* Cap Info %0x*\n", (*(pu8CurrByte - 2) | ((*(pu8CurrByte - 1)) << 8))); + + /* sa*/ + if (pstrHostIFconnectAttr->pu8bssid != NULL) { + WILC_memcpy(pu8CurrByte, pstrHostIFconnectAttr->pu8bssid, 6); + } + pu8CurrByte += 6; + + /* bssid*/ + if (pstrHostIFconnectAttr->pu8bssid != NULL) { + WILC_memcpy(pu8CurrByte, pstrHostIFconnectAttr->pu8bssid, 6); + } + pu8CurrByte += 6; + + /* Beacon Period*/ + *(pu8CurrByte++) = (ptstrJoinBssParam->beacon_period) & 0xFF; + *(pu8CurrByte++) = ((ptstrJoinBssParam->beacon_period) >> 8) & 0xFF; + PRINT_D(HOSTINF_DBG, "* Beacon Period %d*\n", (*(pu8CurrByte - 2) | ((*(pu8CurrByte - 1)) << 8))); + /* DTIM Period*/ + *(pu8CurrByte++) = ptstrJoinBssParam->dtim_period; + PRINT_D(HOSTINF_DBG, "* DTIM Period %d*\n", (*(pu8CurrByte - 1))); + /* Supported rates*/ + WILC_memcpy(pu8CurrByte, ptstrJoinBssParam->supp_rates, MAX_RATES_SUPPORTED + 1); + pu8CurrByte += (MAX_RATES_SUPPORTED + 1); + + /* wmm cap*/ + *(pu8CurrByte++) = ptstrJoinBssParam->wmm_cap; + PRINT_D(HOSTINF_DBG, "* wmm cap%d*\n", (*(pu8CurrByte - 1))); + /* uapsd cap*/ + *(pu8CurrByte++) = ptstrJoinBssParam->uapsd_cap; + + /* ht cap*/ + *(pu8CurrByte++) = ptstrJoinBssParam->ht_capable; + /* copy this information to the user request */ + pstrWFIDrv->strWILC_UsrConnReq.IsHTCapable = ptstrJoinBssParam->ht_capable; + + /* rsn found*/ + *(pu8CurrByte++) = ptstrJoinBssParam->rsn_found; + PRINT_D(HOSTINF_DBG, "* rsn found %d*\n", *(pu8CurrByte - 1)); + /* rsn group policy*/ + *(pu8CurrByte++) = ptstrJoinBssParam->rsn_grp_policy; + PRINT_D(HOSTINF_DBG, "* rsn group policy %0x*\n", (*(pu8CurrByte - 1))); + /* mode_802_11i*/ + *(pu8CurrByte++) = ptstrJoinBssParam->mode_802_11i; + PRINT_D(HOSTINF_DBG, "* mode_802_11i %d*\n", (*(pu8CurrByte - 1))); + /* rsn pcip policy*/ + WILC_memcpy(pu8CurrByte, ptstrJoinBssParam->rsn_pcip_policy, sizeof(ptstrJoinBssParam->rsn_pcip_policy)); + pu8CurrByte += sizeof(ptstrJoinBssParam->rsn_pcip_policy); + + /* rsn auth policy*/ + WILC_memcpy(pu8CurrByte, ptstrJoinBssParam->rsn_auth_policy, sizeof(ptstrJoinBssParam->rsn_auth_policy)); + pu8CurrByte += sizeof(ptstrJoinBssParam->rsn_auth_policy); + + /* rsn auth policy*/ + WILC_memcpy(pu8CurrByte, ptstrJoinBssParam->rsn_cap, sizeof(ptstrJoinBssParam->rsn_cap)); + pu8CurrByte += sizeof(ptstrJoinBssParam->rsn_cap); + + /*BugID_5137*/ + *(pu8CurrByte++) = REAL_JOIN_REQ; + + #ifdef WILC_P2P + *(pu8CurrByte++) = ptstrJoinBssParam->u8NoaEnbaled; + if (ptstrJoinBssParam->u8NoaEnbaled) { + PRINT_D(HOSTINF_DBG, "NOA present\n"); + + *(pu8CurrByte++) = (ptstrJoinBssParam->tsf) & 0xFF; + *(pu8CurrByte++) = ((ptstrJoinBssParam->tsf) >> 8) & 0xFF; + *(pu8CurrByte++) = ((ptstrJoinBssParam->tsf) >> 16) & 0xFF; + *(pu8CurrByte++) = ((ptstrJoinBssParam->tsf) >> 24) & 0xFF; + + *(pu8CurrByte++) = ptstrJoinBssParam->u8Index; + + *(pu8CurrByte++) = ptstrJoinBssParam->u8OppEnable; + + if (ptstrJoinBssParam->u8OppEnable) + *(pu8CurrByte++) = ptstrJoinBssParam->u8CtWindow; + + *(pu8CurrByte++) = ptstrJoinBssParam->u8Count; + + WILC_memcpy(pu8CurrByte, ptstrJoinBssParam->au8Duration, sizeof(ptstrJoinBssParam->au8Duration)); + + pu8CurrByte += sizeof(ptstrJoinBssParam->au8Duration); + + WILC_memcpy(pu8CurrByte, ptstrJoinBssParam->au8Interval, sizeof(ptstrJoinBssParam->au8Interval)); + + pu8CurrByte += sizeof(ptstrJoinBssParam->au8Interval); + + WILC_memcpy(pu8CurrByte, ptstrJoinBssParam->au8StartTime, sizeof(ptstrJoinBssParam->au8StartTime)); + + pu8CurrByte += sizeof(ptstrJoinBssParam->au8StartTime); + + } else + PRINT_D(HOSTINF_DBG, "NOA not present\n"); + #endif + + + /* keep the buffer at the start of the allocated pointer to use it with the free*/ + pu8CurrByte = strWIDList[u32WidsCount].ps8WidVal; + + + #endif /* #ifdef WILC_PARSE_SCAN_IN_HOST*/ + u32WidsCount++; + + #ifndef SIMULATION + /* A temporary workaround to avoid handling the misleading MAC_DISCONNECTED raised from the + * firmware at chip reset when processing the WIDs of the Connect Request. + * (This workaround should be removed in the future when the Chip reset of the Connect WIDs is disabled) */ + /* ////////////////////// */ + gu32WidConnRstHack = 0; + /* ////////////////////// */ + #endif + + /*BugID_5137*/ + if (WILC_memcmp("DIRECT-", pstrHostIFconnectAttr->pu8ssid, 7)) { + memcpy(gu8FlushedJoinReq, pu8CurrByte, gu32FlushedJoinReqSize); + gu8FlushedJoinReqDrvHandler = (WILC_Uint32)pstrWFIDrv; + } + + PRINT_D(GENERIC_DBG, "send HOST_IF_WAITING_CONN_RESP\n"); + + if (pstrHostIFconnectAttr->pu8bssid != NULL) { + WILC_memcpy(u8ConnectedSSID, pstrHostIFconnectAttr->pu8bssid, ETH_ALEN); + + PRINT_D(GENERIC_DBG, "save Bssid = %x:%x:%x:%x:%x:%x\n", (pstrHostIFconnectAttr->pu8bssid[0]), (pstrHostIFconnectAttr->pu8bssid[1]), (pstrHostIFconnectAttr->pu8bssid[2]), (pstrHostIFconnectAttr->pu8bssid[3]), (pstrHostIFconnectAttr->pu8bssid[4]), (pstrHostIFconnectAttr->pu8bssid[5])); + PRINT_D(GENERIC_DBG, "save bssid = %x:%x:%x:%x:%x:%x\n", (u8ConnectedSSID[0]), (u8ConnectedSSID[1]), (u8ConnectedSSID[2]), (u8ConnectedSSID[3]), (u8ConnectedSSID[4]), (u8ConnectedSSID[5])); + } + + s32Error = SendConfigPkt(SET_CFG, strWIDList, u32WidsCount, WILC_FALSE, (WILC_Uint32)pstrWFIDrv); + if (s32Error) { + PRINT_ER("Handle_Connect()] failed to send config packet\n"); + WILC_ERRORREPORT(s32Error, WILC_INVALID_STATE); + } else { + PRINT_D(GENERIC_DBG, "set HOST_IF_WAITING_CONN_RESP\n"); + pstrWFIDrv->enuHostIFstate = HOST_IF_WAITING_CONN_RESP; + } + #endif + + WILC_CATCH(s32Error) + { + tstrConnectInfo strConnectInfo; + + WILC_TimerStop(&(pstrWFIDrv->hConnectTimer), WILC_NULL); + + PRINT_D(HOSTINF_DBG, "could not start connecting to the required network\n"); + + WILC_memset(&strConnectInfo, 0, sizeof(tstrConnectInfo)); + + if (pstrHostIFconnectAttr->pfConnectResult != NULL) { + if (pstrHostIFconnectAttr->pu8bssid != NULL) { + WILC_memcpy(strConnectInfo.au8bssid, pstrHostIFconnectAttr->pu8bssid, 6); + } + + if (pstrHostIFconnectAttr->pu8IEs != NULL) { + strConnectInfo.ReqIEsLen = pstrHostIFconnectAttr->IEsLen; + strConnectInfo.pu8ReqIEs = (WILC_Uint8 *)WILC_MALLOC(pstrHostIFconnectAttr->IEsLen); + WILC_memcpy(strConnectInfo.pu8ReqIEs, + pstrHostIFconnectAttr->pu8IEs, + pstrHostIFconnectAttr->IEsLen); + } + + pstrHostIFconnectAttr->pfConnectResult(CONN_DISCONN_EVENT_CONN_RESP, + &strConnectInfo, + MAC_DISCONNECTED, + NULL, + pstrHostIFconnectAttr->pvUserArg); + /*Change state to idle*/ + pstrWFIDrv->enuHostIFstate = HOST_IF_IDLE; + /* Deallocation */ + if (strConnectInfo.pu8ReqIEs != NULL) { + WILC_FREE(strConnectInfo.pu8ReqIEs); + strConnectInfo.pu8ReqIEs = NULL; + } + + } else { + PRINT_ER("Connect callback function pointer is NULL \n"); + } + } + + PRINT_D(HOSTINF_DBG, "Deallocating connection parameters\n"); + /* Deallocate pstrHostIFconnectAttr->pu8bssid which was prevoisuly allocated by the sending thread */ + if (pstrHostIFconnectAttr->pu8bssid != NULL) { + WILC_FREE(pstrHostIFconnectAttr->pu8bssid); + pstrHostIFconnectAttr->pu8bssid = NULL; + } + + /* Deallocate pstrHostIFconnectAttr->pu8ssid which was prevoisuly allocated by the sending thread */ + if (pstrHostIFconnectAttr->pu8ssid != NULL) { + WILC_FREE(pstrHostIFconnectAttr->pu8ssid); + pstrHostIFconnectAttr->pu8ssid = NULL; + } + + /* Deallocate pstrHostIFconnectAttr->pu8IEs which was prevoisuly allocated by the sending thread */ + if (pstrHostIFconnectAttr->pu8IEs != NULL) { + WILC_FREE(pstrHostIFconnectAttr->pu8IEs); + pstrHostIFconnectAttr->pu8IEs = NULL; + } + + if (pu8CurrByte != WILC_NULL) { + WILC_FREE(pu8CurrByte); + } + return s32Error; +} + +/** + * @brief Handle_FlushConnect + * @details Sending config packet to firmware to flush an old connection + * after switching FW from station one to hybrid one + * @param[in] void * drvHandler + * @return Error code. + * @author Amr Abdel-Moghny + * @date 19 DEC 2013 + * @version 8.0 + */ + +static WILC_Sint32 Handle_FlushConnect(void *drvHandler) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWIDList[5]; + WILC_Uint32 u32WidsCount = 0; + WILC_Uint8 *pu8CurrByte = WILC_NULL; + + + /* IEs to be inserted in Association Request */ + strWIDList[u32WidsCount].u16WIDid = WID_INFO_ELEMENT_ASSOCIATE; + strWIDList[u32WidsCount].enuWIDtype = WID_BIN_DATA; + strWIDList[u32WidsCount].ps8WidVal = gu8FlushedInfoElemAsoc; + strWIDList[u32WidsCount].s32ValueSize = gu32FlushedInfoElemAsocSize; + u32WidsCount++; + + strWIDList[u32WidsCount].u16WIDid = (WILC_Uint16)WID_11I_MODE; + strWIDList[u32WidsCount].enuWIDtype = WID_CHAR; + strWIDList[u32WidsCount].s32ValueSize = sizeof(WILC_Char); + strWIDList[u32WidsCount].ps8WidVal = (WILC_Sint8 *)(&(gu8Flushed11iMode)); + u32WidsCount++; + + + + strWIDList[u32WidsCount].u16WIDid = (WILC_Uint16)WID_AUTH_TYPE; + strWIDList[u32WidsCount].enuWIDtype = WID_CHAR; + strWIDList[u32WidsCount].s32ValueSize = sizeof(WILC_Char); + strWIDList[u32WidsCount].ps8WidVal = (WILC_Sint8 *)(&gu8FlushedAuthType); + u32WidsCount++; + + + #ifdef WILC_PARSE_SCAN_IN_HOST + strWIDList[u32WidsCount].u16WIDid = (WILC_Uint16)WID_JOIN_REQ_EXTENDED; + strWIDList[u32WidsCount].enuWIDtype = WID_STR; + strWIDList[u32WidsCount].s32ValueSize = gu32FlushedJoinReqSize; + strWIDList[u32WidsCount].ps8WidVal = (WILC_Sint8 *)gu8FlushedJoinReq; + pu8CurrByte = strWIDList[u32WidsCount].ps8WidVal; + + pu8CurrByte += FLUSHED_BYTE_POS; + *(pu8CurrByte) = FLUSHED_JOIN_REQ; + + u32WidsCount++; + + #endif + + s32Error = SendConfigPkt(SET_CFG, strWIDList, u32WidsCount, WILC_FALSE, gu8FlushedJoinReqDrvHandler); + if (s32Error) { + PRINT_ER("Handle_Flush_Connect()] failed to send config packet\n"); + WILC_ERRORREPORT(s32Error, WILC_INVALID_STATE); + } + + WILC_CATCH(s32Error) + { + + } + + return s32Error; +} + +/** + * @brief Handle_ConnectTimeout + * @details Call connect notification callback function indicating connection failure + * @param[in] NONE + * @return Error code. + * @author + * @date + * @version 1.0 + */ +static WILC_Sint32 Handle_ConnectTimeout(void *drvHandler) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrConnectInfo strConnectInfo; + tstrWID strWID; + WILC_Uint16 u16DummyReasonCode = 0; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *) drvHandler; + + if (pstrWFIDrv == NULL) { + PRINT_ER("Driver handler is NULL\n"); + return s32Error; + } + + pstrWFIDrv->enuHostIFstate = HOST_IF_IDLE; + + gbScanWhileConnected = WILC_FALSE; + + + WILC_memset(&strConnectInfo, 0, sizeof(tstrConnectInfo)); + + + /* First, we will notify the upper layer with the Connection failure {through the Connect Callback function}, + * then we will notify our firmware also with the Connection failure {through sending to it Cfg packet carrying + * WID_DISCONNECT} */ + if (pstrWFIDrv->strWILC_UsrConnReq.pfUserConnectResult != NULL) { + if (pstrWFIDrv->strWILC_UsrConnReq.pu8bssid != NULL) { + WILC_memcpy(strConnectInfo.au8bssid, + pstrWFIDrv->strWILC_UsrConnReq.pu8bssid, 6); + } + + if (pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs != NULL) { + strConnectInfo.ReqIEsLen = pstrWFIDrv->strWILC_UsrConnReq.ConnReqIEsLen; + strConnectInfo.pu8ReqIEs = (WILC_Uint8 *)WILC_MALLOC(pstrWFIDrv->strWILC_UsrConnReq.ConnReqIEsLen); + WILC_memcpy(strConnectInfo.pu8ReqIEs, + pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs, + pstrWFIDrv->strWILC_UsrConnReq.ConnReqIEsLen); + } + + pstrWFIDrv->strWILC_UsrConnReq.pfUserConnectResult(CONN_DISCONN_EVENT_CONN_RESP, + &strConnectInfo, + MAC_DISCONNECTED, + NULL, + pstrWFIDrv->strWILC_UsrConnReq.u32UserConnectPvoid); + + /* Deallocation of strConnectInfo.pu8ReqIEs */ + if (strConnectInfo.pu8ReqIEs != NULL) { + WILC_FREE(strConnectInfo.pu8ReqIEs); + strConnectInfo.pu8ReqIEs = NULL; + } + } else { + PRINT_ER("Connect callback function pointer is NULL \n"); + } + + /* Here we will notify our firmware also with the Connection failure {through sending to it Cfg packet carrying + * WID_DISCONNECT} */ + strWID.u16WIDid = (WILC_Uint16)WID_DISCONNECT; + strWID.enuWIDtype = WID_CHAR; + strWID.ps8WidVal = (WILC_Sint8 *)&u16DummyReasonCode; + strWID.s32ValueSize = sizeof(WILC_Char); + + PRINT_D(HOSTINF_DBG, "Sending disconnect request\n"); + + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_FALSE, (WILC_Uint32)pstrWFIDrv); + if (s32Error) { + PRINT_ER("Failed to send dissconect config packet\n"); + } + + /* Deallocation of the Saved Connect Request in the global Handle */ + pstrWFIDrv->strWILC_UsrConnReq.ssidLen = 0; + if (pstrWFIDrv->strWILC_UsrConnReq.pu8ssid != NULL) { + WILC_FREE(pstrWFIDrv->strWILC_UsrConnReq.pu8ssid); + pstrWFIDrv->strWILC_UsrConnReq.pu8ssid = NULL; + } + + if (pstrWFIDrv->strWILC_UsrConnReq.pu8bssid != NULL) { + WILC_FREE(pstrWFIDrv->strWILC_UsrConnReq.pu8bssid); + pstrWFIDrv->strWILC_UsrConnReq.pu8bssid = NULL; + } + + pstrWFIDrv->strWILC_UsrConnReq.ConnReqIEsLen = 0; + if (pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs != NULL) { + WILC_FREE(pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs); + pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs = NULL; + } + + WILC_memset(u8ConnectedSSID, 0, ETH_ALEN); + /*BugID_5213*/ + /*Freeing flushed join request params on connect timeout*/ + if (gu8FlushedJoinReq != NULL && gu8FlushedJoinReqDrvHandler == (WILC_Uint32)drvHandler) { + WILC_FREE(gu8FlushedJoinReq); + gu8FlushedJoinReq = NULL; + } + if (gu8FlushedInfoElemAsoc != NULL && gu8FlushedJoinReqDrvHandler == (WILC_Uint32)drvHandler) { + WILC_FREE(gu8FlushedInfoElemAsoc); + gu8FlushedInfoElemAsoc = NULL; + } + + return s32Error; +} + +/** + * @brief Handle_RcvdNtwrkInfo + * @details Handling received network information + * @param[in] tstrRcvdNetworkInfo* pstrRcvdNetworkInfo + * @return Error code. + * @author + * @date + * @version 1.0 + */ +static WILC_Sint32 Handle_RcvdNtwrkInfo(void *drvHandler, tstrRcvdNetworkInfo *pstrRcvdNetworkInfo) +{ + WILC_Uint32 i; + WILC_Bool bNewNtwrkFound; + + + + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrNetworkInfo *pstrNetworkInfo = NULL; + void *pJoinParams = NULL; + + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler; + + + + bNewNtwrkFound = WILC_TRUE; + PRINT_INFO(HOSTINF_DBG, "Handling received network info\n"); + + /*if there is a an ongoing scan request*/ + if (pstrWFIDrv->strWILC_UsrScanReq.pfUserScanResult) { + PRINT_D(HOSTINF_DBG, "State: Scanning, parsing network information received\n"); + ParseNetworkInfo(pstrRcvdNetworkInfo->pu8Buffer, &pstrNetworkInfo); + if ((pstrNetworkInfo == NULL) + || (pstrWFIDrv->strWILC_UsrScanReq.pfUserScanResult == WILC_NULL)) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + /* check whether this network is discovered before */ + for (i = 0; i < pstrWFIDrv->strWILC_UsrScanReq.u32RcvdChCount; i++) { + + if ((pstrWFIDrv->strWILC_UsrScanReq.astrFoundNetworkInfo[i].au8bssid != NULL) && + (pstrNetworkInfo->au8bssid != NULL)) { + if (WILC_memcmp(pstrWFIDrv->strWILC_UsrScanReq.astrFoundNetworkInfo[i].au8bssid, + pstrNetworkInfo->au8bssid, 6) == 0) { + if (pstrNetworkInfo->s8rssi <= pstrWFIDrv->strWILC_UsrScanReq.astrFoundNetworkInfo[i].s8rssi) { + /*we have already found this network with better rssi, so keep the old cached one and don't + * send anything to the upper layer */ + PRINT_D(HOSTINF_DBG, "Network previously discovered\n"); + goto done; + } else { + /* here the same already found network is found again but with a better rssi, so just update + * the rssi for this cached network and send this updated network to the upper layer but + * don't add a new record for it */ + pstrWFIDrv->strWILC_UsrScanReq.astrFoundNetworkInfo[i].s8rssi = pstrNetworkInfo->s8rssi; + bNewNtwrkFound = WILC_FALSE; + break; + } + } + } + } + + if (bNewNtwrkFound == WILC_TRUE) { + /* here it is confirmed that it is a new discovered network, + * so add its record then call the User CallBack function */ + + PRINT_D(HOSTINF_DBG, "New network found\n"); + + if (pstrWFIDrv->strWILC_UsrScanReq.u32RcvdChCount < MAX_NUM_SCANNED_NETWORKS) { + pstrWFIDrv->strWILC_UsrScanReq.astrFoundNetworkInfo[pstrWFIDrv->strWILC_UsrScanReq.u32RcvdChCount].s8rssi = pstrNetworkInfo->s8rssi; + + if ((pstrWFIDrv->strWILC_UsrScanReq.astrFoundNetworkInfo[pstrWFIDrv->strWILC_UsrScanReq.u32RcvdChCount].au8bssid != NULL) + && (pstrNetworkInfo->au8bssid != NULL)) { + WILC_memcpy(pstrWFIDrv->strWILC_UsrScanReq.astrFoundNetworkInfo[pstrWFIDrv->strWILC_UsrScanReq.u32RcvdChCount].au8bssid, + pstrNetworkInfo->au8bssid, 6); + + pstrWFIDrv->strWILC_UsrScanReq.u32RcvdChCount++; + + pstrNetworkInfo->bNewNetwork = WILC_TRUE; + /*Bug4218: Parsing Join Param*/ + /* add new BSS to JoinBssTable */ + #ifdef WILC_PARSE_SCAN_IN_HOST + pJoinParams = host_int_ParseJoinBssParam(pstrNetworkInfo); + #endif /*WILC_PARSE_SCAN_IN_HOST*/ + + pstrWFIDrv->strWILC_UsrScanReq.pfUserScanResult(SCAN_EVENT_NETWORK_FOUND, pstrNetworkInfo, + pstrWFIDrv->strWILC_UsrScanReq.u32UserScanPvoid, + pJoinParams); + + + } + } else { + PRINT_WRN(HOSTINF_DBG, "Discovered networks exceeded max. limit \n"); + } + } else { + pstrNetworkInfo->bNewNetwork = WILC_FALSE; + /* just call the User CallBack function to send the same discovered network with its updated RSSI */ + pstrWFIDrv->strWILC_UsrScanReq.pfUserScanResult(SCAN_EVENT_NETWORK_FOUND, pstrNetworkInfo, + pstrWFIDrv->strWILC_UsrScanReq.u32UserScanPvoid, NULL); + } + } + + + WILC_CATCH(s32Error) + { + + } + +done: + /* Deallocate pstrRcvdNetworkInfo->pu8Buffer which was prevoisuly allocated by the sending thread */ + if (pstrRcvdNetworkInfo->pu8Buffer != NULL) { + WILC_FREE(pstrRcvdNetworkInfo->pu8Buffer); + pstrRcvdNetworkInfo->pu8Buffer = NULL; + } + + /*free structure allocated*/ + if (pstrNetworkInfo != WILC_NULL) { + DeallocateNetworkInfo(pstrNetworkInfo); + pstrNetworkInfo = WILC_NULL; + } + + return s32Error; +} + +/** + * @brief Handle_RcvdGnrlAsyncInfo + * @details Handling received asynchrous general network information + * @param[in] tstrRcvdGnrlAsyncInfo* pstrRcvdGnrlAsyncInfo + * @return Error code. + * @author + * @date + * @version 1.0 + */ +static WILC_Sint32 Handle_RcvdGnrlAsyncInfo(void *drvHandler, tstrRcvdGnrlAsyncInfo *pstrRcvdGnrlAsyncInfo) +{ + /* TODO: mostafa: till now, this function just handles only the received mac status msg, */ + /* which carries only 1 WID which have WID ID = WID_STATUS */ + WILC_Sint32 s32Error = WILC_SUCCESS; + WILC_Uint8 u8MsgType = 0; + WILC_Uint8 u8MsgID = 0; + WILC_Uint16 u16MsgLen = 0; + WILC_Uint16 u16WidID = (WILC_Uint16)WID_NIL; + WILC_Uint8 u8WidLen = 0; + WILC_Uint8 u8MacStatus; + WILC_Uint8 u8MacStatusReasonCode; + WILC_Uint8 u8MacStatusAdditionalInfo; + tstrConnectInfo strConnectInfo; + tstrDisconnectNotifInfo strDisconnectNotifInfo; + WILC_Sint32 s32Err = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *) drvHandler; + if (pstrWFIDrv == NULL) { + PRINT_ER("Driver handler is NULL\n"); + } + PRINT_D(GENERIC_DBG, "Current State = %d,Received state = %d\n", pstrWFIDrv->enuHostIFstate, + pstrRcvdGnrlAsyncInfo->pu8Buffer[7]); + + if ((pstrWFIDrv->enuHostIFstate == HOST_IF_WAITING_CONN_RESP) || + (pstrWFIDrv->enuHostIFstate == HOST_IF_CONNECTED) || + pstrWFIDrv->strWILC_UsrScanReq.pfUserScanResult) { + if ((pstrRcvdGnrlAsyncInfo->pu8Buffer == NULL) || + (pstrWFIDrv->strWILC_UsrConnReq.pfUserConnectResult == WILC_NULL)) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + u8MsgType = pstrRcvdGnrlAsyncInfo->pu8Buffer[0]; + + /* Check whether the received message type is 'I' */ + if ('I' != u8MsgType) { + PRINT_ER("Received Message format incorrect.\n"); + WILC_ERRORREPORT(s32Error, WILC_FAIL); + } + + /* Extract message ID */ + u8MsgID = pstrRcvdGnrlAsyncInfo->pu8Buffer[1]; + + /* Extract message Length */ + u16MsgLen = MAKE_WORD16(pstrRcvdGnrlAsyncInfo->pu8Buffer[2], pstrRcvdGnrlAsyncInfo->pu8Buffer[3]); + + /* Extract WID ID [expected to be = WID_STATUS] */ + u16WidID = MAKE_WORD16(pstrRcvdGnrlAsyncInfo->pu8Buffer[4], pstrRcvdGnrlAsyncInfo->pu8Buffer[5]); + + /* Extract WID Length [expected to be = 1] */ + u8WidLen = pstrRcvdGnrlAsyncInfo->pu8Buffer[6]; + + /* get the WID value [expected to be one of two values: either MAC_CONNECTED = (1) or MAC_DISCONNECTED = (0)] */ + u8MacStatus = pstrRcvdGnrlAsyncInfo->pu8Buffer[7]; + u8MacStatusReasonCode = pstrRcvdGnrlAsyncInfo->pu8Buffer[8]; + u8MacStatusAdditionalInfo = pstrRcvdGnrlAsyncInfo->pu8Buffer[9]; + PRINT_INFO(HOSTINF_DBG, "Recieved MAC status = %d with Reason = %d , Info = %d\n", u8MacStatus, u8MacStatusReasonCode, u8MacStatusAdditionalInfo); + if (pstrWFIDrv->enuHostIFstate == HOST_IF_WAITING_CONN_RESP) { + /* our station had sent Association Request frame, so here it will get the Association Response frame then parse it */ + WILC_Uint32 u32RcvdAssocRespInfoLen; + tstrConnectRespInfo *pstrConnectRespInfo = NULL; + + PRINT_D(HOSTINF_DBG, "Recieved MAC status = %d with Reason = %d , Code = %d\n", u8MacStatus, u8MacStatusReasonCode, u8MacStatusAdditionalInfo); + + WILC_memset(&strConnectInfo, 0, sizeof(tstrConnectInfo)); + + if (u8MacStatus == MAC_CONNECTED) { + WILC_memset(gapu8RcvdAssocResp, 0, MAX_ASSOC_RESP_FRAME_SIZE); + + host_int_get_assoc_res_info((WILC_WFIDrvHandle)pstrWFIDrv, + gapu8RcvdAssocResp, + MAX_ASSOC_RESP_FRAME_SIZE, + &u32RcvdAssocRespInfoLen); + + PRINT_INFO(HOSTINF_DBG, "Received association response with length = %d\n", u32RcvdAssocRespInfoLen); + + if (u32RcvdAssocRespInfoLen != 0) { + + PRINT_D(HOSTINF_DBG, "Parsing association response\n"); + s32Err = ParseAssocRespInfo(gapu8RcvdAssocResp, u32RcvdAssocRespInfoLen, + &pstrConnectRespInfo); + if (s32Err) { + PRINT_ER("ParseAssocRespInfo() returned error %d \n", s32Err); + } else { + /* use the necessary parsed Info from the Received Association Response */ + strConnectInfo.u16ConnectStatus = pstrConnectRespInfo->u16ConnectStatus; + + if (strConnectInfo.u16ConnectStatus == SUCCESSFUL_STATUSCODE) { + PRINT_INFO(HOSTINF_DBG, "Association response received : Successful connection status\n"); + if (pstrConnectRespInfo->pu8RespIEs != NULL) { + strConnectInfo.u16RespIEsLen = pstrConnectRespInfo->u16RespIEsLen; + + + strConnectInfo.pu8RespIEs = (WILC_Uint8 *)WILC_MALLOC(pstrConnectRespInfo->u16RespIEsLen); + WILC_memcpy(strConnectInfo.pu8RespIEs, pstrConnectRespInfo->pu8RespIEs, + pstrConnectRespInfo->u16RespIEsLen); + } + } + + /* deallocate the Assoc. Resp. parsed structure as it is not needed anymore */ + if (pstrConnectRespInfo != NULL) { + DeallocateAssocRespInfo(pstrConnectRespInfo); + pstrConnectRespInfo = NULL; + } + } + } + } + + /* The station has just received mac status and it also received assoc. response which + * it was waiting for. + * So check first the matching between the received mac status and the received status code in Asoc Resp */ + if ((u8MacStatus == MAC_CONNECTED) && + (strConnectInfo.u16ConnectStatus != SUCCESSFUL_STATUSCODE)) { + PRINT_ER("Received MAC status is MAC_CONNECTED while the received status code in Asoc Resp is not SUCCESSFUL_STATUSCODE \n"); + WILC_memset(u8ConnectedSSID, 0, ETH_ALEN); + + } else if (u8MacStatus == MAC_DISCONNECTED) { + PRINT_ER("Received MAC status is MAC_DISCONNECTED\n"); + WILC_memset(u8ConnectedSSID, 0, ETH_ALEN); + } + + /* TODO: mostafa: correct BSSID should be retrieved from actual BSSID received from AP */ + /* through a structure of type tstrConnectRespInfo */ + if (pstrWFIDrv->strWILC_UsrConnReq.pu8bssid != NULL) { + PRINT_D(HOSTINF_DBG, "Retrieving actual BSSID from AP\n"); + WILC_memcpy(strConnectInfo.au8bssid, pstrWFIDrv->strWILC_UsrConnReq.pu8bssid, 6); + + if ((u8MacStatus == MAC_CONNECTED) && + (strConnectInfo.u16ConnectStatus == SUCCESSFUL_STATUSCODE)) { + WILC_memcpy(pstrWFIDrv->au8AssociatedBSSID, + pstrWFIDrv->strWILC_UsrConnReq.pu8bssid, ETH_ALEN); + } + } + + + if (pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs != NULL) { + strConnectInfo.ReqIEsLen = pstrWFIDrv->strWILC_UsrConnReq.ConnReqIEsLen; + strConnectInfo.pu8ReqIEs = (WILC_Uint8 *)WILC_MALLOC(pstrWFIDrv->strWILC_UsrConnReq.ConnReqIEsLen); + WILC_memcpy(strConnectInfo.pu8ReqIEs, + pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs, + pstrWFIDrv->strWILC_UsrConnReq.ConnReqIEsLen); + } + + + WILC_TimerStop(&(pstrWFIDrv->hConnectTimer), WILC_NULL); + pstrWFIDrv->strWILC_UsrConnReq.pfUserConnectResult(CONN_DISCONN_EVENT_CONN_RESP, + &strConnectInfo, + u8MacStatus, + NULL, + pstrWFIDrv->strWILC_UsrConnReq.u32UserConnectPvoid); + + + /* if received mac status is MAC_CONNECTED and + * received status code in Asoc Resp is SUCCESSFUL_STATUSCODE, change state to CONNECTED + * else change state to IDLE */ + if ((u8MacStatus == MAC_CONNECTED) && + (strConnectInfo.u16ConnectStatus == SUCCESSFUL_STATUSCODE)) { + #ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP + + host_int_set_power_mgmt((WILC_WFIDrvHandle)pstrWFIDrv, 0, 0); + #endif + + PRINT_D(HOSTINF_DBG, "MAC status : CONNECTED and Connect Status : Successful\n"); + pstrWFIDrv->enuHostIFstate = HOST_IF_CONNECTED; + + #ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP + PRINT_D(GENERIC_DBG, "Obtaining an IP, Disable Scan\n"); + g_obtainingIP = WILC_TRUE; + WILC_TimerStart(&hDuringIpTimer, 10000, WILC_NULL, WILC_NULL); + #endif + + #ifdef WILC_PARSE_SCAN_IN_HOST + /* open a BA session if possible */ + /* if(pstrWFIDrv->strWILC_UsrConnReq.IsHTCapable) */ + + #endif + + /* host_int_addBASession(pstrWFIDrv->strWILC_UsrConnReq.pu8bssid,0, */ + /* BA_SESSION_DEFAULT_BUFFER_SIZE,BA_SESSION_DEFAULT_TIMEOUT); */ + } else { + PRINT_D(HOSTINF_DBG, "MAC status : %d and Connect Status : %d\n", u8MacStatus, strConnectInfo.u16ConnectStatus); + pstrWFIDrv->enuHostIFstate = HOST_IF_IDLE; + gbScanWhileConnected = WILC_FALSE; + } + + /* Deallocation */ + if (strConnectInfo.pu8RespIEs != NULL) { + WILC_FREE(strConnectInfo.pu8RespIEs); + strConnectInfo.pu8RespIEs = NULL; + } + + if (strConnectInfo.pu8ReqIEs != NULL) { + WILC_FREE(strConnectInfo.pu8ReqIEs); + strConnectInfo.pu8ReqIEs = NULL; + } + + + pstrWFIDrv->strWILC_UsrConnReq.ssidLen = 0; + if (pstrWFIDrv->strWILC_UsrConnReq.pu8ssid != NULL) { + WILC_FREE(pstrWFIDrv->strWILC_UsrConnReq.pu8ssid); + pstrWFIDrv->strWILC_UsrConnReq.pu8ssid = NULL; + } + + if (pstrWFIDrv->strWILC_UsrConnReq.pu8bssid != NULL) { + WILC_FREE(pstrWFIDrv->strWILC_UsrConnReq.pu8bssid); + pstrWFIDrv->strWILC_UsrConnReq.pu8bssid = NULL; + } + + pstrWFIDrv->strWILC_UsrConnReq.ConnReqIEsLen = 0; + if (pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs != NULL) { + WILC_FREE(pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs); + pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs = NULL; + } + + } else if ((u8MacStatus == MAC_DISCONNECTED) && + (pstrWFIDrv->enuHostIFstate == HOST_IF_CONNECTED)) { + /* Disassociation or Deauthentication frame has been received */ + PRINT_D(HOSTINF_DBG, "Received MAC_DISCONNECTED from the FW\n"); + + WILC_memset(&strDisconnectNotifInfo, 0, sizeof(tstrDisconnectNotifInfo)); + + if (pstrWFIDrv->strWILC_UsrScanReq.pfUserScanResult) { + PRINT_D(HOSTINF_DBG, "\n\n<< Abort the running OBSS Scan >> \n\n"); + WILC_TimerStop(&(pstrWFIDrv->hScanTimer), WILC_NULL); + Handle_ScanDone((void *)pstrWFIDrv, SCAN_EVENT_ABORTED); + } + + strDisconnectNotifInfo.u16reason = 0; + strDisconnectNotifInfo.ie = NULL; + strDisconnectNotifInfo.ie_len = 0; + + if (pstrWFIDrv->strWILC_UsrConnReq.pfUserConnectResult != NULL) { + #ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP + + g_obtainingIP = WILC_FALSE; + host_int_set_power_mgmt((WILC_WFIDrvHandle)pstrWFIDrv, 0, 0); + #endif + + pstrWFIDrv->strWILC_UsrConnReq.pfUserConnectResult(CONN_DISCONN_EVENT_DISCONN_NOTIF, + NULL, + 0, + &strDisconnectNotifInfo, + pstrWFIDrv->strWILC_UsrConnReq.u32UserConnectPvoid); + + } else { + PRINT_ER("Connect result callback function is NULL \n"); + } + + WILC_memset(pstrWFIDrv->au8AssociatedBSSID, 0, ETH_ALEN); + + + /* Deallocation */ + + /* if Information Elements were retrieved from the Received deauth/disassoc frame, then they + * should be deallocated here */ + /* + * if(strDisconnectNotifInfo.ie != NULL) + * { + * WILC_FREE(strDisconnectNotifInfo.ie); + * strDisconnectNotifInfo.ie = NULL; + * } + */ + + pstrWFIDrv->strWILC_UsrConnReq.ssidLen = 0; + if (pstrWFIDrv->strWILC_UsrConnReq.pu8ssid != NULL) { + WILC_FREE(pstrWFIDrv->strWILC_UsrConnReq.pu8ssid); + pstrWFIDrv->strWILC_UsrConnReq.pu8ssid = NULL; + } + + if (pstrWFIDrv->strWILC_UsrConnReq.pu8bssid != NULL) { + WILC_FREE(pstrWFIDrv->strWILC_UsrConnReq.pu8bssid); + pstrWFIDrv->strWILC_UsrConnReq.pu8bssid = NULL; + } + + pstrWFIDrv->strWILC_UsrConnReq.ConnReqIEsLen = 0; + if (pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs != NULL) { + WILC_FREE(pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs); + pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs = NULL; + } + + /*BugID_5213*/ + /*Freeing flushed join request params on receiving*/ + /*MAC_DISCONNECTED while connected*/ + if (gu8FlushedJoinReq != NULL && gu8FlushedJoinReqDrvHandler == (WILC_Uint32)drvHandler) { + WILC_FREE(gu8FlushedJoinReq); + gu8FlushedJoinReq = NULL; + } + if (gu8FlushedInfoElemAsoc != NULL && gu8FlushedJoinReqDrvHandler == (WILC_Uint32)drvHandler) { + WILC_FREE(gu8FlushedInfoElemAsoc); + gu8FlushedInfoElemAsoc = NULL; + } + + pstrWFIDrv->enuHostIFstate = HOST_IF_IDLE; + gbScanWhileConnected = WILC_FALSE; + + } else if ((u8MacStatus == MAC_DISCONNECTED) && + (pstrWFIDrv->strWILC_UsrScanReq.pfUserScanResult != NULL)) { + PRINT_D(HOSTINF_DBG, "Received MAC_DISCONNECTED from the FW while scanning\n"); + PRINT_D(HOSTINF_DBG, "\n\n<< Abort the running Scan >> \n\n"); + /*Abort the running scan*/ + WILC_TimerStop(&(pstrWFIDrv->hScanTimer), WILC_NULL); + if (pstrWFIDrv->strWILC_UsrScanReq.pfUserScanResult) { + Handle_ScanDone((void *)pstrWFIDrv, SCAN_EVENT_ABORTED); + + } + } + + } + + WILC_CATCH(s32Error) + { + + } + + /* Deallocate pstrRcvdGnrlAsyncInfo->pu8Buffer which was prevoisuly allocated by the sending thread */ + if (pstrRcvdGnrlAsyncInfo->pu8Buffer != NULL) { + WILC_FREE(pstrRcvdGnrlAsyncInfo->pu8Buffer); + pstrRcvdGnrlAsyncInfo->pu8Buffer = NULL; + } + + return s32Error; +} + +/** + * @brief Handle_Key + * @details Sending config packet to firmware to set key + * @param[in] tstrHostIFkeyAttr* pstrHostIFkeyAttr + * @return Error code. + * @author + * @date + * @version 1.0 + */ +static int Handle_Key(void *drvHandler, tstrHostIFkeyAttr *pstrHostIFkeyAttr) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + #ifdef WILC_AP_EXTERNAL_MLME + tstrWID strWIDList[5]; + #endif + WILC_Uint8 i; + WILC_Uint8 *pu8keybuf; + WILC_Sint8 s8idxarray[1]; + WILC_Sint8 ret = 0; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler; + + + switch (pstrHostIFkeyAttr->enuKeyType) { + + + case WEP: + +#ifdef WILC_AP_EXTERNAL_MLME + if (pstrHostIFkeyAttr->u8KeyAction & ADDKEY_AP) { + + PRINT_D(HOSTINF_DBG, "Handling WEP key\n"); + PRINT_D(GENERIC_DBG, "ID Hostint is %d\n", (pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.u8Wepidx)); + strWIDList[0].u16WIDid = (WILC_Uint16)WID_11I_MODE; + strWIDList[0].enuWIDtype = WID_CHAR; + strWIDList[0].s32ValueSize = sizeof(WILC_Char); + strWIDList[0].ps8WidVal = (WILC_Sint8 *)(&(pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.u8mode)); + + strWIDList[1].u16WIDid = WID_AUTH_TYPE; + strWIDList[1].enuWIDtype = WID_CHAR; + strWIDList[1].s32ValueSize = sizeof(WILC_Char); + strWIDList[1].ps8WidVal = (WILC_Sint8 *)(&(pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.tenuAuth_type)); + + strWIDList[2].u16WIDid = (WILC_Uint16)WID_KEY_ID; + strWIDList[2].enuWIDtype = WID_CHAR; + + strWIDList[2].ps8WidVal = (WILC_Sint8 *)(&(pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.u8Wepidx)); + strWIDList[2].s32ValueSize = sizeof(WILC_Char); + + + pu8keybuf = (WILC_Uint8 *)WILC_MALLOC(pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.u8WepKeylen); + + + if (pu8keybuf == NULL) { + PRINT_ER("No buffer to send Key\n"); + return -1; + } + + WILC_memcpy(pu8keybuf, pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.pu8WepKey, + pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.u8WepKeylen); + + + WILC_FREE(pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.pu8WepKey); + + strWIDList[3].u16WIDid = (WILC_Uint16)WID_WEP_KEY_VALUE; + strWIDList[3].enuWIDtype = WID_STR; + strWIDList[3].s32ValueSize = pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.u8WepKeylen; + strWIDList[3].ps8WidVal = (WILC_Sint8 *)pu8keybuf; + + + s32Error = SendConfigPkt(SET_CFG, strWIDList, 4, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + WILC_FREE(pu8keybuf); + + + } +#endif + + if (pstrHostIFkeyAttr->u8KeyAction & ADDKEY) { + PRINT_D(HOSTINF_DBG, "Handling WEP key\n"); + pu8keybuf = (WILC_Uint8 *)WILC_MALLOC(pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.u8WepKeylen + 2); + if (pu8keybuf == NULL) { + PRINT_ER("No buffer to send Key\n"); + return -1; + } + pu8keybuf[0] = pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.u8Wepidx; + + WILC_memcpy(pu8keybuf + 1, &pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.u8WepKeylen, 1); + + WILC_memcpy(pu8keybuf + 2, pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.pu8WepKey, + pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.u8WepKeylen); + + WILC_FREE(pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.pu8WepKey); + + strWID.u16WIDid = (WILC_Uint16)WID_ADD_WEP_KEY; + strWID.enuWIDtype = WID_STR; + strWID.ps8WidVal = (WILC_Sint8 *)pu8keybuf; + strWID.s32ValueSize = pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.u8WepKeylen + 2; + + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + WILC_FREE(pu8keybuf); + } else if (pstrHostIFkeyAttr->u8KeyAction & REMOVEKEY) { + + PRINT_D(HOSTINF_DBG, "Removing key\n"); + strWID.u16WIDid = (WILC_Uint16)WID_REMOVE_WEP_KEY; + strWID.enuWIDtype = WID_STR; + + s8idxarray[0] = (WILC_Sint8)pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.u8Wepidx; + strWID.ps8WidVal = s8idxarray; + strWID.s32ValueSize = 1; + + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + } else { + strWID.u16WIDid = (WILC_Uint16)WID_KEY_ID; + strWID.enuWIDtype = WID_CHAR; + strWID.ps8WidVal = (WILC_Sint8 *)(&(pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.u8Wepidx)); + strWID.s32ValueSize = sizeof(WILC_Char); + + PRINT_D(HOSTINF_DBG, "Setting default key index\n"); + + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + } + WILC_SemaphoreRelease(&(pstrWFIDrv->hSemTestKeyBlock), WILC_NULL); + break; + + case WPARxGtk: + #ifdef WILC_AP_EXTERNAL_MLME + if (pstrHostIFkeyAttr->u8KeyAction & ADDKEY_AP) { + pu8keybuf = (WILC_Uint8 *)WILC_MALLOC(RX_MIC_KEY_MSG_LEN); + if (pu8keybuf == NULL) { + PRINT_ER("No buffer to send RxGTK Key\n"); + ret = -1; + goto _WPARxGtk_end_case_; + } + + WILC_memset(pu8keybuf, 0, RX_MIC_KEY_MSG_LEN); + + + /*|----------------------------------------------------------------------------| + * |Sta Address | Key RSC | KeyID | Key Length | Temporal Key | Rx Michael Key | + * |------------|---------|-------|------------|---------------|----------------| + | 6 bytes | 8 byte |1 byte | 1 byte | 16 bytes | 8 bytes |*/ + + + + if (pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.pu8seq != NULL) + WILC_memcpy(pu8keybuf + 6, pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.pu8seq, 8); + + + WILC_memcpy(pu8keybuf + 14, &pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.u8keyidx, 1); + + WILC_memcpy(pu8keybuf + 15, &pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.u8Keylen, 1); + + WILC_memcpy(pu8keybuf + 16, pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.pu8key, + pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.u8Keylen); + /* pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.u8Ciphermode = 0X51; */ + strWIDList[0].u16WIDid = (WILC_Uint16)WID_11I_MODE; + strWIDList[0].enuWIDtype = WID_CHAR; + strWIDList[0].s32ValueSize = sizeof(WILC_Char); + strWIDList[0].ps8WidVal = (WILC_Sint8 *)(&(pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.u8Ciphermode)); + + strWIDList[1].u16WIDid = (WILC_Uint16)WID_ADD_RX_GTK; + strWIDList[1].enuWIDtype = WID_STR; + strWIDList[1].ps8WidVal = (WILC_Sint8 *)pu8keybuf; + strWIDList[1].s32ValueSize = RX_MIC_KEY_MSG_LEN; + + s32Error = SendConfigPkt(SET_CFG, strWIDList, 2, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + + WILC_FREE(pu8keybuf); + + /* ////////////////////////// */ + WILC_SemaphoreRelease(&(pstrWFIDrv->hSemTestKeyBlock), WILC_NULL); + /* ///////////////////////// */ + } + + #endif + if (pstrHostIFkeyAttr->u8KeyAction & ADDKEY) { + PRINT_D(HOSTINF_DBG, "Handling group key(Rx) function\n"); + + pu8keybuf = (WILC_Uint8 *)WILC_MALLOC(RX_MIC_KEY_MSG_LEN); + if (pu8keybuf == NULL) { + PRINT_ER("No buffer to send RxGTK Key\n"); + ret = -1; + goto _WPARxGtk_end_case_; + } + + WILC_memset(pu8keybuf, 0, RX_MIC_KEY_MSG_LEN); + + + /*|----------------------------------------------------------------------------| + * |Sta Address | Key RSC | KeyID | Key Length | Temporal Key | Rx Michael Key | + * |------------|---------|-------|------------|---------------|----------------| + | 6 bytes | 8 byte |1 byte | 1 byte | 16 bytes | 8 bytes |*/ + + if (pstrWFIDrv->enuHostIFstate == HOST_IF_CONNECTED) { + WILC_memcpy(pu8keybuf, pstrWFIDrv->au8AssociatedBSSID, ETH_ALEN); + } else { + PRINT_ER("Couldn't handle WPARxGtk while enuHostIFstate is not HOST_IF_CONNECTED \n"); + } + + WILC_memcpy(pu8keybuf + 6, pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.pu8seq, 8); + + WILC_memcpy(pu8keybuf + 14, &pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.u8keyidx, 1); + + WILC_memcpy(pu8keybuf + 15, &pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.u8Keylen, 1); + WILC_memcpy(pu8keybuf + 16, pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.pu8key, + pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.u8Keylen); + + strWID.u16WIDid = (WILC_Uint16)WID_ADD_RX_GTK; + strWID.enuWIDtype = WID_STR; + strWID.ps8WidVal = (WILC_Sint8 *)pu8keybuf; + strWID.s32ValueSize = RX_MIC_KEY_MSG_LEN; + + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + + WILC_FREE(pu8keybuf); + + /* ////////////////////////// */ + WILC_SemaphoreRelease(&(pstrWFIDrv->hSemTestKeyBlock), WILC_NULL); + /* ///////////////////////// */ + } +_WPARxGtk_end_case_: + WILC_FREE(pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.pu8key); + WILC_FREE(pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.pu8seq); + if (ret == -1) + return ret; + + break; + + case WPAPtk: + #ifdef WILC_AP_EXTERNAL_MLME + if (pstrHostIFkeyAttr->u8KeyAction & ADDKEY_AP) { + + + pu8keybuf = (WILC_Uint8 *)WILC_MALLOC(PTK_KEY_MSG_LEN + 1); + + + + if (pu8keybuf == NULL) { + PRINT_ER("No buffer to send PTK Key\n"); + ret = -1; + goto _WPAPtk_end_case_; + + } + + /*|-----------------------------------------------------------------------------| + * |Station address | keyidx |Key Length |Temporal Key | Rx Michael Key |Tx Michael Key | + * |----------------|------------ |--------------|----------------|---------------| + | 6 bytes | 1 byte | 1byte | 16 bytes | 8 bytes | 8 bytes | + |-----------------------------------------------------------------------------|*/ + + WILC_memcpy(pu8keybuf, pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.pu8macaddr, 6); /*1 bytes Key Length */ + + WILC_memcpy(pu8keybuf + 6, &pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.u8keyidx, 1); + WILC_memcpy(pu8keybuf + 7, &pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.u8Keylen, 1); + /*16 byte TK*/ + WILC_memcpy(pu8keybuf + 8, pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.pu8key, + pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.u8Keylen); + + + strWIDList[0].u16WIDid = (WILC_Uint16)WID_11I_MODE; + strWIDList[0].enuWIDtype = WID_CHAR; + strWIDList[0].s32ValueSize = sizeof(WILC_Char); + strWIDList[0].ps8WidVal = (WILC_Sint8 *)(&(pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.u8Ciphermode)); + + strWIDList[1].u16WIDid = (WILC_Uint16)WID_ADD_PTK; + strWIDList[1].enuWIDtype = WID_STR; + strWIDList[1].ps8WidVal = (WILC_Sint8 *)pu8keybuf; + strWIDList[1].s32ValueSize = PTK_KEY_MSG_LEN + 1; + + s32Error = SendConfigPkt(SET_CFG, strWIDList, 2, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + WILC_FREE(pu8keybuf); + + /* ////////////////////////// */ + WILC_SemaphoreRelease(&(pstrWFIDrv->hSemTestKeyBlock), WILC_NULL); + /* ///////////////////////// */ + } + #endif + if (pstrHostIFkeyAttr->u8KeyAction & ADDKEY) { + + + pu8keybuf = (WILC_Uint8 *)WILC_MALLOC(PTK_KEY_MSG_LEN); + + + + if (pu8keybuf == NULL) { + PRINT_ER("No buffer to send PTK Key\n"); + ret = -1; + goto _WPAPtk_end_case_; + + } + + /*|-----------------------------------------------------------------------------| + * |Station address | Key Length | Temporal Key | Rx Michael Key |Tx Michael Key | + * |----------------|------------|--------------|----------------|---------------| + | 6 bytes | 1byte | 16 bytes | 8 bytes | 8 bytes | + |-----------------------------------------------------------------------------|*/ + + WILC_memcpy(pu8keybuf, pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.pu8macaddr, 6); /*1 bytes Key Length */ + + WILC_memcpy(pu8keybuf + 6, &pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.u8Keylen, 1); + /*16 byte TK*/ + WILC_memcpy(pu8keybuf + 7, pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.pu8key, + pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.u8Keylen); + + + strWID.u16WIDid = (WILC_Uint16)WID_ADD_PTK; + strWID.enuWIDtype = WID_STR; + strWID.ps8WidVal = (WILC_Sint8 *)pu8keybuf; + strWID.s32ValueSize = PTK_KEY_MSG_LEN; + + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + WILC_FREE(pu8keybuf); + + /* ////////////////////////// */ + WILC_SemaphoreRelease(&(pstrWFIDrv->hSemTestKeyBlock), WILC_NULL); + /* ///////////////////////// */ + } + +_WPAPtk_end_case_: + WILC_FREE(pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.pu8key); + if (ret == -1) + return ret; + + break; + + + case PMKSA: + + PRINT_D(HOSTINF_DBG, "Handling PMKSA key\n"); + + pu8keybuf = (WILC_Uint8 *)WILC_MALLOC((pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFpmkidAttr.numpmkid * PMKSA_KEY_LEN) + 1); + if (pu8keybuf == NULL) { + PRINT_ER("No buffer to send PMKSA Key\n"); + return -1; + } + + pu8keybuf[0] = pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFpmkidAttr.numpmkid; + + for (i = 0; i < pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFpmkidAttr.numpmkid; i++) { + + WILC_memcpy(pu8keybuf + ((PMKSA_KEY_LEN * i) + 1), pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFpmkidAttr.pmkidlist[i].bssid, ETH_ALEN); + WILC_memcpy(pu8keybuf + ((PMKSA_KEY_LEN * i) + ETH_ALEN + 1), pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFpmkidAttr.pmkidlist[i].pmkid, PMKID_LEN); + } + + strWID.u16WIDid = (WILC_Uint16)WID_PMKID_INFO; + strWID.enuWIDtype = WID_STR; + strWID.ps8WidVal = (WILC_Sint8 *)pu8keybuf; + strWID.s32ValueSize = (pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFpmkidAttr.numpmkid * PMKSA_KEY_LEN) + 1; + + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + + WILC_FREE(pu8keybuf); + break; + } + + if (s32Error) + PRINT_ER("Failed to send key config packet\n"); + + + return s32Error; +} + + +/** + * @brief Handle_Disconnect + * @details Sending config packet to firmware to disconnect + * @param[in] NONE + * @return NONE + * @author + * @date + * @version 1.0 + */ +static void Handle_Disconnect(void *drvHandler) +{ + tstrWID strWID; + + WILC_Sint32 s32Error = WILC_SUCCESS; + WILC_Uint16 u16DummyReasonCode = 0; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler; + + + strWID.u16WIDid = (WILC_Uint16)WID_DISCONNECT; + strWID.enuWIDtype = WID_CHAR; + strWID.ps8WidVal = (WILC_Sint8 *)&u16DummyReasonCode; + strWID.s32ValueSize = sizeof(WILC_Char); + + + + PRINT_D(HOSTINF_DBG, "Sending disconnect request\n"); + + #ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP + + g_obtainingIP = WILC_FALSE; + host_int_set_power_mgmt((WILC_WFIDrvHandle)pstrWFIDrv, 0, 0); + #endif + + WILC_memset(u8ConnectedSSID, 0, ETH_ALEN); + + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_FALSE, (WILC_Uint32)pstrWFIDrv); + + if (s32Error) { + PRINT_ER("Failed to send dissconect config packet\n"); + WILC_ERRORREPORT(s32Error, WILC_FAIL); + } else { + tstrDisconnectNotifInfo strDisconnectNotifInfo; + + WILC_memset(&strDisconnectNotifInfo, 0, sizeof(tstrDisconnectNotifInfo)); + + strDisconnectNotifInfo.u16reason = 0; + strDisconnectNotifInfo.ie = NULL; + strDisconnectNotifInfo.ie_len = 0; + + if (pstrWFIDrv->strWILC_UsrScanReq.pfUserScanResult) { + WILC_TimerStop(&(pstrWFIDrv->hScanTimer), WILC_NULL); + pstrWFIDrv->strWILC_UsrScanReq.pfUserScanResult(SCAN_EVENT_ABORTED, WILC_NULL, + pstrWFIDrv->strWILC_UsrScanReq.u32UserScanPvoid, NULL); + + pstrWFIDrv->strWILC_UsrScanReq.pfUserScanResult = WILC_NULL; + } + + if (pstrWFIDrv->strWILC_UsrConnReq.pfUserConnectResult != NULL) { + + /*BugID_5193*/ + /*Stop connect timer, if connection in progress*/ + if (pstrWFIDrv->enuHostIFstate == HOST_IF_WAITING_CONN_RESP) { + PRINT_D(HOSTINF_DBG, "Upper layer requested termination of connection\n"); + WILC_TimerStop(&(pstrWFIDrv->hConnectTimer), WILC_NULL); + } + + pstrWFIDrv->strWILC_UsrConnReq.pfUserConnectResult(CONN_DISCONN_EVENT_DISCONN_NOTIF, NULL, + 0, &strDisconnectNotifInfo, pstrWFIDrv->strWILC_UsrConnReq.u32UserConnectPvoid); + } else { + PRINT_ER("strWILC_UsrConnReq.pfUserConnectResult = NULL \n"); + } + + gbScanWhileConnected = WILC_FALSE; + + pstrWFIDrv->enuHostIFstate = HOST_IF_IDLE; + + WILC_memset(pstrWFIDrv->au8AssociatedBSSID, 0, ETH_ALEN); + + + /* Deallocation */ + pstrWFIDrv->strWILC_UsrConnReq.ssidLen = 0; + if (pstrWFIDrv->strWILC_UsrConnReq.pu8ssid != NULL) { + WILC_FREE(pstrWFIDrv->strWILC_UsrConnReq.pu8ssid); + pstrWFIDrv->strWILC_UsrConnReq.pu8ssid = NULL; + } + + if (pstrWFIDrv->strWILC_UsrConnReq.pu8bssid != NULL) { + WILC_FREE(pstrWFIDrv->strWILC_UsrConnReq.pu8bssid); + pstrWFIDrv->strWILC_UsrConnReq.pu8bssid = NULL; + } + + pstrWFIDrv->strWILC_UsrConnReq.ConnReqIEsLen = 0; + if (pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs != NULL) { + WILC_FREE(pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs); + pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs = NULL; + } + + + /*BugID_5137*/ + if (gu8FlushedJoinReq != NULL && gu8FlushedJoinReqDrvHandler == (WILC_Uint32)drvHandler) { + WILC_FREE(gu8FlushedJoinReq); + gu8FlushedJoinReq = NULL; + } + if (gu8FlushedInfoElemAsoc != NULL && gu8FlushedJoinReqDrvHandler == (WILC_Uint32)drvHandler) { + WILC_FREE(gu8FlushedInfoElemAsoc); + gu8FlushedInfoElemAsoc = NULL; + } + + } + + WILC_CATCH(s32Error) + { + + } + + /* ////////////////////////// */ + WILC_SemaphoreRelease(&(pstrWFIDrv->hSemTestDisconnectBlock), WILC_NULL); + /* ///////////////////////// */ + +} + + +void resolve_disconnect_aberration(void *drvHandler) +{ + tstrWILC_WFIDrv *pstrWFIDrv; + + pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler; + if (pstrWFIDrv == WILC_NULL) + return; + if ((pstrWFIDrv->enuHostIFstate == HOST_IF_WAITING_CONN_RESP) || (pstrWFIDrv->enuHostIFstate == HOST_IF_CONNECTING)) { + PRINT_D(HOSTINF_DBG, "\n\n<< correcting Supplicant state machine >>\n\n"); + host_int_disconnect((WILC_WFIDrvHandle)pstrWFIDrv, 1); + } +} +static WILC_Sint32 Switch_Log_Terminal(void *drvHandler) +{ + + + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + static char dummy = 9; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler; + + strWID.u16WIDid = (WILC_Uint16)WID_LOGTerminal_Switch; + strWID.enuWIDtype = WID_CHAR; + strWID.ps8WidVal = &dummy; + strWID.s32ValueSize = sizeof(WILC_Char); + + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + + + if (s32Error) { + PRINT_D(HOSTINF_DBG, "Failed to switch log terminal\n"); + WILC_ERRORREPORT(s32Error, WILC_INVALID_STATE); + } else { + PRINT_INFO(HOSTINF_DBG, "MAC address set :: \n"); + + + } + + WILC_CATCH(s32Error) + { + + } + + return s32Error; +} + +/** + * @brief Handle_GetChnl + * @details Sending config packet to get channel + * @param[in] NONE + * @return NONE + * + * @author + * @date + * @version 1.0 + */ +static WILC_Sint32 Handle_GetChnl(void *drvHandler) +{ + + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + /* tstrWILC_WFIDrv * pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; */ + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler; + strWID.u16WIDid = (WILC_Uint16)WID_CURRENT_CHANNEL; + strWID.enuWIDtype = WID_CHAR; + strWID.ps8WidVal = (WILC_Sint8 *)&gu8Chnl; + strWID.s32ValueSize = sizeof(WILC_Char); + + PRINT_D(HOSTINF_DBG, "Getting channel value\n"); + + s32Error = SendConfigPkt(GET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + /*get the value by searching the local copy*/ + if (s32Error) { + PRINT_ER("Failed to get channel number\n"); + WILC_ERRORREPORT(s32Error, WILC_FAIL); + } + + + WILC_CATCH(s32Error) + { + + } + WILC_SemaphoreRelease(&(pstrWFIDrv->hSemGetCHNL), WILC_NULL); + + return s32Error; + + + +} + + +/** + * @brief Handle_GetRssi + * @details Sending config packet to get RSSI + * @param[in] NONE + * @return NONE + * @author + * @date + * @version 1.0 + */ +static void Handle_GetRssi(void *drvHandler) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler; + + strWID.u16WIDid = (WILC_Uint16)WID_RSSI; + strWID.enuWIDtype = WID_CHAR; + strWID.ps8WidVal = &gs8Rssi; + strWID.s32ValueSize = sizeof(WILC_Char); + + /*Sending Cfg*/ + PRINT_D(HOSTINF_DBG, "Getting RSSI value\n"); + + s32Error = SendConfigPkt(GET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + if (s32Error) { + PRINT_ER("Failed to get RSSI value\n"); + WILC_ERRORREPORT(s32Error, WILC_FAIL); + } + + WILC_CATCH(s32Error) + { + + } + WILC_SemaphoreRelease(&(pstrWFIDrv->hSemGetRSSI), WILC_NULL); + + +} + + +static void Handle_GetLinkspeed(void *drvHandler) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler; + + gs8lnkspd = 0; + + strWID.u16WIDid = (WILC_Uint16)WID_LINKSPEED; + strWID.enuWIDtype = WID_CHAR; + strWID.ps8WidVal = &gs8lnkspd; + strWID.s32ValueSize = sizeof(WILC_Char); + /*Sending Cfg*/ + PRINT_D(HOSTINF_DBG, "Getting LINKSPEED value\n"); + + s32Error = SendConfigPkt(GET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + if (s32Error) { + PRINT_ER("Failed to get LINKSPEED value\n"); + WILC_ERRORREPORT(s32Error, WILC_FAIL); + } + + WILC_CATCH(s32Error) + { + + } + WILC_SemaphoreRelease(&(pstrWFIDrv->hSemGetLINKSPEED), WILC_NULL); + + +} + +WILC_Sint32 Handle_GetStatistics(void *drvHandler, tstrStatistics *pstrStatistics) +{ + tstrWID strWIDList[5]; + uint32_t u32WidsCount = 0, s32Error = 0; + + strWIDList[u32WidsCount].u16WIDid = WID_LINKSPEED; + strWIDList[u32WidsCount].enuWIDtype = WID_CHAR; + strWIDList[u32WidsCount].s32ValueSize = sizeof(WILC_Char); + strWIDList[u32WidsCount].ps8WidVal = (WILC_Sint8 *)(&(pstrStatistics->u8LinkSpeed)); + u32WidsCount++; + + strWIDList[u32WidsCount].u16WIDid = WID_RSSI; + strWIDList[u32WidsCount].enuWIDtype = WID_CHAR; + strWIDList[u32WidsCount].s32ValueSize = sizeof(WILC_Char); + strWIDList[u32WidsCount].ps8WidVal = (WILC_Sint8 *)(&(pstrStatistics->s8RSSI)); + u32WidsCount++; + + strWIDList[u32WidsCount].u16WIDid = WID_SUCCESS_FRAME_COUNT; + strWIDList[u32WidsCount].enuWIDtype = WID_INT; + strWIDList[u32WidsCount].s32ValueSize = sizeof(WILC_Uint32); + strWIDList[u32WidsCount].ps8WidVal = (WILC_Sint8 *)(&(pstrStatistics->u32TxCount)); + u32WidsCount++; + + strWIDList[u32WidsCount].u16WIDid = WID_RECEIVED_FRAGMENT_COUNT; + strWIDList[u32WidsCount].enuWIDtype = WID_INT; + strWIDList[u32WidsCount].s32ValueSize = sizeof(WILC_Uint32); + strWIDList[u32WidsCount].ps8WidVal = (WILC_Sint8 *)(&(pstrStatistics->u32RxCount)); + u32WidsCount++; + + strWIDList[u32WidsCount].u16WIDid = WID_FAILED_COUNT; + strWIDList[u32WidsCount].enuWIDtype = WID_INT; + strWIDList[u32WidsCount].s32ValueSize = sizeof(WILC_Uint32); + strWIDList[u32WidsCount].ps8WidVal = (WILC_Sint8 *)(&(pstrStatistics->u32TxFailureCount)); + u32WidsCount++; + + s32Error = SendConfigPkt(GET_CFG, strWIDList, u32WidsCount, WILC_FALSE, (WILC_Uint32)drvHandler); + + if (s32Error) { + PRINT_ER("Failed to send scan paramters config packet\n"); + /* WILC_ERRORREPORT(s32Error, s32Error); */ + } + WILC_SemaphoreRelease(&hWaitResponse, NULL); + return 0; + +} + + +#ifdef WILC_AP_EXTERNAL_MLME + + +/** + * @brief Handle_Get_InActiveTime + * @details Sending config packet to set mac adddress for station and + * get inactive time + * @param[in] NONE + * @return NONE + * + * @author + * @date + * @version 1.0 + */ +static WILC_Sint32 Handle_Get_InActiveTime(void *drvHandler, tstrHostIfStaInactiveT *strHostIfStaInactiveT) +{ + + WILC_Sint32 s32Error = WILC_SUCCESS; + WILC_Uint8 *stamac; + tstrWID strWID; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler; + + + strWID.u16WIDid = (WILC_Uint16)WID_SET_STA_MAC_INACTIVE_TIME; + strWID.enuWIDtype = WID_STR; + strWID.s32ValueSize = ETH_ALEN; + strWID.ps8WidVal = (WILC_Uint8 *)WILC_MALLOC(strWID.s32ValueSize); + + + stamac = strWID.ps8WidVal; + WILC_memcpy(stamac, strHostIfStaInactiveT->mac, ETH_ALEN); + + + PRINT_D(CFG80211_DBG, "SETING STA inactive time\n"); + + + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + /*get the value by searching the local copy*/ + if (s32Error) { + PRINT_ER("Failed to SET incative time\n"); + WILC_ERRORREPORT(s32Error, WILC_FAIL); + } + + + strWID.u16WIDid = (WILC_Uint16)WID_GET_INACTIVE_TIME; + strWID.enuWIDtype = WID_INT; + strWID.ps8WidVal = (WILC_Sint8 *)&gu32InactiveTime; + strWID.s32ValueSize = sizeof(WILC_Uint32); + + + s32Error = SendConfigPkt(GET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + /*get the value by searching the local copy*/ + if (s32Error) { + PRINT_ER("Failed to get incative time\n"); + WILC_ERRORREPORT(s32Error, WILC_FAIL); + } + + + PRINT_D(CFG80211_DBG, "Getting inactive time : %d\n", gu32InactiveTime); + + WILC_SemaphoreRelease(&(pstrWFIDrv->hSemInactiveTime), WILC_NULL); + WILC_CATCH(s32Error) + { + + } + + + return s32Error; + + + +} + + +/** + * @brief Handle_AddBeacon + * @details Sending config packet to add beacon + * @param[in] tstrHostIFSetBeacon* pstrSetBeaconParam + * @return NONE + * @author + * @date + * @version 1.0 + */ +static void Handle_AddBeacon(void *drvHandler, tstrHostIFSetBeacon *pstrSetBeaconParam) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + WILC_Uint8 *pu8CurrByte; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler; + PRINT_D(HOSTINF_DBG, "Adding BEACON\n"); + + strWID.u16WIDid = (WILC_Uint16)WID_ADD_BEACON; + strWID.enuWIDtype = WID_BIN; + strWID.s32ValueSize = pstrSetBeaconParam->u32HeadLen + pstrSetBeaconParam->u32TailLen + 16; + strWID.ps8WidVal = WILC_MALLOC(strWID.s32ValueSize); + if (strWID.ps8WidVal == NULL) { + WILC_ERRORREPORT(s32Error, WILC_NO_MEM); + } + + pu8CurrByte = strWID.ps8WidVal; + *pu8CurrByte++ = (pstrSetBeaconParam->u32Interval & 0xFF); + *pu8CurrByte++ = ((pstrSetBeaconParam->u32Interval >> 8) & 0xFF); + *pu8CurrByte++ = ((pstrSetBeaconParam->u32Interval >> 16) & 0xFF); + *pu8CurrByte++ = ((pstrSetBeaconParam->u32Interval >> 24) & 0xFF); + + *pu8CurrByte++ = (pstrSetBeaconParam->u32DTIMPeriod & 0xFF); + *pu8CurrByte++ = ((pstrSetBeaconParam->u32DTIMPeriod >> 8) & 0xFF); + *pu8CurrByte++ = ((pstrSetBeaconParam->u32DTIMPeriod >> 16) & 0xFF); + *pu8CurrByte++ = ((pstrSetBeaconParam->u32DTIMPeriod >> 24) & 0xFF); + + *pu8CurrByte++ = (pstrSetBeaconParam->u32HeadLen & 0xFF); + *pu8CurrByte++ = ((pstrSetBeaconParam->u32HeadLen >> 8) & 0xFF); + *pu8CurrByte++ = ((pstrSetBeaconParam->u32HeadLen >> 16) & 0xFF); + *pu8CurrByte++ = ((pstrSetBeaconParam->u32HeadLen >> 24) & 0xFF); + + memcpy(pu8CurrByte, pstrSetBeaconParam->pu8Head, pstrSetBeaconParam->u32HeadLen); + pu8CurrByte += pstrSetBeaconParam->u32HeadLen; + + *pu8CurrByte++ = (pstrSetBeaconParam->u32TailLen & 0xFF); + *pu8CurrByte++ = ((pstrSetBeaconParam->u32TailLen >> 8) & 0xFF); + *pu8CurrByte++ = ((pstrSetBeaconParam->u32TailLen >> 16) & 0xFF); + *pu8CurrByte++ = ((pstrSetBeaconParam->u32TailLen >> 24) & 0xFF); + + /* Bug 4599 : if tail length = 0 skip copying */ + if (pstrSetBeaconParam->pu8Tail > 0) + memcpy(pu8CurrByte, pstrSetBeaconParam->pu8Tail, pstrSetBeaconParam->u32TailLen); + pu8CurrByte += pstrSetBeaconParam->u32TailLen; + + + + /*Sending Cfg*/ + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_FALSE, (WILC_Uint32)pstrWFIDrv); + if (s32Error) { + PRINT_ER("Failed to send add beacon config packet\n"); + WILC_ERRORREPORT(s32Error, WILC_FAIL); + } + + WILC_CATCH(s32Error) + { + } + WILC_FREE_IF_TRUE(strWID.ps8WidVal); + WILC_FREE_IF_TRUE(pstrSetBeaconParam->pu8Head); + WILC_FREE_IF_TRUE(pstrSetBeaconParam->pu8Tail); +} + + +/** + * @brief Handle_AddBeacon + * @details Sending config packet to delete beacon + * @param[in] tstrHostIFDelBeacon* pstrDelBeacon + * @return NONE + * @author + * @date + * @version 1.0 + */ +static void Handle_DelBeacon(void *drvHandler, tstrHostIFDelBeacon *pstrDelBeacon) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + WILC_Uint8 *pu8CurrByte; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler; + strWID.u16WIDid = (WILC_Uint16)WID_DEL_BEACON; + strWID.enuWIDtype = WID_CHAR; + strWID.s32ValueSize = sizeof(WILC_Char); + strWID.ps8WidVal = &gu8DelBcn; + + if (strWID.ps8WidVal == NULL) { + WILC_ERRORREPORT(s32Error, WILC_NO_MEM); + } + + pu8CurrByte = strWID.ps8WidVal; + + PRINT_D(HOSTINF_DBG, "Deleting BEACON\n"); + /* TODO: build del beacon message*/ + + /*Sending Cfg*/ + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_FALSE, (WILC_Uint32)pstrWFIDrv); + if (s32Error) { + + PRINT_ER("Failed to send delete beacon config packet\n"); + WILC_ERRORREPORT(s32Error, WILC_FAIL); + } + + WILC_CATCH(s32Error) + { + } +} + + +/** + * @brief WILC_HostIf_PackStaParam + * @details Handling packing of the station params in a buffer + * @param[in] WILC_Uint8* pu8Buffer, tstrWILC_AddStaParam* pstrStationParam + * @return NONE + * @author + * @date + * @version 1.0 + */ +static WILC_Uint32 WILC_HostIf_PackStaParam(WILC_Uint8 *pu8Buffer, tstrWILC_AddStaParam *pstrStationParam) +{ + WILC_Uint8 *pu8CurrByte; + + pu8CurrByte = pu8Buffer; + + PRINT_D(HOSTINF_DBG, "Packing STA params\n"); + WILC_memcpy(pu8CurrByte, pstrStationParam->au8BSSID, ETH_ALEN); + pu8CurrByte += ETH_ALEN; + + *pu8CurrByte++ = pstrStationParam->u16AssocID & 0xFF; + *pu8CurrByte++ = (pstrStationParam->u16AssocID >> 8) & 0xFF; + + *pu8CurrByte++ = pstrStationParam->u8NumRates; + if (pstrStationParam->u8NumRates > 0) { + WILC_memcpy(pu8CurrByte, pstrStationParam->pu8Rates, pstrStationParam->u8NumRates); + } + pu8CurrByte += pstrStationParam->u8NumRates; + + *pu8CurrByte++ = pstrStationParam->bIsHTSupported; + *pu8CurrByte++ = pstrStationParam->u16HTCapInfo & 0xFF; + *pu8CurrByte++ = (pstrStationParam->u16HTCapInfo >> 8) & 0xFF; + + *pu8CurrByte++ = pstrStationParam->u8AmpduParams; + WILC_memcpy(pu8CurrByte, pstrStationParam->au8SuppMCsSet, WILC_SUPP_MCS_SET_SIZE); + pu8CurrByte += WILC_SUPP_MCS_SET_SIZE; + + *pu8CurrByte++ = pstrStationParam->u16HTExtParams & 0xFF; + *pu8CurrByte++ = (pstrStationParam->u16HTExtParams >> 8) & 0xFF; + + *pu8CurrByte++ = pstrStationParam->u32TxBeamformingCap & 0xFF; + *pu8CurrByte++ = (pstrStationParam->u32TxBeamformingCap >> 8) & 0xFF; + *pu8CurrByte++ = (pstrStationParam->u32TxBeamformingCap >> 16) & 0xFF; + *pu8CurrByte++ = (pstrStationParam->u32TxBeamformingCap >> 24) & 0xFF; + + *pu8CurrByte++ = pstrStationParam->u8ASELCap; + + *pu8CurrByte++ = pstrStationParam->u16FlagsMask & 0xFF; + *pu8CurrByte++ = (pstrStationParam->u16FlagsMask >> 8) & 0xFF; + + *pu8CurrByte++ = pstrStationParam->u16FlagsSet & 0xFF; + *pu8CurrByte++ = (pstrStationParam->u16FlagsSet >> 8) & 0xFF; + + return pu8CurrByte - pu8Buffer; +} + +/** + * @brief Handle_AddStation + * @details Sending config packet to add station + * @param[in] tstrWILC_AddStaParam* pstrStationParam + * @return NONE + * @author + * @date + * @version 1.0 + */ +static void Handle_AddStation(void *drvHandler, tstrWILC_AddStaParam *pstrStationParam) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + WILC_Uint8 *pu8CurrByte; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler; + PRINT_D(HOSTINF_DBG, "Handling add station\n"); + strWID.u16WIDid = (WILC_Uint16)WID_ADD_STA; + strWID.enuWIDtype = WID_BIN; + strWID.s32ValueSize = WILC_ADD_STA_LENGTH + pstrStationParam->u8NumRates; + + strWID.ps8WidVal = WILC_MALLOC(strWID.s32ValueSize); + if (strWID.ps8WidVal == NULL) { + WILC_ERRORREPORT(s32Error, WILC_NO_MEM); + } + + pu8CurrByte = strWID.ps8WidVal; + pu8CurrByte += WILC_HostIf_PackStaParam(pu8CurrByte, pstrStationParam); + + /*Sending Cfg*/ + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_FALSE, (WILC_Uint32)pstrWFIDrv); + if (s32Error != WILC_SUCCESS) { + + PRINT_ER("Failed to send add station config packet\n"); + WILC_ERRORREPORT(s32Error, WILC_FAIL); + } + + WILC_CATCH(s32Error) + { + } + WILC_FREE_IF_TRUE(pstrStationParam->pu8Rates); + WILC_FREE_IF_TRUE(strWID.ps8WidVal); +} + +/** + * @brief Handle_DelAllSta + * @details Sending config packet to delete station + * @param[in] tstrHostIFDelSta* pstrDelStaParam + * @return NONE + * @author + * @date + * @version 1.0 + */ +static void Handle_DelAllSta(void *drvHandler, tstrHostIFDelAllSta *pstrDelAllStaParam) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + WILC_Uint8 *pu8CurrByte; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler; + WILC_Uint8 i; + UWORD8 au8Zero_Buff[6] = {0}; + strWID.u16WIDid = (WILC_Uint16)WID_DEL_ALL_STA; + strWID.enuWIDtype = WID_STR; + strWID.s32ValueSize = (pstrDelAllStaParam->u8Num_AssocSta * ETH_ALEN) + 1; + + PRINT_D(HOSTINF_DBG, "Handling delete station \n"); + + strWID.ps8WidVal = WILC_MALLOC((pstrDelAllStaParam->u8Num_AssocSta * ETH_ALEN) + 1); + if (strWID.ps8WidVal == NULL) { + WILC_ERRORREPORT(s32Error, WILC_NO_MEM); + } + + pu8CurrByte = strWID.ps8WidVal; + + *(pu8CurrByte++) = pstrDelAllStaParam->u8Num_AssocSta; + + for (i = 0; i < MAX_NUM_STA; i++) { + if (memcmp(pstrDelAllStaParam->au8Sta_DelAllSta[i], au8Zero_Buff, ETH_ALEN)) + WILC_memcpy(pu8CurrByte, pstrDelAllStaParam->au8Sta_DelAllSta[i], ETH_ALEN); + else + continue; + + pu8CurrByte += ETH_ALEN; + } + + /*Sending Cfg*/ + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + if (s32Error) { + + PRINT_ER("Failed to send add station config packe\n"); + WILC_ERRORREPORT(s32Error, WILC_FAIL); + } + + WILC_CATCH(s32Error) + { + } + WILC_FREE_IF_TRUE(strWID.ps8WidVal); + + WILC_SemaphoreRelease(&hWaitResponse, NULL); +} + + +/** + * @brief Handle_DelStation + * @details Sending config packet to delete station + * @param[in] tstrHostIFDelSta* pstrDelStaParam + * @return NONE + * @author + * @date + * @version 1.0 + */ +static void Handle_DelStation(void *drvHandler, tstrHostIFDelSta *pstrDelStaParam) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + WILC_Uint8 *pu8CurrByte; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler; + + strWID.u16WIDid = (WILC_Uint16)WID_REMOVE_STA; + strWID.enuWIDtype = WID_BIN; + strWID.s32ValueSize = ETH_ALEN; + + PRINT_D(HOSTINF_DBG, "Handling delete station \n"); + + strWID.ps8WidVal = WILC_MALLOC(strWID.s32ValueSize); + if (strWID.ps8WidVal == NULL) { + WILC_ERRORREPORT(s32Error, WILC_NO_MEM); + } + + pu8CurrByte = strWID.ps8WidVal; + + WILC_memcpy(pu8CurrByte, pstrDelStaParam->au8MacAddr, ETH_ALEN); + + /*Sending Cfg*/ + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_FALSE, (WILC_Uint32)pstrWFIDrv); + if (s32Error) { + + PRINT_ER("Failed to send add station config packe\n"); + WILC_ERRORREPORT(s32Error, WILC_FAIL); + } + + WILC_CATCH(s32Error) + { + } + WILC_FREE_IF_TRUE(strWID.ps8WidVal); +} + + +/** + * @brief Handle_EditStation + * @details Sending config packet to edit station + * @param[in] tstrWILC_AddStaParam* pstrStationParam + * @return NONE + * @author + * @date + * @version 1.0 + */ +static void Handle_EditStation(void *drvHandler, tstrWILC_AddStaParam *pstrStationParam) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + WILC_Uint8 *pu8CurrByte; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler; + + strWID.u16WIDid = (WILC_Uint16)WID_EDIT_STA; + strWID.enuWIDtype = WID_BIN; + strWID.s32ValueSize = WILC_ADD_STA_LENGTH + pstrStationParam->u8NumRates; + + PRINT_D(HOSTINF_DBG, "Handling edit station\n"); + strWID.ps8WidVal = WILC_MALLOC(strWID.s32ValueSize); + if (strWID.ps8WidVal == NULL) { + WILC_ERRORREPORT(s32Error, WILC_NO_MEM); + } + + pu8CurrByte = strWID.ps8WidVal; + pu8CurrByte += WILC_HostIf_PackStaParam(pu8CurrByte, pstrStationParam); + + /*Sending Cfg*/ + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_FALSE, (WILC_Uint32)pstrWFIDrv); + if (s32Error) { + + PRINT_ER("Failed to send edit station config packet\n"); + WILC_ERRORREPORT(s32Error, WILC_FAIL); + } + + WILC_CATCH(s32Error) + { + } + WILC_FREE_IF_TRUE(pstrStationParam->pu8Rates); + WILC_FREE_IF_TRUE(strWID.ps8WidVal); +} +#endif /*WILC_AP_EXTERNAL_MLME*/ + +#ifdef WILC_P2P +/** + * @brief Handle_RemainOnChan + * @details Sending config packet to edit station + * @param[in] tstrWILC_AddStaParam* pstrStationParam + * @return NONE + * @author + * @date + * @version 1.0 + */ +static int Handle_RemainOnChan(void *drvHandler, tstrHostIfRemainOnChan *pstrHostIfRemainOnChan) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + WILC_Uint8 u8remain_on_chan_flag; + tstrWID strWID; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *) drvHandler; + + /*If it's a pendig remain-on-channel, don't overwrite gWFiDrvHandle values (since incoming msg is garbbage)*/ + if (!pstrWFIDrv->u8RemainOnChan_pendingreq) { + pstrWFIDrv->strHostIfRemainOnChan.pVoid = pstrHostIfRemainOnChan->pVoid; + pstrWFIDrv->strHostIfRemainOnChan.pRemainOnChanExpired = pstrHostIfRemainOnChan->pRemainOnChanExpired; + pstrWFIDrv->strHostIfRemainOnChan.pRemainOnChanReady = pstrHostIfRemainOnChan->pRemainOnChanReady; + pstrWFIDrv->strHostIfRemainOnChan.u16Channel = pstrHostIfRemainOnChan->u16Channel; + pstrWFIDrv->strHostIfRemainOnChan.u32ListenSessionID = pstrHostIfRemainOnChan->u32ListenSessionID; + } else { + /*Set the channel to use it as a wid val*/ + pstrHostIfRemainOnChan->u16Channel = pstrWFIDrv->strHostIfRemainOnChan.u16Channel; + } + + if (pstrWFIDrv->strWILC_UsrScanReq.pfUserScanResult != NULL) { + PRINT_INFO(GENERIC_DBG, "Required to remain on chan while scanning return\n"); + pstrWFIDrv->u8RemainOnChan_pendingreq = 1; + WILC_ERRORREPORT(s32Error, WILC_BUSY); + } + if (pstrWFIDrv->enuHostIFstate == HOST_IF_WAITING_CONN_RESP) { + PRINT_INFO(GENERIC_DBG, "Required to remain on chan while connecting return\n"); + WILC_ERRORREPORT(s32Error, WILC_BUSY); + } + + #ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP + if (g_obtainingIP || connecting) { + PRINT_D(GENERIC_DBG, "[handle_scan]: Don't do obss scan until IP adresss is obtained\n"); + WILC_ERRORREPORT(s32Error, WILC_BUSY); + } + #endif + + PRINT_D(HOSTINF_DBG, "Setting channel :%d\n", pstrHostIfRemainOnChan->u16Channel); + + u8remain_on_chan_flag = WILC_TRUE; + strWID.u16WIDid = (WILC_Uint16)WID_REMAIN_ON_CHAN; + strWID.enuWIDtype = WID_STR; + strWID.s32ValueSize = 2; + strWID.ps8WidVal = (WILC_Sint8 *)WILC_MALLOC(strWID.s32ValueSize); + + if (strWID.ps8WidVal == WILC_NULL) { + WILC_ERRORREPORT(s32Error, WILC_NO_MEM); + } + + strWID.ps8WidVal[0] = u8remain_on_chan_flag; + strWID.ps8WidVal[1] = (WILC_Sint8)pstrHostIfRemainOnChan->u16Channel; + + /*Sending Cfg*/ + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + if (s32Error != WILC_SUCCESS) { + PRINT_ER("Failed to set remain on channel\n"); + } + + WILC_CATCH(-1) + { + P2P_LISTEN_STATE = 1; + WILC_TimerStart(&(pstrWFIDrv->hRemainOnChannel), pstrHostIfRemainOnChan->u32duration, (void *)pstrWFIDrv, WILC_NULL); + + /*Calling CFG ready_on_channel*/ + if (pstrWFIDrv->strHostIfRemainOnChan.pRemainOnChanReady) { + pstrWFIDrv->strHostIfRemainOnChan.pRemainOnChanReady(pstrWFIDrv->strHostIfRemainOnChan.pVoid); + } + + if (pstrWFIDrv->u8RemainOnChan_pendingreq) + pstrWFIDrv->u8RemainOnChan_pendingreq = 0; + } + return s32Error; +} + +/** + * @brief Handle_RegisterFrame + * @details + * @param[in] + * @return NONE + * @author + * @date + * @version 1.0 + */ +static int Handle_RegisterFrame(void *drvHandler, tstrHostIfRegisterFrame *pstrHostIfRegisterFrame) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + WILC_Uint8 *pu8CurrByte; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler; + + PRINT_D(HOSTINF_DBG, "Handling frame register Flag : %d FrameType: %d\n", pstrHostIfRegisterFrame->bReg, pstrHostIfRegisterFrame->u16FrameType); + + /*prepare configuration packet*/ + strWID.u16WIDid = (WILC_Uint16)WID_REGISTER_FRAME; + strWID.enuWIDtype = WID_STR; + strWID.ps8WidVal = WILC_MALLOC(sizeof(WILC_Uint16) + 2); + if (strWID.ps8WidVal == NULL) { + WILC_ERRORREPORT(s32Error, WILC_NO_MEM); + } + + pu8CurrByte = strWID.ps8WidVal; + + *pu8CurrByte++ = pstrHostIfRegisterFrame->bReg; + *pu8CurrByte++ = pstrHostIfRegisterFrame->u8Regid; + WILC_memcpy(pu8CurrByte, &(pstrHostIfRegisterFrame->u16FrameType), sizeof(WILC_Uint16)); + + + strWID.s32ValueSize = sizeof(WILC_Uint16) + 2; + + + /*Sending Cfg*/ + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + if (s32Error) { + PRINT_ER("Failed to frame register config packet\n"); + WILC_ERRORREPORT(s32Error, WILC_INVALID_STATE); + } + + + WILC_CATCH(s32Error) + { + } + + return s32Error; + +} + +/** + * @brief Handle_ListenStateExpired + * @details Handle of listen state expiration + * @param[in] NONE + * @return Error code. + * @author + * @date + * @version 1.0 + */ +#define FALSE_FRMWR_CHANNEL 100 +static WILC_Uint32 Handle_ListenStateExpired(void *drvHandler, tstrHostIfRemainOnChan *pstrHostIfRemainOnChan) +{ + WILC_Uint8 u8remain_on_chan_flag; + tstrWID strWID; + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *) drvHandler; + + PRINT_D(HOSTINF_DBG, "CANCEL REMAIN ON CHAN\n"); + + /*BugID_5477*/ + /*Make sure we are already in listen state*/ + /*This is to handle duplicate expiry messages (listen timer fired and supplicant called cancel_remain_on_channel())*/ + if (P2P_LISTEN_STATE) { + u8remain_on_chan_flag = WILC_FALSE; + strWID.u16WIDid = (WILC_Uint16)WID_REMAIN_ON_CHAN; + strWID.enuWIDtype = WID_STR; + strWID.s32ValueSize = 2; + strWID.ps8WidVal = WILC_MALLOC(strWID.s32ValueSize); + + if (strWID.ps8WidVal == WILC_NULL) { + PRINT_ER("Failed to allocate memory\n"); + } + + strWID.ps8WidVal[0] = u8remain_on_chan_flag; + strWID.ps8WidVal[1] = FALSE_FRMWR_CHANNEL; + + /*Sending Cfg*/ + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + if (s32Error != WILC_SUCCESS) { + PRINT_ER("Failed to set remain on channel\n"); + goto _done_; + } + + if (pstrWFIDrv->strHostIfRemainOnChan.pRemainOnChanExpired) { + pstrWFIDrv->strHostIfRemainOnChan.pRemainOnChanExpired(pstrWFIDrv->strHostIfRemainOnChan.pVoid + , pstrHostIfRemainOnChan->u32ListenSessionID); + } + P2P_LISTEN_STATE = 0; + } else { + PRINT_D(GENERIC_DBG, "Not in listen state\n"); + s32Error = WILC_FAIL; + } + +_done_: + return s32Error; +} + + +/** + * @brief ListenTimerCB + * @details Callback function of remain-on-channel timer + * @param[in] NONE + * @return Error code. + * @author + * @date + * @version 1.0 + */ +static void ListenTimerCB(void *pvArg) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrHostIFmsg strHostIFmsg; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)pvArg; + /*Stopping remain-on-channel timer*/ + WILC_TimerStop(&(pstrWFIDrv->hRemainOnChannel), WILC_NULL); + + /* prepare the Timer Callback message */ + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + strHostIFmsg.u16MsgId = HOST_IF_MSG_LISTEN_TIMER_FIRED; + strHostIFmsg.drvHandler = pstrWFIDrv; + strHostIFmsg.uniHostIFmsgBody.strHostIfRemainOnChan.u32ListenSessionID = pstrWFIDrv->strHostIfRemainOnChan.u32ListenSessionID; + + /* send the message */ + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + if (s32Error) { + WILC_ERRORREPORT(s32Error, s32Error); + } + WILC_CATCH(s32Error) + { + + } +} +#endif + + +/** + * @brief Handle_EditStation + * @details Sending config packet to edit station + * @param[in] tstrWILC_AddStaParam* pstrStationParam + * @return NONE + * @author + * @date + * @version 1.0 + */ +static void Handle_PowerManagement(void *drvHandler, tstrHostIfPowerMgmtParam *strPowerMgmtParam) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + WILC_Sint8 s8PowerMode; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler; + strWID.u16WIDid = (WILC_Uint16)WID_POWER_MANAGEMENT; + + if (strPowerMgmtParam->bIsEnabled == WILC_TRUE) { + s8PowerMode = MIN_FAST_PS; + } else { + s8PowerMode = NO_POWERSAVE; + } + PRINT_D(HOSTINF_DBG, "Handling power mgmt to %d\n", s8PowerMode); + strWID.ps8WidVal = &s8PowerMode; + strWID.s32ValueSize = sizeof(WILC_Char); + + PRINT_D(HOSTINF_DBG, "Handling Power Management\n"); + + /*Sending Cfg*/ + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + if (s32Error) { + PRINT_ER("Failed to send power management config packet\n"); + WILC_ERRORREPORT(s32Error, WILC_INVALID_STATE); + } + + WILC_CATCH(s32Error) + { + + } +} + +/** + * @brief Handle_SetMulticastFilter + * @details Set Multicast filter in firmware + * @param[in] tstrHostIFSetMulti* strHostIfSetMulti + * @return NONE + * @author asobhy + * @date + * @version 1.0 + */ +static void Handle_SetMulticastFilter(void *drvHandler, tstrHostIFSetMulti *strHostIfSetMulti) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + WILC_Uint8 *pu8CurrByte; + + PRINT_D(HOSTINF_DBG, "Setup Multicast Filter\n"); + + strWID.u16WIDid = (WILC_Uint16)WID_SETUP_MULTICAST_FILTER; + strWID.enuWIDtype = WID_BIN; + strWID.s32ValueSize = sizeof(tstrHostIFSetMulti) + ((strHostIfSetMulti->u32count) * ETH_ALEN); + strWID.ps8WidVal = WILC_MALLOC(strWID.s32ValueSize); + if (strWID.ps8WidVal == NULL) { + WILC_ERRORREPORT(s32Error, WILC_NO_MEM); + } + + pu8CurrByte = strWID.ps8WidVal; + *pu8CurrByte++ = (strHostIfSetMulti->bIsEnabled & 0xFF); + *pu8CurrByte++ = ((strHostIfSetMulti->bIsEnabled >> 8) & 0xFF); + *pu8CurrByte++ = ((strHostIfSetMulti->bIsEnabled >> 16) & 0xFF); + *pu8CurrByte++ = ((strHostIfSetMulti->bIsEnabled >> 24) & 0xFF); + + *pu8CurrByte++ = (strHostIfSetMulti->u32count & 0xFF); + *pu8CurrByte++ = ((strHostIfSetMulti->u32count >> 8) & 0xFF); + *pu8CurrByte++ = ((strHostIfSetMulti->u32count >> 16) & 0xFF); + *pu8CurrByte++ = ((strHostIfSetMulti->u32count >> 24) & 0xFF); + + if ((strHostIfSetMulti->u32count) > 0) + memcpy(pu8CurrByte, gau8MulticastMacAddrList, ((strHostIfSetMulti->u32count) * ETH_ALEN)); + + /*Sending Cfg*/ + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_FALSE, (WILC_Uint32)drvHandler); + if (s32Error) { + PRINT_ER("Failed to send setup multicast config packet\n"); + WILC_ERRORREPORT(s32Error, WILC_FAIL); + } + + WILC_CATCH(s32Error) + { + } + WILC_FREE_IF_TRUE(strWID.ps8WidVal); + +} + + +/*BugID_5222*/ +/** + * @brief Handle_AddBASession + * @details Add block ack session + * @param[in] tstrHostIFSetMulti* strHostIfSetMulti + * @return NONE + * @author Amr Abdel-Moghny + * @date Feb. 2014 + * @version 9.0 + */ +static WILC_Sint32 Handle_AddBASession(void *drvHandler, tstrHostIfBASessionInfo *strHostIfBASessionInfo) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + int AddbaTimeout = 100; + char *ptr = NULL; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler; + + PRINT_D(HOSTINF_DBG, "Opening Block Ack session with\nBSSID = %.2x:%.2x:%.2x \nTID=%d \nBufferSize == %d \nSessionTimeOut = %d\n", + strHostIfBASessionInfo->au8Bssid[0], + strHostIfBASessionInfo->au8Bssid[1], + strHostIfBASessionInfo->au8Bssid[2], + strHostIfBASessionInfo->u16BufferSize, + strHostIfBASessionInfo->u16SessionTimeout, + strHostIfBASessionInfo->u8Ted); + + strWID.u16WIDid = (WILC_Uint16)WID_11E_P_ACTION_REQ; + strWID.enuWIDtype = WID_STR; + strWID.ps8WidVal = (WILC_Uint8 *)WILC_MALLOC(BLOCK_ACK_REQ_SIZE); + strWID.s32ValueSize = BLOCK_ACK_REQ_SIZE; + ptr = strWID.ps8WidVal; + /* *ptr++ = 0x14; */ + *ptr++ = 0x14; + *ptr++ = 0x3; + *ptr++ = 0x0; + WILC_memcpy(ptr, strHostIfBASessionInfo->au8Bssid, ETH_ALEN); + ptr += ETH_ALEN; + *ptr++ = strHostIfBASessionInfo->u8Ted; + /* BA Policy*/ + *ptr++ = 1; + /* Buffer size*/ + *ptr++ = (strHostIfBASessionInfo->u16BufferSize & 0xFF); + *ptr++ = ((strHostIfBASessionInfo->u16BufferSize >> 16) & 0xFF); + /* BA timeout*/ + *ptr++ = (strHostIfBASessionInfo->u16SessionTimeout & 0xFF); + *ptr++ = ((strHostIfBASessionInfo->u16SessionTimeout >> 16) & 0xFF); + /* ADDBA timeout*/ + *ptr++ = (AddbaTimeout & 0xFF); + *ptr++ = ((AddbaTimeout >> 16) & 0xFF); + /* Group Buffer Max Frames*/ + *ptr++ = 8; + /* Group Buffer Timeout */ + *ptr++ = 0; + + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + if (s32Error) + PRINT_D(HOSTINF_DBG, "Couldn't open BA Session\n"); + + + strWID.u16WIDid = (WILC_Uint16)WID_11E_P_ACTION_REQ; + strWID.enuWIDtype = WID_STR; + strWID.s32ValueSize = 15; + ptr = strWID.ps8WidVal; + /* *ptr++ = 0x14; */ + *ptr++ = 15; + *ptr++ = 7; + *ptr++ = 0x2; + WILC_memcpy(ptr, strHostIfBASessionInfo->au8Bssid, ETH_ALEN); + ptr += ETH_ALEN; + /* TID*/ + *ptr++ = strHostIfBASessionInfo->u8Ted; + /* Max Num MSDU */ + *ptr++ = 8; + /* BA timeout*/ + *ptr++ = (strHostIfBASessionInfo->u16BufferSize & 0xFF); + *ptr++ = ((strHostIfBASessionInfo->u16SessionTimeout >> 16) & 0xFF); + /*Ack-Policy */ + *ptr++ = 3; + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + + if (strWID.ps8WidVal != NULL) + WILC_FREE(strWID.ps8WidVal); + + return s32Error; + +} + + +/*BugID_5222*/ +/** + * @brief Handle_DelBASession + * @details Delete block ack session + * @param[in] tstrHostIFSetMulti* strHostIfSetMulti + * @return NONE + * @author Amr Abdel-Moghny + * @date Feb. 2013 + * @version 9.0 + */ +static WILC_Sint32 Handle_DelBASession(void *drvHandler, tstrHostIfBASessionInfo *strHostIfBASessionInfo) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + char *ptr = NULL; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler; + + PRINT_D(GENERIC_DBG, "Delete Block Ack session with\nBSSID = %.2x:%.2x:%.2x \nTID=%d\n", + strHostIfBASessionInfo->au8Bssid[0], + strHostIfBASessionInfo->au8Bssid[1], + strHostIfBASessionInfo->au8Bssid[2], + strHostIfBASessionInfo->u8Ted); + + strWID.u16WIDid = (WILC_Uint16)WID_11E_P_ACTION_REQ; + strWID.enuWIDtype = WID_STR; + strWID.ps8WidVal = (WILC_Uint8 *)WILC_MALLOC(BLOCK_ACK_REQ_SIZE); + strWID.s32ValueSize = BLOCK_ACK_REQ_SIZE; + ptr = strWID.ps8WidVal; + /* *ptr++ = 0x14; */ + *ptr++ = 0x14; + *ptr++ = 0x3; + *ptr++ = 0x2; + WILC_memcpy(ptr, strHostIfBASessionInfo->au8Bssid, ETH_ALEN); + ptr += ETH_ALEN; + *ptr++ = strHostIfBASessionInfo->u8Ted; + /* BA direction = recipent*/ + *ptr++ = 0; + /* Delba Reason */ + *ptr++ = 32; /* Unspecific QOS reason */ + + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + if (s32Error) + PRINT_D(HOSTINF_DBG, "Couldn't delete BA Session\n"); + + + strWID.u16WIDid = (WILC_Uint16)WID_11E_P_ACTION_REQ; + strWID.enuWIDtype = WID_STR; + strWID.s32ValueSize = 15; + ptr = strWID.ps8WidVal; + /* *ptr++ = 0x14; */ + *ptr++ = 15; + *ptr++ = 7; + *ptr++ = 0x3; + WILC_memcpy(ptr, strHostIfBASessionInfo->au8Bssid, ETH_ALEN); + ptr += ETH_ALEN; + /* TID*/ + *ptr++ = strHostIfBASessionInfo->u8Ted; + + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + + if (strWID.ps8WidVal != NULL) + WILC_FREE(strWID.ps8WidVal); + + /*BugID_5222*/ + WILC_SemaphoreRelease(&hWaitResponse, NULL); + + return s32Error; + +} + + +/** + * @brief Handle_DelAllRxBASessions + * @details Delete all Rx BA sessions + * @param[in] tstrHostIFSetMulti* strHostIfSetMulti + * @return NONE + * @author Abdelrahman Sobhy + * @date Feb. 2013 + * @version 9.0 + */ +static WILC_Sint32 Handle_DelAllRxBASessions(void *drvHandler, tstrHostIfBASessionInfo *strHostIfBASessionInfo) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + char *ptr = NULL; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler; + + PRINT_D(GENERIC_DBG, "Delete Block Ack session with\nBSSID = %.2x:%.2x:%.2x \nTID=%d\n", + strHostIfBASessionInfo->au8Bssid[0], + strHostIfBASessionInfo->au8Bssid[1], + strHostIfBASessionInfo->au8Bssid[2], + strHostIfBASessionInfo->u8Ted); + + strWID.u16WIDid = (WILC_Uint16)WID_DEL_ALL_RX_BA; + strWID.enuWIDtype = WID_STR; + strWID.ps8WidVal = (WILC_Uint8 *)WILC_MALLOC(BLOCK_ACK_REQ_SIZE); + strWID.s32ValueSize = BLOCK_ACK_REQ_SIZE; + ptr = strWID.ps8WidVal; + *ptr++ = 0x14; + *ptr++ = 0x3; + *ptr++ = 0x2; + WILC_memcpy(ptr, strHostIfBASessionInfo->au8Bssid, ETH_ALEN); + ptr += ETH_ALEN; + *ptr++ = strHostIfBASessionInfo->u8Ted; + /* BA direction = recipent*/ + *ptr++ = 0; + /* Delba Reason */ + *ptr++ = 32; /* Unspecific QOS reason */ + + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + if (s32Error) + PRINT_D(HOSTINF_DBG, "Couldn't delete BA Session\n"); + + + if (strWID.ps8WidVal != NULL) + WILC_FREE(strWID.ps8WidVal); + + /*BugID_5222*/ + WILC_SemaphoreRelease(&hWaitResponse, NULL); + + return s32Error; + +} + +/** + * @brief hostIFthread + * @details Main thread to handle message queue requests + * @param[in] void* pvArg + * @return NONE + * @author + * @date + * @version 1.0 + */ +static void hostIFthread(void *pvArg) +{ + WILC_Uint32 u32Ret; + tstrHostIFmsg strHostIFmsg; + tstrWILC_WFIDrv *pstrWFIDrv; + + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + while (1) { + WILC_MsgQueueRecv(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), &u32Ret, WILC_NULL); + pstrWFIDrv = (tstrWILC_WFIDrv *)strHostIFmsg.drvHandler; + if (strHostIFmsg.u16MsgId == HOST_IF_MSG_EXIT) { + PRINT_D(GENERIC_DBG, "THREAD: Exiting HostIfThread\n"); + break; + } + + + /*Re-Queue HIF message*/ + if ((!g_wilc_initialized)) { + PRINT_D(GENERIC_DBG, "--WAIT--"); + WILC_Sleep(200); + WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + continue; + } + + if (strHostIFmsg.u16MsgId == HOST_IF_MSG_CONNECT && pstrWFIDrv->strWILC_UsrScanReq.pfUserScanResult != NULL) { + PRINT_D(HOSTINF_DBG, "Requeue connect request till scan done received\n"); + WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + WILC_Sleep(2); + continue; + } + + switch (strHostIFmsg.u16MsgId) { + case HOST_IF_MSG_Q_IDLE: + Handle_wait_msg_q_empty(); + break; + + case HOST_IF_MSG_SCAN: + Handle_Scan(strHostIFmsg.drvHandler, &strHostIFmsg.uniHostIFmsgBody.strHostIFscanAttr); + break; + + case HOST_IF_MSG_CONNECT: + Handle_Connect(strHostIFmsg.drvHandler, &strHostIFmsg.uniHostIFmsgBody.strHostIFconnectAttr); + break; + + /*BugID_5137*/ + case HOST_IF_MSG_FLUSH_CONNECT: + Handle_FlushConnect(strHostIFmsg.drvHandler); + break; + + case HOST_IF_MSG_RCVD_NTWRK_INFO: + Handle_RcvdNtwrkInfo(strHostIFmsg.drvHandler, &strHostIFmsg.uniHostIFmsgBody.strRcvdNetworkInfo); + break; + + case HOST_IF_MSG_RCVD_GNRL_ASYNC_INFO: + Handle_RcvdGnrlAsyncInfo(strHostIFmsg.drvHandler, &strHostIFmsg.uniHostIFmsgBody.strRcvdGnrlAsyncInfo); + break; + + case HOST_IF_MSG_KEY: + Handle_Key(strHostIFmsg.drvHandler, &strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr); + break; + + case HOST_IF_MSG_CFG_PARAMS: + + Handle_CfgParam(strHostIFmsg.drvHandler, &strHostIFmsg.uniHostIFmsgBody.strHostIFCfgParamAttr); + break; + + case HOST_IF_MSG_SET_CHANNEL: + Handle_SetChannel(strHostIFmsg.drvHandler, &strHostIFmsg.uniHostIFmsgBody.strHostIFSetChan); + break; + + case HOST_IF_MSG_DISCONNECT: + Handle_Disconnect(strHostIFmsg.drvHandler); + break; + + case HOST_IF_MSG_RCVD_SCAN_COMPLETE: + WILC_TimerStop(&(pstrWFIDrv->hScanTimer), WILC_NULL); + PRINT_D(HOSTINF_DBG, "scan completed successfully\n"); + + /*BugID_5213*/ + /*Allow chip sleep, only if both interfaces are not connected*/ + if (!linux_wlan_get_num_conn_ifcs()) { + chip_sleep_manually(INFINITE_SLEEP_TIME); + } + + Handle_ScanDone(strHostIFmsg.drvHandler, SCAN_EVENT_DONE); + + #ifdef WILC_P2P + if (pstrWFIDrv->u8RemainOnChan_pendingreq) + Handle_RemainOnChan(strHostIFmsg.drvHandler, &strHostIFmsg.uniHostIFmsgBody.strHostIfRemainOnChan); + #endif + + break; + + case HOST_IF_MSG_GET_RSSI: + Handle_GetRssi(strHostIFmsg.drvHandler); + break; + + case HOST_IF_MSG_GET_LINKSPEED: + Handle_GetLinkspeed(strHostIFmsg.drvHandler); + break; + + case HOST_IF_MSG_GET_STATISTICS: + Handle_GetStatistics(strHostIFmsg.drvHandler, (tstrStatistics *)strHostIFmsg.uniHostIFmsgBody.pUserData); + break; + + case HOST_IF_MSG_GET_CHNL: + Handle_GetChnl(strHostIFmsg.drvHandler); + break; + +#ifdef WILC_AP_EXTERNAL_MLME + case HOST_IF_MSG_ADD_BEACON: + Handle_AddBeacon(strHostIFmsg.drvHandler, &strHostIFmsg.uniHostIFmsgBody.strHostIFSetBeacon); + break; + + case HOST_IF_MSG_DEL_BEACON: + Handle_DelBeacon(strHostIFmsg.drvHandler, &strHostIFmsg.uniHostIFmsgBody.strHostIFDelBeacon); + break; + + case HOST_IF_MSG_ADD_STATION: + Handle_AddStation(strHostIFmsg.drvHandler, &strHostIFmsg.uniHostIFmsgBody.strAddStaParam); + break; + + case HOST_IF_MSG_DEL_STATION: + Handle_DelStation(strHostIFmsg.drvHandler, &strHostIFmsg.uniHostIFmsgBody.strDelStaParam); + break; + + case HOST_IF_MSG_EDIT_STATION: + Handle_EditStation(strHostIFmsg.drvHandler, &strHostIFmsg.uniHostIFmsgBody.strEditStaParam); + break; + + case HOST_IF_MSG_GET_INACTIVETIME: + Handle_Get_InActiveTime(strHostIFmsg.drvHandler, &strHostIFmsg.uniHostIFmsgBody.strHostIfStaInactiveT); + break; + +#endif /*WILC_AP_EXTERNAL_MLME*/ + case HOST_IF_MSG_SCAN_TIMER_FIRED: + PRINT_D(HOSTINF_DBG, "Scan Timeout\n"); + + Handle_ScanDone(strHostIFmsg.drvHandler, SCAN_EVENT_ABORTED); + break; + + case HOST_IF_MSG_CONNECT_TIMER_FIRED: + PRINT_D(HOSTINF_DBG, "Connect Timeout \n"); + Handle_ConnectTimeout(strHostIFmsg.drvHandler); + break; + + case HOST_IF_MSG_POWER_MGMT: + Handle_PowerManagement(strHostIFmsg.drvHandler, &strHostIFmsg.uniHostIFmsgBody.strPowerMgmtparam); + break; + + case HOST_IF_MSG_SET_WFIDRV_HANDLER: + Handle_SetWfiDrvHandler(&strHostIFmsg.uniHostIFmsgBody.strHostIfSetDrvHandler); + break; + + case HOST_IF_MSG_SET_OPERATION_MODE: + Handle_SetOperationMode(strHostIFmsg.drvHandler, &strHostIFmsg.uniHostIFmsgBody.strHostIfSetOperationMode); + break; + + case HOST_IF_MSG_SET_IPADDRESS: + PRINT_D(HOSTINF_DBG, "HOST_IF_MSG_SET_IPADDRESS\n"); + Handle_set_IPAddress(strHostIFmsg.drvHandler, strHostIFmsg.uniHostIFmsgBody.strHostIfSetIP.au8IPAddr, strHostIFmsg.uniHostIFmsgBody.strHostIfSetIP.idx); + break; + + case HOST_IF_MSG_GET_IPADDRESS: + PRINT_D(HOSTINF_DBG, "HOST_IF_MSG_SET_IPADDRESS\n"); + Handle_get_IPAddress(strHostIFmsg.drvHandler, strHostIFmsg.uniHostIFmsgBody.strHostIfSetIP.au8IPAddr, strHostIFmsg.uniHostIFmsgBody.strHostIfSetIP.idx); + break; + + /*BugID_5077*/ + case HOST_IF_MSG_SET_MAC_ADDRESS: + Handle_SetMacAddress(strHostIFmsg.drvHandler, &strHostIFmsg.uniHostIFmsgBody.strHostIfSetMacAddress); + break; + + /*BugID_5213*/ + case HOST_IF_MSG_GET_MAC_ADDRESS: + Handle_GetMacAddress(strHostIFmsg.drvHandler, &strHostIFmsg.uniHostIFmsgBody.strHostIfGetMacAddress); + break; + +#ifdef WILC_P2P + case HOST_IF_MSG_REMAIN_ON_CHAN: + PRINT_D(HOSTINF_DBG, "HOST_IF_MSG_REMAIN_ON_CHAN\n"); + Handle_RemainOnChan(strHostIFmsg.drvHandler, &strHostIFmsg.uniHostIFmsgBody.strHostIfRemainOnChan); + break; + + case HOST_IF_MSG_REGISTER_FRAME: + PRINT_D(HOSTINF_DBG, "HOST_IF_MSG_REGISTER_FRAME\n"); + Handle_RegisterFrame(strHostIFmsg.drvHandler, &strHostIFmsg.uniHostIFmsgBody.strHostIfRegisterFrame); + break; + + case HOST_IF_MSG_LISTEN_TIMER_FIRED: + Handle_ListenStateExpired(strHostIFmsg.drvHandler, &strHostIFmsg.uniHostIFmsgBody.strHostIfRemainOnChan); + break; + + #endif + case HOST_IF_MSG_SET_MULTICAST_FILTER: + PRINT_D(HOSTINF_DBG, "HOST_IF_MSG_SET_MULTICAST_FILTER\n"); + Handle_SetMulticastFilter(strHostIFmsg.drvHandler, &strHostIFmsg.uniHostIFmsgBody.strHostIfSetMulti); + break; + + /*BugID_5222*/ + case HOST_IF_MSG_ADD_BA_SESSION: + Handle_AddBASession(strHostIFmsg.drvHandler, &strHostIFmsg.uniHostIFmsgBody.strHostIfBASessionInfo); + break; + + case HOST_IF_MSG_DEL_ALL_RX_BA_SESSIONS: + Handle_DelAllRxBASessions(strHostIFmsg.drvHandler, &strHostIFmsg.uniHostIFmsgBody.strHostIfBASessionInfo); + break; + + case HOST_IF_MSG_DEL_ALL_STA: + Handle_DelAllSta(strHostIFmsg.drvHandler, &strHostIFmsg.uniHostIFmsgBody.strHostIFDelAllSta); + break; + + default: + PRINT_ER("[Host Interface] undefined Received Msg ID \n"); + break; + } + } + + PRINT_D(HOSTINF_DBG, "Releasing thread exit semaphore\n"); + WILC_SemaphoreRelease(&hSemHostIFthrdEnd, WILC_NULL); + return; + /* do_exit(error); */ + /* PRINT_D(HOSTINF_DBG,"do_exit error code %d\n",error); */ + +} + +static void TimerCB_Scan(void *pvArg) +{ + tstrHostIFmsg strHostIFmsg; + + /* prepare the Timer Callback message */ + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + strHostIFmsg.drvHandler = pvArg; + strHostIFmsg.u16MsgId = HOST_IF_MSG_SCAN_TIMER_FIRED; + + /* send the message */ + WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); +} + +static void TimerCB_Connect(void *pvArg) +{ + tstrHostIFmsg strHostIFmsg; + + /* prepare the Timer Callback message */ + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + strHostIFmsg.drvHandler = pvArg; + strHostIFmsg.u16MsgId = HOST_IF_MSG_CONNECT_TIMER_FIRED; + + /* send the message */ + WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); +} + + +/** + * @brief removes wpa/wpa2 keys + * @details only in BSS STA mode if External Supplicant support is enabled. + * removes all WPA/WPA2 station key entries from MAC hardware. + * @param[in,out] handle to the wifi driver + * @param[in] 6 bytes of Station Adress in the station entry table + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +/* Check implementation in core adding 9 bytes to the input! */ +WILC_Sint32 host_int_remove_key(WILC_WFIDrvHandle hWFIDrv, const WILC_Uint8 *pu8StaAddress) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + /* tstrWILC_WFIDrv * pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; */ + + strWID.u16WIDid = (WILC_Uint16)WID_REMOVE_KEY; + strWID.enuWIDtype = WID_STR; + strWID.ps8WidVal = (WILC_Sint8 *)pu8StaAddress; + strWID.s32ValueSize = 6; + + return s32Error; + +} + +/** + * @brief removes WEP key + * @details valid only in BSS STA mode if External Supplicant support is enabled. + * remove a WEP key entry from MAC HW. + * The BSS Station automatically finds the index of the entry using its + * BSS ID and removes that entry from the MAC hardware. + * @param[in,out] handle to the wifi driver + * @param[in] 6 bytes of Station Adress in the station entry table + * @return Error code indicating success/failure + * @note NO need for the STA add since it is not used for processing + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_remove_wep_key(WILC_WFIDrvHandle hWFIDrv, WILC_Uint8 u8keyIdx) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + tstrHostIFmsg strHostIFmsg; + + + if (pstrWFIDrv == WILC_NULL) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + /* prepare the Remove Wep Key Message */ + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + + strHostIFmsg.u16MsgId = HOST_IF_MSG_KEY; + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.enuKeyType = WEP; + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.u8KeyAction = REMOVEKEY; + strHostIFmsg.drvHandler = hWFIDrv; + + + + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr. + uniHostIFkeyAttr.strHostIFwepAttr.u8Wepidx = u8keyIdx; + + /* send the message */ + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + if (s32Error) + PRINT_ER("Error in sending message queue : Request to remove WEP key \n"); + WILC_SemaphoreAcquire(&(pstrWFIDrv->hSemTestKeyBlock), NULL); + + WILC_CATCH(s32Error) + { + + } + return s32Error; +} + +/** + * @brief sets WEP default key + * @details Sets the index of the WEP encryption key in use, + * in the key table + * @param[in,out] handle to the wifi driver + * @param[in] key index ( 0, 1, 2, 3) + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_set_WEPDefaultKeyID(WILC_WFIDrvHandle hWFIDrv, WILC_Uint8 u8Index) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + tstrHostIFmsg strHostIFmsg; + + + if (pstrWFIDrv == WILC_NULL) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + /* prepare the Key Message */ + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + + strHostIFmsg.u16MsgId = HOST_IF_MSG_KEY; + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.enuKeyType = WEP; + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.u8KeyAction = DEFAULTKEY; + strHostIFmsg.drvHandler = hWFIDrv; + + + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr. + uniHostIFkeyAttr.strHostIFwepAttr.u8Wepidx = u8Index; + + /* send the message */ + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + if (s32Error) + PRINT_ER("Error in sending message queue : Default key index\n"); + WILC_SemaphoreAcquire(&(pstrWFIDrv->hSemTestKeyBlock), NULL); + + WILC_CATCH(s32Error) + { + + } + + return s32Error; +} + +/** + * @brief sets WEP deafault key + * @details valid only in BSS STA mode if External Supplicant support is enabled. + * sets WEP key entry into MAC hardware when it receives the + * corresponding request from NDIS. + * @param[in,out] handle to the wifi driver + * @param[in] message containing WEP Key in the following format + *|---------------------------------------| + *|Key ID Value | Key Length | Key | + *|-------------|------------|------------| + | 1byte | 1byte | Key Length | + ||---------------------------------------| + | + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_add_wep_key_bss_sta(WILC_WFIDrvHandle hWFIDrv, const WILC_Uint8 *pu8WepKey, WILC_Uint8 u8WepKeylen, WILC_Uint8 u8Keyidx) +{ + + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + tstrHostIFmsg strHostIFmsg; + + if (pstrWFIDrv == WILC_NULL) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + + } + + /* prepare the Key Message */ + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + + strHostIFmsg.u16MsgId = HOST_IF_MSG_KEY; + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.enuKeyType = WEP; + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.u8KeyAction = ADDKEY; + strHostIFmsg.drvHandler = hWFIDrv; + + + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr. + uniHostIFkeyAttr.strHostIFwepAttr.pu8WepKey = (WILC_Uint8 *)WILC_MALLOC(u8WepKeylen); + + WILC_memcpy(strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.uniHostIFkeyAttr.strHostIFwepAttr.pu8WepKey, + pu8WepKey, u8WepKeylen); + + + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr. + uniHostIFkeyAttr.strHostIFwepAttr.u8WepKeylen = (u8WepKeylen); + + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr. + uniHostIFkeyAttr.strHostIFwepAttr.u8Wepidx = u8Keyidx; + + /* send the message */ + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + if (s32Error) + PRINT_ER("Error in sending message queue :WEP Key\n"); + WILC_SemaphoreAcquire(&(pstrWFIDrv->hSemTestKeyBlock), NULL); + + WILC_CATCH(s32Error) + { + + } + return s32Error; + +} + +#ifdef WILC_AP_EXTERNAL_MLME +/** + * + * @brief host_int_add_wep_key_bss_ap + * @details valid only in BSS AP mode if External Supplicant support is enabled. + * sets WEP key entry into MAC hardware when it receives the + * + * corresponding request from NDIS. + * @param[in,out] handle to the wifi driver + * + * + * @return Error code indicating success/failure + * @note + * @author mdaftedar + * @date 28 FEB 2013 + * @version 1.0 + */ +WILC_Sint32 host_int_add_wep_key_bss_ap(WILC_WFIDrvHandle hWFIDrv, const WILC_Uint8 *pu8WepKey, WILC_Uint8 u8WepKeylen, WILC_Uint8 u8Keyidx, WILC_Uint8 u8mode, AUTHTYPE_T tenuAuth_type) +{ + + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + tstrHostIFmsg strHostIFmsg; + WILC_Uint8 i; + + if (pstrWFIDrv == WILC_NULL) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + + } + + /* prepare the Key Message */ + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + if (INFO) { + for (i = 0; i < u8WepKeylen; i++) + PRINT_INFO(HOSTAPD_DBG, "KEY is %x\n", pu8WepKey[i]); + } + strHostIFmsg.u16MsgId = HOST_IF_MSG_KEY; + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.enuKeyType = WEP; + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.u8KeyAction = ADDKEY_AP; + strHostIFmsg.drvHandler = hWFIDrv; + + + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr. + uniHostIFkeyAttr.strHostIFwepAttr.pu8WepKey = (WILC_Uint8 *)WILC_MALLOC((u8WepKeylen)); + + + WILC_memcpy(strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.uniHostIFkeyAttr.strHostIFwepAttr.pu8WepKey, + pu8WepKey, (u8WepKeylen)); + + + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr. + uniHostIFkeyAttr.strHostIFwepAttr.u8WepKeylen = (u8WepKeylen); + + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr. + uniHostIFkeyAttr.strHostIFwepAttr.u8Wepidx = u8Keyidx; + + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr. + uniHostIFkeyAttr.strHostIFwepAttr.u8mode = u8mode; + + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr. + uniHostIFkeyAttr.strHostIFwepAttr.tenuAuth_type = tenuAuth_type; + /* send the message */ + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + + if (s32Error) + PRINT_ER("Error in sending message queue :WEP Key\n"); + WILC_SemaphoreAcquire(&(pstrWFIDrv->hSemTestKeyBlock), NULL); + + WILC_CATCH(s32Error) + { + + } + return s32Error; + +} +#endif +/** + * @brief adds ptk Key + * @details + * @param[in,out] handle to the wifi driver + * @param[in] message containing PTK Key in the following format + *|-----------------------------------------------------------------------------| + *|Station address | Key Length | Temporal Key | Rx Michael Key |Tx Michael Key | + *|----------------|------------|--------------|----------------|---------------| + | 6 bytes | 1byte | 16 bytes | 8 bytes | 8 bytes | + ||-----------------------------------------------------------------------------| + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_add_ptk(WILC_WFIDrvHandle hWFIDrv, WILC_Uint8 *pu8Ptk, WILC_Uint8 u8PtkKeylen, + const WILC_Uint8 *mac_addr, WILC_Uint8 *pu8RxMic, WILC_Uint8 *pu8TxMic, WILC_Uint8 mode, WILC_Uint8 u8Ciphermode, WILC_Uint8 u8Idx) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + tstrHostIFmsg strHostIFmsg; + WILC_Uint8 u8KeyLen = u8PtkKeylen; + WILC_Uint32 i; + if (pstrWFIDrv == WILC_NULL) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + if (pu8RxMic != NULL) { + u8KeyLen += RX_MIC_KEY_LEN; + } + if (pu8TxMic != NULL) { + u8KeyLen += TX_MIC_KEY_LEN; + } + + /* prepare the Key Message */ + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + + strHostIFmsg.u16MsgId = HOST_IF_MSG_KEY; + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.enuKeyType = WPAPtk; + #ifdef WILC_AP_EXTERNAL_MLME + if (mode == AP_MODE) { + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.u8KeyAction = ADDKEY_AP; + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr. + uniHostIFkeyAttr.strHostIFwpaAttr.u8keyidx = u8Idx; + } + #endif + if (mode == STATION_MODE) + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.u8KeyAction = ADDKEY; + + + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr. + uniHostIFkeyAttr.strHostIFwpaAttr.pu8key = (WILC_Uint8 *)WILC_MALLOC(u8PtkKeylen); + + + WILC_memcpy(strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.uniHostIFkeyAttr.strHostIFwpaAttr.pu8key, + pu8Ptk, u8PtkKeylen); + + if (pu8RxMic != NULL) { + + WILC_memcpy(strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.uniHostIFkeyAttr.strHostIFwpaAttr.pu8key + 16, + pu8RxMic, RX_MIC_KEY_LEN); + if (INFO) { + for (i = 0; i < RX_MIC_KEY_LEN; i++) + PRINT_INFO(CFG80211_DBG, "PairwiseRx[%d] = %x\n", i, pu8RxMic[i]); + } + } + if (pu8TxMic != NULL) { + + WILC_memcpy(strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.uniHostIFkeyAttr.strHostIFwpaAttr.pu8key + 24, + pu8TxMic, TX_MIC_KEY_LEN); + if (INFO) { + for (i = 0; i < TX_MIC_KEY_LEN; i++) + PRINT_INFO(CFG80211_DBG, "PairwiseTx[%d] = %x\n", i, pu8TxMic[i]); + } + } + + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr. + uniHostIFkeyAttr.strHostIFwpaAttr.u8Keylen = u8KeyLen; + + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr. + uniHostIFkeyAttr.strHostIFwpaAttr.u8Ciphermode = u8Ciphermode; + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr. + uniHostIFkeyAttr.strHostIFwpaAttr.pu8macaddr = mac_addr; + strHostIFmsg.drvHandler = hWFIDrv; + + /* send the message */ + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + + if (s32Error) + PRINT_ER("Error in sending message queue: PTK Key\n"); + + /* ////////////// */ + WILC_SemaphoreAcquire(&(pstrWFIDrv->hSemTestKeyBlock), NULL); + /* WILC_Sleep(100); */ + /* /////// */ + + WILC_CATCH(s32Error) + { + + } + + return s32Error; +} + +/** + * @brief adds Rx GTk Key + * @details + * @param[in,out] handle to the wifi driver + * @param[in] pu8RxGtk : contains temporal key | Rx Mic | Tx Mic + * u8GtkKeylen :The total key length + * + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_add_rx_gtk(WILC_WFIDrvHandle hWFIDrv, WILC_Uint8 *pu8RxGtk, WILC_Uint8 u8GtkKeylen, + WILC_Uint8 u8KeyIdx, WILC_Uint32 u32KeyRSClen, WILC_Uint8 *KeyRSC, + WILC_Uint8 *pu8RxMic, WILC_Uint8 *pu8TxMic, WILC_Uint8 mode, WILC_Uint8 u8Ciphermode) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + tstrHostIFmsg strHostIFmsg; + WILC_Uint8 u8KeyLen = u8GtkKeylen; + + if (pstrWFIDrv == WILC_NULL) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + /* prepare the Key Message */ + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + + if (pu8RxMic != NULL) { + u8KeyLen += RX_MIC_KEY_LEN; + } + if (pu8TxMic != NULL) { + u8KeyLen += TX_MIC_KEY_LEN; + } + if (KeyRSC != NULL) { + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr. + uniHostIFkeyAttr.strHostIFwpaAttr.pu8seq = (WILC_Uint8 *)WILC_MALLOC(u32KeyRSClen); + + WILC_memcpy(strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.uniHostIFkeyAttr.strHostIFwpaAttr.pu8seq, + KeyRSC, u32KeyRSClen); + } + + + strHostIFmsg.u16MsgId = HOST_IF_MSG_KEY; + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.enuKeyType = WPARxGtk; + strHostIFmsg.drvHandler = hWFIDrv; + + #ifdef WILC_AP_EXTERNAL_MLME + if (mode == AP_MODE) { + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.u8KeyAction = ADDKEY_AP; + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.uniHostIFkeyAttr.strHostIFwpaAttr.u8Ciphermode = u8Ciphermode; + } + #endif + if (mode == STATION_MODE) + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.u8KeyAction = ADDKEY; + + + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr. + uniHostIFkeyAttr.strHostIFwpaAttr.pu8key = (WILC_Uint8 *)WILC_MALLOC(u8KeyLen); + + WILC_memcpy(strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.uniHostIFkeyAttr.strHostIFwpaAttr.pu8key, + pu8RxGtk, u8GtkKeylen); + + if (pu8RxMic != NULL) { + + WILC_memcpy(strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.uniHostIFkeyAttr.strHostIFwpaAttr.pu8key + 16, + pu8RxMic, RX_MIC_KEY_LEN); + + } + if (pu8TxMic != NULL) { + + WILC_memcpy(strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.uniHostIFkeyAttr.strHostIFwpaAttr.pu8key + 24, + pu8TxMic, TX_MIC_KEY_LEN); + + } + + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr. + uniHostIFkeyAttr.strHostIFwpaAttr.u8keyidx = u8KeyIdx; + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr. + uniHostIFkeyAttr.strHostIFwpaAttr.u8Keylen = u8KeyLen; + + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr. + uniHostIFkeyAttr.strHostIFwpaAttr.u8seqlen = u32KeyRSClen; + + + + /* send the message */ + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + if (s32Error) + PRINT_ER("Error in sending message queue: RX GTK\n"); + /* ////////////// */ + WILC_SemaphoreAcquire(&(pstrWFIDrv->hSemTestKeyBlock), NULL); + /* WILC_Sleep(100); */ + /* /////// */ + + WILC_CATCH(s32Error) + { + + } + return s32Error; +} +#if 0 +/** + * @brief host_int_add_tx_gtk + * @details adds Tx GTk Key + * @param[in,out] handle to the wifi driver + * @param[in] message containing Tx GTK Key in the following format + *|----------------------------------------------------| + | KeyID | Key Length | Temporal Key | Tx Michael Key | + ||-------|------------|--------------|----------------| + ||1 byte | 1 byte | 16 bytes | 8 bytes | + ||----------------------------------------------------| + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_add_tx_gtk(WILC_WFIDrvHandle hWFIDrv, WILC_Uint8 u8KeyLen, WILC_Uint8 *pu8TxGtk, WILC_Uint8 u8KeyIdx) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + tstrHostIFmsg strHostIFmsg; + + if (pstrWFIDrv == WILC_NULL) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + /* prepare the Key Message */ + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + strHostIFmsg.u16MsgId = HOST_IF_MSG_KEY; + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.enuKeyType = WPATxGtk; + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.u8KeyAction = ADDKEY; + + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr. + uniHostIFkeyAttr.strHostIFwpaAttr.pu8key = (WILC_Uint8 *)WILC_MALLOC(u8KeyLen); + + WILC_memcpy(strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.uniHostIFkeyAttr.strHostIFwpaAttr.pu8key, + pu8TxGtk, u8KeyLen); + + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.uniHostIFkeyAttr.strHostIFwpaAttr.u8Keylen = u8KeyLen; + + /* send the message */ + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + if (s32Error) + PRINT_ER("Error in sending message queue: TX GTK\n"); + + /* ////////////// */ + WILC_SemaphoreAcquire(&hSemTestKeyBlock, NULL); + WILC_Sleep(100); + /* /////// */ + + WILC_CATCH(s32Error) + { + + } + return s32Error; +} +#endif +/** + * @brief host_int_set_pmkid_info + * @details caches the pmkid valid only in BSS STA mode if External Supplicant + * support is enabled. This Function sets the PMKID in firmware + * when host drivr receives the corresponding request from NDIS. + * The firmware then includes theset PMKID in the appropriate + * management frames + * @param[in,out] handle to the wifi driver + * @param[in] message containing PMKID Info in the following format + *|-----------------------------------------------------------------| + *|NumEntries | BSSID[1] | PMKID[1] | ... | BSSID[K] | PMKID[K] | + *|-----------|------------|----------|-------|----------|----------| + | 1 | 6 | 16 | ... | 6 | 16 | + ||-----------------------------------------------------------------| + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_set_pmkid_info(WILC_WFIDrvHandle hWFIDrv, tstrHostIFpmkidAttr *pu8PmkidInfoArray) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + tstrHostIFmsg strHostIFmsg; + WILC_Uint32 i; + + + if (pstrWFIDrv == WILC_NULL) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + /* prepare the Key Message */ + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + strHostIFmsg.u16MsgId = HOST_IF_MSG_KEY; + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.enuKeyType = PMKSA; + strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.u8KeyAction = ADDKEY; + strHostIFmsg.drvHandler = hWFIDrv; + + for (i = 0; i < pu8PmkidInfoArray->numpmkid; i++) { + + WILC_memcpy(strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.uniHostIFkeyAttr.strHostIFpmkidAttr.pmkidlist[i].bssid, &pu8PmkidInfoArray->pmkidlist[i].bssid, + ETH_ALEN); + + WILC_memcpy(strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.uniHostIFkeyAttr.strHostIFpmkidAttr.pmkidlist[i].pmkid, &pu8PmkidInfoArray->pmkidlist[i].pmkid, + PMKID_LEN); + } + + /* send the message */ + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + if (s32Error) + PRINT_ER(" Error in sending messagequeue: PMKID Info\n"); + + WILC_CATCH(s32Error) + { + + } + + return s32Error; +} + +/** + * @brief gets the cached the pmkid info + * @details valid only in BSS STA mode if External Supplicant + * support is enabled. This Function sets the PMKID in firmware + * when host drivr receives the corresponding request from NDIS. + * The firmware then includes theset PMKID in the appropriate + * management frames + * @param[in,out] handle to the wifi driver, + * message containing PMKID Info in the following format + *|-----------------------------------------------------------------| + *|NumEntries | BSSID[1] | PMKID[1] | ... | BSSID[K] | PMKID[K] | + *|-----------|------------|----------|-------|----------|----------| + | 1 | 6 | 16 | ... | 6 | 16 | + ||-----------------------------------------------------------------| + * @param[in] + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_get_pmkid_info(WILC_WFIDrvHandle hWFIDrv, WILC_Uint8 *pu8PmkidInfoArray, + WILC_Uint32 u32PmkidInfoLen) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + /* tstrWILC_WFIDrv * pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; */ + + strWID.u16WIDid = (WILC_Uint16)WID_PMKID_INFO; + strWID.enuWIDtype = WID_STR; + strWID.s32ValueSize = u32PmkidInfoLen; + strWID.ps8WidVal = pu8PmkidInfoArray; + + return s32Error; +} + +/** + * @brief sets the pass phrase + * @details AP/STA mode. This function gives the pass phrase used to + * generate the Pre-Shared Key when WPA/WPA2 is enabled + * The length of the field can vary from 8 to 64 bytes, + * the lower layer should get the + * @param[in,out] handle to the wifi driver, + * @param[in] String containing PSK + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_set_RSNAConfigPSKPassPhrase(WILC_WFIDrvHandle hWFIDrv, WILC_Uint8 *pu8PassPhrase, + WILC_Uint8 u8Psklength) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + /* tstrWILC_WFIDrv * pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; */ + + /* WILC_Uint8 u8Psklength = WILC_strlen(pu8PassPhrase); */ + /*validating psk length*/ + if ((u8Psklength > 7) && (u8Psklength < 65)) { + strWID.u16WIDid = (WILC_Uint16)WID_11I_PSK; + strWID.enuWIDtype = WID_STR; + strWID.ps8WidVal = pu8PassPhrase; + strWID.s32ValueSize = u8Psklength; + } + + return s32Error; +} +/** + * @brief host_int_get_MacAddress + * @details gets mac address + * @param[in,out] handle to the wifi driver, + * + * @return Error code indicating success/failure + * @note + * @author mdaftedar + * @date 19 April 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_get_MacAddress(WILC_WFIDrvHandle hWFIDrv, WILC_Uint8 *pu8MacAddress) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrHostIFmsg strHostIFmsg; + + + /* prepare the Message */ + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + strHostIFmsg.u16MsgId = HOST_IF_MSG_GET_MAC_ADDRESS; + strHostIFmsg.uniHostIFmsgBody.strHostIfGetMacAddress.u8MacAddress = pu8MacAddress; + strHostIFmsg.drvHandler = hWFIDrv; + /* send the message */ + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + if (s32Error) { + PRINT_ER("Failed to send get mac address\n"); + return WILC_FAIL; + } + + WILC_SemaphoreAcquire(&hWaitResponse, NULL); + return s32Error; +} + +/** + * @brief host_int_set_MacAddress + * @details sets mac address + * @param[in,out] handle to the wifi driver, + * + * @return Error code indicating success/failure + * @note + * @author mabubakr + * @date 16 July 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_set_MacAddress(WILC_WFIDrvHandle hWFIDrv, WILC_Uint8 *pu8MacAddress) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrHostIFmsg strHostIFmsg; + + PRINT_D(GENERIC_DBG, "mac addr = %x:%x:%x\n", pu8MacAddress[0], pu8MacAddress[1], pu8MacAddress[2]); + + /* prepare setting mac address message */ + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + strHostIFmsg.u16MsgId = HOST_IF_MSG_SET_MAC_ADDRESS; + WILC_memcpy(strHostIFmsg.uniHostIFmsgBody.strHostIfSetMacAddress.u8MacAddress, pu8MacAddress, ETH_ALEN); + strHostIFmsg.drvHandler = hWFIDrv; + + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + if (s32Error) { + PRINT_ER("Failed to send message queue: Set mac address\n"); + WILC_ERRORREPORT(s32Error, s32Error); + } + WILC_CATCH(s32Error) + { + + } + + return s32Error; + +} + +/** + * @brief host_int_get_RSNAConfigPSKPassPhrase + * @details gets the pass phrase:AP/STA mode. This function gets the pass phrase used to + * generate the Pre-Shared Key when WPA/WPA2 is enabled + * The length of the field can vary from 8 to 64 bytes, + * the lower layer should get the + * @param[in,out] handle to the wifi driver, + * String containing PSK + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_get_RSNAConfigPSKPassPhrase(WILC_WFIDrvHandle hWFIDrv, + WILC_Uint8 *pu8PassPhrase, WILC_Uint8 u8Psklength) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + /* tstrWILC_WFIDrv * pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; */ + + strWID.u16WIDid = (WILC_Uint16)WID_11I_PSK; + strWID.enuWIDtype = WID_STR; + strWID.s32ValueSize = u8Psklength; + strWID.ps8WidVal = pu8PassPhrase; + + return s32Error; +} + +/** + * @brief host_int_get_site_survey_results + * @details gets the site survey results + * @param[in,out] handle to the wifi driver, + * Message containing site survey results in the + * following format + *|---------------------------------------------------| + | MsgLength | fragNo. | MsgBodyLength | MsgBody | + ||-----------|-----------|---------------|-----------| + | 1 | 1 | 1 | 1 | + | ----------------------------------------- | ---------------- + | + ||---------------------------------------| + | Network1 | Netweork2 | ... | Network5 | + ||---------------------------------------| + | 44 | 44 | ... | 44 | + | -------------------------- | --------------------------------------- + | + ||---------------------------------------------------------------------| + | SSID | BSS Type | Channel | Security Status| BSSID | RSSI |Reserved | + | + | + ||------|----------|---------|----------------|-------|------|---------| + | 33 | 1 | 1 | 1 | 6 | 1 | 1 | + ||---------------------------------------------------------------------| + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +#ifndef CONNECT_DIRECT +WILC_Sint32 host_int_get_site_survey_results(WILC_WFIDrvHandle hWFIDrv, + WILC_Uint8 ppu8RcvdSiteSurveyResults[][MAX_SURVEY_RESULT_FRAG_SIZE], + WILC_Uint32 u32MaxSiteSrvyFragLen) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID astrWIDList[2]; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + + astrWIDList[0].u16WIDid = (WILC_Uint16)WID_SITE_SURVEY_RESULTS; + astrWIDList[0].enuWIDtype = WID_STR; + astrWIDList[0].ps8WidVal = ppu8RcvdSiteSurveyResults[0]; + astrWIDList[0].s32ValueSize = u32MaxSiteSrvyFragLen; + + astrWIDList[1].u16WIDid = (WILC_Uint16)WID_SITE_SURVEY_RESULTS; + astrWIDList[1].enuWIDtype = WID_STR; + astrWIDList[1].ps8WidVal = ppu8RcvdSiteSurveyResults[1]; + astrWIDList[1].s32ValueSize = u32MaxSiteSrvyFragLen; + + s32Error = SendConfigPkt(GET_CFG, astrWIDList, 2, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + + /*get the value by searching the local copy*/ + if (s32Error) { + PRINT_ER("Failed to send config packet to get survey results\n"); + WILC_ERRORREPORT(s32Error, WILC_INVALID_STATE); + } + + WILC_CATCH(s32Error) + { + + } + + return s32Error; +} +#endif + +/** + * @brief sets a start scan request + * @details + * @param[in,out] handle to the wifi driver, + * @param[in] Scan Source one of the following values + * DEFAULT_SCAN 0 + * USER_SCAN BIT0 + * OBSS_PERIODIC_SCAN BIT1 + * OBSS_ONETIME_SCAN BIT2 + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_set_start_scan_req(WILC_WFIDrvHandle hWFIDrv, WILC_Uint8 scanSource) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + /* tstrWILC_WFIDrv * pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; */ + + strWID.u16WIDid = (WILC_Uint16)WID_START_SCAN_REQ; + strWID.enuWIDtype = WID_CHAR; + strWID.ps8WidVal = (WILC_Sint8 *)&scanSource; + strWID.s32ValueSize = sizeof(WILC_Char); + + return s32Error; +} + +/** + * @brief host_int_get_start_scan_req + * @details gets a start scan request + * @param[in,out] handle to the wifi driver, + * @param[in] Scan Source one of the following values + * DEFAULT_SCAN 0 + * USER_SCAN BIT0 + * OBSS_PERIODIC_SCAN BIT1 + * OBSS_ONETIME_SCAN BIT2 + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ + +WILC_Sint32 host_int_get_start_scan_req(WILC_WFIDrvHandle hWFIDrv, WILC_Uint8 *pu8ScanSource) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + /* tstrWILC_WFIDrv * pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; */ + + strWID.u16WIDid = (WILC_Uint16)WID_START_SCAN_REQ; + strWID.enuWIDtype = WID_CHAR; + strWID.ps8WidVal = (WILC_Sint8 *)pu8ScanSource; + strWID.s32ValueSize = sizeof(WILC_Char); + + return s32Error; +} + +/** + * @brief host_int_set_join_req + * @details sets a join request + * @param[in,out] handle to the wifi driver, + * @param[in] Index of the bss descriptor + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_set_join_req(WILC_WFIDrvHandle hWFIDrv, WILC_Uint8 *pu8bssid, + WILC_Uint8 *pu8ssid, size_t ssidLen, + const WILC_Uint8 *pu8IEs, size_t IEsLen, + tWILCpfConnectResult pfConnectResult, void *pvUserArg, + WILC_Uint8 u8security, AUTHTYPE_T tenuAuth_type, + WILC_Uint8 u8channel, + void *pJoinParams) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + tstrHostIFmsg strHostIFmsg; + tenuScanConnTimer enuScanConnTimer; + + if (pstrWFIDrv == WILC_NULL || pfConnectResult == WILC_NULL) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + if (hWFIDrv == NULL) { + PRINT_ER("Driver not initialized: gWFiDrvHandle = NULL\n"); + WILC_ERRORREPORT(s32Error, WILC_FAIL); + } + + if (pJoinParams == NULL) { + PRINT_ER("Unable to Join - JoinParams is NULL\n"); + WILC_ERRORREPORT(s32Error, WILC_FAIL); + + } +/* + * if(gWFiDrvHandle->strWILC_UsrScanReq.u32RcvdChCount == 0) + * { + * PRINT_ER("No scan results exist: Scanning should be done\n"); + * WILC_ERRORREPORT(s32Error, WILC_FAIL); + * } + */ + /* prepare the Connect Message */ + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + strHostIFmsg.u16MsgId = HOST_IF_MSG_CONNECT; + + strHostIFmsg.uniHostIFmsgBody.strHostIFconnectAttr.u8security = u8security; + strHostIFmsg.uniHostIFmsgBody.strHostIFconnectAttr.tenuAuth_type = tenuAuth_type; + strHostIFmsg.uniHostIFmsgBody.strHostIFconnectAttr.u8channel = u8channel; + strHostIFmsg.uniHostIFmsgBody.strHostIFconnectAttr.pfConnectResult = pfConnectResult; + strHostIFmsg.uniHostIFmsgBody.strHostIFconnectAttr.pvUserArg = pvUserArg; + strHostIFmsg.uniHostIFmsgBody.strHostIFconnectAttr.pJoinParams = pJoinParams; + strHostIFmsg.drvHandler = hWFIDrv; + + if (pu8bssid != NULL) { + strHostIFmsg.uniHostIFmsgBody.strHostIFconnectAttr.pu8bssid = (WILC_Uint8 *)WILC_MALLOC(6); /* will be deallocated by the receiving thread */ + WILC_memcpy(strHostIFmsg.uniHostIFmsgBody.strHostIFconnectAttr.pu8bssid, + pu8bssid, 6); + } + + if (pu8ssid != NULL) { + strHostIFmsg.uniHostIFmsgBody.strHostIFconnectAttr.ssidLen = ssidLen; + strHostIFmsg.uniHostIFmsgBody.strHostIFconnectAttr.pu8ssid = (WILC_Uint8 *)WILC_MALLOC(ssidLen); /* will be deallocated by the receiving thread */ + WILC_memcpy(strHostIFmsg.uniHostIFmsgBody.strHostIFconnectAttr.pu8ssid, + + pu8ssid, ssidLen); + } + + if (pu8IEs != NULL) { + strHostIFmsg.uniHostIFmsgBody.strHostIFconnectAttr.IEsLen = IEsLen; + strHostIFmsg.uniHostIFmsgBody.strHostIFconnectAttr.pu8IEs = (WILC_Uint8 *)WILC_MALLOC(IEsLen); /* will be deallocated by the receiving thread */ + WILC_memcpy(strHostIFmsg.uniHostIFmsgBody.strHostIFconnectAttr.pu8IEs, + pu8IEs, IEsLen); + } + if (pstrWFIDrv->enuHostIFstate < HOST_IF_CONNECTING) { + pstrWFIDrv->enuHostIFstate = HOST_IF_CONNECTING; + } else + PRINT_D(GENERIC_DBG, "Don't set state to 'connecting' as state is %d\n", pstrWFIDrv->enuHostIFstate); + + /* send the message */ + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + if (s32Error) { + PRINT_ER("Failed to send message queue: Set join request\n"); + WILC_ERRORREPORT(s32Error, WILC_FAIL); + } + + enuScanConnTimer = CONNECT_TIMER; + WILC_TimerStart(&(pstrWFIDrv->hConnectTimer), HOST_IF_CONNECT_TIMEOUT, (void *) hWFIDrv, WILC_NULL); + + WILC_CATCH(s32Error) + { + + } + + return s32Error; +} + +/** + * @brief Flush a join request parameters to FW, but actual connection + * @details The function is called in situation where WILC is connected to AP and + * required to switch to hybrid FW for P2P connection + * @param[in] handle to the wifi driver, + * @return Error code indicating success/failure + * @note + * @author Amr Abdel-Moghny + * @date 19 DEC 2013 + * @version 8.0 + */ + +WILC_Sint32 host_int_flush_join_req(WILC_WFIDrvHandle hWFIDrv) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrHostIFmsg strHostIFmsg; + + if (!gu8FlushedJoinReq) { + s32Error = WILC_FAIL; + return s32Error; + } + + + if (hWFIDrv == WILC_NULL) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + + strHostIFmsg.u16MsgId = HOST_IF_MSG_FLUSH_CONNECT; + strHostIFmsg.drvHandler = hWFIDrv; + + /* send the message */ + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + if (s32Error) { + PRINT_ER("Failed to send message queue: Flush join request\n"); + WILC_ERRORREPORT(s32Error, WILC_FAIL); + } + + WILC_CATCH(s32Error) + { + + } + return s32Error; +} + +/** + * @brief host_int_disconnect + * @details disconnects from the currently associated network + * @param[in,out] handle to the wifi driver, + * @param[in] Reason Code of the Disconnection + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_disconnect(WILC_WFIDrvHandle hWFIDrv, WILC_Uint16 u16ReasonCode) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrHostIFmsg strHostIFmsg; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + + if (pstrWFIDrv == WILC_NULL) { + PRINT_ER("Driver not initialized: pstrWFIDrv = NULL \n"); + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + if (pstrWFIDrv == NULL) { + PRINT_ER("gWFiDrvHandle = NULL\n"); + WILC_ERRORREPORT(s32Error, WILC_FAIL); + } + + /* prepare the Disconnect Message */ + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + strHostIFmsg.u16MsgId = HOST_IF_MSG_DISCONNECT; + strHostIFmsg.drvHandler = hWFIDrv; + + /* send the message */ + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + if (s32Error) + PRINT_ER("Failed to send message queue: disconnect\n"); + /* ////////////// */ + WILC_SemaphoreAcquire(&(pstrWFIDrv->hSemTestDisconnectBlock), NULL); + /* /////// */ + + WILC_CATCH(s32Error) + { + + } + + return s32Error; +} + +/** + * @brief host_int_disconnect_station + * @details disconnects a sta + * @param[in,out] handle to the wifi driver, + * @param[in] Association Id of the station to be disconnected + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_disconnect_station(WILC_WFIDrvHandle hWFIDrv, WILC_Uint8 assoc_id) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + /* tstrWILC_WFIDrv * pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; */ + + strWID.u16WIDid = (WILC_Uint16)WID_DISCONNECT; + strWID.enuWIDtype = WID_CHAR; + strWID.ps8WidVal = (WILC_Sint8 *)&assoc_id; + strWID.s32ValueSize = sizeof(WILC_Char); + + return s32Error; +} + +/** + * @brief host_int_get_assoc_req_info + * @details gets a Association request info + * @param[in,out] handle to the wifi driver, + * Message containg assoc. req info in the following format + * ------------------------------------------------------------------------ + | Management Frame Format | + ||-------------------------------------------------------------------| + ||Frame Control|Duration|DA|SA|BSSID|Sequence Control|Frame Body|FCS | + ||-------------|--------|--|--|-----|----------------|----------|----| + | 2 |2 |6 |6 |6 | 2 |0 - 2312 | 4 | + ||-------------------------------------------------------------------| + | | + | Association Request Frame - Frame Body | + ||-------------------------------------------------------------------| + | Capability Information | Listen Interval | SSID | Supported Rates | + ||------------------------|-----------------|------|-----------------| + | 2 | 2 | 2-34 | 3-10 | + | --------------------------------------------------------------------- + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ + +WILC_Sint32 host_int_get_assoc_req_info(WILC_WFIDrvHandle hWFIDrv, WILC_Uint8 *pu8AssocReqInfo, + WILC_Uint32 u32AssocReqInfoLen) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + /* tstrWILC_WFIDrv * pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; */ + + strWID.u16WIDid = (WILC_Uint16)WID_ASSOC_REQ_INFO; + strWID.enuWIDtype = WID_STR; + strWID.ps8WidVal = pu8AssocReqInfo; + strWID.s32ValueSize = u32AssocReqInfoLen; + + + return s32Error; +} + +/** + * @brief gets a Association Response info + * @details + * @param[in,out] handle to the wifi driver, + * Message containg assoc. resp info + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_get_assoc_res_info(WILC_WFIDrvHandle hWFIDrv, WILC_Uint8 *pu8AssocRespInfo, + WILC_Uint32 u32MaxAssocRespInfoLen, WILC_Uint32 *pu32RcvdAssocRespInfoLen) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + + if (pstrWFIDrv == WILC_NULL) { + PRINT_ER("Driver not initialized: pstrWFIDrv = NULL \n"); + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + strWID.u16WIDid = (WILC_Uint16)WID_ASSOC_RES_INFO; + strWID.enuWIDtype = WID_STR; + strWID.ps8WidVal = pu8AssocRespInfo; + strWID.s32ValueSize = u32MaxAssocRespInfoLen; + + + /* Sending Configuration packet */ + s32Error = SendConfigPkt(GET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + if (s32Error) { + PRINT_ER("Failed to send association response config packet\n"); + *pu32RcvdAssocRespInfoLen = 0; + WILC_ERRORREPORT(s32Error, WILC_INVALID_STATE); + } else { + *pu32RcvdAssocRespInfoLen = strWID.s32ValueSize; + } + + WILC_CATCH(s32Error) + { + + } + return s32Error; +} + +/** + * @brief gets a Association Response info + * @details Valid only in STA mode. This function gives the RSSI + * values observed in all the channels at the time of scanning. + * The length of the field is 1 greater that the total number of + * channels supported. Byte 0 contains the number of channels while + * each of Byte N contains the observed RSSI value for the channel index N. + * @param[in,out] handle to the wifi driver, + * array of scanned channels' RSSI + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_get_rx_power_level(WILC_WFIDrvHandle hWFIDrv, WILC_Uint8 *pu8RxPowerLevel, + WILC_Uint32 u32RxPowerLevelLen) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + /* tstrWILC_WFIDrv * pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; */ + + strWID.u16WIDid = (WILC_Uint16)WID_RX_POWER_LEVEL; + strWID.enuWIDtype = WID_STR; + strWID.ps8WidVal = pu8RxPowerLevel; + strWID.s32ValueSize = u32RxPowerLevelLen; + + + return s32Error; +} + +/** + * @brief sets a channel + * @details + * @param[in,out] handle to the wifi driver, + * @param[in] Index of the channel to be set + *|-------------------------------------------------------------------| + | CHANNEL1 CHANNEL2 .... CHANNEL14 | + | Input: 1 2 14 | + ||-------------------------------------------------------------------| + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_set_mac_chnl_num(WILC_WFIDrvHandle hWFIDrv, WILC_Uint8 u8ChNum) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + tstrHostIFmsg strHostIFmsg; + + if (pstrWFIDrv == WILC_NULL) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + /* prepare the set channel message */ + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + strHostIFmsg.u16MsgId = HOST_IF_MSG_SET_CHANNEL; + strHostIFmsg.uniHostIFmsgBody.strHostIFSetChan.u8SetChan = u8ChNum; + strHostIFmsg.drvHandler = hWFIDrv; + + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + if (s32Error) { + WILC_ERRORREPORT(s32Error, s32Error); + } + WILC_CATCH(s32Error) + { + + } + + return s32Error; +} + + +WILC_Sint32 host_int_wait_msg_queue_idle(void) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + + tstrHostIFmsg strHostIFmsg; + + /* prepare the set driver handler message */ + + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + strHostIFmsg.u16MsgId = HOST_IF_MSG_Q_IDLE; + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + if (s32Error) { + WILC_ERRORREPORT(s32Error, s32Error); + } + WILC_CATCH(s32Error) + { + + } + + /* wait untill MSG Q is empty */ + WILC_SemaphoreAcquire(&hWaitResponse, NULL); + + return s32Error; + +} + +WILC_Sint32 host_int_set_wfi_drv_handler(WILC_Uint32 u32address) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + + tstrHostIFmsg strHostIFmsg; + + + /* prepare the set driver handler message */ + + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + strHostIFmsg.u16MsgId = HOST_IF_MSG_SET_WFIDRV_HANDLER; + strHostIFmsg.uniHostIFmsgBody.strHostIfSetDrvHandler.u32Address = u32address; + /* strHostIFmsg.drvHandler=hWFIDrv; */ + + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + if (s32Error) { + WILC_ERRORREPORT(s32Error, s32Error); + } + WILC_CATCH(s32Error) + { + + } + + return s32Error; +} + + + +WILC_Sint32 host_int_set_operation_mode(WILC_WFIDrvHandle hWFIDrv, WILC_Uint32 u32mode) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + + tstrHostIFmsg strHostIFmsg; + + + /* prepare the set driver handler message */ + + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + strHostIFmsg.u16MsgId = HOST_IF_MSG_SET_OPERATION_MODE; + strHostIFmsg.uniHostIFmsgBody.strHostIfSetOperationMode.u32Mode = u32mode; + strHostIFmsg.drvHandler = hWFIDrv; + + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + if (s32Error) { + WILC_ERRORREPORT(s32Error, s32Error); + } + WILC_CATCH(s32Error) + { + + } + + return s32Error; +} + +/** + * @brief gets the current channel index + * @details + * @param[in,out] handle to the wifi driver, + * current channel index + *|-----------------------------------------------------------------------| + | CHANNEL1 CHANNEL2 .... CHANNEL14 | + | Input: 1 2 14 | + ||-----------------------------------------------------------------------| + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_get_host_chnl_num(WILC_WFIDrvHandle hWFIDrv, WILC_Uint8 *pu8ChNo) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + tstrHostIFmsg strHostIFmsg; + + if (pstrWFIDrv == WILC_NULL) { + PRINT_ER("Driver not initialized: pstrWFIDrv = NULL \n"); + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + /* prepare the Get Channel Message */ + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + strHostIFmsg.u16MsgId = HOST_IF_MSG_GET_CHNL; + strHostIFmsg.drvHandler = hWFIDrv; + + /* send the message */ + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + if (s32Error) + PRINT_ER("Failed to send get host channel param's message queue "); + WILC_SemaphoreAcquire(&(pstrWFIDrv->hSemGetCHNL), NULL); + /* gu8Chnl = 11; */ + + *pu8ChNo = gu8Chnl; + + WILC_CATCH(s32Error) + { + } + + return s32Error; + + +} + + +/** + * @brief host_int_test_set_int_wid + * @details Test function for setting wids + * @param[in,out] WILC_WFIDrvHandle hWFIDrv, WILC_Uint32 u32TestMemAddr + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_test_set_int_wid(WILC_WFIDrvHandle hWFIDrv, WILC_Uint32 u32TestMemAddr) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + + + if (pstrWFIDrv == WILC_NULL) { + PRINT_ER("Driver not initialized: pstrWFIDrv = NULL \n"); + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + /*prepare configuration packet*/ + strWID.u16WIDid = (WILC_Uint16)WID_MEMORY_ADDRESS; + strWID.enuWIDtype = WID_INT; + strWID.ps8WidVal = (WILC_Char *)&u32TestMemAddr; + strWID.s32ValueSize = sizeof(WILC_Uint32); + + /*Sending Cfg*/ + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + if (s32Error) { + PRINT_ER("Test Function: Failed to set wid value\n"); + WILC_ERRORREPORT(s32Error, WILC_INVALID_STATE); + } else { + PRINT_D(HOSTINF_DBG, "Successfully set wid value\n"); + + } + + WILC_CATCH(s32Error) + { + + } + return s32Error; +} + +#ifdef WILC_AP_EXTERNAL_MLME +/** + * @brief host_int_get_inactive_time + * @details + * @param[in,out] handle to the wifi driver, + * current sta macaddress, inactive_time + * @return + * @note + * @author + * @date + * @version 1.0 + */ +WILC_Sint32 host_int_get_inactive_time(WILC_WFIDrvHandle hWFIDrv, WILC_Uint8 *mac, WILC_Uint32 *pu32InactiveTime) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + tstrHostIFmsg strHostIFmsg; + + if (pstrWFIDrv == WILC_NULL) { + PRINT_ER("Driver not initialized: pstrWFIDrv = NULL \n"); + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + + WILC_memcpy(strHostIFmsg.uniHostIFmsgBody.strHostIfStaInactiveT.mac, + mac, ETH_ALEN); + + strHostIFmsg.u16MsgId = HOST_IF_MSG_GET_INACTIVETIME; + strHostIFmsg.drvHandler = hWFIDrv; + + /* send the message */ + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + if (s32Error) + PRINT_ER("Failed to send get host channel param's message queue "); + + WILC_SemaphoreAcquire(&(pstrWFIDrv->hSemInactiveTime), NULL); + + *pu32InactiveTime = gu32InactiveTime; + + WILC_CATCH(s32Error) + { + } + + return s32Error; +} +#endif +/** + * @brief host_int_test_get_int_wid + * @details Test function for getting wids + * @param[in,out] WILC_WFIDrvHandle hWFIDrv, WILC_Uint32* pu32TestMemAddr + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_test_get_int_wid(WILC_WFIDrvHandle hWFIDrv, WILC_Uint32 *pu32TestMemAddr) +{ + + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWID strWID; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + + + if (pstrWFIDrv == WILC_NULL) { + PRINT_ER("Driver not initialized: pstrWFIDrv = NULL \n"); + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + strWID.u16WIDid = (WILC_Uint16)WID_MEMORY_ADDRESS; + strWID.enuWIDtype = WID_INT; + strWID.ps8WidVal = (WILC_Sint8 *)pu32TestMemAddr; + strWID.s32ValueSize = sizeof(WILC_Uint32); + + s32Error = SendConfigPkt(GET_CFG, &strWID, 1, WILC_TRUE, (WILC_Uint32)pstrWFIDrv); + /*get the value by searching the local copy*/ + if (s32Error) { + PRINT_ER("Test Function: Failed to get wid value\n"); + WILC_ERRORREPORT(s32Error, WILC_INVALID_STATE); + } else { + PRINT_D(HOSTINF_DBG, "Successfully got wid value\n"); + + } + + WILC_CATCH(s32Error) + { + + } + return s32Error; +} + + +/** + * @brief host_int_get_rssi + * @details gets the currently maintained RSSI value for the station. + * The received signal strength value in dB. + * The range of valid values is -128 to 0. + * @param[in,out] handle to the wifi driver, + * rssi value in dB + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_get_rssi(WILC_WFIDrvHandle hWFIDrv, WILC_Sint8 *ps8Rssi) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrHostIFmsg strHostIFmsg; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + + + /* prepare the Get RSSI Message */ + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + strHostIFmsg.u16MsgId = HOST_IF_MSG_GET_RSSI; + strHostIFmsg.drvHandler = hWFIDrv; + + /* send the message */ + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + if (s32Error) { + PRINT_ER("Failed to send get host channel param's message queue "); + return WILC_FAIL; + } + + WILC_SemaphoreAcquire(&(pstrWFIDrv->hSemGetRSSI), NULL); + + + if (ps8Rssi == NULL) { + PRINT_ER("RSS pointer value is null"); + return WILC_FAIL; + } + + + *ps8Rssi = gs8Rssi; + + + return s32Error; +} + +WILC_Sint32 host_int_get_link_speed(WILC_WFIDrvHandle hWFIDrv, WILC_Sint8 *ps8lnkspd) +{ + tstrHostIFmsg strHostIFmsg; + WILC_Sint32 s32Error = WILC_SUCCESS; + + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + + + + /* prepare the Get LINKSPEED Message */ + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + strHostIFmsg.u16MsgId = HOST_IF_MSG_GET_LINKSPEED; + strHostIFmsg.drvHandler = hWFIDrv; + + /* send the message */ + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + if (s32Error) { + PRINT_ER("Failed to send GET_LINKSPEED to message queue "); + return WILC_FAIL; + } + + WILC_SemaphoreAcquire(&(pstrWFIDrv->hSemGetLINKSPEED), NULL); + + + if (ps8lnkspd == NULL) { + PRINT_ER("LINKSPEED pointer value is null"); + return WILC_FAIL; + } + + + *ps8lnkspd = gs8lnkspd; + + + return s32Error; +} + +WILC_Sint32 host_int_get_statistics(WILC_WFIDrvHandle hWFIDrv, tstrStatistics *pstrStatistics) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrHostIFmsg strHostIFmsg; + + + /* prepare the Get RSSI Message */ + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + strHostIFmsg.u16MsgId = HOST_IF_MSG_GET_STATISTICS; + strHostIFmsg.uniHostIFmsgBody.pUserData = (WILC_Char *)pstrStatistics; + strHostIFmsg.drvHandler = hWFIDrv; + /* send the message */ + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + if (s32Error) { + PRINT_ER("Failed to send get host channel param's message queue "); + return WILC_FAIL; + } + + WILC_SemaphoreAcquire(&hWaitResponse, NULL); + return s32Error; +} + + +/** + * @brief host_int_scan + * @details scans a set of channels + * @param[in,out] handle to the wifi driver, + * @param[in] Scan source + * Scan Type PASSIVE_SCAN = 0, + * ACTIVE_SCAN = 1 + * Channels Array + * Channels Array length + * Scan Callback function + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 host_int_scan(WILC_WFIDrvHandle hWFIDrv, WILC_Uint8 u8ScanSource, + WILC_Uint8 u8ScanType, WILC_Uint8 *pu8ChnlFreqList, + WILC_Uint8 u8ChnlListLen, const WILC_Uint8 *pu8IEs, + size_t IEsLen, tWILCpfScanResult ScanResult, + void *pvUserArg, tstrHiddenNetwork *pstrHiddenNetwork) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + tstrHostIFmsg strHostIFmsg; + tenuScanConnTimer enuScanConnTimer; + + if (pstrWFIDrv == WILC_NULL || ScanResult == WILC_NULL) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + + /* prepare the Scan Message */ + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + strHostIFmsg.u16MsgId = HOST_IF_MSG_SCAN; + + if (pstrHiddenNetwork != NULL) { + strHostIFmsg.uniHostIFmsgBody.strHostIFscanAttr.strHiddenNetwork.pstrHiddenNetworkInfo = pstrHiddenNetwork->pstrHiddenNetworkInfo; + strHostIFmsg.uniHostIFmsgBody.strHostIFscanAttr.strHiddenNetwork.u8ssidnum = pstrHiddenNetwork->u8ssidnum; + + } else + PRINT_D(HOSTINF_DBG, "pstrHiddenNetwork IS EQUAL TO NULL\n"); + + strHostIFmsg.drvHandler = hWFIDrv; + strHostIFmsg.uniHostIFmsgBody.strHostIFscanAttr.u8ScanSource = u8ScanSource; + strHostIFmsg.uniHostIFmsgBody.strHostIFscanAttr.u8ScanType = u8ScanType; + strHostIFmsg.uniHostIFmsgBody.strHostIFscanAttr.pfScanResult = ScanResult; + strHostIFmsg.uniHostIFmsgBody.strHostIFscanAttr.pvUserArg = pvUserArg; + + strHostIFmsg.uniHostIFmsgBody.strHostIFscanAttr.u8ChnlListLen = u8ChnlListLen; + strHostIFmsg.uniHostIFmsgBody.strHostIFscanAttr.pu8ChnlFreqList = (WILC_Uint8 *)WILC_MALLOC(u8ChnlListLen); /* will be deallocated by the receiving thread */ + WILC_memcpy(strHostIFmsg.uniHostIFmsgBody.strHostIFscanAttr.pu8ChnlFreqList, + pu8ChnlFreqList, u8ChnlListLen); + + strHostIFmsg.uniHostIFmsgBody.strHostIFscanAttr.IEsLen = IEsLen; + strHostIFmsg.uniHostIFmsgBody.strHostIFscanAttr.pu8IEs = (WILC_Uint8 *)WILC_MALLOC(IEsLen); /* will be deallocated by the receiving thread */ + WILC_memcpy(strHostIFmsg.uniHostIFmsgBody.strHostIFscanAttr.pu8IEs, + pu8IEs, IEsLen); + + /* send the message */ + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + if (s32Error) { + PRINT_ER("Error in sending message queue scanning parameters: Error(%d)\n", s32Error); + WILC_ERRORREPORT(s32Error, WILC_FAIL); + } + + enuScanConnTimer = SCAN_TIMER; + PRINT_D(HOSTINF_DBG, ">> Starting the SCAN timer\n"); + WILC_TimerStart(&(pstrWFIDrv->hScanTimer), HOST_IF_SCAN_TIMEOUT, (void *) hWFIDrv, WILC_NULL); + + + WILC_CATCH(s32Error) + { + + } + return s32Error; + +} +/** + * @brief hif_set_cfg + * @details sets configuration wids values + * @param[in,out] handle to the wifi driver, + * @param[in] WID, WID value + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 hif_set_cfg(WILC_WFIDrvHandle hWFIDrv, tstrCfgParamVal *pstrCfgParamVal) +{ + + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + + tstrHostIFmsg strHostIFmsg; + + + if (pstrWFIDrv == WILC_NULL) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + /* prepare the WiphyParams Message */ + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + strHostIFmsg.u16MsgId = HOST_IF_MSG_CFG_PARAMS; + strHostIFmsg.uniHostIFmsgBody.strHostIFCfgParamAttr.pstrCfgParamVal = *pstrCfgParamVal; + strHostIFmsg.drvHandler = hWFIDrv; + + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + + WILC_CATCH(s32Error) + { + } + + return s32Error; + +} + + +/** + * @brief hif_get_cfg + * @details gets configuration wids values + * @param[in,out] handle to the wifi driver, + * WID value + * @param[in] WID, + * @return Error code indicating success/failure + * @note + * @author zsalah + * + * @date 8 March 2012 + * @version 1.0 + */ +WILC_Sint32 hif_get_cfg(WILC_WFIDrvHandle hWFIDrv, WILC_Uint16 u16WID, WILC_Uint16 *pu16WID_Value) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + + WILC_SemaphoreAcquire(&(pstrWFIDrv->gtOsCfgValuesSem), NULL); + + if (pstrWFIDrv == WILC_NULL) { + PRINT_ER("Driver not initialized: pstrWFIDrv = NULL \n"); + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + PRINT_D(HOSTINF_DBG, "Getting configuration parameters\n"); + switch (u16WID) { + + case WID_BSS_TYPE: + *pu16WID_Value = (WILC_Uint16)pstrWFIDrv->strCfgValues.bss_type; + break; + + case WID_AUTH_TYPE: + *pu16WID_Value = (WILC_Uint16)pstrWFIDrv->strCfgValues.auth_type; + break; + + case WID_AUTH_TIMEOUT: + *pu16WID_Value = pstrWFIDrv->strCfgValues.auth_timeout; + break; + + case WID_POWER_MANAGEMENT: + *pu16WID_Value = (WILC_Uint16)pstrWFIDrv->strCfgValues.power_mgmt_mode; + break; + + case WID_SHORT_RETRY_LIMIT: + *pu16WID_Value = pstrWFIDrv->strCfgValues.short_retry_limit; + break; + + case WID_LONG_RETRY_LIMIT: + *pu16WID_Value = pstrWFIDrv->strCfgValues.long_retry_limit; + break; + + case WID_FRAG_THRESHOLD: + *pu16WID_Value = pstrWFIDrv->strCfgValues.frag_threshold; + break; + + case WID_RTS_THRESHOLD: + *pu16WID_Value = pstrWFIDrv->strCfgValues.rts_threshold; + break; + + case WID_PREAMBLE: + *pu16WID_Value = (WILC_Uint16)pstrWFIDrv->strCfgValues.preamble_type; + break; + + case WID_SHORT_SLOT_ALLOWED: + *pu16WID_Value = (WILC_Uint16) pstrWFIDrv->strCfgValues.short_slot_allowed; + break; + + case WID_11N_TXOP_PROT_DISABLE: + *pu16WID_Value = (WILC_Uint16)pstrWFIDrv->strCfgValues.txop_prot_disabled; + break; + + case WID_BEACON_INTERVAL: + *pu16WID_Value = pstrWFIDrv->strCfgValues.beacon_interval; + break; + + case WID_DTIM_PERIOD: + *pu16WID_Value = (WILC_Uint16)pstrWFIDrv->strCfgValues.dtim_period; + break; + + case WID_SITE_SURVEY: + *pu16WID_Value = (WILC_Uint16)pstrWFIDrv->strCfgValues.site_survey_enabled; + break; + + case WID_SITE_SURVEY_SCAN_TIME: + *pu16WID_Value = pstrWFIDrv->strCfgValues.site_survey_scan_time; + break; + + case WID_ACTIVE_SCAN_TIME: + *pu16WID_Value = pstrWFIDrv->strCfgValues.active_scan_time; + break; + + case WID_PASSIVE_SCAN_TIME: + *pu16WID_Value = pstrWFIDrv->strCfgValues.passive_scan_time; + break; + + case WID_CURRENT_TX_RATE: + *pu16WID_Value = pstrWFIDrv->strCfgValues.curr_tx_rate; + break; + + default: + break; + } + + WILC_SemaphoreRelease(&(pstrWFIDrv->gtOsCfgValuesSem), NULL); + + WILC_CATCH(s32Error) + { + } + return s32Error; + +} + +/*****************************************************************************/ +/* Notification Functions */ +/*****************************************************************************/ +/** + * @brief notifies host with join and leave requests + * @details This function prepares an Information frame having the + * information about a joining/leaving station. + * @param[in,out] handle to the wifi driver, + * @param[in] 6 byte Sta Adress + * Join or leave flag: + * Join = 1, + * Leave =0 + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +void host_int_send_join_leave_info_to_host + (WILC_Uint16 assocId, WILC_Uint8 *stationAddr, WILC_Bool joining) +{ +} +/** + * @brief notifies host with stations found in scan + * @details sends the beacon/probe response from scan + * @param[in,out] handle to the wifi driver, + * @param[in] Sta Address, + * Frame length, + * Rssi of the Station found + * @return Error code indicating success/failure + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ + +void GetPeriodicRSSI(void *pvArg) +{ + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)pvArg; + if (pstrWFIDrv == NULL) { + PRINT_ER("Driver handler is NULL\n"); + return; + } + + if (pstrWFIDrv->enuHostIFstate == HOST_IF_CONNECTED) { + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrHostIFmsg strHostIFmsg; + + /* prepare the Get RSSI Message */ + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + strHostIFmsg.u16MsgId = HOST_IF_MSG_GET_RSSI; + strHostIFmsg.drvHandler = pstrWFIDrv; + + /* send the message */ + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + if (s32Error) { + PRINT_ER("Failed to send get host channel param's message queue "); + return; + } + } + WILC_TimerStart(&(g_hPeriodicRSSI), 5000, (void *)pstrWFIDrv, NULL); +} + + +void host_int_send_network_info_to_host + (WILC_Uint8 *macStartAddress, WILC_Uint16 u16RxFrameLen, WILC_Sint8 s8Rssi) +{ +} +/** + * @brief host_int_init + * @details host interface initialization function + * @param[in,out] handle to the wifi driver, + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ +static WILC_Uint32 u32Intialized; +static WILC_Uint32 msgQ_created; +static WILC_Uint32 clients_count; + +WILC_Sint32 host_int_init(WILC_WFIDrvHandle *phWFIDrv) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv; + tstrWILC_SemaphoreAttrs strSemaphoreAttrs; + + + /*if(u32Intialized == 1) + * { + * PRINT_D(HOSTINF_DBG,"Host interface is previously initialized\n"); + * *phWFIDrv = (WILC_WFIDrvHandle)gWFiDrvHandle; //Will be adjusted later for P2P + * return 0; + * } */ + PRINT_D(HOSTINF_DBG, "Initializing host interface for client %d\n", clients_count + 1); + + gbScanWhileConnected = WILC_FALSE; + + WILC_SemaphoreFillDefault(&strSemaphoreAttrs); + + + strSemaphoreAttrs.u32InitCount = 0; + WILC_SemaphoreCreate(&hWaitResponse, &strSemaphoreAttrs); + + + + /*Allocate host interface private structure*/ + pstrWFIDrv = (tstrWILC_WFIDrv *)WILC_MALLOC(sizeof(tstrWILC_WFIDrv)); + if (pstrWFIDrv == WILC_NULL) { + /* WILC_ERRORREPORT(s32Error,WILC_NO_MEM); */ + s32Error = WILC_NO_MEM; + PRINT_ER("Failed to allocate memory\n"); + goto _fail_timer_2; + } + WILC_memset(pstrWFIDrv, 0, sizeof(tstrWILC_WFIDrv)); + /*return driver handle to user*/ + *phWFIDrv = (WILC_WFIDrvHandle)pstrWFIDrv; + /*save into globl handle*/ + + #ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP + + g_obtainingIP = WILC_FALSE; + #endif + + PRINT_D(HOSTINF_DBG, "Global handle pointer value=%x\n", (WILC_Uint32)pstrWFIDrv); + /* /////////////////////////////////////// */ + if (clients_count == 0) { + strSemaphoreAttrs.u32InitCount = 0; + WILC_SemaphoreCreate(&hSemHostIFthrdEnd, &strSemaphoreAttrs); + + strSemaphoreAttrs.u32InitCount = 0; + WILC_SemaphoreCreate(&hSemDeinitDrvHandle, &strSemaphoreAttrs); + + /*BugID_5348*/ + strSemaphoreAttrs.u32InitCount = 1; + WILC_SemaphoreCreate(&hSemHostIntDeinit, &strSemaphoreAttrs); + } + + strSemaphoreAttrs.u32InitCount = 0; + WILC_SemaphoreCreate(&(pstrWFIDrv->hSemTestKeyBlock), &strSemaphoreAttrs); + strSemaphoreAttrs.u32InitCount = 0; + WILC_SemaphoreCreate(&(pstrWFIDrv->hSemTestDisconnectBlock), &strSemaphoreAttrs); + strSemaphoreAttrs.u32InitCount = 0; + WILC_SemaphoreCreate(&(pstrWFIDrv->hSemGetRSSI), &strSemaphoreAttrs); + strSemaphoreAttrs.u32InitCount = 0; + WILC_SemaphoreCreate(&(pstrWFIDrv->hSemGetLINKSPEED), &strSemaphoreAttrs); + strSemaphoreAttrs.u32InitCount = 0; + WILC_SemaphoreCreate(&(pstrWFIDrv->hSemGetCHNL), &strSemaphoreAttrs); + strSemaphoreAttrs.u32InitCount = 0; + WILC_SemaphoreCreate(&(pstrWFIDrv->hSemInactiveTime), &strSemaphoreAttrs); + + /* /////////////////////////////////////// */ + + + + PRINT_D(HOSTINF_DBG, "INIT: CLIENT COUNT %d\n", clients_count); + + if (clients_count == 0) { + + s32Error = WILC_MsgQueueCreate(&gMsgQHostIF, WILC_NULL); + + + if (s32Error < 0) { + PRINT_ER("Failed to creat MQ\n"); + goto _fail_; + } + msgQ_created = 1; + s32Error = WILC_ThreadCreate(&HostIFthreadHandler, hostIFthread, WILC_NULL, WILC_NULL); + if (s32Error < 0) { + PRINT_ER("Failed to creat Thread\n"); + goto _fail_mq_; + } + s32Error = WILC_TimerCreate(&(g_hPeriodicRSSI), GetPeriodicRSSI, WILC_NULL); + if (s32Error < 0) { + PRINT_ER("Failed to creat Timer\n"); + goto _fail_timer_1; + } + WILC_TimerStart(&(g_hPeriodicRSSI), 5000, (void *)pstrWFIDrv, NULL); + + } + + + s32Error = WILC_TimerCreate(&(pstrWFIDrv->hScanTimer), TimerCB_Scan, WILC_NULL); + if (s32Error < 0) { + PRINT_ER("Failed to creat Timer\n"); + goto _fail_thread_; + } + + s32Error = WILC_TimerCreate(&(pstrWFIDrv->hConnectTimer), TimerCB_Connect, WILC_NULL); + if (s32Error < 0) { + PRINT_ER("Failed to creat Timer\n"); + goto _fail_timer_1; + } + + + #ifdef WILC_P2P + /*Remain on channel timer*/ + s32Error = WILC_TimerCreate(&(pstrWFIDrv->hRemainOnChannel), ListenTimerCB, WILC_NULL); + if (s32Error < 0) { + PRINT_ER("Failed to creat Remain-on-channel Timer\n"); + goto _fail_timer_3; + } + #endif + + WILC_SemaphoreCreate(&(pstrWFIDrv->gtOsCfgValuesSem), NULL); + WILC_SemaphoreAcquire(&(pstrWFIDrv->gtOsCfgValuesSem), NULL); + + + +#ifdef SIMULATION + TransportInit(); +#endif + + pstrWFIDrv->enuHostIFstate = HOST_IF_IDLE; + /* gWFiDrvHandle->bPendingConnRequest = WILC_FALSE; */ + + /*Initialize CFG WIDS Defualt Values*/ + + pstrWFIDrv->strCfgValues.site_survey_enabled = SITE_SURVEY_OFF; + pstrWFIDrv->strCfgValues.scan_source = DEFAULT_SCAN; + pstrWFIDrv->strCfgValues.active_scan_time = ACTIVE_SCAN_TIME; + pstrWFIDrv->strCfgValues.passive_scan_time = PASSIVE_SCAN_TIME; + pstrWFIDrv->strCfgValues.curr_tx_rate = AUTORATE; + + + #ifdef WILC_P2P + + pstrWFIDrv->u64P2p_MgmtTimeout = 0; + + #endif + + PRINT_INFO(HOSTINF_DBG, "Initialization values, Site survey value: %d\n Scan source: %d\n Active scan time: %d\n Passive scan time: %d\nCurrent tx Rate = %d\n", + + pstrWFIDrv->strCfgValues.site_survey_enabled, pstrWFIDrv->strCfgValues.scan_source, + pstrWFIDrv->strCfgValues.active_scan_time, pstrWFIDrv->strCfgValues.passive_scan_time, + pstrWFIDrv->strCfgValues.curr_tx_rate); + + + WILC_SemaphoreRelease(&(pstrWFIDrv->gtOsCfgValuesSem), NULL); + + /*TODO Code to setup simulation to be removed later*/ + /*Intialize configurator module*/ + s32Error = CoreConfiguratorInit(); + if (s32Error < 0) { + PRINT_ER("Failed to initialize core configurator\n"); + goto _fail_mem_; + } + +#ifdef SIMULATION + /*Initialize Simulaor*/ + CoreConfigSimulatorInit(); +#endif + + u32Intialized = 1; + clients_count++; /* increase number of created entities */ + + return s32Error; + + +_fail_mem_: + if (pstrWFIDrv != WILC_NULL) + WILC_FREE(pstrWFIDrv); +#ifdef WILC_P2P +_fail_timer_3: + WILC_TimerDestroy(&(pstrWFIDrv->hRemainOnChannel), WILC_NULL); +#endif +_fail_timer_2: + WILC_SemaphoreRelease(&(pstrWFIDrv->gtOsCfgValuesSem), NULL); + WILC_TimerDestroy(&(pstrWFIDrv->hConnectTimer), WILC_NULL); +_fail_timer_1: + WILC_TimerDestroy(&(pstrWFIDrv->hScanTimer), WILC_NULL); +_fail_thread_: + WILC_ThreadDestroy(&HostIFthreadHandler, WILC_NULL); +_fail_mq_: + WILC_MsgQueueDestroy(&gMsgQHostIF, WILC_NULL); +_fail_: + return s32Error; + + +} +/** + * @brief host_int_deinit + * @details host interface initialization function + * @param[in,out] handle to the wifi driver, + * @note + * @author zsalah + * @date 8 March 2012 + * @version 1.0 + */ + +WILC_Sint32 host_int_deinit(WILC_WFIDrvHandle hWFIDrv) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrHostIFmsg strHostIFmsg; + + + /*obtain driver handle*/ + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + /*if(u32Intialized == 0) + * { + * PRINT_ER("Host Interface is not initialized\n"); + * return 0; + * }*/ + + /*BugID_5348*/ + + if (pstrWFIDrv == NULL) { + PRINT_ER("pstrWFIDrv = NULL\n"); + return 0; + } + + WILC_SemaphoreAcquire(&hSemHostIntDeinit, NULL); + + terminated_handle = pstrWFIDrv; + PRINT_D(HOSTINF_DBG, "De-initializing host interface for client %d\n", clients_count); + + /*BugID_5348*/ + /*Destroy all timers before acquiring hSemDeinitDrvHandle*/ + /*to guarantee handling all messages befor proceeding*/ + if (WILC_TimerDestroy(&(pstrWFIDrv->hScanTimer), WILC_NULL)) { + PRINT_D(HOSTINF_DBG, ">> Scan timer is active \n"); + /* msleep(HOST_IF_SCAN_TIMEOUT+1000); */ + } + + if (WILC_TimerDestroy(&(pstrWFIDrv->hConnectTimer), WILC_NULL)) { + PRINT_D(HOSTINF_DBG, ">> Connect timer is active \n"); + /* msleep(HOST_IF_CONNECT_TIMEOUT+1000); */ + } + + + if (WILC_TimerDestroy(&(g_hPeriodicRSSI), WILC_NULL)) { + PRINT_D(HOSTINF_DBG, ">> Connect timer is active \n"); + /* msleep(HOST_IF_CONNECT_TIMEOUT+1000); */ + } + + #ifdef WILC_P2P + /*Destroy Remain-onchannel Timer*/ + WILC_TimerDestroy(&(pstrWFIDrv->hRemainOnChannel), WILC_NULL); + #endif + + host_int_set_wfi_drv_handler((WILC_Uint32)WILC_NULL); + WILC_SemaphoreAcquire(&hSemDeinitDrvHandle, NULL); + + + /*Calling the CFG80211 scan done function with the abort flag set to true*/ + if (pstrWFIDrv->strWILC_UsrScanReq.pfUserScanResult) { + pstrWFIDrv->strWILC_UsrScanReq.pfUserScanResult(SCAN_EVENT_ABORTED, WILC_NULL, + pstrWFIDrv->strWILC_UsrScanReq.u32UserScanPvoid, NULL); + + pstrWFIDrv->strWILC_UsrScanReq.pfUserScanResult = WILC_NULL; + } + /*deinit configurator and simulator*/ +#ifdef SIMULATION + CoreConfigSimulatorDeInit(); +#endif + CoreConfiguratorDeInit(); +#ifdef SIMULATION + TransportDeInit(); +#endif + + pstrWFIDrv->enuHostIFstate = HOST_IF_IDLE; + + gbScanWhileConnected = WILC_FALSE; + + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + if (clients_count == 1) { + if (WILC_TimerDestroy(&g_hPeriodicRSSI, WILC_NULL)) { + PRINT_D(HOSTINF_DBG, ">> Connect timer is active \n"); + /* msleep(HOST_IF_CONNECT_TIMEOUT+1000); */ + } + strHostIFmsg.u16MsgId = HOST_IF_MSG_EXIT; + strHostIFmsg.drvHandler = hWFIDrv; + + + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + if (s32Error != WILC_SUCCESS) { + PRINT_ER("Error in sending deinit's message queue message function: Error(%d)\n", s32Error); + } + + WILC_SemaphoreAcquire(&hSemHostIFthrdEnd, NULL); + + + + WILC_MsgQueueDestroy(&gMsgQHostIF, WILC_NULL); + msgQ_created = 0; + + + WILC_SemaphoreDestroy(&hSemHostIFthrdEnd, NULL); + WILC_SemaphoreDestroy(&hSemDeinitDrvHandle, NULL); + + } + + WILC_SemaphoreDestroy(&(pstrWFIDrv->hSemTestKeyBlock), NULL); + WILC_SemaphoreDestroy(&(pstrWFIDrv->hSemTestDisconnectBlock), NULL); + WILC_SemaphoreDestroy(&(pstrWFIDrv->hSemGetRSSI), NULL); + WILC_SemaphoreDestroy(&(pstrWFIDrv->hSemGetLINKSPEED), NULL); + WILC_SemaphoreDestroy(&(pstrWFIDrv->hSemGetCHNL), NULL); + WILC_SemaphoreDestroy(&(pstrWFIDrv->hSemInactiveTime), NULL); + WILC_SemaphoreDestroy(&hWaitResponse, NULL); + + WILC_SemaphoreAcquire(&(pstrWFIDrv->gtOsCfgValuesSem), NULL); + WILC_SemaphoreDestroy(&(pstrWFIDrv->gtOsCfgValuesSem), NULL); + + /*Setting the gloabl driver handler with NULL*/ + u32Intialized = 0; + /* gWFiDrvHandle = NULL; */ + if (pstrWFIDrv != WILC_NULL) { + WILC_FREE(pstrWFIDrv); + /* pstrWFIDrv=WILC_NULL; */ + + } + + clients_count--; /* Decrease number of created entities */ + terminated_handle = WILC_NULL; + WILC_SemaphoreRelease(&hSemHostIntDeinit, NULL); + return s32Error; +} + + +/** + * @brief NetworkInfoReceived + * @details function to to be called when network info packet is received + * @param[in] pu8Buffer the received packet + * @param[in] u32Length length of the received packet + * @return none + * @note + * @author + * @date 1 Mar 2012 + * @version 1.0 + */ +void NetworkInfoReceived(WILC_Uint8 *pu8Buffer, WILC_Uint32 u32Length) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrHostIFmsg strHostIFmsg; + WILC_Uint32 drvHandler; + tstrWILC_WFIDrv *pstrWFIDrv = WILC_NULL; + + drvHandler = ((pu8Buffer[u32Length - 4]) | (pu8Buffer[u32Length - 3] << 8) | (pu8Buffer[u32Length - 2] << 16) | (pu8Buffer[u32Length - 1] << 24)); + pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler; + + + + + if (pstrWFIDrv == WILC_NULL || pstrWFIDrv == terminated_handle) { + PRINT_ER("NetworkInfo received but driver not init[%x]\n", (WILC_Uint32)pstrWFIDrv); + return; + } + + /* prepare the Asynchronous Network Info message */ + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + strHostIFmsg.u16MsgId = HOST_IF_MSG_RCVD_NTWRK_INFO; + strHostIFmsg.drvHandler = pstrWFIDrv; + + strHostIFmsg.uniHostIFmsgBody.strRcvdNetworkInfo.u32Length = u32Length; + strHostIFmsg.uniHostIFmsgBody.strRcvdNetworkInfo.pu8Buffer = (WILC_Uint8 *)WILC_MALLOC(u32Length); /* will be deallocated by the receiving thread */ + WILC_memcpy(strHostIFmsg.uniHostIFmsgBody.strRcvdNetworkInfo.pu8Buffer, + pu8Buffer, u32Length); + + /* send the message */ + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + if (s32Error) { + PRINT_ER("Error in sending network info message queue message parameters: Error(%d)\n", s32Error); + } + + + return; +} + +/** + * @brief GnrlAsyncInfoReceived + * @details function to be called when general Asynchronous info packet is received + * @param[in] pu8Buffer the received packet + * @param[in] u32Length length of the received packet + * @return none + * @note + * @author + * @date 15 Mar 2012 + * @version 1.0 + */ +void GnrlAsyncInfoReceived(WILC_Uint8 *pu8Buffer, WILC_Uint32 u32Length) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrHostIFmsg strHostIFmsg; + WILC_Uint32 drvHandler; + tstrWILC_WFIDrv *pstrWFIDrv = WILC_NULL; + + /*BugID_5348*/ + WILC_SemaphoreAcquire(&hSemHostIntDeinit, NULL); + + drvHandler = ((pu8Buffer[u32Length - 4]) | (pu8Buffer[u32Length - 3] << 8) | (pu8Buffer[u32Length - 2] << 16) | (pu8Buffer[u32Length - 1] << 24)); + pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler; + PRINT_D(HOSTINF_DBG, "General asynchronous info packet received \n"); + + + if (pstrWFIDrv == NULL || pstrWFIDrv == terminated_handle) { + PRINT_D(HOSTINF_DBG, "Wifi driver handler is equal to NULL\n"); + /*BugID_5348*/ + WILC_SemaphoreRelease(&hSemHostIntDeinit, NULL); + return; + } + + if (pstrWFIDrv->strWILC_UsrConnReq.pfUserConnectResult == WILC_NULL) { + /* received mac status is not needed when there is no current Connect Request */ + PRINT_ER("Received mac status is not needed when there is no current Connect Reques\n"); + /*BugID_5348*/ + WILC_SemaphoreRelease(&hSemHostIntDeinit, NULL); + return; + } + + /* prepare the General Asynchronous Info message */ + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + + strHostIFmsg.u16MsgId = HOST_IF_MSG_RCVD_GNRL_ASYNC_INFO; + strHostIFmsg.drvHandler = pstrWFIDrv; + + + strHostIFmsg.uniHostIFmsgBody.strRcvdGnrlAsyncInfo.u32Length = u32Length; + strHostIFmsg.uniHostIFmsgBody.strRcvdGnrlAsyncInfo.pu8Buffer = (WILC_Uint8 *)WILC_MALLOC(u32Length); /* will be deallocated by the receiving thread */ + WILC_memcpy(strHostIFmsg.uniHostIFmsgBody.strRcvdGnrlAsyncInfo.pu8Buffer, + pu8Buffer, u32Length); + + /* send the message */ + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + if (s32Error) { + PRINT_ER("Error in sending message queue asynchronous message info: Error(%d)\n", s32Error); + } + + /*BugID_5348*/ + WILC_SemaphoreRelease(&hSemHostIntDeinit, NULL); + return; +} + +/** + * @brief host_int_ScanCompleteReceived + * @details Setting scan complete received notifcation in message queue + * @param[in] WILC_Uint8* pu8Buffer, WILC_Uint32 u32Length + * @return Error code. + * @author + * @date + * @version 1.0 + */ +void host_int_ScanCompleteReceived(WILC_Uint8 *pu8Buffer, WILC_Uint32 u32Length) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrHostIFmsg strHostIFmsg; + WILC_Uint32 drvHandler; + tstrWILC_WFIDrv *pstrWFIDrv = WILC_NULL; + drvHandler = ((pu8Buffer[u32Length - 4]) | (pu8Buffer[u32Length - 3] << 8) | (pu8Buffer[u32Length - 2] << 16) | (pu8Buffer[u32Length - 1] << 24)); + pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler; + + + PRINT_D(GENERIC_DBG, "Scan notification received %x\n", (WILC_Uint32)pstrWFIDrv); + + if (pstrWFIDrv == NULL || pstrWFIDrv == terminated_handle) { + return; + } + + /*if there is an ongoing scan request*/ + if (pstrWFIDrv->strWILC_UsrScanReq.pfUserScanResult) { + /* prepare theScan Done message */ + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + strHostIFmsg.u16MsgId = HOST_IF_MSG_RCVD_SCAN_COMPLETE; + strHostIFmsg.drvHandler = pstrWFIDrv; + + + /* will be deallocated by the receiving thread */ + /*no need to send message body*/ + + /*strHostIFmsg.uniHostIFmsgBody.strScanComplete.u32Length = u32Length; + * strHostIFmsg.uniHostIFmsgBody.strScanComplete.pu8Buffer = (WILC_Uint8*)WILC_MALLOC(u32Length); + * WILC_memcpy(strHostIFmsg.uniHostIFmsgBody.strScanComplete.pu8Buffer, + * pu8Buffer, u32Length); */ + + /* send the message */ + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + if (s32Error) { + PRINT_ER("Error in sending message queue scan complete parameters: Error(%d)\n", s32Error); + } + } + + + return; + +} + +#ifdef WILC_P2P +/** + * @brief host_int_remain_on_channel + * @details + * @param[in] Handle to wifi driver + * Duration to remain on channel + * Channel to remain on + * Pointer to fn to be called on receive frames in listen state + * Pointer to remain-on-channel expired fn + * Priv + * @return Error code. + * @author + * @date + * @version 1.0 + */ +WILC_Sint32 host_int_remain_on_channel(WILC_WFIDrvHandle hWFIDrv, WILC_Uint32 u32SessionID, WILC_Uint32 u32duration, WILC_Uint16 chan, tWILCpfRemainOnChanExpired RemainOnChanExpired, tWILCpfRemainOnChanReady RemainOnChanReady, void *pvUserArg) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + tstrHostIFmsg strHostIFmsg; + + if (pstrWFIDrv == WILC_NULL) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + /* prepare the remainonchan Message */ + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + /* prepare the WiphyParams Message */ + strHostIFmsg.u16MsgId = HOST_IF_MSG_REMAIN_ON_CHAN; + strHostIFmsg.uniHostIFmsgBody.strHostIfRemainOnChan.u16Channel = chan; + strHostIFmsg.uniHostIFmsgBody.strHostIfRemainOnChan.pRemainOnChanExpired = RemainOnChanExpired; + strHostIFmsg.uniHostIFmsgBody.strHostIfRemainOnChan.pRemainOnChanReady = RemainOnChanReady; + strHostIFmsg.uniHostIFmsgBody.strHostIfRemainOnChan.pVoid = pvUserArg; + strHostIFmsg.uniHostIFmsgBody.strHostIfRemainOnChan.u32duration = u32duration; + strHostIFmsg.uniHostIFmsgBody.strHostIfRemainOnChan.u32ListenSessionID = u32SessionID; + strHostIFmsg.drvHandler = hWFIDrv; + + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + if (s32Error) { + WILC_ERRORREPORT(s32Error, s32Error); + } + WILC_CATCH(s32Error) + { + + } + + return s32Error; +} + +/** + * @brief host_int_ListenStateExpired + * @details + * @param[in] Handle to wifi driver + * Duration to remain on channel + * Channel to remain on + * Pointer to fn to be called on receive frames in listen state + * Pointer to remain-on-channel expired fn + * Priv + * @return Error code. + * @author + * @date + * @version 1.0 + */ +WILC_Sint32 host_int_ListenStateExpired(WILC_WFIDrvHandle hWFIDrv, WILC_Uint32 u32SessionID) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + tstrHostIFmsg strHostIFmsg; + + if (pstrWFIDrv == WILC_NULL) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + /*Stopping remain-on-channel timer*/ + WILC_TimerStop(&(pstrWFIDrv->hRemainOnChannel), WILC_NULL); + + /* prepare the timer fire Message */ + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + strHostIFmsg.u16MsgId = HOST_IF_MSG_LISTEN_TIMER_FIRED; + strHostIFmsg.drvHandler = hWFIDrv; + strHostIFmsg.uniHostIFmsgBody.strHostIfRemainOnChan.u32ListenSessionID = u32SessionID; + + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + if (s32Error) { + WILC_ERRORREPORT(s32Error, s32Error); + } + WILC_CATCH(s32Error) + { + + } + return s32Error; +} + +/** + * @brief host_int_frame_register + * @details + * @param[in] Handle to wifi driver + * @return Error code. + * @author + * @date + * @version 1.0*/ +WILC_Sint32 host_int_frame_register(WILC_WFIDrvHandle hWFIDrv, WILC_Uint16 u16FrameType, WILC_Bool bReg) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + tstrHostIFmsg strHostIFmsg; + + if (pstrWFIDrv == WILC_NULL) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + /* prepare the WiphyParams Message */ + strHostIFmsg.u16MsgId = HOST_IF_MSG_REGISTER_FRAME; + switch (u16FrameType) { + case ACTION: + PRINT_D(HOSTINF_DBG, "ACTION\n"); + strHostIFmsg.uniHostIFmsgBody.strHostIfRegisterFrame.u8Regid = ACTION_FRM_IDX; + break; + + case PROBE_REQ: + PRINT_D(HOSTINF_DBG, "PROBE REQ\n"); + strHostIFmsg.uniHostIFmsgBody.strHostIfRegisterFrame.u8Regid = PROBE_REQ_IDX; + break; + + default: + PRINT_D(HOSTINF_DBG, "Not valid frame type\n"); + break; + } + strHostIFmsg.uniHostIFmsgBody.strHostIfRegisterFrame.u16FrameType = u16FrameType; + strHostIFmsg.uniHostIFmsgBody.strHostIfRegisterFrame.bReg = bReg; + strHostIFmsg.drvHandler = hWFIDrv; + + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + if (s32Error) { + WILC_ERRORREPORT(s32Error, s32Error); + } + WILC_CATCH(s32Error) + { + + } + + return s32Error; + + +} +#endif + +#ifdef WILC_AP_EXTERNAL_MLME +/** + * @brief host_int_add_beacon + * @details Setting add beacon params in message queue + * @param[in] WILC_WFIDrvHandle hWFIDrv, WILC_Uint32 u32Interval, + * WILC_Uint32 u32DTIMPeriod,WILC_Uint32 u32HeadLen, WILC_Uint8* pu8Head, + * WILC_Uint32 u32TailLen, WILC_Uint8* pu8Tail + * @return Error code. + * @author + * @date + * @version 1.0 + */ +WILC_Sint32 host_int_add_beacon(WILC_WFIDrvHandle hWFIDrv, WILC_Uint32 u32Interval, + WILC_Uint32 u32DTIMPeriod, + WILC_Uint32 u32HeadLen, WILC_Uint8 *pu8Head, + WILC_Uint32 u32TailLen, WILC_Uint8 *pu8Tail) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + tstrHostIFmsg strHostIFmsg; + tstrHostIFSetBeacon *pstrSetBeaconParam = &strHostIFmsg.uniHostIFmsgBody.strHostIFSetBeacon; + + if (pstrWFIDrv == WILC_NULL) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + PRINT_D(HOSTINF_DBG, "Setting adding beacon message queue params\n"); + + + /* prepare the WiphyParams Message */ + strHostIFmsg.u16MsgId = HOST_IF_MSG_ADD_BEACON; + strHostIFmsg.drvHandler = hWFIDrv; + pstrSetBeaconParam->u32Interval = u32Interval; + pstrSetBeaconParam->u32DTIMPeriod = u32DTIMPeriod; + pstrSetBeaconParam->u32HeadLen = u32HeadLen; + pstrSetBeaconParam->pu8Head = (WILC_Uint8 *)WILC_MALLOC(u32HeadLen); + if (pstrSetBeaconParam->pu8Head == NULL) { + WILC_ERRORREPORT(s32Error, WILC_NO_MEM); + } + WILC_memcpy(pstrSetBeaconParam->pu8Head, pu8Head, u32HeadLen); + pstrSetBeaconParam->u32TailLen = u32TailLen; + + /* Bug 4599 : if tail length = 0 skip allocating & copying */ + if (u32TailLen > 0) { + pstrSetBeaconParam->pu8Tail = (WILC_Uint8 *)WILC_MALLOC(u32TailLen); + if (pstrSetBeaconParam->pu8Tail == NULL) { + WILC_ERRORREPORT(s32Error, WILC_NO_MEM); + } + WILC_memcpy(pstrSetBeaconParam->pu8Tail, pu8Tail, u32TailLen); + } else { + pstrSetBeaconParam->pu8Tail = NULL; + } + + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + if (s32Error) { + WILC_ERRORREPORT(s32Error, s32Error); + } + + WILC_CATCH(s32Error) + { + if (pstrSetBeaconParam->pu8Head != NULL) { + WILC_FREE(pstrSetBeaconParam->pu8Head); + } + + if (pstrSetBeaconParam->pu8Tail != NULL) { + WILC_FREE(pstrSetBeaconParam->pu8Tail); + } + } + + return s32Error; + +} + + +/** + * @brief host_int_del_beacon + * @details Setting add beacon params in message queue + * @param[in] WILC_WFIDrvHandle hWFIDrv + * @return Error code. + * @author + * @date + * @version 1.0 + */ +WILC_Sint32 host_int_del_beacon(WILC_WFIDrvHandle hWFIDrv) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + tstrHostIFmsg strHostIFmsg; + + if (pstrWFIDrv == WILC_NULL) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + /* prepare the WiphyParams Message */ + strHostIFmsg.u16MsgId = HOST_IF_MSG_DEL_BEACON; + strHostIFmsg.drvHandler = hWFIDrv; + PRINT_D(HOSTINF_DBG, "Setting deleting beacon message queue params\n"); + + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + WILC_ERRORCHECK(s32Error); + + WILC_CATCH(s32Error) + { + } + return s32Error; +} + + +/** + * @brief host_int_add_station + * @details Setting add station params in message queue + * @param[in] WILC_WFIDrvHandle hWFIDrv, tstrWILC_AddStaParam* pstrStaParams + * @return Error code. + * @author + * @date + * @version 1.0 + */ +WILC_Sint32 host_int_add_station(WILC_WFIDrvHandle hWFIDrv, tstrWILC_AddStaParam *pstrStaParams) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + tstrHostIFmsg strHostIFmsg; + tstrWILC_AddStaParam *pstrAddStationMsg = &strHostIFmsg.uniHostIFmsgBody.strAddStaParam; + + + if (pstrWFIDrv == WILC_NULL) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + PRINT_D(HOSTINF_DBG, "Setting adding station message queue params\n"); + + + /* prepare the WiphyParams Message */ + strHostIFmsg.u16MsgId = HOST_IF_MSG_ADD_STATION; + strHostIFmsg.drvHandler = hWFIDrv; + + WILC_memcpy(pstrAddStationMsg, pstrStaParams, sizeof(tstrWILC_AddStaParam)); + if (pstrAddStationMsg->u8NumRates > 0) { + pstrAddStationMsg->pu8Rates = WILC_MALLOC(pstrAddStationMsg->u8NumRates); + WILC_NULLCHECK(s32Error, pstrAddStationMsg->pu8Rates); + + WILC_memcpy(pstrAddStationMsg->pu8Rates, pstrStaParams->pu8Rates, pstrAddStationMsg->u8NumRates); + } + + + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + if (s32Error) { + WILC_ERRORREPORT(s32Error, s32Error); + } + + WILC_CATCH(s32Error) + { + } + return s32Error; +} + +/** + * @brief host_int_del_station + * @details Setting delete station params in message queue + * @param[in] WILC_WFIDrvHandle hWFIDrv, WILC_Uint8* pu8MacAddr + * @return Error code. + * @author + * @date + * @version 1.0 + */ +WILC_Sint32 host_int_del_station(WILC_WFIDrvHandle hWFIDrv, WILC_Uint8 *pu8MacAddr) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + tstrHostIFmsg strHostIFmsg; + tstrHostIFDelSta *pstrDelStationMsg = &strHostIFmsg.uniHostIFmsgBody.strDelStaParam; + + if (pstrWFIDrv == WILC_NULL) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + PRINT_D(HOSTINF_DBG, "Setting deleting station message queue params\n"); + + + + /* prepare the WiphyParams Message */ + strHostIFmsg.u16MsgId = HOST_IF_MSG_DEL_STATION; + strHostIFmsg.drvHandler = hWFIDrv; + + /*BugID_4795: Handling situation of deleting all stations*/ + if (pu8MacAddr == WILC_NULL) + WILC_memset(pstrDelStationMsg->au8MacAddr, 255, ETH_ALEN); + else + WILC_memcpy(pstrDelStationMsg->au8MacAddr, pu8MacAddr, ETH_ALEN); + + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + if (s32Error) { + WILC_ERRORREPORT(s32Error, s32Error); + } + + WILC_CATCH(s32Error) + { + } + return s32Error; +} +/** + * @brief host_int_del_allstation + * @details Setting del station params in message queue + * @param[in] WILC_WFIDrvHandle hWFIDrv, WILC_Uint8 pu8MacAddr[][ETH_ALEN]s + * @return Error code. + * @author + * @date + * @version 1.0 + */ +WILC_Sint32 host_int_del_allstation(WILC_WFIDrvHandle hWFIDrv, WILC_Uint8 pu8MacAddr[][ETH_ALEN]) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + tstrHostIFmsg strHostIFmsg; + tstrHostIFDelAllSta *pstrDelAllStationMsg = &strHostIFmsg.uniHostIFmsgBody.strHostIFDelAllSta; + WILC_Uint8 au8Zero_Buff[ETH_ALEN] = {0}; + WILC_Uint32 i; + WILC_Uint8 u8AssocNumb = 0; + + + if (pstrWFIDrv == WILC_NULL) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + PRINT_D(HOSTINF_DBG, "Setting deauthenticating station message queue params\n"); + + /* prepare the WiphyParams Message */ + strHostIFmsg.u16MsgId = HOST_IF_MSG_DEL_ALL_STA; + strHostIFmsg.drvHandler = hWFIDrv; + + /* Handling situation of deauthenticing all associated stations*/ + for (i = 0; i < MAX_NUM_STA; i++) { + if (memcmp(pu8MacAddr[i], au8Zero_Buff, ETH_ALEN)) { + WILC_memcpy(pstrDelAllStationMsg->au8Sta_DelAllSta[i], pu8MacAddr[i], ETH_ALEN); + PRINT_D(CFG80211_DBG, "BSSID = %x%x%x%x%x%x\n", pstrDelAllStationMsg->au8Sta_DelAllSta[i][0], pstrDelAllStationMsg->au8Sta_DelAllSta[i][1], pstrDelAllStationMsg->au8Sta_DelAllSta[i][2], pstrDelAllStationMsg->au8Sta_DelAllSta[i][3], pstrDelAllStationMsg->au8Sta_DelAllSta[i][4], + pstrDelAllStationMsg->au8Sta_DelAllSta[i][5]); + u8AssocNumb++; + } + } + if (!u8AssocNumb) { + PRINT_D(CFG80211_DBG, "NO ASSOCIATED STAS\n"); + return s32Error; + } + + pstrDelAllStationMsg->u8Num_AssocSta = u8AssocNumb; + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + + + if (s32Error) { + WILC_ERRORREPORT(s32Error, s32Error); + + } + WILC_CATCH(s32Error) + { + + } + WILC_SemaphoreAcquire(&hWaitResponse, NULL); + + return s32Error; + +} + +/** + * @brief host_int_edit_station + * @details Setting edit station params in message queue + * @param[in] WILC_WFIDrvHandle hWFIDrv, tstrWILC_AddStaParam* pstrStaParams + * @return Error code. + * @author + * @date + * @version 1.0 + */ +WILC_Sint32 host_int_edit_station(WILC_WFIDrvHandle hWFIDrv, tstrWILC_AddStaParam *pstrStaParams) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + tstrHostIFmsg strHostIFmsg; + tstrWILC_AddStaParam *pstrAddStationMsg = &strHostIFmsg.uniHostIFmsgBody.strAddStaParam; + + if (pstrWFIDrv == WILC_NULL) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + PRINT_D(HOSTINF_DBG, "Setting editing station message queue params\n"); + + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + + /* prepare the WiphyParams Message */ + strHostIFmsg.u16MsgId = HOST_IF_MSG_EDIT_STATION; + strHostIFmsg.drvHandler = hWFIDrv; + + WILC_memcpy(pstrAddStationMsg, pstrStaParams, sizeof(tstrWILC_AddStaParam)); + if (pstrAddStationMsg->u8NumRates > 0) { + pstrAddStationMsg->pu8Rates = WILC_MALLOC(pstrAddStationMsg->u8NumRates); + WILC_memcpy(pstrAddStationMsg->pu8Rates, pstrStaParams->pu8Rates, pstrAddStationMsg->u8NumRates); + WILC_NULLCHECK(s32Error, pstrAddStationMsg->pu8Rates); + } + + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + if (s32Error) { + WILC_ERRORREPORT(s32Error, s32Error); + } + WILC_CATCH(s32Error) + { + } + return s32Error; +} +#endif /*WILC_AP_EXTERNAL_MLME*/ +uint32_t wilc_get_chipid(uint8_t); + +WILC_Sint32 host_int_set_power_mgmt(WILC_WFIDrvHandle hWFIDrv, WILC_Bool bIsEnabled, WILC_Uint32 u32Timeout) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + tstrHostIFmsg strHostIFmsg; + tstrHostIfPowerMgmtParam *pstrPowerMgmtParam = &strHostIFmsg.uniHostIFmsgBody.strPowerMgmtparam; + + PRINT_INFO(HOSTINF_DBG, "\n\n>> Setting PS to %d << \n\n", bIsEnabled); + + if (pstrWFIDrv == WILC_NULL) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + PRINT_D(HOSTINF_DBG, "Setting Power management message queue params\n"); + + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + + /* prepare the WiphyParams Message */ + strHostIFmsg.u16MsgId = HOST_IF_MSG_POWER_MGMT; + strHostIFmsg.drvHandler = hWFIDrv; + + pstrPowerMgmtParam->bIsEnabled = bIsEnabled; + pstrPowerMgmtParam->u32Timeout = u32Timeout; + + + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + if (s32Error) { + WILC_ERRORREPORT(s32Error, s32Error); + } + WILC_CATCH(s32Error) + { + } + return s32Error; +} + +WILC_Sint32 host_int_setup_multicast_filter(WILC_WFIDrvHandle hWFIDrv, WILC_Bool bIsEnabled, WILC_Uint32 u32count) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + tstrHostIFmsg strHostIFmsg; + tstrHostIFSetMulti *pstrMulticastFilterParam = &strHostIFmsg.uniHostIFmsgBody.strHostIfSetMulti; + + + if (pstrWFIDrv == WILC_NULL) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + PRINT_D(HOSTINF_DBG, "Setting Multicast Filter params\n"); + + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + + /* prepare the WiphyParams Message */ + strHostIFmsg.u16MsgId = HOST_IF_MSG_SET_MULTICAST_FILTER; + strHostIFmsg.drvHandler = hWFIDrv; + + pstrMulticastFilterParam->bIsEnabled = bIsEnabled; + pstrMulticastFilterParam->u32count = u32count; + + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + if (s32Error) { + WILC_ERRORREPORT(s32Error, s32Error); + } + WILC_CATCH(s32Error) + { + } + return s32Error; +} + + + +/*Bug4218: Parsing Join Param*/ +#ifdef WILC_PARSE_SCAN_IN_HOST + +/*Bug4218: Parsing Join Param*/ +/** + * @brief host_int_ParseJoinBssParam + * @details Parse Needed Join Parameters and save it in a new JoinBssParam entry + * @param[in] tstrNetworkInfo* ptstrNetworkInfo + * @return + * @author zsalah + * @date + * @version 1.0**/ +static void *host_int_ParseJoinBssParam(tstrNetworkInfo *ptstrNetworkInfo) +{ + tstrJoinBssParam *pNewJoinBssParam = NULL; + WILC_Uint8 *pu8IEs; + WILC_Uint16 u16IEsLen; + WILC_Uint16 index = 0; + WILC_Uint8 suppRatesNo = 0; + WILC_Uint8 extSuppRatesNo; + WILC_Uint16 jumpOffset; + WILC_Uint8 pcipherCount; + WILC_Uint8 authCount; + WILC_Uint8 pcipherTotalCount = 0; + WILC_Uint8 authTotalCount = 0; + WILC_Uint8 i, j; + + pu8IEs = ptstrNetworkInfo->pu8IEs; + u16IEsLen = ptstrNetworkInfo->u16IEsLen; + + pNewJoinBssParam = WILC_MALLOC(sizeof(tstrJoinBssParam)); + if (pNewJoinBssParam != NULL) { + WILC_memset(pNewJoinBssParam, 0, sizeof(tstrJoinBssParam)); + pNewJoinBssParam->dtim_period = ptstrNetworkInfo->u8DtimPeriod; + pNewJoinBssParam->beacon_period = ptstrNetworkInfo->u16BeaconPeriod; + pNewJoinBssParam->cap_info = ptstrNetworkInfo->u16CapInfo; + WILC_memcpy(pNewJoinBssParam->au8bssid, ptstrNetworkInfo->au8bssid, 6); + /*for(i=0; i<6;i++) + * PRINT_D(HOSTINF_DBG,"%c",pNewJoinBssParam->au8bssid[i]);*/ + WILC_memcpy((WILC_Uint8 *)pNewJoinBssParam->ssid, ptstrNetworkInfo->au8ssid, ptstrNetworkInfo->u8SsidLen + 1); + pNewJoinBssParam->ssidLen = ptstrNetworkInfo->u8SsidLen; + WILC_memset(pNewJoinBssParam->rsn_pcip_policy, 0xFF, 3); + WILC_memset(pNewJoinBssParam->rsn_auth_policy, 0xFF, 3); + /*for(i=0; issidLen;i++) + * PRINT_D(HOSTINF_DBG,"%c",pNewJoinBssParam->ssid[i]);*/ + + /* parse supported rates: */ + while (index < u16IEsLen) { + /* supportedRates IE */ + if (pu8IEs[index] == SUPP_RATES_IE) { + /* PRINT_D(HOSTINF_DBG, "Supported Rates\n"); */ + suppRatesNo = pu8IEs[index + 1]; + pNewJoinBssParam->supp_rates[0] = suppRatesNo; + index += 2; /* skipping ID and length bytes; */ + + for (i = 0; i < suppRatesNo; i++) { + pNewJoinBssParam->supp_rates[i + 1] = pu8IEs[index + i]; + /* PRINT_D(HOSTINF_DBG,"%0x ",pNewJoinBssParam->supp_rates[i+1]); */ + } + index += suppRatesNo; + continue; + } + /* Ext SupportedRates IE */ + else if (pu8IEs[index] == EXT_SUPP_RATES_IE) { + /* PRINT_D(HOSTINF_DBG, "Extended Supported Rates\n"); */ + /* checking if no of ext. supp and supp rates < max limit */ + extSuppRatesNo = pu8IEs[index + 1]; + if (extSuppRatesNo > (MAX_RATES_SUPPORTED - suppRatesNo)) + pNewJoinBssParam->supp_rates[0] = MAX_RATES_SUPPORTED; + else + pNewJoinBssParam->supp_rates[0] += extSuppRatesNo; + index += 2; + /* pNewJoinBssParam.supp_rates[0] contains now old number not the ext. no */ + for (i = 0; i < (pNewJoinBssParam->supp_rates[0] - suppRatesNo); i++) { + pNewJoinBssParam->supp_rates[suppRatesNo + i + 1] = pu8IEs[index + i]; + /* PRINT_D(HOSTINF_DBG,"%0x ",pNewJoinBssParam->supp_rates[suppRatesNo+i+1]); */ + } + index += extSuppRatesNo; + continue; + } + /* HT Cap. IE */ + else if (pu8IEs[index] == HT_CAPABILITY_IE) { + /* if IE found set the flag */ + pNewJoinBssParam->ht_capable = BTRUE; + index += pu8IEs[index + 1] + 2; /* ID,Length bytes and IE body */ + /* PRINT_D(HOSTINF_DBG,"HT_CAPABALE\n"); */ + continue; + } else if ((pu8IEs[index] == WMM_IE) && /* WMM Element ID */ + (pu8IEs[index + 2] == 0x00) && (pu8IEs[index + 3] == 0x50) && + (pu8IEs[index + 4] == 0xF2) && /* OUI */ + (pu8IEs[index + 5] == 0x02) && /* OUI Type */ + ((pu8IEs[index + 6] == 0x00) || (pu8IEs[index + 6] == 0x01)) && /* OUI Sub Type */ + (pu8IEs[index + 7] == 0x01)) { + /* Presence of WMM Info/Param element indicates WMM capability */ + pNewJoinBssParam->wmm_cap = BTRUE; + + /* Check if Bit 7 is set indicating U-APSD capability */ + if (pu8IEs[index + 8] & (1 << 7)) { + pNewJoinBssParam->uapsd_cap = BTRUE; + } + index += pu8IEs[index + 1] + 2; + continue; + } + #ifdef WILC_P2P + else if ((pu8IEs[index] == P2P_IE) && /* P2P Element ID */ + (pu8IEs[index + 2] == 0x50) && (pu8IEs[index + 3] == 0x6f) && + (pu8IEs[index + 4] == 0x9a) && /* OUI */ + (pu8IEs[index + 5] == 0x09) && (pu8IEs[index + 6] == 0x0c)) { /* OUI Type */ + WILC_Uint16 u16P2P_count; + pNewJoinBssParam->tsf = ptstrNetworkInfo->u32Tsf; + pNewJoinBssParam->u8NoaEnbaled = 1; + pNewJoinBssParam->u8Index = pu8IEs[index + 9]; + + /* Check if Bit 7 is set indicating Opss capability */ + if (pu8IEs[index + 10] & (1 << 7)) { + pNewJoinBssParam->u8OppEnable = 1; + pNewJoinBssParam->u8CtWindow = pu8IEs[index + 10]; + } else + pNewJoinBssParam->u8OppEnable = 0; + /* HOSTINF_DBG */ + PRINT_D(GENERIC_DBG, "P2P Dump \n"); + for (i = 0; i < pu8IEs[index + 7]; i++) + PRINT_D(GENERIC_DBG, " %x \n", pu8IEs[index + 9 + i]); + + pNewJoinBssParam->u8Count = pu8IEs[index + 11]; + u16P2P_count = index + 12; + + WILC_memcpy(pNewJoinBssParam->au8Duration, pu8IEs + u16P2P_count, 4); + u16P2P_count += 4; + + WILC_memcpy(pNewJoinBssParam->au8Interval, pu8IEs + u16P2P_count, 4); + u16P2P_count += 4; + + WILC_memcpy(pNewJoinBssParam->au8StartTime, pu8IEs + u16P2P_count, 4); + + index += pu8IEs[index + 1] + 2; + continue; + + } + #endif + else if ((pu8IEs[index] == RSN_IE) || + ((pu8IEs[index] == WPA_IE) && (pu8IEs[index + 2] == 0x00) && + (pu8IEs[index + 3] == 0x50) && (pu8IEs[index + 4] == 0xF2) && + (pu8IEs[index + 5] == 0x01))) { + WILC_Uint16 rsnIndex = index; + /*PRINT_D(HOSTINF_DBG,"RSN IE Length:%d\n",pu8IEs[rsnIndex+1]); + * for(i=0; imode_802_11i = 2; + /* PRINT_D(HOSTINF_DBG,"\nRSN_IE\n"); */ + } else { /* check if rsn was previously parsed */ + if (pNewJoinBssParam->mode_802_11i == 0) + pNewJoinBssParam->mode_802_11i = 1; + /* PRINT_D(HOSTINF_DBG,"\nWPA_IE\n"); */ + rsnIndex += 4; + } + rsnIndex += 7; /* skipping id, length, version(2B) and first 3 bytes of gcipher */ + pNewJoinBssParam->rsn_grp_policy = pu8IEs[rsnIndex]; + rsnIndex++; + /* PRINT_D(HOSTINF_DBG,"Group Policy: %0x \n",pNewJoinBssParam->rsn_grp_policy); */ + /* initialize policies with invalid values */ + + jumpOffset = pu8IEs[rsnIndex] * 4; /* total no.of bytes of pcipher field (count*4) */ + + /*parsing pairwise cipher*/ + + /* saving 3 pcipher max. */ + pcipherCount = (pu8IEs[rsnIndex] > 3) ? 3 : pu8IEs[rsnIndex]; + rsnIndex += 2; /* jump 2 bytes of pcipher count */ + + /* PRINT_D(HOSTINF_DBG,"\npcipher:%d \n",pcipherCount); */ + for (i = pcipherTotalCount, j = 0; i < pcipherCount + pcipherTotalCount && i < 3; i++, j++) { + /* each count corresponds to 4 bytes, only last byte is saved */ + pNewJoinBssParam->rsn_pcip_policy[i] = pu8IEs[rsnIndex + ((j + 1) * 4) - 1]; + /* PRINT_D(HOSTINF_DBG,"PAIR policy = [%0x,%0x]\n",pNewJoinBssParam->rsn_pcip_policy[i],i); */ + } + pcipherTotalCount += pcipherCount; + rsnIndex += jumpOffset; + + jumpOffset = pu8IEs[rsnIndex] * 4; + + /*parsing AKM suite (auth_policy)*/ + /* saving 3 auth policies max. */ + authCount = (pu8IEs[rsnIndex] > 3) ? 3 : pu8IEs[rsnIndex]; + rsnIndex += 2; /* jump 2 bytes of pcipher count */ + + for (i = authTotalCount, j = 0; i < authTotalCount + authCount; i++, j++) { + /* each count corresponds to 4 bytes, only last byte is saved */ + pNewJoinBssParam->rsn_auth_policy[i] = pu8IEs[rsnIndex + ((j + 1) * 4) - 1]; + } + authTotalCount += authCount; + rsnIndex += jumpOffset; + /*pasring rsn cap. only if rsn IE*/ + if (pu8IEs[index] == RSN_IE) { + pNewJoinBssParam->rsn_cap[0] = pu8IEs[rsnIndex]; + pNewJoinBssParam->rsn_cap[1] = pu8IEs[rsnIndex + 1]; + rsnIndex += 2; + } + pNewJoinBssParam->rsn_found = 1; + index += pu8IEs[index + 1] + 2; /* ID,Length bytes and IE body */ + continue; + } else + index += pu8IEs[index + 1] + 2; /* ID,Length bytes and IE body */ + + } + + + } + + return (void *)pNewJoinBssParam; + +} + +void host_int_freeJoinParams(void *pJoinParams) +{ + if ((tstrJoinBssParam *)pJoinParams != NULL) + WILC_FREE((tstrJoinBssParam *)pJoinParams); + else + PRINT_ER("Unable to FREE null pointer\n"); +} +#endif /*WILC_PARSE_SCAN_IN_HOST*/ + + +/** + * @brief host_int_addBASession + * @details Open a block Ack session with the given parameters + * @param[in] tstrNetworkInfo* ptstrNetworkInfo + * @return + * @author anoureldin + * @date + * @version 1.0**/ + +static int host_int_addBASession(WILC_WFIDrvHandle hWFIDrv, char *pBSSID, char TID, short int BufferSize, + short int SessionTimeout, void *drvHandler) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + tstrHostIFmsg strHostIFmsg; + tstrHostIfBASessionInfo *pBASessionInfo = &strHostIFmsg.uniHostIFmsgBody.strHostIfBASessionInfo; + + if (pstrWFIDrv == WILC_NULL) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + /* prepare the WiphyParams Message */ + strHostIFmsg.u16MsgId = HOST_IF_MSG_ADD_BA_SESSION; + + memcpy(pBASessionInfo->au8Bssid, pBSSID, ETH_ALEN); + pBASessionInfo->u8Ted = TID; + pBASessionInfo->u16BufferSize = BufferSize; + pBASessionInfo->u16SessionTimeout = SessionTimeout; + strHostIFmsg.drvHandler = hWFIDrv; + + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + if (s32Error) { + WILC_ERRORREPORT(s32Error, s32Error); + } + WILC_CATCH(s32Error) + { + + } + + return s32Error; +} + + +WILC_Sint32 host_int_delBASession(WILC_WFIDrvHandle hWFIDrv, char *pBSSID, char TID) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + tstrHostIFmsg strHostIFmsg; + tstrHostIfBASessionInfo *pBASessionInfo = &strHostIFmsg.uniHostIFmsgBody.strHostIfBASessionInfo; + + if (pstrWFIDrv == WILC_NULL) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + /* prepare the WiphyParams Message */ + strHostIFmsg.u16MsgId = HOST_IF_MSG_DEL_BA_SESSION; + + memcpy(pBASessionInfo->au8Bssid, pBSSID, ETH_ALEN); + pBASessionInfo->u8Ted = TID; + strHostIFmsg.drvHandler = hWFIDrv; + + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + if (s32Error) { + WILC_ERRORREPORT(s32Error, s32Error); + } + WILC_CATCH(s32Error) + { + + } + + /*BugID_5222*/ + WILC_SemaphoreAcquire(&hWaitResponse, NULL); + + return s32Error; +} + +WILC_Sint32 host_int_del_All_Rx_BASession(WILC_WFIDrvHandle hWFIDrv, char *pBSSID, char TID) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + tstrHostIFmsg strHostIFmsg; + tstrHostIfBASessionInfo *pBASessionInfo = &strHostIFmsg.uniHostIFmsgBody.strHostIfBASessionInfo; + + if (pstrWFIDrv == WILC_NULL) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + /* prepare the WiphyParams Message */ + strHostIFmsg.u16MsgId = HOST_IF_MSG_DEL_ALL_RX_BA_SESSIONS; + + memcpy(pBASessionInfo->au8Bssid, pBSSID, ETH_ALEN); + pBASessionInfo->u8Ted = TID; + strHostIFmsg.drvHandler = hWFIDrv; + + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + if (s32Error) { + WILC_ERRORREPORT(s32Error, s32Error); + } + WILC_CATCH(s32Error) + { + + } + + /*BugID_5222*/ + WILC_SemaphoreAcquire(&hWaitResponse, NULL); + + return s32Error; +} + +/** + * @brief host_int_setup_ipaddress + * @details setup IP in firmware + * @param[in] Handle to wifi driver + * @return Error code. + * @author Abdelrahman Sobhy + * @date + * @version 1.0*/ +WILC_Sint32 host_int_setup_ipaddress(WILC_WFIDrvHandle hWFIDrv, WILC_Uint8 *u16ipadd, WILC_Uint8 idx) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + tstrHostIFmsg strHostIFmsg; + + /* TODO: Enable This feature on softap firmware */ + return 0; + + if (pstrWFIDrv == WILC_NULL) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + /* prepare the WiphyParams Message */ + strHostIFmsg.u16MsgId = HOST_IF_MSG_SET_IPADDRESS; + + strHostIFmsg.uniHostIFmsgBody.strHostIfSetIP.au8IPAddr = u16ipadd; + strHostIFmsg.drvHandler = hWFIDrv; + strHostIFmsg.uniHostIFmsgBody.strHostIfSetIP.idx = idx; + + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + if (s32Error) { + WILC_ERRORREPORT(s32Error, s32Error); + } + WILC_CATCH(s32Error) + { + + } + + return s32Error; + + +} + +/** + * @brief host_int_get_ipaddress + * @details Get IP from firmware + * @param[in] Handle to wifi driver + * @return Error code. + * @author Abdelrahman Sobhy + * @date + * @version 1.0*/ +WILC_Sint32 host_int_get_ipaddress(WILC_WFIDrvHandle hWFIDrv, WILC_Uint8 *u16ipadd, WILC_Uint8 idx) +{ + WILC_Sint32 s32Error = WILC_SUCCESS; + tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; + tstrHostIFmsg strHostIFmsg; + + if (pstrWFIDrv == WILC_NULL) { + WILC_ERRORREPORT(s32Error, WILC_INVALID_ARGUMENT); + } + + WILC_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + /* prepare the WiphyParams Message */ + strHostIFmsg.u16MsgId = HOST_IF_MSG_GET_IPADDRESS; + + strHostIFmsg.uniHostIFmsgBody.strHostIfSetIP.au8IPAddr = u16ipadd; + strHostIFmsg.drvHandler=hWFIDrv; + strHostIFmsg.uniHostIFmsgBody.strHostIfSetIP.idx= idx; + + s32Error = WILC_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), WILC_NULL); + if (s32Error) { + WILC_ERRORREPORT(s32Error, s32Error); + } + WILC_CATCH(s32Error) + { + + } + + return s32Error; + + +} + diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h new file mode 100644 index 000000000000..f2a348506a8b --- /dev/null +++ b/drivers/staging/wilc1000/host_interface.h @@ -0,0 +1,1344 @@ +/*! + * @file host_interface.h + * @brief File containg host interface APIs + * @author zsalah + * @sa host_interface.c + * @date 8 March 2012 + * @version 1.0 + */ + +#ifndef HOST_INT_H +#define HOST_INT_H + +#include "coreconfigurator.h" +#include "coreconfigsimulator.h" +/*****************************************************************************/ +/* Macros */ +/*****************************************************************************/ +#if 0 +#define WID_BSS_TYPE 0x0000 +#define WID_CURRENT_TX_RATE 0x0001 +#define WID_CURRENT_CHANNEL 0x0002 +#define WID_PREAMBLE 0x0003 +#define WID_STATUS 0x0005 +#define WID_SCAN_TYPE 0x0007 +#define WID_KEY_ID 0x0009 +#define WID_DTIM_PERIOD 0x0010 +#define WID_POWER_MANAGEMENT 0x000B +#define WID_AUTH_TYPE 0x000D +#define WID_SITE_SURVEY 0x000E +#define WID_DTIM_PERIOD 0x0010 +#define WID_DISCONNECT 0x0016 +#define WID_SHORT_SLOT_ALLOWED 0x001A +#define WID_START_SCAN_REQ 0x001E +#define WID_RSSI 0x001F +#define WID_JOIN_REQ 0x0020 +#define WID_11N_TXOP_PROT_DISABLE 0x00B0 +#define WID_RTS_THRESHOLD 0x1000 +#define WID_FRAG_THRESHOLD 0x1001 +#define WID_SHORT_RETRY_LIMIT 0x1002 +#define WID_LONG_RETRY_LIMIT 0x1003 +#define WID_BEACON_INTERVAL 0x1006 +#define WID_ACTIVE_SCAN_TIME 0x100C +#define WID_PASSIVE_SCAN_TIME 0x100D +#define WID_SITE_SURVEY_SCAN_TIME 0x100E +#define WID_AUTH_TIMEOUT 0x1010 +#define WID_11I_PSK 0x3008 +#define WID_SITE_SURVEY_RESULTS 0x3012 +#define WID_ADD_PTK 0x301B +#define WID_ADD_RX_GTK 0x301C +#define WID_ADD_TX_GTK 0x301D +#define WID_ADD_WEP_KEY 0x3019 +#define WID_REMOVE_WEP_KEY 0x301A +#define WID_REMOVE_KEY 0x301E +#define WID_ASSOC_REQ_INFO 0x301F +#define WID_ASSOC_RES_INFO 0x3020 +#define WID_PMKID_INFO 0x3082 +#define WID_SCAN_CHANNEL_LIST 0x4084 +#define WID_11I_MODE 0x000C +#endif +#define FAIL 0x0000 +#define SUCCESS 0x0001 + +#define IP_ALEN 4 + +#define BIT2 ((WILC_Uint32)(1 << 2)) +#define BIT1 ((WILC_Uint32)(1 << 1)) +#define BIT0 ((WILC_Uint32)(1 << 0)) + +#define AP_MODE 0x01 +#define STATION_MODE 0x02 +#define GO_MODE 0x03 +#define CLIENT_MODE 0x04 + + +#define MAX_NUM_STA 9 +#define ACTIVE_SCAN_TIME 10 +#define PASSIVE_SCAN_TIME 1200 +#define MIN_SCAN_TIME 10 +#define MAX_SCAN_TIME 1200 +#define DEFAULT_SCAN 0 +#define USER_SCAN BIT0 +#define OBSS_PERIODIC_SCAN BIT1 +#define OBSS_ONETIME_SCAN BIT2 +#define GTK_RX_KEY_BUFF_LEN 24 +#define ADDKEY 0x1 +#define REMOVEKEY 0x2 +#define DEFAULTKEY 0x4 +#define ADDKEY_AP 0x8 +#define MAX_NUM_SCANNED_NETWORKS 100 /* 30 // rachel */ +#define MAX_NUM_SCANNED_NETWORKS_SHADOW 130 +#define MAX_NUM_PROBED_SSID 10 /*One more than the number of scanned ssids*/ +#define CHANNEL_SCAN_TIME 250 /* 250 */ + +#define TX_MIC_KEY_LEN 8 +#define RX_MIC_KEY_LEN 8 +#define PTK_KEY_LEN 16 + +#define TX_MIC_KEY_MSG_LEN 26 +#define RX_MIC_KEY_MSG_LEN 48 +#define PTK_KEY_MSG_LEN 39 + +#define PMKSA_KEY_LEN 22 +#define ETH_ALEN 6 +#define PMKID_LEN 16 +#define WILC_MAX_NUM_PMKIDS 16 +#define WILC_SUPP_MCS_SET_SIZE 16 +#define WILC_ADD_STA_LENGTH 40 /* Not including the rates field cause it has variable length*/ +#define SCAN_EVENT_DONE_ABORTED +/*****************************************************************************/ +/* Data Types */ +/*****************************************************************************/ +/* typedef unsigned char uint8; */ +/* typedef signed char int8; */ +/* typedef unsigned short uint16; */ +/* typedef unsigned long uint32; */ +/* typedef uint32 Bool; */ + +#if 0 +typedef enum {WID_CHAR = 0, + WID_SHORT = 1, + WID_INT = 2, + WID_STR = 3, + WID_ADR = 4, + WID_BIN = 5, + WID_IP = 6, + WID_UNDEF = 7} WID_TYPE_T; +#endif +typedef struct { + WILC_Uint16 cfg_wid; + WID_TYPE_T cfg_type; + WILC_Sint8 *pu8Para; +} cfg_param_t; + +typedef struct _tstrStatistics { + WILC_Uint8 u8LinkSpeed; + WILC_Sint8 s8RSSI; + WILC_Uint32 u32TxCount; + WILC_Uint32 u32RxCount; + WILC_Uint32 u32TxFailureCount; + +} tstrStatistics; + + +typedef enum { + HOST_IF_IDLE = 0, + HOST_IF_SCANNING = 1, + HOST_IF_CONNECTING = 2, + HOST_IF_WAITING_CONN_RESP = 3, + HOST_IF_CONNECTED = 4, + HOST_IF_P2P_LISTEN = 5, + HOST_IF_FORCE_32BIT = 0xFFFFFFFF +} tenuHostIFstate; + +typedef struct _tstrHostIFpmkid { + WILC_Uint8 bssid[ETH_ALEN]; + WILC_Uint8 pmkid[PMKID_LEN]; +} tstrHostIFpmkid; + +typedef struct _tstrHostIFpmkidAttr { + WILC_Uint8 numpmkid; + tstrHostIFpmkid pmkidlist[WILC_MAX_NUM_PMKIDS]; +} tstrHostIFpmkidAttr; +#if 0 +/* Scan type parameter for scan request */ +typedef enum { + PASSIVE_SCAN = 0, + ACTIVE_SCAN = 1, + NUM_SCANTYPE +} tenuScanType; + +typedef enum {SITE_SURVEY_1CH = 0, + SITE_SURVEY_ALL_CH = 1, + SITE_SURVEY_OFF = 2} SITE_SURVEY_T; +#endif +typedef enum { + AUTORATE = 0, + MBPS_1 = 1, + MBPS_2 = 2, + MBPS_5_5 = 5, + MBPS_11 = 11, + MBPS_6 = 6, + MBPS_9 = 9, + MBPS_12 = 12, + MBPS_18 = 18, + MBPS_24 = 24, + MBPS_36 = 36, + MBPS_48 = 48, + MBPS_54 = 54 +} CURRENT_TX_RATE_T; + +typedef struct { + WILC_Uint32 u32SetCfgFlag; + WILC_Uint8 ht_enable; + WILC_Uint8 bss_type; + WILC_Uint8 auth_type; + WILC_Uint16 auth_timeout; + WILC_Uint8 power_mgmt_mode; + WILC_Uint16 short_retry_limit; + WILC_Uint16 long_retry_limit; + WILC_Uint16 frag_threshold; + WILC_Uint16 rts_threshold; + WILC_Uint16 preamble_type; + WILC_Uint8 short_slot_allowed; + WILC_Uint8 txop_prot_disabled; + WILC_Uint16 beacon_interval; + WILC_Uint16 dtim_period; + SITE_SURVEY_T site_survey_enabled; + WILC_Uint16 site_survey_scan_time; + WILC_Uint8 scan_source; + WILC_Uint16 active_scan_time; + WILC_Uint16 passive_scan_time; + CURRENT_TX_RATE_T curr_tx_rate; + +} tstrCfgParamVal; + +typedef enum { + RETRY_SHORT = 1 << 0, + RETRY_LONG = 1 << 1, + FRAG_THRESHOLD = 1 << 2, + RTS_THRESHOLD = 1 << 3, + BSS_TYPE = 1 << 4, + AUTH_TYPE = 1 << 5, + AUTHEN_TIMEOUT = 1 << 6, + POWER_MANAGEMENT = 1 << 7, + PREAMBLE = 1 << 8, + SHORT_SLOT_ALLOWED = 1 << 9, + TXOP_PROT_DISABLE = 1 << 10, + BEACON_INTERVAL = 1 << 11, + DTIM_PERIOD = 1 << 12, + SITE_SURVEY = 1 << 13, + SITE_SURVEY_SCAN_TIME = 1 << 14, + ACTIVE_SCANTIME = 1 << 15, + PASSIVE_SCANTIME = 1 << 16, + CURRENT_TX_RATE = 1 << 17, + HT_ENABLE = 1 << 18, +} tenuCfgParam; + +typedef struct { + WILC_Uint8 au8bssid[6]; + WILC_Sint8 s8rssi; +} tstrFoundNetworkInfo; + +typedef enum {SCAN_EVENT_NETWORK_FOUND = 0, + SCAN_EVENT_DONE = 1, + SCAN_EVENT_ABORTED = 2, + SCAN_EVENT_FORCE_32BIT = 0xFFFFFFFF} tenuScanEvent; + +typedef enum { + CONN_DISCONN_EVENT_CONN_RESP = 0, + CONN_DISCONN_EVENT_DISCONN_NOTIF = 1, + CONN_DISCONN_EVENT_FORCE_32BIT = 0xFFFFFFFF +} tenuConnDisconnEvent; + +typedef enum { + WEP, + WPARxGtk, + /* WPATxGtk, */ + WPAPtk, + PMKSA, +} tenuKeyType; + + +/*Scan callBack function definition*/ +typedef void (*tWILCpfScanResult)(tenuScanEvent, tstrNetworkInfo *, void *, void *); + +/*Connect callBack function definition*/ +typedef void (*tWILCpfConnectResult)(tenuConnDisconnEvent, + tstrConnectInfo *, + WILC_Uint8, + tstrDisconnectNotifInfo *, + void *); + +#ifdef WILC_P2P +typedef void (*tWILCpfRemainOnChanExpired)(void *, WILC_Uint32); /*Remain on channel expiration callback function*/ +typedef void (*tWILCpfRemainOnChanReady)(void *); /*Remain on channel callback function*/ +#endif + +/* typedef WILC_Uint32 WILC_WFIDrvHandle; */ +typedef struct { + WILC_Sint32 s32Dummy; +} *WILC_WFIDrvHandle; + +/*! + * @struct tstrRcvdNetworkInfo + * @brief Structure to hold Received Asynchronous Network info + * @details + * @todo + * @sa + * @author Mostafa Abu Bakr + * @date 25 March 2012 + * @version 1.0 + */ +typedef struct _tstrRcvdNetworkInfo { + WILC_Uint8 *pu8Buffer; + WILC_Uint32 u32Length; +} tstrRcvdNetworkInfo; + +/*BugID_4156*/ +typedef struct _tstrHiddenNetworkInfo { + WILC_Uint8 *pu8ssid; + WILC_Uint8 u8ssidlen; + +} tstrHiddenNetworkInfo; + +typedef struct _tstrHiddenNetwork { + /* MAX_SSID_LEN */ + tstrHiddenNetworkInfo *pstrHiddenNetworkInfo; + WILC_Uint8 u8ssidnum; + +} tstrHiddenNetwork; + +typedef struct { + /* Scan user call back function */ + tWILCpfScanResult pfUserScanResult; + + /* User specific parameter to be delivered through the Scan User Callback function */ + void *u32UserScanPvoid; + + WILC_Uint32 u32RcvdChCount; + tstrFoundNetworkInfo astrFoundNetworkInfo[MAX_NUM_SCANNED_NETWORKS]; +} tstrWILC_UsrScanReq; + +typedef struct { + WILC_Uint8 *pu8bssid; + WILC_Uint8 *pu8ssid; + WILC_Uint8 u8security; + AUTHTYPE_T tenuAuth_type; + size_t ssidLen; + WILC_Uint8 *pu8ConnReqIEs; + size_t ConnReqIEsLen; + /* Connect user call back function */ + tWILCpfConnectResult pfUserConnectResult; + WILC_Bool IsHTCapable; + /* User specific parameter to be delivered through the Connect User Callback function */ + void *u32UserConnectPvoid; +} tstrWILC_UsrConnReq; + +typedef struct { + WILC_Uint32 u32Address; +} tstrHostIfSetDrvHandler; + +typedef struct { + WILC_Uint32 u32Mode; +} tstrHostIfSetOperationMode; + +/*BugID_5077*/ +typedef struct { + WILC_Uint8 u8MacAddress[ETH_ALEN]; +} tstrHostIfSetMacAddress; + +/*BugID_5213*/ +typedef struct { + WILC_Uint8 *u8MacAddress; +} tstrHostIfGetMacAddress; + +/*BugID_5222*/ +typedef struct { + WILC_Uint8 au8Bssid[ETH_ALEN]; + WILC_Uint8 u8Ted; + WILC_Uint16 u16BufferSize; + WILC_Uint16 u16SessionTimeout; +} tstrHostIfBASessionInfo; + +#ifdef WILC_P2P +typedef struct { + WILC_Uint16 u16Channel; + WILC_Uint32 u32duration; + tWILCpfRemainOnChanExpired pRemainOnChanExpired; + tWILCpfRemainOnChanReady pRemainOnChanReady; + void *pVoid; + WILC_Uint32 u32ListenSessionID; +} tstrHostIfRemainOnChan; + +typedef struct { + + WILC_Bool bReg; + WILC_Uint16 u16FrameType; + WILC_Uint8 u8Regid; + + +} tstrHostIfRegisterFrame; + + +#define ACTION 0xD0 +#define PROBE_REQ 0x40 +#define PROBE_RESP 0x50 +#define ACTION_FRM_IDX 0 +#define PROBE_REQ_IDX 1 + + +enum p2p_listen_state { + P2P_IDLE, + P2P_LISTEN, + P2P_GRP_FORMATION +}; + +#endif +typedef struct { + /* Scan user structure */ + tstrWILC_UsrScanReq strWILC_UsrScanReq; + + /* Connect User structure */ + tstrWILC_UsrConnReq strWILC_UsrConnReq; + + #ifdef WILC_P2P + /*Remain on channel struvture*/ + tstrHostIfRemainOnChan strHostIfRemainOnChan; + WILC_Uint8 u8RemainOnChan_pendingreq; + WILC_Uint64 u64P2p_MgmtTimeout; + WILC_Uint8 u8P2PConnect; + #endif + + tenuHostIFstate enuHostIFstate; + + /* WILC_Bool bPendingConnRequest; */ + + #ifndef CONNECT_DIRECT + WILC_Uint32 u32SurveyResultsCount; + wid_site_survey_reslts_s astrSurveyResults[MAX_NUM_SCANNED_NETWORKS]; + #endif + + WILC_Uint8 au8AssociatedBSSID[ETH_ALEN]; + tstrCfgParamVal strCfgValues; +/* semaphores */ + WILC_SemaphoreHandle gtOsCfgValuesSem; + WILC_SemaphoreHandle hSemTestKeyBlock; + + WILC_SemaphoreHandle hSemTestDisconnectBlock; + WILC_SemaphoreHandle hSemGetRSSI; + WILC_SemaphoreHandle hSemGetLINKSPEED; + WILC_SemaphoreHandle hSemGetCHNL; + WILC_SemaphoreHandle hSemInactiveTime; +/* timer handlers */ + WILC_TimerHandle hScanTimer; + WILC_TimerHandle hConnectTimer; + #ifdef WILC_P2P + WILC_TimerHandle hRemainOnChannel; + #endif + + WILC_Bool IFC_UP; +} tstrWILC_WFIDrv; + +/*! + * @enum tenuWILC_StaFlag + * @brief Used to decode the station flag set and mask in tstrWILC_AddStaParam + * @details + * @todo + * @sa tstrWILC_AddStaParam, enum nl80211_sta_flags + * @author Enumeraion's creator + * @date 12 July 2012 + * @version 1.0 Description + */ + +typedef enum { + WILC_STA_FLAG_INVALID = 0, + WILC_STA_FLAG_AUTHORIZED, /*!< station is authorized (802.1X)*/ + WILC_STA_FLAG_SHORT_PREAMBLE, /*!< station is capable of receiving frames with short barker preamble*/ + WILC_STA_FLAG_WME, /*!< station is WME/QoS capable*/ + WILC_STA_FLAG_MFP, /*!< station uses management frame protection*/ + WILC_STA_FLAG_AUTHENTICATED /*!< station is authenticated*/ +} tenuWILC_StaFlag; + +typedef struct { + WILC_Uint8 au8BSSID[ETH_ALEN]; + WILC_Uint16 u16AssocID; + WILC_Uint8 u8NumRates; + WILC_Uint8 *pu8Rates; + WILC_Bool bIsHTSupported; + WILC_Uint16 u16HTCapInfo; + WILC_Uint8 u8AmpduParams; + WILC_Uint8 au8SuppMCsSet[16]; + WILC_Uint16 u16HTExtParams; + WILC_Uint32 u32TxBeamformingCap; + WILC_Uint8 u8ASELCap; + WILC_Uint16 u16FlagsMask; /**/ + WILC_Uint16 u16FlagsSet; /*