summaryrefslogblamecommitdiffstats
path: root/drivers/staging/wilc1000/coreconfigurator.c
blob: 1a5b16577fd506d89ae5f2b4b6606cf4b266359b (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12
13
14













                                                                               


























                                                                                           





                                           































































































                                                                       
                           

                              
                           











                                                                               
                                                          


                                                                        


                                                                               

                                         
 
                            


                                           
                  
 
                                   
 
                   
 
                                   









                                                  
                                                  




















                                                   









                                                   







                                                                                     












































































                                                      
                                                                 








                                                                               
                                  










                                              
                              
 
                                        





                                                                                
                                                















                                                                                
                                              
 

                  

                                            

                                                                     










                                                                              
                                           
 

                   






















                                                                            
                                          
 



                       
































                                                           
                                            
































                                                                               
                                      
 
                        






                                  
                                            
 

                                   








                                            
                                            
 

                                         











                                                                               
                                            






                                                                               
                                              






                                                                               
                               






                                                                               
                                 





                                                                               
                                              
 
                                    



                                                                               
                                              
 
                                     



                                                                               
                                              
 
                                     




                                                                               
                                          









                                                                               
                                                        
 


                   




















                                                                                   
                                 
 

                                   
                          















                                                                                           
                                            
 
                         








                                                                               
                                    
 
                            








                                                                                                               
                                
 
                        
















                                                         
                              
 
                                    
                                                            
 

                                        
 
                                                                   
                                       
                                                                    



                                       
                                                                  
 
                                                                           



                        
                                                                
 
                         














                                                                                   
                                             
                                                 
                    
                                                                        

         
                 



                                                          
                                                        
 
                  



                                              
                                                 










                                                                               
                                                








                                                       
                                                             
















                                                                                                               
                                                                          
 
                                    
                                                

                         
                          
 

                                    
                           

























                                                                  
                                
                                 

                                  
                                  
                               

                              

                                                                                          
                                                                              





















                                                                              
                                                                             


















                                                                                               
                                   
                                                                     



                                                                                                           
                                                                               
                                                                                
 
                                                                           




















                                                              
                                                           
 
                                    
 

                                                      
                                                       
                                                       



                                             
                                       
                                       


















                                                                                                                                
                                                       

                                                                          
                                    
                                                        
                                
                       
                          

                                                                                              
                                                                              

                                             
                                            














                                                                                         
                                                                               
                                                                                
 
                                                                           


















                                                                                
                                                                     
 
                                    
 

                                                              
                                                               
                                                               



                                             
                                           
                                           








                                     
                                                                                   
                                                                             
                                                           
 
                                    
                                                           

                                      
                         
                                        
                                  

              















                                                                                                                              
                                                                                                         













                                                                                  
                                                                                                              












                                                             
                                                                        
 
                                    
 
                                        
                                         
































                                                                               
                                                    
                                                    
 

                                     
                                    





                                                                                              

                                                                    



                                     
                                                   


































                                                                               
                                                     
                                                     
 

                                        
                                    





                                                                                                

                                                                      




                                     
                                                    

                           

                                                                   






























                                                                               
                                                   
                                                   
 

                                        
                                    





                                                                                               

                                                                      




                                     
                                                    

                           



                                                                    































                                                                               
                                                  
                                              
 
                       
                                    






                                                                                  

                                                                      


                                     
                                                    




                                                              



                                                                    






























                                                                               
                                                   
                                                                  
 

                          
                                    





                                                                                 

                                                                      


                                     
                                              

                            
                                                      


































                                                                               
                                                   
                                                
 
                          
                                    






                                                                                  

                                                                      





                                         
                                                      










































                                                                                    
                                                   
                                                                  
 

                          
                                    
                          






                                                                                 

                                                                      


                                     
                                              

                            


                                                                      















































                                                                               
                                      

                                                  
                                                          
                                             

                                                            

                       
                        
                         
                         
                              

                                           
                            
                                                     
            
                                                       










                                                      
                                                                 

                                                                
                                                                   





                                   
                                                                 




                                                                         
                                                              




                                   
                                                     
                                                                                                
                                                             
                                                                                                                                    

                                                              
                                                                                                          







                                                     
                                                                            
                                                                 







                                                                         


                          
                                                             
                                                                              












































                                                                                                                          
                                                      
 


                           
                                           
                                       


                       















                                                                                        
                                                                      


                              
                                                                      
                                                 
 
                                                                                                                                





                                                                          
                                                                                                                     































                                                                                                        
                                         
 
                                 
                                      






                                                                  



























                                                                                
                                                             
 
                                    

                                                 


























                                                                                   

                                                              



















                                                                                   
                                                            
                                                                   
 
                                    
                       






















                                                                                                 



















                                                                                                 
                                                                                     
                                                  
 
                                    






                                                                   
                                              
                                        



                                                                
                                                                           



                        
                                                             
 
                                    
 
                                              
                                                                        
                                                                                         

                                                                    
                                                                                                                  
                                                                                             
                                                                                                          

                 
                                      

















                                                                                           
                                                          
 
                                    
                         






















                                                                            
                                                                                                      















                                                           
                                
 
                                    
 
                                                              
 

                                       
                                        





                                        
















                                                                                           
                                               
                                                                               
 
                                 



























                                                                                                     






















                                                                                                                  

/*!
 *  @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 s8 *gps8ConfigPacket;

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);

	gps8ConfigPacket = (s8 *)WILC_MALLOC(MAX_PACKET_BUFF_SIZE);
	if (gps8ConfigPacket == NULL) {
		PRINT_ER("failed in gps8ConfigPacket allocation\n");
		s32Error = WILC_NO_MEM;
		goto _fail_;
	}

	memset((void *)gps8ConfigPacket, 0, MAX_PACKET_BUFF_SIZE);

	memset((void *)(&gstrConfigPktInfo), 0, sizeof(tstrConfigPktInfo));
_fail_:
	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 = (tstrNetworkInfo *)WILC_MALLOC(sizeof(tstrNetworkInfo));
		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 = (u8 *)WILC_MALLOC(u16IEsLen);
			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 = (tstrConnectRespInfo *)WILC_MALLOC(sizeof(tstrConnectRespInfo));
	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 = (u8 *)WILC_MALLOC(u16IEsLen);
		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 = (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);
	}

	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");

	if (gps8ConfigPacket != NULL) {

		kfree(gps8ConfigPacket);
		gps8ConfigPacket = NULL;
	}

	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;
}