Commit | Line | Data |
---|---|---|
c5c77ba1 JK |
1 | |
2 | /*! | |
3 | * @file coreconfigurator.c | |
4 | * @brief | |
5 | * @author | |
6 | * @sa coreconfigurator.h | |
7 | * @date 1 Mar 2012 | |
8 | * @version 1.0 | |
9 | */ | |
10 | ||
11 | ||
12 | /*****************************************************************************/ | |
13 | /* File Includes */ | |
14 | /*****************************************************************************/ | |
c5c77ba1 | 15 | #include "coreconfigurator.h" |
24db713f | 16 | #include <linux/errno.h> |
c5c77ba1 JK |
17 | /*****************************************************************************/ |
18 | /* Constants */ | |
19 | /*****************************************************************************/ | |
20 | #define INLINE static __inline | |
c5c77ba1 JK |
21 | #define TAG_PARAM_OFFSET (MAC_HDR_LEN + TIME_STAMP_LEN + \ |
22 | BEACON_INTERVAL_LEN + CAP_INFO_LEN) | |
23 | ||
24 | /*****************************************************************************/ | |
25 | /* Function Macros */ | |
26 | /*****************************************************************************/ | |
27 | ||
28 | ||
29 | /*****************************************************************************/ | |
30 | /* Type Definitions */ | |
31 | /*****************************************************************************/ | |
32 | ||
33 | /* Basic Frame Type Codes (2-bit) */ | |
13994d1e SK |
34 | typedef enum { |
35 | FRAME_TYPE_CONTROL = 0x04, | |
36 | FRAME_TYPE_DATA = 0x08, | |
37 | FRAME_TYPE_MANAGEMENT = 0x00, | |
38 | FRAME_TYPE_RESERVED = 0x0C, | |
39 | FRAME_TYPE_FORCE_32BIT = 0xFFFFFFFF | |
c5c77ba1 JK |
40 | } tenuBasicFrmType; |
41 | ||
42 | /* Frame Type and Subtype Codes (6-bit) */ | |
43 | typedef enum { | |
44 | ASSOC_REQ = 0x00, | |
45 | ASSOC_RSP = 0x10, | |
46 | REASSOC_REQ = 0x20, | |
47 | REASSOC_RSP = 0x30, | |
48 | PROBE_REQ = 0x40, | |
49 | PROBE_RSP = 0x50, | |
50 | BEACON = 0x80, | |
51 | ATIM = 0x90, | |
52 | DISASOC = 0xA0, | |
53 | AUTH = 0xB0, | |
54 | DEAUTH = 0xC0, | |
55 | ACTION = 0xD0, | |
56 | PS_POLL = 0xA4, | |
57 | RTS = 0xB4, | |
58 | CTS = 0xC4, | |
59 | ACK = 0xD4, | |
60 | CFEND = 0xE4, | |
61 | CFEND_ACK = 0xF4, | |
62 | DATA = 0x08, | |
63 | DATA_ACK = 0x18, | |
64 | DATA_POLL = 0x28, | |
65 | DATA_POLL_ACK = 0x38, | |
66 | NULL_FRAME = 0x48, | |
67 | CFACK = 0x58, | |
68 | CFPOLL = 0x68, | |
69 | CFPOLL_ACK = 0x78, | |
70 | QOS_DATA = 0x88, | |
71 | QOS_DATA_ACK = 0x98, | |
72 | QOS_DATA_POLL = 0xA8, | |
73 | QOS_DATA_POLL_ACK = 0xB8, | |
74 | QOS_NULL_FRAME = 0xC8, | |
75 | QOS_CFPOLL = 0xE8, | |
76 | QOS_CFPOLL_ACK = 0xF8, | |
77 | BLOCKACK_REQ = 0x84, | |
78 | BLOCKACK = 0x94, | |
79 | FRAME_SUBTYPE_FORCE_32BIT = 0xFFFFFFFF | |
80 | } tenuFrmSubtype; | |
81 | ||
c5c77ba1 JK |
82 | /* Element ID of various Information Elements */ |
83 | typedef enum { | |
84 | ISSID = 0, /* Service Set Identifier */ | |
85 | ISUPRATES = 1, /* Supported Rates */ | |
86 | IFHPARMS = 2, /* FH parameter set */ | |
87 | IDSPARMS = 3, /* DS parameter set */ | |
88 | ICFPARMS = 4, /* CF parameter set */ | |
89 | ITIM = 5, /* Traffic Information Map */ | |
90 | IIBPARMS = 6, /* IBSS parameter set */ | |
91 | ICOUNTRY = 7, /* Country element */ | |
92 | IEDCAPARAMS = 12, /* EDCA parameter set */ | |
93 | ITSPEC = 13, /* Traffic Specification */ | |
94 | ITCLAS = 14, /* Traffic Classification */ | |
95 | ISCHED = 15, /* Schedule */ | |
96 | ICTEXT = 16, /* Challenge Text */ | |
97 | IPOWERCONSTRAINT = 32, /* Power Constraint */ | |
98 | IPOWERCAPABILITY = 33, /* Power Capability */ | |
99 | ITPCREQUEST = 34, /* TPC Request */ | |
100 | ITPCREPORT = 35, /* TPC Report */ | |
101 | ISUPCHANNEL = 36, /* Supported channel list */ | |
102 | ICHSWANNOUNC = 37, /* Channel Switch Announcement */ | |
103 | IMEASUREMENTREQUEST = 38, /* Measurement request */ | |
104 | IMEASUREMENTREPORT = 39, /* Measurement report */ | |
105 | IQUIET = 40, /* Quiet element Info */ | |
106 | IIBSSDFS = 41, /* IBSS DFS */ | |
107 | IERPINFO = 42, /* ERP Information */ | |
108 | ITSDELAY = 43, /* TS Delay */ | |
109 | ITCLASPROCESS = 44, /* TCLAS Processing */ | |
110 | IHTCAP = 45, /* HT Capabilities */ | |
111 | IQOSCAP = 46, /* QoS Capability */ | |
112 | IRSNELEMENT = 48, /* RSN Information Element */ | |
113 | IEXSUPRATES = 50, /* Extended Supported Rates */ | |
114 | IEXCHSWANNOUNC = 60, /* Extended Ch Switch Announcement*/ | |
115 | IHTOPERATION = 61, /* HT Information */ | |
116 | ISECCHOFF = 62, /* Secondary Channel Offeset */ | |
117 | I2040COEX = 72, /* 20/40 Coexistence IE */ | |
118 | I2040INTOLCHREPORT = 73, /* 20/40 Intolerant channel report*/ | |
119 | IOBSSSCAN = 74, /* OBSS Scan parameters */ | |
120 | IEXTCAP = 127, /* Extended capability */ | |
121 | IWMM = 221, /* WMM parameters */ | |
122 | IWPAELEMENT = 221, /* WPA Information Element */ | |
123 | INFOELEM_ID_FORCE_32BIT = 0xFFFFFFFF | |
124 | } tenuInfoElemID; | |
125 | ||
126 | ||
127 | typedef struct { | |
576917ad | 128 | char *pcRespBuffer; |
fb4ec9ca CL |
129 | s32 s32MaxRespBuffLen; |
130 | s32 s32BytesRead; | |
72ed4dc7 | 131 | bool bRespRequired; |
c5c77ba1 JK |
132 | } tstrConfigPktInfo; |
133 | ||
134 | ||
135 | ||
136 | /*****************************************************************************/ | |
137 | /* Extern Variable Declarations */ | |
138 | /*****************************************************************************/ | |
139 | ||
c5c77ba1 JK |
140 | /*****************************************************************************/ |
141 | /* Global Variables */ | |
142 | /*****************************************************************************/ | |
c5c77ba1 JK |
143 | /*****************************************************************************/ |
144 | /* Static Function Declarations */ | |
145 | /*****************************************************************************/ | |
146 | ||
147 | ||
148 | ||
149 | /*****************************************************************************/ | |
150 | /* Functions */ | |
151 | /*****************************************************************************/ | |
c5c77ba1 JK |
152 | |
153 | /* This function extracts the beacon period field from the beacon or probe */ | |
154 | /* response frame. */ | |
d85f5326 | 155 | INLINE u16 get_beacon_period(u8 *data) |
c5c77ba1 | 156 | { |
d85f5326 | 157 | u16 bcn_per = 0; |
c5c77ba1 JK |
158 | |
159 | bcn_per = data[0]; | |
160 | bcn_per |= (data[1] << 8); | |
161 | ||
162 | return bcn_per; | |
163 | } | |
164 | ||
4e4467fd | 165 | INLINE u32 get_beacon_timestamp_lo(u8 *data) |
c5c77ba1 | 166 | { |
4e4467fd CL |
167 | u32 time_stamp = 0; |
168 | u32 index = MAC_HDR_LEN; | |
c5c77ba1 JK |
169 | |
170 | time_stamp |= data[index++]; | |
171 | time_stamp |= (data[index++] << 8); | |
172 | time_stamp |= (data[index++] << 16); | |
173 | time_stamp |= (data[index] << 24); | |
174 | ||
175 | return time_stamp; | |
176 | } | |
177 | ||
8a54d917 | 178 | INLINE u32 get_beacon_timestamp_hi(u8 *data) |
c5c77ba1 | 179 | { |
8a54d917 CL |
180 | u32 time_stamp = 0; |
181 | u32 index = (MAC_HDR_LEN + 4); | |
c5c77ba1 JK |
182 | |
183 | time_stamp |= data[index++]; | |
184 | time_stamp |= (data[index++] << 8); | |
185 | time_stamp |= (data[index++] << 16); | |
186 | time_stamp |= (data[index] << 24); | |
187 | ||
188 | return time_stamp; | |
189 | } | |
190 | ||
c5c77ba1 JK |
191 | /* This function extracts the 'frame type and sub type' bits from the MAC */ |
192 | /* header of the input frame. */ | |
193 | /* Returns the value in the LSB of the returned value. */ | |
63d03e47 | 194 | INLINE tenuFrmSubtype get_sub_type(u8 *header) |
c5c77ba1 JK |
195 | { |
196 | return ((tenuFrmSubtype)(header[0] & 0xFC)); | |
197 | } | |
198 | ||
199 | /* This function extracts the 'to ds' bit from the MAC header of the input */ | |
200 | /* frame. */ | |
201 | /* Returns the value in the LSB of the returned value. */ | |
63d03e47 | 202 | INLINE u8 get_to_ds(u8 *header) |
c5c77ba1 JK |
203 | { |
204 | return (header[1] & 0x01); | |
205 | } | |
206 | ||
207 | /* This function extracts the 'from ds' bit from the MAC header of the input */ | |
208 | /* frame. */ | |
209 | /* Returns the value in the LSB of the returned value. */ | |
63d03e47 | 210 | INLINE u8 get_from_ds(u8 *header) |
c5c77ba1 JK |
211 | { |
212 | return ((header[1] & 0x02) >> 1); | |
213 | } | |
214 | ||
215 | /* This function extracts the MAC Address in 'address1' field of the MAC */ | |
216 | /* header and updates the MAC Address in the allocated 'addr' variable. */ | |
63d03e47 | 217 | INLINE void get_address1(u8 *pu8msa, u8 *addr) |
c5c77ba1 | 218 | { |
d00d2ba3 | 219 | memcpy(addr, pu8msa + 4, 6); |
c5c77ba1 JK |
220 | } |
221 | ||
222 | /* This function extracts the MAC Address in 'address2' field of the MAC */ | |
223 | /* header and updates the MAC Address in the allocated 'addr' variable. */ | |
63d03e47 | 224 | INLINE void get_address2(u8 *pu8msa, u8 *addr) |
c5c77ba1 | 225 | { |
d00d2ba3 | 226 | memcpy(addr, pu8msa + 10, 6); |
c5c77ba1 JK |
227 | } |
228 | ||
229 | /* This function extracts the MAC Address in 'address3' field of the MAC */ | |
230 | /* header and updates the MAC Address in the allocated 'addr' variable. */ | |
63d03e47 | 231 | INLINE void get_address3(u8 *pu8msa, u8 *addr) |
c5c77ba1 | 232 | { |
d00d2ba3 | 233 | memcpy(addr, pu8msa + 16, 6); |
c5c77ba1 JK |
234 | } |
235 | ||
236 | /* This function extracts the BSSID from the incoming WLAN packet based on */ | |
237 | /* the 'from ds' bit, and updates the MAC Address in the allocated 'addr' */ | |
238 | /* variable. */ | |
63d03e47 | 239 | INLINE void get_BSSID(u8 *data, u8 *bssid) |
c5c77ba1 JK |
240 | { |
241 | if (get_from_ds(data) == 1) | |
242 | get_address2(data, bssid); | |
243 | else if (get_to_ds(data) == 1) | |
244 | get_address1(data, bssid); | |
245 | else | |
246 | get_address3(data, bssid); | |
247 | } | |
248 | ||
249 | /* This function extracts the SSID from a beacon/probe response frame */ | |
63d03e47 | 250 | INLINE void get_ssid(u8 *data, u8 *ssid, u8 *p_ssid_len) |
c5c77ba1 | 251 | { |
63d03e47 GKH |
252 | u8 len = 0; |
253 | u8 i = 0; | |
254 | u8 j = 0; | |
c5c77ba1 JK |
255 | |
256 | len = data[MAC_HDR_LEN + TIME_STAMP_LEN + BEACON_INTERVAL_LEN + | |
257 | CAP_INFO_LEN + 1]; | |
258 | j = MAC_HDR_LEN + TIME_STAMP_LEN + BEACON_INTERVAL_LEN + | |
259 | CAP_INFO_LEN + 2; | |
260 | ||
261 | /* If the SSID length field is set wrongly to a value greater than the */ | |
262 | /* allowed maximum SSID length limit, reset the length to 0 */ | |
263 | if (len >= MAX_SSID_LEN) | |
264 | len = 0; | |
265 | ||
266 | for (i = 0; i < len; i++, j++) | |
267 | ssid[i] = data[j]; | |
268 | ||
269 | ssid[len] = '\0'; | |
270 | ||
271 | *p_ssid_len = len; | |
272 | } | |
273 | ||
274 | /* This function extracts the capability info field from the beacon or probe */ | |
275 | /* response frame. */ | |
d85f5326 | 276 | INLINE u16 get_cap_info(u8 *data) |
c5c77ba1 | 277 | { |
d85f5326 CL |
278 | u16 cap_info = 0; |
279 | u16 index = MAC_HDR_LEN; | |
ab6ebe3a | 280 | tenuFrmSubtype st; |
c5c77ba1 JK |
281 | |
282 | st = get_sub_type(data); | |
283 | ||
284 | /* Location of the Capability field is different for Beacon and */ | |
285 | /* Association frames. */ | |
286 | if ((st == BEACON) || (st == PROBE_RSP)) | |
287 | index += TIME_STAMP_LEN + BEACON_INTERVAL_LEN; | |
288 | ||
289 | cap_info = data[index]; | |
290 | cap_info |= (data[index + 1] << 8); | |
291 | ||
292 | return cap_info; | |
293 | } | |
294 | ||
295 | /* This function extracts the capability info field from the Association */ | |
296 | /* response frame. */ | |
d85f5326 | 297 | INLINE u16 get_assoc_resp_cap_info(u8 *data) |
c5c77ba1 | 298 | { |
d85f5326 | 299 | u16 cap_info = 0; |
c5c77ba1 JK |
300 | |
301 | cap_info = data[0]; | |
302 | cap_info |= (data[1] << 8); | |
303 | ||
304 | return cap_info; | |
305 | } | |
306 | ||
307 | /* This funcion extracts the association status code from the incoming */ | |
308 | /* association response frame and returns association status code */ | |
d85f5326 | 309 | INLINE u16 get_asoc_status(u8 *data) |
c5c77ba1 | 310 | { |
d85f5326 | 311 | u16 asoc_status = 0; |
c5c77ba1 JK |
312 | |
313 | asoc_status = data[3]; | |
314 | asoc_status = (asoc_status << 8) | data[2]; | |
315 | ||
316 | return asoc_status; | |
317 | } | |
318 | ||
319 | /* This function extracts association ID from the incoming association */ | |
320 | /* response frame */ | |
d85f5326 | 321 | INLINE u16 get_asoc_id(u8 *data) |
c5c77ba1 | 322 | { |
d85f5326 | 323 | u16 asoc_id = 0; |
c5c77ba1 JK |
324 | |
325 | asoc_id = data[4]; | |
326 | asoc_id |= (data[5] << 8); | |
327 | ||
328 | return asoc_id; | |
329 | } | |
330 | ||
331 | /** | |
332 | * @brief initializes the Core Configurator | |
333 | * @details | |
334 | * @return Error code indicating success/failure | |
335 | * @note | |
336 | * @author mabubakr | |
337 | * @date 1 Mar 2012 | |
338 | * @version 1.0 | |
339 | */ | |
340 | ||
fb4ec9ca | 341 | s32 CoreConfiguratorInit(void) |
c5c77ba1 | 342 | { |
fb4ec9ca | 343 | s32 s32Error = WILC_SUCCESS; |
8dfaafd6 | 344 | |
1fad279d | 345 | PRINT_D(CORECONFIG_DBG, "CoreConfiguratorInit()\n"); |
c5c77ba1 | 346 | |
c5c77ba1 JK |
347 | return s32Error; |
348 | } | |
349 | ||
d85f5326 | 350 | u8 *get_tim_elm(u8 *pu8msa, u16 u16RxLen, u16 u16TagParamOffset) |
c5c77ba1 | 351 | { |
d85f5326 | 352 | u16 u16index = 0; |
c5c77ba1 JK |
353 | |
354 | /*************************************************************************/ | |
355 | /* Beacon Frame - Frame Body */ | |
356 | /* --------------------------------------------------------------------- */ | |
357 | /* |Timestamp |BeaconInt |CapInfo |SSID |SupRates |DSParSet |TIM elm | */ | |
358 | /* --------------------------------------------------------------------- */ | |
359 | /* |8 |2 |2 |2-34 |3-10 |3 |4-256 | */ | |
360 | /* --------------------------------------------------------------------- */ | |
361 | /* */ | |
362 | /*************************************************************************/ | |
363 | ||
364 | u16index = u16TagParamOffset; | |
365 | ||
366 | /* Search for the TIM Element Field and return if the element is found */ | |
367 | while (u16index < (u16RxLen - FCS_LEN)) { | |
78174ada | 368 | if (pu8msa[u16index] == ITIM) |
cea3b202 | 369 | return &pu8msa[u16index]; |
78174ada | 370 | else |
c5c77ba1 | 371 | u16index += (IE_HDR_LEN + pu8msa[u16index + 1]); |
c5c77ba1 JK |
372 | } |
373 | ||
0e04f3f3 | 374 | return NULL; |
c5c77ba1 JK |
375 | } |
376 | ||
377 | /* This function gets the current channel information from | |
378 | * the 802.11n beacon/probe response frame */ | |
d85f5326 | 379 | u8 get_current_channel_802_11n(u8 *pu8msa, u16 u16RxLen) |
c5c77ba1 | 380 | { |
d85f5326 | 381 | u16 index; |
c5c77ba1 JK |
382 | |
383 | index = TAG_PARAM_OFFSET; | |
384 | while (index < (u16RxLen - FCS_LEN)) { | |
385 | if (pu8msa[index] == IDSPARMS) | |
cea3b202 | 386 | return pu8msa[index + 2]; |
c5c77ba1 JK |
387 | else |
388 | /* Increment index by length information and header */ | |
389 | index += pu8msa[index + 1] + IE_HDR_LEN; | |
390 | } | |
391 | ||
392 | /* Return current channel information from the MIB, if beacon/probe */ | |
393 | /* response frame does not contain the DS parameter set IE */ | |
394 | /* return (mget_CurrentChannel() + 1); */ | |
395 | return 0; /* no MIB here */ | |
396 | } | |
397 | ||
d85f5326 | 398 | u8 get_current_channel(u8 *pu8msa, u16 u16RxLen) |
c5c77ba1 | 399 | { |
c5c77ba1 JK |
400 | /* Extract current channel information from */ |
401 | /* the beacon/probe response frame */ | |
cea3b202 | 402 | return get_current_channel_802_11n(pu8msa, u16RxLen); |
c5c77ba1 JK |
403 | } |
404 | ||
405 | /** | |
406 | * @brief parses the received 'N' message | |
407 | * @details | |
408 | * @param[in] pu8MsgBuffer The message to be parsed | |
409 | * @param[out] ppstrNetworkInfo pointer to pointer to the structure containing the parsed Network Info | |
410 | * @return Error code indicating success/failure | |
411 | * @note | |
412 | * @author mabubakr | |
413 | * @date 1 Mar 2012 | |
414 | * @version 1.0 | |
415 | */ | |
fb4ec9ca | 416 | s32 ParseNetworkInfo(u8 *pu8MsgBuffer, tstrNetworkInfo **ppstrNetworkInfo) |
c5c77ba1 | 417 | { |
fb4ec9ca | 418 | s32 s32Error = WILC_SUCCESS; |
b1413b60 | 419 | tstrNetworkInfo *pstrNetworkInfo = NULL; |
63d03e47 GKH |
420 | u8 u8MsgType = 0; |
421 | u8 u8MsgID = 0; | |
d85f5326 | 422 | u16 u16MsgLen = 0; |
c5c77ba1 | 423 | |
d85f5326 CL |
424 | u16 u16WidID = (u16)WID_NIL; |
425 | u16 u16WidLen = 0; | |
0e04f3f3 | 426 | u8 *pu8WidVal = NULL; |
c5c77ba1 JK |
427 | |
428 | u8MsgType = pu8MsgBuffer[0]; | |
429 | ||
430 | /* Check whether the received message type is 'N' */ | |
431 | if ('N' != u8MsgType) { | |
432 | PRINT_ER("Received Message format incorrect.\n"); | |
24db713f | 433 | return -EFAULT; |
c5c77ba1 JK |
434 | } |
435 | ||
436 | /* Extract message ID */ | |
437 | u8MsgID = pu8MsgBuffer[1]; | |
438 | ||
439 | /* Extract message Length */ | |
440 | u16MsgLen = MAKE_WORD16(pu8MsgBuffer[2], pu8MsgBuffer[3]); | |
441 | ||
442 | /* Extract WID ID */ | |
443 | u16WidID = MAKE_WORD16(pu8MsgBuffer[4], pu8MsgBuffer[5]); | |
444 | ||
445 | /* Extract WID Length */ | |
446 | u16WidLen = MAKE_WORD16(pu8MsgBuffer[6], pu8MsgBuffer[7]); | |
447 | ||
448 | /* Assign a pointer to the WID value */ | |
449 | pu8WidVal = &pu8MsgBuffer[8]; | |
450 | ||
451 | /* parse the WID value of the WID "WID_NEWORK_INFO" */ | |
452 | { | |
0e04f3f3 | 453 | u8 *pu8msa = NULL; |
d85f5326 | 454 | u16 u16RxLen = 0; |
0e04f3f3 RH |
455 | u8 *pu8TimElm = NULL; |
456 | u8 *pu8IEs = NULL; | |
d85f5326 | 457 | u16 u16IEsLen = 0; |
63d03e47 | 458 | u8 u8index = 0; |
4e4467fd CL |
459 | u32 u32Tsf_Lo; |
460 | u32 u32Tsf_Hi; | |
c5c77ba1 | 461 | |
0ac87998 | 462 | pstrNetworkInfo = kmalloc(sizeof(tstrNetworkInfo), GFP_KERNEL); |
a78d9a38 CL |
463 | if (!pstrNetworkInfo) |
464 | return -ENOMEM; | |
465 | ||
2cc46837 | 466 | memset((void *)(pstrNetworkInfo), 0, sizeof(tstrNetworkInfo)); |
c5c77ba1 JK |
467 | |
468 | pstrNetworkInfo->s8rssi = pu8WidVal[0]; | |
469 | ||
470 | /* Assign a pointer to msa "Mac Header Start Address" */ | |
471 | pu8msa = &pu8WidVal[1]; | |
472 | ||
473 | u16RxLen = u16WidLen - 1; | |
474 | ||
475 | /* parse msa*/ | |
476 | ||
477 | /* Get the cap_info */ | |
478 | pstrNetworkInfo->u16CapInfo = get_cap_info(pu8msa); | |
479 | #ifdef WILC_P2P | |
480 | /* Get time-stamp [Low only 32 bit] */ | |
481 | pstrNetworkInfo->u32Tsf = get_beacon_timestamp_lo(pu8msa); | |
482 | PRINT_D(CORECONFIG_DBG, "TSF :%x\n", pstrNetworkInfo->u32Tsf); | |
483 | #endif | |
484 | ||
485 | /* Get full time-stamp [Low and High 64 bit] */ | |
486 | u32Tsf_Lo = get_beacon_timestamp_lo(pu8msa); | |
487 | u32Tsf_Hi = get_beacon_timestamp_hi(pu8msa); | |
488 | ||
57b298f5 | 489 | pstrNetworkInfo->u64Tsf = u32Tsf_Lo | ((u64)u32Tsf_Hi << 32); |
c5c77ba1 JK |
490 | |
491 | /* Get SSID */ | |
492 | get_ssid(pu8msa, pstrNetworkInfo->au8ssid, &(pstrNetworkInfo->u8SsidLen)); | |
493 | ||
494 | /* Get BSSID */ | |
495 | get_BSSID(pu8msa, pstrNetworkInfo->au8bssid); | |
496 | ||
497 | /* Get the current channel */ | |
498 | pstrNetworkInfo->u8channel = get_current_channel(pu8msa, (u16RxLen + FCS_LEN)); | |
499 | ||
500 | /* Get beacon period */ | |
501 | u8index = (MAC_HDR_LEN + TIME_STAMP_LEN); | |
502 | ||
503 | pstrNetworkInfo->u16BeaconPeriod = get_beacon_period(pu8msa + u8index); | |
504 | ||
505 | u8index += BEACON_INTERVAL_LEN + CAP_INFO_LEN; | |
506 | ||
507 | /* Get DTIM Period */ | |
508 | pu8TimElm = get_tim_elm(pu8msa, (u16RxLen + FCS_LEN), u8index); | |
0e04f3f3 | 509 | if (pu8TimElm != NULL) |
c5c77ba1 | 510 | pstrNetworkInfo->u8DtimPeriod = pu8TimElm[3]; |
c5c77ba1 JK |
511 | pu8IEs = &pu8msa[MAC_HDR_LEN + TIME_STAMP_LEN + BEACON_INTERVAL_LEN + CAP_INFO_LEN]; |
512 | u16IEsLen = u16RxLen - (MAC_HDR_LEN + TIME_STAMP_LEN + BEACON_INTERVAL_LEN + CAP_INFO_LEN); | |
513 | ||
514 | if (u16IEsLen > 0) { | |
0ac87998 | 515 | pstrNetworkInfo->pu8IEs = kmalloc(u16IEsLen, GFP_KERNEL); |
a78d9a38 CL |
516 | if (!pstrNetworkInfo->pu8IEs) |
517 | return -ENOMEM; | |
518 | ||
2cc46837 | 519 | memset((void *)(pstrNetworkInfo->pu8IEs), 0, u16IEsLen); |
c5c77ba1 | 520 | |
d00d2ba3 | 521 | memcpy(pstrNetworkInfo->pu8IEs, pu8IEs, u16IEsLen); |
c5c77ba1 JK |
522 | } |
523 | pstrNetworkInfo->u16IEsLen = u16IEsLen; | |
524 | ||
525 | } | |
526 | ||
527 | *ppstrNetworkInfo = pstrNetworkInfo; | |
528 | ||
c5c77ba1 JK |
529 | return s32Error; |
530 | } | |
531 | ||
532 | /** | |
533 | * @brief Deallocates the parsed Network Info | |
534 | * @details | |
535 | * @param[in] pstrNetworkInfo Network Info to be deallocated | |
536 | * @return Error code indicating success/failure | |
537 | * @note | |
538 | * @author mabubakr | |
539 | * @date 1 Mar 2012 | |
540 | * @version 1.0 | |
541 | */ | |
fb4ec9ca | 542 | s32 DeallocateNetworkInfo(tstrNetworkInfo *pstrNetworkInfo) |
c5c77ba1 | 543 | { |
fb4ec9ca | 544 | s32 s32Error = WILC_SUCCESS; |
c5c77ba1 | 545 | |
b1413b60 GKH |
546 | if (pstrNetworkInfo != NULL) { |
547 | if (pstrNetworkInfo->pu8IEs != NULL) { | |
49188af2 | 548 | kfree(pstrNetworkInfo->pu8IEs); |
b1413b60 | 549 | pstrNetworkInfo->pu8IEs = NULL; |
c5c77ba1 JK |
550 | } else { |
551 | s32Error = WILC_FAIL; | |
552 | } | |
553 | ||
49188af2 | 554 | kfree(pstrNetworkInfo); |
b1413b60 | 555 | pstrNetworkInfo = NULL; |
c5c77ba1 JK |
556 | |
557 | } else { | |
558 | s32Error = WILC_FAIL; | |
559 | } | |
560 | ||
561 | return s32Error; | |
562 | } | |
563 | ||
564 | /** | |
565 | * @brief parses the received Association Response frame | |
566 | * @details | |
567 | * @param[in] pu8Buffer The Association Response frame to be parsed | |
568 | * @param[out] ppstrConnectRespInfo pointer to pointer to the structure containing the parsed Association Response Info | |
569 | * @return Error code indicating success/failure | |
570 | * @note | |
571 | * @author mabubakr | |
572 | * @date 2 Apr 2012 | |
573 | * @version 1.0 | |
574 | */ | |
fb4ec9ca | 575 | s32 ParseAssocRespInfo(u8 *pu8Buffer, u32 u32BufferLen, |
c5c77ba1 JK |
576 | tstrConnectRespInfo **ppstrConnectRespInfo) |
577 | { | |
fb4ec9ca | 578 | s32 s32Error = WILC_SUCCESS; |
b1413b60 | 579 | tstrConnectRespInfo *pstrConnectRespInfo = NULL; |
d85f5326 | 580 | u16 u16AssocRespLen = 0; |
0e04f3f3 | 581 | u8 *pu8IEs = NULL; |
d85f5326 | 582 | u16 u16IEsLen = 0; |
c5c77ba1 | 583 | |
0ac87998 | 584 | pstrConnectRespInfo = kmalloc(sizeof(tstrConnectRespInfo), GFP_KERNEL); |
a78d9a38 CL |
585 | if (!pstrConnectRespInfo) |
586 | return -ENOMEM; | |
587 | ||
2cc46837 | 588 | memset((void *)(pstrConnectRespInfo), 0, sizeof(tstrConnectRespInfo)); |
c5c77ba1 JK |
589 | |
590 | /* u16AssocRespLen = pu8Buffer[0]; */ | |
d85f5326 | 591 | u16AssocRespLen = (u16)u32BufferLen; |
c5c77ba1 JK |
592 | |
593 | /* get the status code */ | |
594 | pstrConnectRespInfo->u16ConnectStatus = get_asoc_status(pu8Buffer); | |
595 | if (pstrConnectRespInfo->u16ConnectStatus == SUCCESSFUL_STATUSCODE) { | |
596 | ||
597 | /* get the capability */ | |
598 | pstrConnectRespInfo->u16capability = get_assoc_resp_cap_info(pu8Buffer); | |
599 | ||
600 | /* get the Association ID */ | |
601 | pstrConnectRespInfo->u16AssocID = get_asoc_id(pu8Buffer); | |
602 | ||
603 | /* get the Information Elements */ | |
604 | pu8IEs = &pu8Buffer[CAP_INFO_LEN + STATUS_CODE_LEN + AID_LEN]; | |
605 | u16IEsLen = u16AssocRespLen - (CAP_INFO_LEN + STATUS_CODE_LEN + AID_LEN); | |
606 | ||
0ac87998 | 607 | pstrConnectRespInfo->pu8RespIEs = kmalloc(u16IEsLen, GFP_KERNEL); |
a78d9a38 CL |
608 | if (!pstrConnectRespInfo->pu8RespIEs) |
609 | return -ENOMEM; | |
610 | ||
2cc46837 | 611 | memset((void *)(pstrConnectRespInfo->pu8RespIEs), 0, u16IEsLen); |
c5c77ba1 | 612 | |
d00d2ba3 | 613 | memcpy(pstrConnectRespInfo->pu8RespIEs, pu8IEs, u16IEsLen); |
c5c77ba1 JK |
614 | pstrConnectRespInfo->u16RespIEsLen = u16IEsLen; |
615 | } | |
616 | ||
617 | *ppstrConnectRespInfo = pstrConnectRespInfo; | |
618 | ||
619 | ||
620 | return s32Error; | |
621 | } | |
622 | ||
623 | /** | |
624 | * @brief Deallocates the parsed Association Response Info | |
625 | * @details | |
626 | * @param[in] pstrNetworkInfo Network Info to be deallocated | |
627 | * @return Error code indicating success/failure | |
628 | * @note | |
629 | * @author mabubakr | |
630 | * @date 2 Apr 2012 | |
631 | * @version 1.0 | |
632 | */ | |
fb4ec9ca | 633 | s32 DeallocateAssocRespInfo(tstrConnectRespInfo *pstrConnectRespInfo) |
c5c77ba1 | 634 | { |
fb4ec9ca | 635 | s32 s32Error = WILC_SUCCESS; |
c5c77ba1 | 636 | |
b1413b60 GKH |
637 | if (pstrConnectRespInfo != NULL) { |
638 | if (pstrConnectRespInfo->pu8RespIEs != NULL) { | |
49188af2 | 639 | kfree(pstrConnectRespInfo->pu8RespIEs); |
b1413b60 | 640 | pstrConnectRespInfo->pu8RespIEs = NULL; |
c5c77ba1 JK |
641 | } else { |
642 | s32Error = WILC_FAIL; | |
643 | } | |
644 | ||
49188af2 | 645 | kfree(pstrConnectRespInfo); |
b1413b60 | 646 | pstrConnectRespInfo = NULL; |
c5c77ba1 JK |
647 | |
648 | } else { | |
649 | s32Error = WILC_FAIL; | |
650 | } | |
651 | ||
652 | return s32Error; | |
653 | } | |
654 | ||
655 | #ifndef CONNECT_DIRECT | |
fb4ec9ca | 656 | s32 ParseSurveyResults(u8 ppu8RcvdSiteSurveyResults[][MAX_SURVEY_RESULT_FRAG_SIZE], |
c5c77ba1 | 657 | wid_site_survey_reslts_s **ppstrSurveyResults, |
4e4467fd | 658 | u32 *pu32SurveyResultsCount) |
c5c77ba1 | 659 | { |
fb4ec9ca | 660 | s32 s32Error = WILC_SUCCESS; |
c5c77ba1 | 661 | wid_site_survey_reslts_s *pstrSurveyResults = NULL; |
4e4467fd CL |
662 | u32 u32SurveyResultsCount = 0; |
663 | u32 u32SurveyBytesLength = 0; | |
63d03e47 | 664 | u8 *pu8BufferPtr; |
4e4467fd | 665 | u32 u32RcvdSurveyResultsNum = 2; |
63d03e47 | 666 | u8 u8ReadSurveyResFragNum; |
4e4467fd CL |
667 | u32 i; |
668 | u32 j; | |
c5c77ba1 JK |
669 | |
670 | for (i = 0; i < u32RcvdSurveyResultsNum; i++) { | |
671 | u32SurveyBytesLength = ppu8RcvdSiteSurveyResults[i][0]; | |
672 | ||
673 | ||
674 | for (j = 0; j < u32SurveyBytesLength; j += SURVEY_RESULT_LENGTH) { | |
675 | u32SurveyResultsCount++; | |
676 | } | |
677 | } | |
678 | ||
0ac87998 CL |
679 | pstrSurveyResults = kmalloc_array(u32SurveyResultsCount, |
680 | sizeof(wid_site_survey_reslts_s), GFP_KERNEL); | |
a78d9a38 CL |
681 | if (!pstrSurveyResults) |
682 | return -ENOMEM; | |
c5c77ba1 | 683 | |
2cc46837 | 684 | memset((void *)(pstrSurveyResults), 0, u32SurveyResultsCount * sizeof(wid_site_survey_reslts_s)); |
c5c77ba1 JK |
685 | |
686 | u32SurveyResultsCount = 0; | |
687 | ||
688 | for (i = 0; i < u32RcvdSurveyResultsNum; i++) { | |
689 | pu8BufferPtr = ppu8RcvdSiteSurveyResults[i]; | |
690 | ||
691 | u32SurveyBytesLength = pu8BufferPtr[0]; | |
692 | ||
693 | /* TODO: mostafa: pu8BufferPtr[1] contains the fragment num */ | |
694 | u8ReadSurveyResFragNum = pu8BufferPtr[1]; | |
695 | ||
696 | pu8BufferPtr += 2; | |
697 | ||
698 | for (j = 0; j < u32SurveyBytesLength; j += SURVEY_RESULT_LENGTH) { | |
d00d2ba3 | 699 | memcpy(&pstrSurveyResults[u32SurveyResultsCount], pu8BufferPtr, SURVEY_RESULT_LENGTH); |
c5c77ba1 JK |
700 | pu8BufferPtr += SURVEY_RESULT_LENGTH; |
701 | u32SurveyResultsCount++; | |
702 | } | |
703 | } | |
704 | ||
705 | ERRORHANDLER: | |
706 | *ppstrSurveyResults = pstrSurveyResults; | |
707 | *pu32SurveyResultsCount = u32SurveyResultsCount; | |
708 | ||
709 | return s32Error; | |
710 | } | |
711 | ||
712 | ||
fb4ec9ca | 713 | s32 DeallocateSurveyResults(wid_site_survey_reslts_s *pstrSurveyResults) |
c5c77ba1 | 714 | { |
fb4ec9ca | 715 | s32 s32Error = WILC_SUCCESS; |
c5c77ba1 | 716 | |
b1413b60 | 717 | if (pstrSurveyResults != NULL) { |
49188af2 | 718 | kfree(pstrSurveyResults); |
c5c77ba1 JK |
719 | } |
720 | ||
721 | return s32Error; | |
722 | } | |
723 | #endif | |
724 | ||
c5c77ba1 JK |
725 | /** |
726 | * @brief Deinitializes the Core Configurator | |
727 | * @details | |
728 | * @return Error code indicating success/failure | |
729 | * @note | |
730 | * @author mabubakr | |
731 | * @date 1 Mar 2012 | |
732 | * @version 1.0 | |
733 | */ | |
734 | ||
fb4ec9ca | 735 | s32 CoreConfiguratorDeInit(void) |
c5c77ba1 | 736 | { |
fb4ec9ca | 737 | s32 s32Error = WILC_SUCCESS; |
c5c77ba1 | 738 | |
1fad279d | 739 | PRINT_D(CORECONFIG_DBG, "CoreConfiguratorDeInit()\n"); |
c5c77ba1 | 740 | |
c5c77ba1 JK |
741 | |
742 | return s32Error; | |
743 | } | |
744 | ||
c5c77ba1 JK |
745 | /*Using the global handle of the driver*/ |
746 | extern wilc_wlan_oup_t *gpstrWlanOps; | |
747 | /** | |
748 | * @brief sends certain Configuration Packet based on the input WIDs pstrWIDs | |
749 | * using driver config layer | |
750 | * | |
751 | * @details | |
752 | * @param[in] pstrWIDs WIDs to be sent in the configuration packet | |
753 | * @param[in] u32WIDsCount number of WIDs to be sent in the configuration packet | |
754 | * @param[out] pu8RxResp The received Packet Response | |
755 | * @param[out] ps32RxRespLen Length of the received Packet Response | |
756 | * @return Error code indicating success/failure | |
757 | * @note | |
758 | * @author mabubakr | |
759 | * @date 1 Mar 2012 | |
760 | * @version 1.0 | |
761 | */ | |
fb4ec9ca | 762 | s32 SendConfigPkt(u8 u8Mode, tstrWID *pstrWIDs, |
72ed4dc7 | 763 | u32 u32WIDsCount, bool bRespRequired, u32 drvHandler) |
c5c77ba1 | 764 | { |
fb4ec9ca | 765 | s32 counter = 0, ret = 0; |
8dfaafd6 | 766 | |
c5c77ba1 JK |
767 | if (gpstrWlanOps == NULL) { |
768 | PRINT_D(CORECONFIG_DBG, "Net Dev is still not initialized\n"); | |
769 | return 1; | |
770 | } else { | |
771 | PRINT_D(CORECONFIG_DBG, "Net Dev is initialized\n"); | |
772 | } | |
773 | if (gpstrWlanOps->wlan_cfg_set == NULL || | |
774 | gpstrWlanOps->wlan_cfg_get == NULL) { | |
775 | PRINT_D(CORECONFIG_DBG, "Set and Get is still not initialized\n"); | |
776 | return 1; | |
777 | } else { | |
778 | PRINT_D(CORECONFIG_DBG, "SET is initialized\n"); | |
779 | } | |
780 | if (u8Mode == GET_CFG) { | |
781 | for (counter = 0; counter < u32WIDsCount; counter++) { | |
782 | PRINT_INFO(CORECONFIG_DBG, "Sending CFG packet [%d][%d]\n", !counter, | |
783 | (counter == u32WIDsCount - 1)); | |
784 | if (!gpstrWlanOps->wlan_cfg_get(!counter, | |
785 | pstrWIDs[counter].u16WIDid, | |
786 | (counter == u32WIDsCount - 1), drvHandler)) { | |
787 | ret = -1; | |
788 | printk("[Sendconfigpkt]Get Timed out\n"); | |
789 | break; | |
790 | } | |
791 | } | |
792 | /** | |
793 | * get the value | |
794 | **/ | |
c5c77ba1 JK |
795 | counter = 0; |
796 | for (counter = 0; counter < u32WIDsCount; counter++) { | |
797 | pstrWIDs[counter].s32ValueSize = gpstrWlanOps->wlan_cfg_get_value( | |
798 | pstrWIDs[counter].u16WIDid, | |
799 | pstrWIDs[counter].ps8WidVal, pstrWIDs[counter].s32ValueSize); | |
800 | ||
801 | } | |
802 | } else if (u8Mode == SET_CFG) { | |
803 | for (counter = 0; counter < u32WIDsCount; counter++) { | |
804 | PRINT_D(CORECONFIG_DBG, "Sending config SET PACKET WID:%x\n", pstrWIDs[counter].u16WIDid); | |
805 | if (!gpstrWlanOps->wlan_cfg_set(!counter, | |
806 | pstrWIDs[counter].u16WIDid, pstrWIDs[counter].ps8WidVal, | |
807 | pstrWIDs[counter].s32ValueSize, | |
808 | (counter == u32WIDsCount - 1), drvHandler)) { | |
809 | ret = -1; | |
810 | printk("[Sendconfigpkt]Set Timed out\n"); | |
811 | break; | |
812 | } | |
813 | } | |
814 | } | |
815 | ||
816 | return ret; | |
817 | } |