b8e898e2b99724d788f780e249548c0887564943
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rockchip_wlan / combo_mt66xx / mt6620 / wlan / mgmt / p2p_scan.c
1 /*
2 ** $Id: @(#) p2p_scan.c@@
3 */
4
5 /*! \file   "p2p_scan.c"
6     \brief  This file defines the p2p scan profile and the processing function of
7             scan result for SCAN Module.
8
9     The SCAN Profile selection is part of SCAN MODULE and responsible for defining
10     SCAN Parameters - e.g. MIN_CHANNEL_TIME, number of scan channels.
11     In this file we also define the process of SCAN Result including adding, searching
12     and removing SCAN record from the list.
13 */
14
15
16
17
18
19 /*******************************************************************************
20 *                         C O M P I L E R   F L A G S
21 ********************************************************************************
22 */
23
24 /*******************************************************************************
25 *                    E X T E R N A L   R E F E R E N C E S
26 ********************************************************************************
27 */
28
29 #include "precomp.h"
30
31 /*******************************************************************************
32 *                              C O N S T A N T S
33 ********************************************************************************
34 */
35
36 /*******************************************************************************
37 *                             D A T A   T Y P E S
38 ********************************************************************************
39 */
40
41 /*******************************************************************************
42 *                            P U B L I C   D A T A
43 ********************************************************************************
44 */
45
46 /*******************************************************************************
47 *                           P R I V A T E   D A T A
48 ********************************************************************************
49 */
50
51 /*******************************************************************************
52 *                                 M A C R O S
53 ********************************************************************************
54 */
55
56 /*******************************************************************************
57 *                   F U N C T I O N   D E C L A R A T I O N S
58 ********************************************************************************
59 */
60
61 /*******************************************************************************
62 *                              F U N C T I O N S
63 ********************************************************************************
64 */
65
66 P_P2P_DEVICE_DESC_T
67 scanSearchTargetP2pDesc (
68     IN P_ADAPTER_T prAdapter,
69     IN UINT_8 aucDeviceID[],
70     IN PP_BSS_DESC_T pprBssDesc
71     )
72 {
73
74     P_P2P_DEVICE_DESC_T prTargetP2pDesc = (P_P2P_DEVICE_DESC_T)NULL;
75     P_SCAN_INFO_T prScanInfo = (P_SCAN_INFO_T)NULL;
76     P_LINK_T prBSSDescList;
77     P_BSS_DESC_T prBssDesc = (P_BSS_DESC_T)NULL;
78
79
80     ASSERT(prAdapter);
81     ASSERT(aucDeviceID);
82
83     prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
84     prBSSDescList = &prScanInfo->rBSSDescList;
85
86     //4 <1> The outer loop to search for a candidate.
87     LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) {
88
89         /* Loop for each prBssDesc */
90         prTargetP2pDesc = scanFindP2pDeviceDesc(prAdapter,
91                                                 prBssDesc,
92                                                 aucDeviceID,
93                                                 TRUE,
94                                                 FALSE);
95
96         if (prTargetP2pDesc != NULL) {
97             break;
98         }
99     }
100
101     if ((pprBssDesc) && (prTargetP2pDesc != NULL)) {
102         /* Only valid if prTargetP2pDesc is not NULL. */
103         *pprBssDesc = prBssDesc;
104     }
105
106     return prTargetP2pDesc;
107 } /* scanSearchTargetP2pDesc */
108
109
110
111
112 VOID
113 scanInvalidAllP2pClientDevice (
114     IN P_ADAPTER_T prAdapter,
115     IN P_BSS_DESC_T prBssDesc
116     )
117 {
118     P_LINK_ENTRY_T prLinkEntry = (P_LINK_ENTRY_T)NULL;
119     P_P2P_DEVICE_DESC_T prTargetDesc = (P_P2P_DEVICE_DESC_T)NULL;
120
121     LINK_FOR_EACH(prLinkEntry, &prBssDesc->rP2pDeviceList) {
122         prTargetDesc = LINK_ENTRY(prLinkEntry, P2P_DEVICE_DESC_T, rLinkEntry);
123
124         if (prTargetDesc->fgDevInfoValid) {
125             prTargetDesc->fgDevInfoValid = FALSE;
126         }
127     }
128
129     return;
130 } /* scanRenewP2pClientDevice */
131
132 VOID
133 scanRemoveInvalidP2pClientDevice (
134     IN P_ADAPTER_T prAdapter,
135     IN P_BSS_DESC_T prBssDesc
136     )
137 {
138     P_LINK_ENTRY_T prLinkEntry = (P_LINK_ENTRY_T)NULL, prNexEntry = (P_LINK_ENTRY_T)NULL;
139     P_P2P_DEVICE_DESC_T prTargetDesc = (P_P2P_DEVICE_DESC_T)NULL;
140     P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T)NULL;
141
142     prP2pConnSettings = prAdapter->rWifiVar.prP2PConnSettings;
143
144     LINK_FOR_EACH_SAFE(prLinkEntry, prNexEntry, &prBssDesc->rP2pDeviceList) {
145         prTargetDesc = LINK_ENTRY(prLinkEntry, P2P_DEVICE_DESC_T, rLinkEntry);
146
147         if (!prTargetDesc->fgDevInfoValid) {
148             LINK_REMOVE_KNOWN_ENTRY(&prBssDesc->rP2pDeviceList, prLinkEntry);
149             if ((prP2pConnSettings) &&
150                     (prP2pConnSettings->prTargetP2pDesc == prTargetDesc)) {
151                 prP2pConnSettings->prTargetP2pDesc = NULL;
152             }
153             kalMemFree(prTargetDesc, VIR_MEM_TYPE, sizeof(P2P_DEVICE_DESC_T));
154         }
155     }
156
157     return;
158 } /* scanRenewP2pClientDevice */
159
160
161
162 P_P2P_DEVICE_DESC_T
163 scanFindP2pDeviceDesc (
164     IN P_ADAPTER_T prAdapter,
165     IN P_BSS_DESC_T prBssDesc,
166     IN UINT_8 aucMacAddr[],
167     IN BOOLEAN fgIsDeviceAddr,
168     IN BOOLEAN fgAddIfNoFound
169     )
170 {
171
172     P_P2P_DEVICE_DESC_T prTargetDesc = (P_P2P_DEVICE_DESC_T)NULL;
173     P_LINK_ENTRY_T prLinkEntry = (P_LINK_ENTRY_T)NULL;
174
175     do {
176         ASSERT_BREAK((prAdapter != NULL) &&
177                                         (prBssDesc != NULL) &&
178                                         (aucMacAddr != NULL));
179
180         LINK_FOR_EACH(prLinkEntry, &prBssDesc->rP2pDeviceList) {
181             prTargetDesc = LINK_ENTRY(prLinkEntry, P2P_DEVICE_DESC_T, rLinkEntry);
182
183             if (fgIsDeviceAddr) {
184                 if (EQUAL_MAC_ADDR(prTargetDesc->aucDeviceAddr, aucMacAddr)) {
185                     break;
186                 }
187             }
188             else {
189                 if (EQUAL_MAC_ADDR(prTargetDesc->aucInterfaceAddr, aucMacAddr)) {
190                     break;
191                 }
192             }
193
194             prTargetDesc = NULL;
195         }
196
197         if ((fgAddIfNoFound) && (prTargetDesc == NULL)) {
198             /* Target Not Found. */
199             // TODO: Use memory pool in the future.
200             prTargetDesc = kalMemAlloc(sizeof(P2P_DEVICE_DESC_T), VIR_MEM_TYPE);
201
202             if (prTargetDesc) {
203                 kalMemZero(prTargetDesc, sizeof(P2P_DEVICE_DESC_T));
204                 LINK_ENTRY_INITIALIZE(&(prTargetDesc->rLinkEntry));
205                 COPY_MAC_ADDR(prTargetDesc->aucDeviceAddr, aucMacAddr);
206                 LINK_INSERT_TAIL(&prBssDesc->rP2pDeviceList, &prTargetDesc->rLinkEntry);
207                 prTargetDesc->fgDevInfoValid = TRUE;
208             }
209             else {
210                 ASSERT(FALSE);
211             }
212         }
213
214     } while (FALSE);
215
216     return prTargetDesc;
217 } /* scanFindP2pDeviceDesc */
218
219
220 P_P2P_DEVICE_DESC_T
221 scanGetP2pDeviceDesc (
222     IN P_ADAPTER_T prAdapter,
223     IN P_BSS_DESC_T prBssDesc
224     )
225 {
226
227     P_P2P_DEVICE_DESC_T prTargetDesc = (P_P2P_DEVICE_DESC_T)NULL;
228
229     ASSERT(prAdapter);
230     ASSERT(prBssDesc);
231
232     if (prBssDesc->prP2pDesc == NULL) {
233
234         prTargetDesc = kalMemAlloc(sizeof(P2P_DEVICE_DESC_T), VIR_MEM_TYPE);
235
236         if (prTargetDesc) {
237             kalMemZero(prTargetDesc, sizeof(P2P_DEVICE_DESC_T));
238             LINK_ENTRY_INITIALIZE(&(prTargetDesc->rLinkEntry));
239             LINK_INSERT_TAIL(&prBssDesc->rP2pDeviceList, &prTargetDesc->rLinkEntry);
240             prTargetDesc->fgDevInfoValid = TRUE;
241             prBssDesc->prP2pDesc = prTargetDesc;
242             /* We are not sure the SrcAddr is Device Address or Interface Address. */
243             COPY_MAC_ADDR(prTargetDesc->aucDeviceAddr, prBssDesc->aucSrcAddr);
244             COPY_MAC_ADDR(prTargetDesc->aucInterfaceAddr, prBssDesc->aucSrcAddr);
245         }
246         else {
247
248             ASSERT(FALSE);
249         }
250     }
251     else {
252         prTargetDesc = prBssDesc->prP2pDesc;
253     }
254
255
256     return prTargetDesc;
257
258 } /* scanFindP2pDeviceDesc */
259
260
261 #if 0
262 /*----------------------------------------------------------------------------*/
263 /*!
264 * @brief Convert the Beacon or ProbeResp Frame in SW_RFB_T to Event Packet
265 *
266 * @param[in] prSwRfb            Pointer to the receiving SW_RFB_T structure.
267 *
268 * @retval WLAN_STATUS_SUCCESS   It is a valid Scan Result and been sent to the host.
269 * @retval WLAN_STATUS_FAILURE   It is not a valid Scan Result.
270 */
271 /*----------------------------------------------------------------------------*/
272 BOOLEAN
273 scanUpdateP2pDeviceDesc (
274     IN P_ADAPTER_T prAdapter,
275     IN P_BSS_DESC_T prBssDesc
276     )
277 {
278     P_P2P_DEVICE_DESC_T prP2pDesc = (P_P2P_DEVICE_DESC_T)NULL;
279     P_P2P_ATTRIBUTE_T prP2pAttribute = (P_P2P_ATTRIBUTE_T)NULL;
280     UINT_16 u2AttributeLen = 0;
281     UINT_32 u4Idx = 0;
282     BOOLEAN fgUpdateDevInfo = FALSE;
283
284     P_DEVICE_NAME_TLV_T prP2pDevName = (P_DEVICE_NAME_TLV_T)NULL;
285     P_P2P_ATTRI_GROUP_INFO_T prP2pAttriGroupInfo = (P_P2P_ATTRI_GROUP_INFO_T)NULL;
286
287     ASSERT(prAdapter);
288
289     prP2pDesc = scanGetP2pDeviceDesc(prAdapter, prBssDesc);
290
291     if (!prP2pDesc) {
292         ASSERT(FALSE);
293         return fgUpdateDevInfo;
294     }
295
296     p2pGetP2PAttriList(prAdapter, prBssDesc->aucIEBuf, prBssDesc->u2IELength, (PPUINT_8)&prP2pAttribute, &u2AttributeLen);
297
298     while (u2AttributeLen >= P2P_ATTRI_HDR_LEN) {
299         switch (prP2pAttribute->ucId) {
300             case P2P_ATTRI_ID_P2P_CAPABILITY: /* Beacon, Probe Response */
301                 {
302                     P_P2P_ATTRI_CAPABILITY_T prP2pAttriCapability = (P_P2P_ATTRI_CAPABILITY_T)NULL;
303
304                     prP2pAttriCapability = (P_P2P_ATTRI_CAPABILITY_T)prP2pAttribute;
305                     ASSERT(prP2pAttriCapability->u2Length == 2);
306
307                     prP2pDesc->ucDeviceCapabilityBitmap = prP2pAttriCapability->ucDeviceCap;
308                     prP2pDesc->ucGroupCapabilityBitmap = prP2pAttriCapability->ucGroupCap;
309                 }
310                 break;
311             case P2P_ATTRI_ID_P2P_DEV_ID:  /* Beacon */
312                 {
313                     P_P2P_ATTRI_DEV_ID_T prP2pAttriDevID = (P_P2P_ATTRI_DEV_ID_T)NULL;
314
315                     prP2pAttriDevID = (P_P2P_ATTRI_DEV_ID_T)prP2pAttribute;
316                     ASSERT(prP2pAttriDevID->u2Length == P2P_ATTRI_MAX_LEN_P2P_DEV_ID);
317
318                     kalMemCopy(prP2pDesc->aucDeviceAddr, prP2pAttriDevID->aucDevAddr, MAC_ADDR_LEN);
319                 }
320                 break;
321             case P2P_ATTRI_ID_P2P_DEV_INFO:  /* Probe Response */
322                 {
323                     P_P2P_ATTRI_DEV_INFO_T prP2pAttriDevInfo = (P_P2P_ATTRI_DEV_INFO_T)NULL;
324                     P_P2P_DEVICE_TYPE_T prP2pDevType = (P_P2P_DEVICE_TYPE_T)NULL;
325                     UINT_16 u2NameLen = 0, u2Id = 0;
326
327                     fgUpdateDevInfo = TRUE;
328
329                     prP2pAttriDevInfo = (P_P2P_ATTRI_DEV_INFO_T)prP2pAttribute;
330
331                     kalMemCopy(prP2pDesc->aucDeviceAddr, prP2pAttriDevInfo->aucDevAddr, MAC_ADDR_LEN);
332
333                     WLAN_GET_FIELD_BE16(&prP2pAttriDevInfo->u2ConfigMethodsBE, &prP2pDesc->u2ConfigMethod);
334
335                     prP2pDevType = &prP2pDesc->rPriDevType;
336                     WLAN_GET_FIELD_BE16(&prP2pAttriDevInfo->rPrimaryDevTypeBE.u2CategoryId, &prP2pDevType->u2CategoryID);
337                     WLAN_GET_FIELD_BE16(&prP2pAttriDevInfo->rPrimaryDevTypeBE.u2SubCategoryId, &prP2pDevType->u2SubCategoryID);
338
339                     ASSERT(prP2pAttriDevInfo->ucNumOfSecondaryDevType <= P2P_GC_MAX_CACHED_SEC_DEV_TYPE_COUNT);  // TODO: Fixme if secondary device type is more than 2.
340                     prP2pDesc->ucSecDevTypeNum = 0;
341                     for (u4Idx = 0; u4Idx < prP2pAttriDevInfo->ucNumOfSecondaryDevType; u4Idx++) {
342                         if (u4Idx < P2P_GC_MAX_CACHED_SEC_DEV_TYPE_COUNT) {
343                             prP2pDevType = &(prP2pDesc->arSecDevType[u4Idx]);
344                             WLAN_GET_FIELD_BE16(&prP2pAttriDevInfo->arSecondaryDevTypeListBE[u4Idx].u2CategoryId, &prP2pDevType->u2CategoryID);
345                             WLAN_GET_FIELD_BE16(&prP2pAttriDevInfo->arSecondaryDevTypeListBE[u4Idx].u2SubCategoryId, &prP2pDevType->u2SubCategoryID);
346                             prP2pDesc->ucSecDevTypeNum++;
347                         }
348
349                     }
350                     prP2pDevName = (P_DEVICE_NAME_TLV_T)((PUINT_8)prP2pAttriDevInfo->arSecondaryDevTypeListBE + (u4Idx * sizeof(DEVICE_TYPE_T)));
351                     WLAN_GET_FIELD_BE16(&prP2pDevName->u2Length, &u2NameLen);
352                     WLAN_GET_FIELD_BE16(&prP2pDevName->u2Id, &u2Id);
353                     ASSERT(u2Id == WPS_ATTRI_ID_DEVICE_NAME);
354                     if (u2NameLen > WPS_ATTRI_MAX_LEN_DEVICE_NAME) {
355                         u2NameLen = WPS_ATTRI_MAX_LEN_DEVICE_NAME;
356                     }
357                     prP2pDesc->u2NameLength = u2NameLen;
358                     kalMemCopy(prP2pDesc->aucName, prP2pDevName->aucName, prP2pDesc->u2NameLength);
359                 }
360                 break;
361             case P2P_ATTRI_ID_P2P_GROUP_INFO:  /* Probe Response */
362                 prP2pAttriGroupInfo = (P_P2P_ATTRI_GROUP_INFO_T)prP2pAttribute;
363                 break;
364             case P2P_ATTRI_ID_NOTICE_OF_ABSENCE:
365                 break;
366             case P2P_ATTRI_ID_EXT_LISTEN_TIMING:
367                 // TODO: Not implement yet.
368                 //ASSERT(FALSE);
369                 break;
370             default:
371                 break;
372         }
373
374         u2AttributeLen -= (prP2pAttribute->u2Length + P2P_ATTRI_HDR_LEN);
375
376         prP2pAttribute = (P_P2P_ATTRIBUTE_T)((UINT_32)prP2pAttribute + (prP2pAttribute->u2Length + P2P_ATTRI_HDR_LEN));
377
378     }
379
380
381     if (prP2pAttriGroupInfo != NULL) {
382         P_P2P_CLIENT_INFO_DESC_T prClientInfoDesc = (P_P2P_CLIENT_INFO_DESC_T)NULL;
383         P_P2P_DEVICE_TYPE_T prP2pDevType = (P_P2P_DEVICE_TYPE_T)NULL;
384
385         scanInvalidAllP2pClientDevice(prAdapter, prBssDesc);
386
387         /* GO/Device itself. */
388         prP2pDesc->fgDevInfoValid = TRUE;
389
390         prClientInfoDesc = (P_P2P_CLIENT_INFO_DESC_T)prP2pAttriGroupInfo->arClientDesc;
391         u2AttributeLen = prP2pAttriGroupInfo->u2Length;
392
393
394         while (u2AttributeLen > 0) {
395             prP2pDesc = scanFindP2pDeviceDesc(prAdapter, prBssDesc, prClientInfoDesc->aucDevAddr, TRUE, TRUE);
396
397             if (!prP2pDesc) {
398                 ASSERT(FALSE);
399                 break; /* while */
400             }
401
402             prP2pDesc->fgDevInfoValid = TRUE;
403
404             /* Basic size for P2P client info descriptor. */
405             ASSERT(u2AttributeLen >= 25);
406             if (u2AttributeLen < 25) {
407                 DBGLOG(P2P, WARN, ("Length incorrect warning.\n"));
408                 break;
409             }
410             COPY_MAC_ADDR(prP2pDesc->aucInterfaceAddr, prClientInfoDesc->aucIfAddr);
411
412             prP2pDesc->ucDeviceCapabilityBitmap = prClientInfoDesc->ucDeviceCap;
413
414             WLAN_GET_FIELD_BE16(&prClientInfoDesc->u2ConfigMethodsBE, &prP2pDesc->u2ConfigMethod);
415
416             prP2pDevType = &(prP2pDesc->rPriDevType);
417             WLAN_GET_FIELD_BE16(&prClientInfoDesc->rPrimaryDevTypeBE.u2CategoryId, &prP2pDevType->u2CategoryID);
418             WLAN_GET_FIELD_BE16(&prClientInfoDesc->rPrimaryDevTypeBE.u2SubCategoryId, &prP2pDevType->u2SubCategoryID);
419
420             ASSERT(prClientInfoDesc->ucNumOfSecondaryDevType <= P2P_GC_MAX_CACHED_SEC_DEV_TYPE_COUNT);
421             prP2pDesc->ucSecDevTypeNum = 0;
422             for (u4Idx = 0; u4Idx < prClientInfoDesc->ucNumOfSecondaryDevType; u4Idx++) {
423                 if (u4Idx < P2P_GC_MAX_CACHED_SEC_DEV_TYPE_COUNT) {
424                     prP2pDevType = &(prP2pDesc->arSecDevType[u4Idx]);
425                     WLAN_GET_FIELD_BE16(&prClientInfoDesc->arSecondaryDevTypeListBE[u4Idx].u2CategoryId, &prP2pDevType->u2CategoryID);
426                     WLAN_GET_FIELD_BE16(&prClientInfoDesc->arSecondaryDevTypeListBE[u4Idx].u2SubCategoryId, &prP2pDevType->u2SubCategoryID);
427                     prP2pDesc->ucSecDevTypeNum++;
428                 }
429
430             }
431             prP2pDevName = (P_DEVICE_NAME_TLV_T)(prClientInfoDesc->arSecondaryDevTypeListBE + (u4Idx * sizeof(DEVICE_TYPE_T)));
432             WLAN_GET_FIELD_BE16(&prP2pDevName->u2Length, &prP2pDesc->u2NameLength);
433             if (prP2pDesc->u2NameLength > WPS_ATTRI_MAX_LEN_DEVICE_NAME) {
434                 prP2pDesc->u2NameLength = WPS_ATTRI_MAX_LEN_DEVICE_NAME;
435             }
436
437             kalMemCopy(prP2pDesc->aucName, prP2pDevName->aucName, prP2pDesc->u2NameLength);
438
439             u2AttributeLen -= (prClientInfoDesc->ucLength + P2P_CLIENT_INFO_DESC_HDR_LEN);
440             prClientInfoDesc = (P_P2P_CLIENT_INFO_DESC_T)((UINT_32)prClientInfoDesc + (UINT_32)prClientInfoDesc->ucLength + P2P_CLIENT_INFO_DESC_HDR_LEN);
441         }
442
443         scanRemoveInvalidP2pClientDevice(prAdapter, prBssDesc);
444     }
445
446     return fgUpdateDevInfo;
447 } /* end of scanAddP2pDeviceInfo() */
448
449 #endif
450
451
452
453 /*----------------------------------------------------------------------------*/
454 /*!
455 * @brief Convert the Beacon or ProbeResp Frame in SW_RFB_T to Event Packet
456 *
457 * @param[in] prSwRfb            Pointer to the receiving SW_RFB_T structure.
458 *
459 * @retval WLAN_STATUS_SUCCESS   It is a valid Scan Result and been sent to the host.
460 * @retval WLAN_STATUS_FAILURE   It is not a valid Scan Result.
461 */
462 /*----------------------------------------------------------------------------*/
463 WLAN_STATUS
464 scanSendDeviceDiscoverEvent (
465     IN P_ADAPTER_T prAdapter,
466     IN P_BSS_DESC_T prBssDesc,
467     IN P_SW_RFB_T prSwRfb
468     )
469 {
470     EVENT_P2P_DEV_DISCOVER_RESULT_T rEventDevInfo;
471 #if 1
472     P_LINK_ENTRY_T prLinkEntry = (P_LINK_ENTRY_T)NULL;
473     P_P2P_DEVICE_DESC_T prTargetDesc = (P_P2P_DEVICE_DESC_T)NULL;
474
475     LINK_FOR_EACH(prLinkEntry, &prBssDesc->rP2pDeviceList) {
476         prTargetDesc = LINK_ENTRY(prLinkEntry, P2P_DEVICE_DESC_T, rLinkEntry);
477
478         COPY_MAC_ADDR(rEventDevInfo.aucDeviceAddr, prTargetDesc->aucDeviceAddr);
479         COPY_MAC_ADDR(rEventDevInfo.aucInterfaceAddr, prTargetDesc->aucInterfaceAddr);
480
481         rEventDevInfo.ucDeviceCapabilityBitmap = prTargetDesc->ucDeviceCapabilityBitmap;
482         rEventDevInfo.ucGroupCapabilityBitmap = prTargetDesc->ucGroupCapabilityBitmap;
483         rEventDevInfo.u2ConfigMethod = prTargetDesc->u2ConfigMethod;
484
485         kalMemCopy(&rEventDevInfo.rPriDevType,
486                                 &prTargetDesc->rPriDevType,
487                                 sizeof(P2P_DEVICE_TYPE_T));
488
489         kalMemCopy(rEventDevInfo.arSecDevType,
490                                 prTargetDesc->arSecDevType,
491                                 (prTargetDesc->ucSecDevTypeNum * sizeof(P2P_DEVICE_TYPE_T)));
492
493         rEventDevInfo.ucSecDevTypeNum = prTargetDesc->ucSecDevTypeNum;
494
495         rEventDevInfo.u2NameLength = prTargetDesc->u2NameLength;
496         kalMemCopy(rEventDevInfo.aucName,
497                                 prTargetDesc->aucName,
498                                 prTargetDesc->u2NameLength);
499
500         COPY_MAC_ADDR(rEventDevInfo.aucBSSID, prBssDesc->aucBSSID);
501
502         if (prTargetDesc == prBssDesc->prP2pDesc) {
503             nicRxAddP2pDevice(prAdapter,
504                 &rEventDevInfo,
505                 prBssDesc->aucIEBuf,
506                 prBssDesc->u2IELength);
507         }
508         else {
509             nicRxAddP2pDevice(prAdapter,
510                 &rEventDevInfo,
511                 NULL,
512                 0);
513         }
514     }
515
516     kalP2PIndicateFound(prAdapter->prGlueInfo);
517
518 #else
519
520     P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T)NULL;
521     P_P2P_ATTRIBUTE_T prP2pAttribute = (P_P2P_ATTRIBUTE_T)NULL;
522     UINT_16 u2AttributeLen = 0;
523     UINT_32 u4Idx = 0;
524     P_P2P_ATTRI_GROUP_INFO_T prP2pAttriGroupInfo = (P_P2P_ATTRI_GROUP_INFO_T)NULL;
525     P_DEVICE_NAME_TLV_T prP2pDevName = (P_DEVICE_NAME_TLV_T)NULL;
526
527     ASSERT(prAdapter);
528
529     prP2pSpecificBssInfo = &prAdapter->rWifiVar.rP2pSpecificBssInfo;
530
531 #if 1
532     p2pGetP2PAttriList(prAdapter, prBssDesc->aucIEBuf, prBssDesc->u2IELength, (PPUINT_8)&prP2pAttribute, &u2AttributeLen);
533 #else
534     prP2pAttribute = (P_P2P_ATTRIBUTE_T)&prP2pSpecificBssInfo->aucAttributesCache[0];
535     u2AttributeLen = prP2pSpecificBssInfo->u2AttributeLen;
536 #endif
537     rEventDevInfo.fgDevInfoValid = FALSE;
538
539     while (u2AttributeLen >= P2P_ATTRI_HDR_LEN) {
540         switch (prP2pAttribute->ucId) {
541             case P2P_ATTRI_ID_P2P_CAPABILITY:
542                 {
543                     P_P2P_ATTRI_CAPABILITY_T prP2pAttriCapability = (P_P2P_ATTRI_CAPABILITY_T)NULL;
544
545                     prP2pAttriCapability = (P_P2P_ATTRI_CAPABILITY_T)prP2pAttribute;
546                     ASSERT(prP2pAttriCapability->u2Length == 2);
547                     rEventDevInfo.ucDeviceCapabilityBitmap = prP2pAttriCapability->ucDeviceCap;
548                     rEventDevInfo.ucGroupCapabilityBitmap = prP2pAttriCapability->ucGroupCap;
549                 }
550                 break;
551             case P2P_ATTRI_ID_P2P_DEV_ID:
552                 {
553                     P_P2P_ATTRI_DEV_ID_T prP2pAttriDevID = (P_P2P_ATTRI_DEV_ID_T)NULL;
554
555                     prP2pAttriDevID = (P_P2P_ATTRI_DEV_ID_T)prP2pAttribute;
556                     ASSERT(prP2pAttriDevID->u2Length == 6);
557                     kalMemCopy(rEventDevInfo.aucCommunicateAddr, prP2pAttriDevID->aucDevAddr, MAC_ADDR_LEN);
558                 }
559                 break;
560             case P2P_ATTRI_ID_P2P_DEV_INFO:
561                 {
562                     P_P2P_ATTRI_DEV_INFO_T prP2pAttriDevInfo = (P_P2P_ATTRI_DEV_INFO_T)NULL;
563                     P_P2P_DEVICE_TYPE_T prP2pDevType = (P_P2P_DEVICE_TYPE_T)NULL;
564
565                     prP2pAttriDevInfo = (P_P2P_ATTRI_DEV_INFO_T)prP2pAttribute;
566                     rEventDevInfo.fgDevInfoValid = TRUE;
567                     kalMemCopy(rEventDevInfo.aucCommunicateAddr, prP2pAttriDevInfo->aucDevAddr, MAC_ADDR_LEN);
568                     rEventDevInfo.u2ConfigMethod = prP2pAttriDevInfo->u2ConfigMethodsBE;
569
570                     prP2pDevType = &rEventDevInfo.rPriDevType;
571                     prP2pDevType->u2CategoryID = prP2pAttriDevInfo->rPrimaryDevTypeBE.u2CategoryId;
572                     prP2pDevType->u2SubCategoryID = prP2pAttriDevInfo->rPrimaryDevTypeBE.u2SubCategoryId;
573
574                     ASSERT(prP2pAttriDevInfo->ucNumOfSecondaryDevType <= 2);  // TODO: Fixme if secondary device type is more than 2.
575                     for (u4Idx = 0; u4Idx < prP2pAttriDevInfo->ucNumOfSecondaryDevType; u4Idx++) {
576                         // TODO: Current sub device type can only support 2.
577                         prP2pDevType = &rEventDevInfo.arSecDevType[u4Idx];
578                         prP2pDevType->u2CategoryID = prP2pAttriDevInfo->rPrimaryDevTypeBE.u2CategoryId;
579                         prP2pDevType->u2SubCategoryID = prP2pAttriDevInfo->rPrimaryDevTypeBE.u2SubCategoryId;
580                     }
581
582                     prP2pDevName = (P_DEVICE_NAME_TLV_T)(prP2pAttriDevInfo->arSecondaryDevTypeListBE + (u4Idx * sizeof(DEVICE_TYPE_T)));
583                     ASSERT(prP2pDevName->u2Id == 0x1011);
584                     ASSERT(prP2pDevName->u2Length <= 32);   // TODO: Fixme if device name length is longer than 32 bytes.
585                     kalMemCopy(rEventDevInfo.aucName, prP2pDevName->aucName, prP2pDevName->u2Length);
586                 }
587                 break;
588             case P2P_ATTRI_ID_P2P_GROUP_INFO:
589                 prP2pAttriGroupInfo = (P_P2P_ATTRI_GROUP_INFO_T)prP2pAttribute;
590                 break;
591         }
592
593         u2AttributeLen -= (prP2pAttribute->u2Length + P2P_ATTRI_HDR_LEN);
594
595         prP2pAttribute = (P_P2P_ATTRIBUTE_T)((UINT_32)prP2pAttribute + (prP2pAttribute->u2Length + P2P_ATTRI_HDR_LEN));
596
597     }
598
599     nicRxAddP2pDevice(prAdapter,
600             &rEventDevInfo);
601
602     if (prP2pAttriGroupInfo != NULL) {
603         P_P2P_CLIENT_INFO_DESC_T prClientInfoDesc = (P_P2P_CLIENT_INFO_DESC_T)NULL;
604         P_P2P_DEVICE_TYPE_T prP2pDevType = (P_P2P_DEVICE_TYPE_T)NULL;
605
606         prClientInfoDesc = prP2pAttriGroupInfo->arClientDesc;
607         u2AttributeLen = prP2pAttriGroupInfo->u2Length;
608
609         while (u2AttributeLen > 0) {
610             /* Basic size for P2P client info descriptor. */
611             ASSERT(u2AttributeLen >= 25);
612             rEventDevInfo.fgDevInfoValid = TRUE;
613             kalMemCopy(rEventDevInfo.aucCommunicateAddr, prClientInfoDesc->aucIfAddr, MAC_ADDR_LEN);
614             rEventDevInfo.ucDeviceCapabilityBitmap = prClientInfoDesc->ucDeviceCap;
615             rEventDevInfo.u2ConfigMethod = prClientInfoDesc->u2ConfigMethodsBE;
616
617             prP2pDevType = &rEventDevInfo.rPriDevType;
618             prP2pDevType->u2CategoryID = prClientInfoDesc->rPrimaryDevTypeBE.u2CategoryId;
619             prP2pDevType->u2SubCategoryID = prClientInfoDesc->rPrimaryDevTypeBE.u2SubCategoryId;
620
621             ASSERT(prClientInfoDesc->ucNumOfSecondaryDevType <= 2);  // TODO: Fixme if secondary device type is more than 2.
622             for (u4Idx = 0; u4Idx < prClientInfoDesc->ucNumOfSecondaryDevType; u4Idx++) {
623                 // TODO: Current sub device type can only support 2.
624                 prP2pDevType = &rEventDevInfo.arSecDevType[u4Idx];
625                 prP2pDevType->u2CategoryID = prClientInfoDesc->arSecondaryDevTypeListBE[u4Idx].u2CategoryId;
626                 prP2pDevType->u2SubCategoryID = prClientInfoDesc->arSecondaryDevTypeListBE[u4Idx].u2SubCategoryId;
627             }
628
629             prP2pDevName = (P_DEVICE_NAME_TLV_T)(prClientInfoDesc->arSecondaryDevTypeListBE + (u4Idx * sizeof(DEVICE_TYPE_T)));
630             ASSERT(prP2pDevName->u2Id == 0x1011);
631             ASSERT(prP2pDevName->u2Length <= 32);   // TODO: Fixme if device name length is longer than 32 bytes.
632             kalMemCopy(&rEventDevInfo.aucName, prP2pDevName->aucName, prP2pDevName->u2Length);
633
634             nicRxAddP2pDevice(prAdapter,
635                 &rEventDevInfo);
636
637             u2AttributeLen -= prP2pAttriGroupInfo->u2Length;
638             prP2pAttriGroupInfo = prP2pAttriGroupInfo + prP2pAttriGroupInfo->u2Length + 1;
639         }
640
641     }
642 #endif
643     return WLAN_STATUS_SUCCESS;
644 } /* scanSendDeviceDiscoverEvent */
645
646 VOID
647 scanP2pProcessBeaconAndProbeResp(
648     IN P_ADAPTER_T prAdapter,
649     IN P_SW_RFB_T prSwRfb,
650     IN P_WLAN_STATUS prStatus,
651     IN P_BSS_DESC_T prBssDesc,
652     IN P_WLAN_BEACON_FRAME_T prWlanBeaconFrame
653     )
654 {
655     P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T)NULL;
656     P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T)NULL;
657     prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]);
658     prP2pConnSettings = prAdapter->rWifiVar.prP2PConnSettings;
659
660     if (prBssDesc->fgIsP2PPresent) {
661
662         if ((!prP2pBssInfo->ucDTIMPeriod) &&          // First time.
663             (prP2pBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE) &&     // P2P GC
664                 (prP2pBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED) &&   // Connected
665                 ((prWlanBeaconFrame->u2FrameCtrl & MASK_FRAME_TYPE) == MAC_FRAME_BEACON) &&  // TX Beacon
666                 EQUAL_SSID(prBssDesc->aucSSID,                                                                  // SSID Match
667                             prBssDesc->ucSSIDLen,
668                             prP2pConnSettings->aucSSID,
669                             prP2pConnSettings->ucSSIDLen)) {
670
671
672             prP2pBssInfo->ucDTIMPeriod = prBssDesc->ucDTIMPeriod;
673             nicPmIndicateBssConnected(prAdapter, NETWORK_TYPE_P2P_INDEX);
674         }
675
676         do {
677             RF_CHANNEL_INFO_T rChannelInfo;
678
679             ASSERT_BREAK((prSwRfb != NULL) && (prBssDesc != NULL));
680
681                         if (((prWlanBeaconFrame->u2FrameCtrl & MASK_FRAME_TYPE) != MAC_FRAME_PROBE_RSP)) {
682                 // Only report Probe Response frame to supplicant.
683                 /* Probe response collect much more information. */
684                 break;
685             }
686
687             rChannelInfo.ucChannelNum = prBssDesc->ucChannelNum;
688             rChannelInfo.eBand = prBssDesc->eBand;
689
690             kalP2PIndicateBssInfo(prAdapter->prGlueInfo,
691                             (PUINT_8)prSwRfb->pvHeader,
692                             (UINT_32)prSwRfb->u2PacketLen,
693                             &rChannelInfo,
694                             RCPI_TO_dBm(prBssDesc->ucRCPI));
695
696
697         } while (FALSE);
698     }
699 }
700
701 VOID
702 scnEventReturnChannel (
703     IN P_ADAPTER_T prAdapter,
704     IN UINT_8 ucScnSeqNum
705     )
706 {
707
708     CMD_SCAN_CANCEL rCmdScanCancel;
709
710     /* send cancel message to firmware domain */
711     rCmdScanCancel.ucSeqNum = ucScnSeqNum;
712     rCmdScanCancel.ucIsExtChannel = (UINT_8) FALSE;
713
714     wlanSendSetQueryCmd(prAdapter,
715             CMD_ID_SCAN_CANCEL,
716             TRUE,
717             FALSE,
718             FALSE,
719             NULL,
720             NULL,
721             sizeof(CMD_SCAN_CANCEL),
722             (PUINT_8)&rCmdScanCancel,
723             NULL,
724             0);
725
726     return;
727 } /* scnEventReturnChannel */
728
729 VOID
730 scanRemoveAllP2pBssDesc(
731     IN P_ADAPTER_T prAdapter
732     )
733 {
734     P_LINK_T prBSSDescList;
735     P_BSS_DESC_T prBssDesc;
736     P_BSS_DESC_T prBSSDescNext;
737
738     ASSERT(prAdapter);
739
740     prBSSDescList = &(prAdapter->rWifiVar.rScanInfo.rBSSDescList);
741
742     /* Search BSS Desc from current SCAN result list. */
743     LINK_FOR_EACH_ENTRY_SAFE(prBssDesc, prBSSDescNext, prBSSDescList, rLinkEntry, BSS_DESC_T) {
744         scanRemoveP2pBssDesc(prAdapter, prBssDesc);
745     }
746 } /* scanRemoveAllP2pBssDesc */
747
748 VOID
749 scanRemoveP2pBssDesc(
750     IN P_ADAPTER_T prAdapter,
751     IN P_BSS_DESC_T prBssDesc
752     )
753 {
754
755     return;
756 } /* scanRemoveP2pBssDesc */
757
758
759 P_BSS_DESC_T
760 scanP2pSearchDesc (
761     IN P_ADAPTER_T prAdapter,
762     IN P_BSS_INFO_T prP2pBssInfo,
763     IN P_P2P_CONNECTION_REQ_INFO_T prConnReqInfo
764     )
765 {
766     P_BSS_DESC_T prCandidateBssDesc = (P_BSS_DESC_T)NULL, prBssDesc = (P_BSS_DESC_T)NULL;
767     P_LINK_T prBssDescList = (P_LINK_T)NULL;
768
769     do {
770         if ((prAdapter == NULL) ||
771                 (prP2pBssInfo == NULL) ||
772                 (prConnReqInfo == NULL)) {
773             break;
774         }
775
776
777         prBssDescList = &(prAdapter->rWifiVar.rScanInfo.rBSSDescList);
778
779         DBGLOG(P2P, LOUD, ("Connecting to BSSID: "MACSTR"\n", MAC2STR(prConnReqInfo->aucBssid)));
780         DBGLOG(P2P, LOUD, ("Connecting to SSID:%s, length:%d\n",
781                             prConnReqInfo->rSsidStruct.aucSsid,
782                             prConnReqInfo->rSsidStruct.ucSsidLen));
783
784         LINK_FOR_EACH_ENTRY(prBssDesc, prBssDescList, rLinkEntry, BSS_DESC_T) {
785             DBGLOG(P2P, LOUD, ("Checking BSS: "MACSTR"\n", MAC2STR(prBssDesc->aucBSSID)));
786
787             if (prBssDesc->eBSSType != BSS_TYPE_INFRASTRUCTURE) {
788                 DBGLOG(P2P, LOUD, ("Ignore mismatch BSS type.\n"));
789                 continue;
790             }
791
792
793             if (UNEQUAL_MAC_ADDR(prBssDesc->aucBSSID, prConnReqInfo->aucBssid)) {
794                 DBGLOG(P2P, LOUD, ("Ignore mismatch BSSID.\n"));
795                 continue;
796             }
797
798
799             /* SSID should be the same? SSID is vary for each connection. so... */
800             if (UNEQUAL_SSID(prConnReqInfo->rSsidStruct.aucSsid,
801                                                 prConnReqInfo->rSsidStruct.ucSsidLen,
802                                                 prBssDesc->aucSSID,
803                                                 prBssDesc->ucSSIDLen)) {
804
805                 DBGLOG(P2P, TRACE, ("Connecting to BSSID: "MACSTR"\n", MAC2STR(prConnReqInfo->aucBssid)));
806                 DBGLOG(P2P, TRACE, ("Connecting to SSID:%s, length:%d\n",
807                                     prConnReqInfo->rSsidStruct.aucSsid,
808                                     prConnReqInfo->rSsidStruct.ucSsidLen));
809                 DBGLOG(P2P, TRACE, ("Checking SSID:%s, length:%d\n",
810                                                 prBssDesc->aucSSID,
811                                                 prBssDesc->ucSSIDLen));
812                 DBGLOG(P2P, TRACE, ("Ignore mismatch SSID, (But BSSID match).\n"));
813                 ASSERT(FALSE);
814                 continue;
815             }
816
817             if (!prBssDesc->fgIsP2PPresent) {
818                 DBGLOG(P2P, ERROR, ("SSID, BSSID, BSSTYPE match, but no P2P IE present.\n"));
819                 continue;
820             }
821
822
823             /* Final decision. */
824             prCandidateBssDesc = prBssDesc;
825             break;
826         }
827
828
829
830     } while (FALSE);
831
832     return prCandidateBssDesc;
833 } /* scanP2pSearchDesc */
834
835
836
837