![Chaehyun Lim](/assets/img/avatar_default.png)
It is added and fixed error check when kmalloc is failed. Signed-off-by: Chaehyun Lim <chaehyun.lim@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2034 lines
71 KiB
C
2034 lines
71 KiB
C
|
|
/*!
|
|
* @file coreconfigurator.c
|
|
* @brief
|
|
* @author
|
|
* @sa coreconfigurator.h
|
|
* @date 1 Mar 2012
|
|
* @version 1.0
|
|
*/
|
|
|
|
|
|
/*****************************************************************************/
|
|
/* File Includes */
|
|
/*****************************************************************************/
|
|
#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 {
|
|
char *pcRespBuffer;
|
|
s32 s32MaxRespBuffLen;
|
|
s32 s32BytesRead;
|
|
bool bRespRequired;
|
|
} tstrConfigPktInfo;
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
/* Extern Variable Declarations */
|
|
/*****************************************************************************/
|
|
|
|
|
|
/*****************************************************************************/
|
|
/* Extern Function Declarations */
|
|
/*****************************************************************************/
|
|
extern s32 SendRawPacket(s8 *ps8Packet, s32 s32PacketLen);
|
|
extern void NetworkInfoReceived(u8 *pu8Buffer, u32 u32Length);
|
|
extern void GnrlAsyncInfoReceived(u8 *pu8Buffer, u32 u32Length);
|
|
extern void host_int_ScanCompleteReceived(u8 *pu8Buffer, u32 u32Length);
|
|
/*****************************************************************************/
|
|
/* Global Variables */
|
|
/*****************************************************************************/
|
|
static struct semaphore SemHandleSendPkt;
|
|
static struct semaphore SemHandlePktResp;
|
|
|
|
|
|
static tstrConfigPktInfo gstrConfigPktInfo;
|
|
|
|
static u8 g_seqno;
|
|
|
|
static s16 g_wid_num = -1;
|
|
|
|
static u16 Res_Len;
|
|
|
|
static u8 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},
|
|
{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 */
|
|
};
|
|
|
|
u16 g_num_total_switches = (sizeof(gastrWIDs) / sizeof(tstrWID));
|
|
/*****************************************************************************/
|
|
/* Static Function Declarations */
|
|
/*****************************************************************************/
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
/* Functions */
|
|
/*****************************************************************************/
|
|
INLINE u8 ascii_hex_to_dec(u8 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 u8 get_hex_char(u8 inp)
|
|
{
|
|
u8 *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 u16 extract_mac_addr(char *str, u8 *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(u8 *str, u8 *buff)
|
|
{
|
|
u32 i = 0;
|
|
u32 j = 0;
|
|
|
|
for (i = 0; i < MAC_ADDR_LEN; i++) {
|
|
str[j++] = get_hex_char((u8)((buff[i] >> 4) & 0x0F));
|
|
str[j++] = get_hex_char((u8)(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 u8 conv_ip_to_int(u8 *ips, u32 *ipn)
|
|
{
|
|
u8 i = 0;
|
|
u8 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 u8 conv_int_to_ip(u8 *ips, u32 ipn)
|
|
{
|
|
u8 i = 0;
|
|
u8 ipb = 0;
|
|
u8 cnt = 0;
|
|
u8 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(u32 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 u16 get_beacon_period(u8 *data)
|
|
{
|
|
u16 bcn_per = 0;
|
|
|
|
bcn_per = data[0];
|
|
bcn_per |= (data[1] << 8);
|
|
|
|
return bcn_per;
|
|
}
|
|
|
|
INLINE u32 get_beacon_timestamp_lo(u8 *data)
|
|
{
|
|
u32 time_stamp = 0;
|
|
u32 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 u32 get_beacon_timestamp_hi(u8 *data)
|
|
{
|
|
u32 time_stamp = 0;
|
|
u32 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(u8 *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(u8 *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 u8 get_to_ds(u8 *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 u8 get_from_ds(u8 *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(u8 *pu8msa, u8 *addr)
|
|
{
|
|
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(u8 *pu8msa, u8 *addr)
|
|
{
|
|
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(u8 *pu8msa, u8 *addr)
|
|
{
|
|
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(u8 *data, u8 *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(u8 *data, u8 *ssid, u8 *p_ssid_len)
|
|
{
|
|
u8 len = 0;
|
|
u8 i = 0;
|
|
u8 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 u16 get_cap_info(u8 *data)
|
|
{
|
|
u16 cap_info = 0;
|
|
u16 index = MAC_HDR_LEN;
|
|
tenuFrmSubtype st;
|
|
|
|
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 u16 get_assoc_resp_cap_info(u8 *data)
|
|
{
|
|
u16 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 u16 get_asoc_status(u8 *data)
|
|
{
|
|
u16 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 u16 get_asoc_id(u8 *data)
|
|
{
|
|
u16 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
|
|
*/
|
|
|
|
s32 CoreConfiguratorInit(void)
|
|
{
|
|
s32 s32Error = WILC_SUCCESS;
|
|
PRINT_D(CORECONFIG_DBG, "CoreConfiguratorInit()\n");
|
|
|
|
sema_init(&SemHandleSendPkt, 1);
|
|
sema_init(&SemHandlePktResp, 0);
|
|
|
|
|
|
memset((void *)(&gstrConfigPktInfo), 0, sizeof(tstrConfigPktInfo));
|
|
return s32Error;
|
|
}
|
|
|
|
u8 *get_tim_elm(u8 *pu8msa, u16 u16RxLen, u16 u16TagParamOffset)
|
|
{
|
|
u16 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 */
|
|
u8 get_current_channel_802_11n(u8 *pu8msa, u16 u16RxLen)
|
|
{
|
|
u16 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 */
|
|
}
|
|
|
|
u8 get_current_channel(u8 *pu8msa, u16 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
|
|
*/
|
|
s32 ParseNetworkInfo(u8 *pu8MsgBuffer, tstrNetworkInfo **ppstrNetworkInfo)
|
|
{
|
|
s32 s32Error = WILC_SUCCESS;
|
|
tstrNetworkInfo *pstrNetworkInfo = NULL;
|
|
u8 u8MsgType = 0;
|
|
u8 u8MsgID = 0;
|
|
u16 u16MsgLen = 0;
|
|
|
|
u16 u16WidID = (u16)WID_NIL;
|
|
u16 u16WidLen = 0;
|
|
u8 *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" */
|
|
{
|
|
u8 *pu8msa = 0;
|
|
u16 u16RxLen = 0;
|
|
u8 *pu8TimElm = 0;
|
|
u8 *pu8IEs = 0;
|
|
u16 u16IEsLen = 0;
|
|
u8 u8index = 0;
|
|
u32 u32Tsf_Lo;
|
|
u32 u32Tsf_Hi;
|
|
|
|
pstrNetworkInfo = kmalloc(sizeof(tstrNetworkInfo), GFP_KERNEL);
|
|
if (!pstrNetworkInfo)
|
|
return -ENOMEM;
|
|
|
|
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 | ((u64)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 = kmalloc(u16IEsLen, GFP_KERNEL);
|
|
if (!pstrNetworkInfo->pu8IEs)
|
|
return -ENOMEM;
|
|
|
|
memset((void *)(pstrNetworkInfo->pu8IEs), 0, u16IEsLen);
|
|
|
|
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
|
|
*/
|
|
s32 DeallocateNetworkInfo(tstrNetworkInfo *pstrNetworkInfo)
|
|
{
|
|
s32 s32Error = WILC_SUCCESS;
|
|
|
|
if (pstrNetworkInfo != NULL) {
|
|
if (pstrNetworkInfo->pu8IEs != NULL) {
|
|
kfree(pstrNetworkInfo->pu8IEs);
|
|
pstrNetworkInfo->pu8IEs = NULL;
|
|
} else {
|
|
s32Error = WILC_FAIL;
|
|
}
|
|
|
|
kfree(pstrNetworkInfo);
|
|
pstrNetworkInfo = 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
|
|
*/
|
|
s32 ParseAssocRespInfo(u8 *pu8Buffer, u32 u32BufferLen,
|
|
tstrConnectRespInfo **ppstrConnectRespInfo)
|
|
{
|
|
s32 s32Error = WILC_SUCCESS;
|
|
tstrConnectRespInfo *pstrConnectRespInfo = NULL;
|
|
u16 u16AssocRespLen = 0;
|
|
u8 *pu8IEs = 0;
|
|
u16 u16IEsLen = 0;
|
|
|
|
pstrConnectRespInfo = kmalloc(sizeof(tstrConnectRespInfo), GFP_KERNEL);
|
|
if (!pstrConnectRespInfo)
|
|
return -ENOMEM;
|
|
|
|
memset((void *)(pstrConnectRespInfo), 0, sizeof(tstrConnectRespInfo));
|
|
|
|
/* u16AssocRespLen = pu8Buffer[0]; */
|
|
u16AssocRespLen = (u16)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 = kmalloc(u16IEsLen, GFP_KERNEL);
|
|
if (!pstrConnectRespInfo->pu8RespIEs)
|
|
return -ENOMEM;
|
|
|
|
memset((void *)(pstrConnectRespInfo->pu8RespIEs), 0, u16IEsLen);
|
|
|
|
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
|
|
*/
|
|
s32 DeallocateAssocRespInfo(tstrConnectRespInfo *pstrConnectRespInfo)
|
|
{
|
|
s32 s32Error = WILC_SUCCESS;
|
|
|
|
if (pstrConnectRespInfo != NULL) {
|
|
if (pstrConnectRespInfo->pu8RespIEs != NULL) {
|
|
kfree(pstrConnectRespInfo->pu8RespIEs);
|
|
pstrConnectRespInfo->pu8RespIEs = NULL;
|
|
} else {
|
|
s32Error = WILC_FAIL;
|
|
}
|
|
|
|
kfree(pstrConnectRespInfo);
|
|
pstrConnectRespInfo = NULL;
|
|
|
|
} else {
|
|
s32Error = WILC_FAIL;
|
|
}
|
|
|
|
return s32Error;
|
|
}
|
|
|
|
#ifndef CONNECT_DIRECT
|
|
s32 ParseSurveyResults(u8 ppu8RcvdSiteSurveyResults[][MAX_SURVEY_RESULT_FRAG_SIZE],
|
|
wid_site_survey_reslts_s **ppstrSurveyResults,
|
|
u32 *pu32SurveyResultsCount)
|
|
{
|
|
s32 s32Error = WILC_SUCCESS;
|
|
wid_site_survey_reslts_s *pstrSurveyResults = NULL;
|
|
u32 u32SurveyResultsCount = 0;
|
|
u32 u32SurveyBytesLength = 0;
|
|
u8 *pu8BufferPtr;
|
|
u32 u32RcvdSurveyResultsNum = 2;
|
|
u8 u8ReadSurveyResFragNum;
|
|
u32 i;
|
|
u32 j;
|
|
|
|
for (i = 0; i < u32RcvdSurveyResultsNum; i++) {
|
|
u32SurveyBytesLength = ppu8RcvdSiteSurveyResults[i][0];
|
|
|
|
|
|
for (j = 0; j < u32SurveyBytesLength; j += SURVEY_RESULT_LENGTH) {
|
|
u32SurveyResultsCount++;
|
|
}
|
|
}
|
|
|
|
pstrSurveyResults = kmalloc_array(u32SurveyResultsCount,
|
|
sizeof(wid_site_survey_reslts_s), GFP_KERNEL);
|
|
if (!pstrSurveyResults)
|
|
return -ENOMEM;
|
|
|
|
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) {
|
|
memcpy(&pstrSurveyResults[u32SurveyResultsCount], pu8BufferPtr, SURVEY_RESULT_LENGTH);
|
|
pu8BufferPtr += SURVEY_RESULT_LENGTH;
|
|
u32SurveyResultsCount++;
|
|
}
|
|
}
|
|
|
|
ERRORHANDLER:
|
|
*ppstrSurveyResults = pstrSurveyResults;
|
|
*pu32SurveyResultsCount = u32SurveyResultsCount;
|
|
|
|
return s32Error;
|
|
}
|
|
|
|
|
|
s32 DeallocateSurveyResults(wid_site_survey_reslts_s *pstrSurveyResults)
|
|
{
|
|
s32 s32Error = WILC_SUCCESS;
|
|
|
|
if (pstrSurveyResults != NULL) {
|
|
kfree(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(char *pcPacket, s32 *ps32PktLen,
|
|
tstrWID *pstrWID, s8 *ps8WidVal)
|
|
{
|
|
u8 *pu8val = (u8 *)ps8WidVal;
|
|
u8 u8val = 0;
|
|
s32 s32PktLen = *ps32PktLen;
|
|
if (pstrWID == NULL) {
|
|
PRINT_WRN(CORECONFIG_DBG, "Can't set CHAR val 0x%x ,NULL structure\n", u8val);
|
|
return;
|
|
}
|
|
|
|
/* WID */
|
|
pcPacket[s32PktLen++] = (u8)(pstrWID->u16WIDid & 0xFF);
|
|
pcPacket[s32PktLen++] = (u8)(pstrWID->u16WIDid >> 8) & 0xFF;
|
|
if (g_oper_mode == SET_CFG) {
|
|
u8val = *pu8val;
|
|
|
|
/* Length */
|
|
pcPacket[s32PktLen++] = sizeof(u8);
|
|
|
|
|
|
/* 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(char *pcPacket, s32 *ps32PktLen,
|
|
tstrWID *pstrWID, s8 *ps8WidVal)
|
|
{
|
|
u16 *pu16val = (u16 *)ps8WidVal;
|
|
u16 u16val = 0;
|
|
s32 s32PktLen = *ps32PktLen;
|
|
if (pstrWID == NULL) {
|
|
PRINT_WRN(CORECONFIG_DBG, "Can't set SHORT val 0x%x ,NULL structure\n", u16val);
|
|
return;
|
|
}
|
|
|
|
/* WID */
|
|
pcPacket[s32PktLen++] = (u8)(pstrWID->u16WIDid & 0xFF);
|
|
pcPacket[s32PktLen++] = (u8)((pstrWID->u16WIDid >> 8) & 0xFF);
|
|
|
|
if (g_oper_mode == SET_CFG) {
|
|
u16val = *pu16val;
|
|
|
|
/* Length */
|
|
pcPacket[s32PktLen++] = sizeof(u16);
|
|
|
|
/* Value */
|
|
pcPacket[s32PktLen++] = (u8)(u16val & 0xFF);
|
|
pcPacket[s32PktLen++] = (u8)((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(char *pcPacket, s32 *ps32PktLen,
|
|
tstrWID *pstrWID, s8 *ps8WidVal)
|
|
{
|
|
u32 *pu32val = (u32 *)ps8WidVal;
|
|
u32 u32val = 0;
|
|
s32 s32PktLen = *ps32PktLen;
|
|
if (pstrWID == NULL) {
|
|
PRINT_WRN(CORECONFIG_DBG, "Can't set INT val 0x%x , NULL structure\n", u32val);
|
|
return;
|
|
}
|
|
|
|
/* WID */
|
|
pcPacket[s32PktLen++] = (u8)(pstrWID->u16WIDid & 0xFF);
|
|
pcPacket[s32PktLen++] = (u8)((pstrWID->u16WIDid >> 8) & 0xFF);
|
|
|
|
if (g_oper_mode == SET_CFG) {
|
|
u32val = *pu32val;
|
|
|
|
/* Length */
|
|
pcPacket[s32PktLen++] = sizeof(u32);
|
|
|
|
/* Value */
|
|
pcPacket[s32PktLen++] = (u8)(u32val & 0xFF);
|
|
pcPacket[s32PktLen++] = (u8)((u32val >> 8) & 0xFF);
|
|
pcPacket[s32PktLen++] = (u8)((u32val >> 16) & 0xFF);
|
|
pcPacket[s32PktLen++] = (u8)((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(char *pcPacket, s32 *ps32PktLen,
|
|
tstrWID *pstrWID, u8 *pu8ip)
|
|
{
|
|
u32 u32val = 0;
|
|
s32 s32PktLen = *ps32PktLen;
|
|
|
|
if (pstrWID == NULL) {
|
|
PRINT_WRN(CORECONFIG_DBG, "Can't set IP Addr , NULL structure\n");
|
|
return;
|
|
}
|
|
|
|
/* WID */
|
|
pcPacket[s32PktLen++] = (u8)(pstrWID->u16WIDid & 0xFF);
|
|
pcPacket[s32PktLen++] = (u8)((pstrWID->u16WIDid >> 8) & 0xFF);
|
|
|
|
if (g_oper_mode == SET_CFG) {
|
|
/* Length */
|
|
pcPacket[s32PktLen++] = sizeof(u32);
|
|
|
|
/* Convert the IP Address String to Integer */
|
|
conv_ip_to_int(pu8ip, &u32val);
|
|
|
|
/* Value */
|
|
pcPacket[s32PktLen++] = (u8)(u32val & 0xFF);
|
|
pcPacket[s32PktLen++] = (u8)((u32val >> 8) & 0xFF);
|
|
pcPacket[s32PktLen++] = (u8)((u32val >> 16) & 0xFF);
|
|
pcPacket[s32PktLen++] = (u8)((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(char *pcPacket, s32 *ps32PktLen,
|
|
tstrWID *pstrWID, u8 *pu8val, s32 s32ValueSize)
|
|
{
|
|
u16 u16MsgLen = 0;
|
|
u16 idx = 0;
|
|
s32 s32PktLen = *ps32PktLen;
|
|
if (pstrWID == NULL) {
|
|
PRINT_WRN(CORECONFIG_DBG, "Can't set STR val, NULL structure\n");
|
|
return;
|
|
}
|
|
|
|
/* WID */
|
|
pcPacket[s32PktLen++] = (u8)(pstrWID->u16WIDid & 0xFF);
|
|
pcPacket[s32PktLen++] = (u8)((pstrWID->u16WIDid >> 8) & 0xFF);
|
|
|
|
if (g_oper_mode == SET_CFG) {
|
|
/* Message Length */
|
|
u16MsgLen = (u16)s32ValueSize;
|
|
|
|
/* Length */
|
|
pcPacket[s32PktLen++] = (u8)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(char *pcPacket, s32 *ps32PktLen,
|
|
tstrWID *pstrWID, u8 *pu8val)
|
|
{
|
|
u16 u16MsgLen = 0;
|
|
s32 s32PktLen = *ps32PktLen;
|
|
|
|
if (pstrWID == NULL) {
|
|
PRINT_WRN(CORECONFIG_DBG, "Can't set Addr WID, NULL structure\n");
|
|
return;
|
|
}
|
|
|
|
/* WID */
|
|
pcPacket[s32PktLen++] = (u8)(pstrWID->u16WIDid & 0xFF);
|
|
pcPacket[s32PktLen++] = (u8)((pstrWID->u16WIDid >> 8) & 0xFF);
|
|
|
|
if (g_oper_mode == SET_CFG) {
|
|
/* Message Length */
|
|
u16MsgLen = MAC_ADDR_LEN;
|
|
|
|
/* Length */
|
|
pcPacket[s32PktLen++] = (u8)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(char *pcPacket, s32 *ps32PktLen,
|
|
tstrWID *pstrWID, u8 *pu8val, s32 s32ValueSize)
|
|
{
|
|
u16 u16MsgLen = 0;
|
|
u16 idx = 0;
|
|
s32 s32PktLen = *ps32PktLen;
|
|
u8 u8checksum = 0;
|
|
|
|
if (pstrWID == NULL) {
|
|
PRINT_WRN(CORECONFIG_DBG, "Can't set BIN val, NULL structure\n");
|
|
return;
|
|
}
|
|
|
|
/* WID */
|
|
pcPacket[s32PktLen++] = (u8)(pstrWID->u16WIDid & 0xFF);
|
|
pcPacket[s32PktLen++] = (u8)((pstrWID->u16WIDid >> 8) & 0xFF);
|
|
|
|
if (g_oper_mode == SET_CFG) {
|
|
/* Message Length */
|
|
u16MsgLen = (u16)s32ValueSize;
|
|
|
|
/* Length */
|
|
/* pcPacket[s32PktLen++] = (u8)u16MsgLen; */
|
|
pcPacket[s32PktLen++] = (u8)(u16MsgLen & 0xFF);
|
|
pcPacket[s32PktLen++] = (u8)((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 */
|
|
/* */
|
|
/*****************************************************************************/
|
|
|
|
s32 further_process_response(u8 *resp,
|
|
u16 u16WIDid,
|
|
u16 cfg_len,
|
|
bool process_wid_num,
|
|
u32 cnt,
|
|
tstrWID *pstrWIDresult)
|
|
{
|
|
u32 retval = 0;
|
|
u32 idx = 0;
|
|
u8 cfg_chr = 0;
|
|
u16 cfg_sht = 0;
|
|
u32 cfg_int = 0;
|
|
u8 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:
|
|
{
|
|
u16 *pu16val = (u16 *)(pstrWIDresult->ps8WidVal);
|
|
cfg_sht = MAKE_WORD16(resp[idx], resp[idx + 1]);
|
|
/*Set local copy of WID*/
|
|
/* pstrWIDresult->ps8WidVal = (s8*)(s32)cfg_sht; */
|
|
*pu16val = cfg_sht;
|
|
break;
|
|
}
|
|
|
|
case WID_INT:
|
|
{
|
|
u32 *pu32val = (u32 *)(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 = (s8*)cfg_int; */
|
|
*pu32val = cfg_int;
|
|
break;
|
|
}
|
|
|
|
case WID_STR:
|
|
memcpy(cfg_str, resp + idx, cfg_len);
|
|
/* cfg_str[cfg_len] = '\0'; //mostafa: no need currently for NULL termination */
|
|
if (pstrWIDresult->s32ValueSize >= cfg_len) {
|
|
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);
|
|
|
|
strncpy(pstrWIDresult->ps8WidVal, cfg_str, strlen(cfg_str));
|
|
pstrWIDresult->ps8WidVal[strlen(cfg_str)] = '\0';
|
|
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);
|
|
break;
|
|
|
|
case WID_BIN_DATA:
|
|
if (pstrWIDresult->s32ValueSize >= cfg_len) {
|
|
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 */
|
|
/* */
|
|
/*****************************************************************************/
|
|
|
|
s32 ParseResponse(u8 *resp, tstrWID *pstrWIDcfgResult)
|
|
{
|
|
u16 u16RespLen = 0;
|
|
u16 u16WIDid = 0;
|
|
u16 cfg_len = 0;
|
|
tenuWIDtype enuWIDtype = WID_UNDEF;
|
|
bool num_wid_processed = false;
|
|
u32 cnt = 0;
|
|
u32 idx = 0;
|
|
u32 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 |= ((u16)resp[idx + 3] << 8) & 0xFF00;
|
|
idx++;
|
|
}
|
|
idx += 3;
|
|
if ((u16WIDid == g_wid_num) && (!num_wid_processed)) {
|
|
num_wid_processed = true;
|
|
|
|
if (-2 == further_process_response(&resp[idx], u16WIDid, cfg_len, 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, 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
|
|
*/
|
|
|
|
s32 ParseWriteResponse(u8 *pu8RespBuffer)
|
|
{
|
|
s32 s32Error = WILC_FAIL;
|
|
u16 u16WIDtype = (u16)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;
|
|
}
|
|
|
|
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
|
|
*/
|
|
|
|
s32 CreatePacketHeader(char *pcpacket, s32 *ps32PacketLength)
|
|
{
|
|
s32 s32Error = WILC_SUCCESS;
|
|
u16 u16MsgLen = (u16)(*ps32PacketLength);
|
|
u16 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++] = (u8)(u16MsgLen & 0xFF);
|
|
pcpacket[u16MsgInd++] = (u8)((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
|
|
*/
|
|
|
|
s32 CreateConfigPacket(s8 *ps8packet, s32 *ps32PacketLength,
|
|
tstrWID *pstrWIDs, u32 u32WIDsCount)
|
|
{
|
|
s32 s32Error = WILC_SUCCESS;
|
|
u32 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;
|
|
|
|
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;
|
|
}
|
|
|
|
s32 ConfigWaitResponse(char *pcRespBuffer, s32 s32MaxRespBuffLen, s32 *ps32BytesRead,
|
|
bool bRespRequired)
|
|
{
|
|
s32 s32Error = WILC_SUCCESS;
|
|
/*bug 3878*/
|
|
/*removed to caller function*/
|
|
/*gstrConfigPktInfo.pcRespBuffer = pcRespBuffer;
|
|
* gstrConfigPktInfo.s32MaxRespBuffLen = s32MaxRespBuffLen;
|
|
* gstrConfigPktInfo.bRespRequired = bRespRequired;*/
|
|
|
|
|
|
if (gstrConfigPktInfo.bRespRequired) {
|
|
down(&SemHandlePktResp);
|
|
|
|
*ps32BytesRead = gstrConfigPktInfo.s32BytesRead;
|
|
}
|
|
|
|
memset((void *)(&gstrConfigPktInfo), 0, sizeof(tstrConfigPktInfo));
|
|
|
|
return s32Error;
|
|
}
|
|
|
|
s32 ConfigProvideResponse(char *pcRespBuffer, s32 s32RespLen)
|
|
{
|
|
s32 s32Error = WILC_SUCCESS;
|
|
|
|
if (gstrConfigPktInfo.bRespRequired) {
|
|
if (s32RespLen <= gstrConfigPktInfo.s32MaxRespBuffLen) {
|
|
memcpy(gstrConfigPktInfo.pcRespBuffer, pcRespBuffer, s32RespLen);
|
|
gstrConfigPktInfo.s32BytesRead = s32RespLen;
|
|
} else {
|
|
memcpy(gstrConfigPktInfo.pcRespBuffer, pcRespBuffer, gstrConfigPktInfo.s32MaxRespBuffLen);
|
|
gstrConfigPktInfo.s32BytesRead = gstrConfigPktInfo.s32MaxRespBuffLen;
|
|
PRINT_ER("BusProvideResponse() Response greater than the prepared Buffer Size\n");
|
|
}
|
|
|
|
up(&SemHandlePktResp);
|
|
}
|
|
|
|
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
|
|
*/
|
|
|
|
s32 ConfigPktReceived(u8 *pu8RxPacket, s32 s32RxPacketLen)
|
|
{
|
|
s32 s32Error = WILC_SUCCESS;
|
|
u8 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
|
|
*/
|
|
|
|
s32 CoreConfiguratorDeInit(void)
|
|
{
|
|
s32 s32Error = WILC_SUCCESS;
|
|
|
|
PRINT_D(CORECONFIG_DBG, "CoreConfiguratorDeInit()\n");
|
|
|
|
|
|
return s32Error;
|
|
}
|
|
|
|
/*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
|
|
*/
|
|
s32 SendConfigPkt(u8 u8Mode, tstrWID *pstrWIDs,
|
|
u32 u32WIDsCount, bool bRespRequired, u32 drvHandler)
|
|
{
|
|
s32 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
|
|
**/
|
|
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;
|
|
}
|