rtw_p2p.c 142 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077
  1. /******************************************************************************
  2. *
  3. * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
  4. *
  5. * This program is free software; you can redistribute it and/or modify it
  6. * under the terms of version 2 of the GNU General Public License as
  7. * published by the Free Software Foundation.
  8. *
  9. * This program is distributed in the hope that it will be useful, but WITHOUT
  10. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  12. * more details.
  13. *
  14. * You should have received a copy of the GNU General Public License along with
  15. * this program; if not, write to the Free Software Foundation, Inc.,
  16. * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
  17. *
  18. *
  19. ******************************************************************************/
  20. #define _RTW_P2P_C_
  21. #include <drv_types.h>
  22. #ifdef CONFIG_P2P
  23. int rtw_p2p_is_channel_list_ok( u8 desired_ch, u8* ch_list, u8 ch_cnt )
  24. {
  25. int found = 0, i = 0;
  26. for( i = 0; i < ch_cnt; i++ )
  27. {
  28. if ( ch_list[ i ] == desired_ch )
  29. {
  30. found = 1;
  31. break;
  32. }
  33. }
  34. return( found );
  35. }
  36. int is_any_client_associated(_adapter *padapter)
  37. {
  38. return padapter->stapriv.asoc_list_cnt ? _TRUE : _FALSE;
  39. }
  40. static u32 go_add_group_info_attr(struct wifidirect_info *pwdinfo, u8 *pbuf)
  41. {
  42. _irqL irqL;
  43. _list *phead, *plist;
  44. u32 len=0;
  45. u16 attr_len = 0;
  46. u8 tmplen, *pdata_attr, *pstart, *pcur;
  47. struct sta_info *psta = NULL;
  48. _adapter *padapter = pwdinfo->padapter;
  49. struct sta_priv *pstapriv = &padapter->stapriv;
  50. DBG_871X("%s\n", __FUNCTION__);
  51. pdata_attr = rtw_zmalloc(MAX_P2P_IE_LEN);
  52. pstart = pdata_attr;
  53. pcur = pdata_attr;
  54. _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
  55. phead = &pstapriv->asoc_list;
  56. plist = get_next(phead);
  57. //look up sta asoc_queue
  58. while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)
  59. {
  60. psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
  61. plist = get_next(plist);
  62. if(psta->is_p2p_device)
  63. {
  64. tmplen = 0;
  65. pcur++;
  66. //P2P device address
  67. _rtw_memcpy(pcur, psta->dev_addr, ETH_ALEN);
  68. pcur += ETH_ALEN;
  69. //P2P interface address
  70. _rtw_memcpy(pcur, psta->hwaddr, ETH_ALEN);
  71. pcur += ETH_ALEN;
  72. *pcur = psta->dev_cap;
  73. pcur++;
  74. //*(u16*)(pcur) = cpu_to_be16(psta->config_methods);
  75. RTW_PUT_BE16(pcur, psta->config_methods);
  76. pcur += 2;
  77. _rtw_memcpy(pcur, psta->primary_dev_type, 8);
  78. pcur += 8;
  79. *pcur = psta->num_of_secdev_type;
  80. pcur++;
  81. _rtw_memcpy(pcur, psta->secdev_types_list, psta->num_of_secdev_type*8);
  82. pcur += psta->num_of_secdev_type*8;
  83. if(psta->dev_name_len>0)
  84. {
  85. //*(u16*)(pcur) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
  86. RTW_PUT_BE16(pcur, WPS_ATTR_DEVICE_NAME);
  87. pcur += 2;
  88. //*(u16*)(pcur) = cpu_to_be16( psta->dev_name_len );
  89. RTW_PUT_BE16(pcur, psta->dev_name_len);
  90. pcur += 2;
  91. _rtw_memcpy(pcur, psta->dev_name, psta->dev_name_len);
  92. pcur += psta->dev_name_len;
  93. }
  94. tmplen = (u8)(pcur-pstart);
  95. *pstart = (tmplen-1);
  96. attr_len += tmplen;
  97. //pstart += tmplen;
  98. pstart = pcur;
  99. }
  100. }
  101. _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
  102. if(attr_len>0)
  103. {
  104. len = rtw_set_p2p_attr_content(pbuf, P2P_ATTR_GROUP_INFO, attr_len, pdata_attr);
  105. }
  106. rtw_mfree(pdata_attr, MAX_P2P_IE_LEN);
  107. return len;
  108. }
  109. static void issue_group_disc_req(struct wifidirect_info *pwdinfo, u8 *da)
  110. {
  111. struct xmit_frame *pmgntframe;
  112. struct pkt_attrib *pattrib;
  113. unsigned char *pframe;
  114. struct rtw_ieee80211_hdr *pwlanhdr;
  115. unsigned short *fctrl;
  116. _adapter *padapter = pwdinfo->padapter;
  117. struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
  118. struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
  119. unsigned char category = RTW_WLAN_CATEGORY_P2P;//P2P action frame
  120. u32 p2poui = cpu_to_be32(P2POUI);
  121. u8 oui_subtype = P2P_GO_DISC_REQUEST;
  122. u8 dialogToken=0;
  123. DBG_871X("[%s]\n", __FUNCTION__);
  124. if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
  125. {
  126. return;
  127. }
  128. //update attribute
  129. pattrib = &pmgntframe->attrib;
  130. update_mgntframe_attrib(padapter, pattrib);
  131. _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
  132. pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
  133. pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
  134. fctrl = &(pwlanhdr->frame_ctl);
  135. *(fctrl) = 0;
  136. _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
  137. _rtw_memcpy(pwlanhdr->addr2, pwdinfo->interface_addr, ETH_ALEN);
  138. _rtw_memcpy(pwlanhdr->addr3, pwdinfo->interface_addr, ETH_ALEN);
  139. SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
  140. pmlmeext->mgnt_seq++;
  141. SetFrameSubType(pframe, WIFI_ACTION);
  142. pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
  143. pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
  144. //Build P2P action frame header
  145. pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
  146. pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
  147. pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
  148. pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->pktlen));
  149. //there is no IE in this P2P action frame
  150. pattrib->last_txcmdsz = pattrib->pktlen;
  151. dump_mgntframe(padapter, pmgntframe);
  152. }
  153. static void issue_p2p_devdisc_resp(struct wifidirect_info *pwdinfo, u8 *da, u8 status, u8 dialogToken)
  154. {
  155. struct xmit_frame *pmgntframe;
  156. struct pkt_attrib *pattrib;
  157. unsigned char *pframe;
  158. struct rtw_ieee80211_hdr *pwlanhdr;
  159. unsigned short *fctrl;
  160. _adapter *padapter = pwdinfo->padapter;
  161. struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
  162. struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
  163. unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
  164. u8 action = P2P_PUB_ACTION_ACTION;
  165. u32 p2poui = cpu_to_be32(P2POUI);
  166. u8 oui_subtype = P2P_DEVDISC_RESP;
  167. u8 p2pie[8] = { 0x00 };
  168. u32 p2pielen = 0;
  169. DBG_871X("[%s]\n", __FUNCTION__);
  170. if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
  171. {
  172. return;
  173. }
  174. //update attribute
  175. pattrib = &pmgntframe->attrib;
  176. update_mgntframe_attrib(padapter, pattrib);
  177. _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
  178. pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
  179. pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
  180. fctrl = &(pwlanhdr->frame_ctl);
  181. *(fctrl) = 0;
  182. _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
  183. _rtw_memcpy(pwlanhdr->addr2, pwdinfo->device_addr, ETH_ALEN);
  184. _rtw_memcpy(pwlanhdr->addr3, pwdinfo->device_addr, ETH_ALEN);
  185. SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
  186. pmlmeext->mgnt_seq++;
  187. SetFrameSubType(pframe, WIFI_ACTION);
  188. pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
  189. pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
  190. //Build P2P public action frame header
  191. pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
  192. pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
  193. pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
  194. pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
  195. pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->pktlen));
  196. //Build P2P IE
  197. // P2P OUI
  198. p2pielen = 0;
  199. p2pie[ p2pielen++ ] = 0x50;
  200. p2pie[ p2pielen++ ] = 0x6F;
  201. p2pie[ p2pielen++ ] = 0x9A;
  202. p2pie[ p2pielen++ ] = 0x09; // WFA P2P v1.0
  203. // P2P_ATTR_STATUS
  204. p2pielen += rtw_set_p2p_attr_content(&p2pie[p2pielen], P2P_ATTR_STATUS, 1, &status);
  205. pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, p2pie, &pattrib->pktlen);
  206. pattrib->last_txcmdsz = pattrib->pktlen;
  207. dump_mgntframe(padapter, pmgntframe);
  208. }
  209. static void issue_p2p_provision_resp(struct wifidirect_info *pwdinfo, u8* raddr, u8* frame_body, u16 config_method)
  210. {
  211. _adapter *padapter = pwdinfo->padapter;
  212. unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
  213. u8 action = P2P_PUB_ACTION_ACTION;
  214. u8 dialogToken = frame_body[7]; // The Dialog Token of provisioning discovery request frame.
  215. u32 p2poui = cpu_to_be32(P2POUI);
  216. u8 oui_subtype = P2P_PROVISION_DISC_RESP;
  217. u8 wpsie[ 100 ] = { 0x00 };
  218. u8 wpsielen = 0;
  219. #ifdef CONFIG_WFD
  220. u32 wfdielen = 0;
  221. #endif //CONFIG_WFD
  222. struct xmit_frame *pmgntframe;
  223. struct pkt_attrib *pattrib;
  224. unsigned char *pframe;
  225. struct rtw_ieee80211_hdr *pwlanhdr;
  226. unsigned short *fctrl;
  227. struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
  228. struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
  229. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  230. if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
  231. {
  232. return;
  233. }
  234. //update attribute
  235. pattrib = &pmgntframe->attrib;
  236. update_mgntframe_attrib(padapter, pattrib);
  237. _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
  238. pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
  239. pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
  240. fctrl = &(pwlanhdr->frame_ctl);
  241. *(fctrl) = 0;
  242. _rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
  243. _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
  244. _rtw_memcpy(pwlanhdr->addr3, myid(&(padapter->eeprompriv)), ETH_ALEN);
  245. SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
  246. pmlmeext->mgnt_seq++;
  247. SetFrameSubType(pframe, WIFI_ACTION);
  248. pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
  249. pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
  250. pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
  251. pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
  252. pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
  253. pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
  254. pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->pktlen));
  255. wpsielen = 0;
  256. // WPS OUI
  257. //*(u32*) ( wpsie ) = cpu_to_be32( WPSOUI );
  258. RTW_PUT_BE32(wpsie, WPSOUI);
  259. wpsielen += 4;
  260. #if 0
  261. // WPS version
  262. // Type:
  263. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_VER1 );
  264. wpsielen += 2;
  265. // Length:
  266. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
  267. wpsielen += 2;
  268. // Value:
  269. wpsie[wpsielen++] = WPS_VERSION_1; // Version 1.0
  270. #endif
  271. // Config Method
  272. // Type:
  273. //*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_CONF_METHOD );
  274. RTW_PUT_BE16(wpsie + wpsielen, WPS_ATTR_CONF_METHOD);
  275. wpsielen += 2;
  276. // Length:
  277. //*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
  278. RTW_PUT_BE16(wpsie + wpsielen, 0x0002);
  279. wpsielen += 2;
  280. // Value:
  281. //*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( config_method );
  282. RTW_PUT_BE16(wpsie + wpsielen, config_method);
  283. wpsielen += 2;
  284. pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen );
  285. #ifdef CONFIG_WFD
  286. wfdielen = build_provdisc_resp_wfd_ie(pwdinfo, pframe);
  287. pframe += wfdielen;
  288. pattrib->pktlen += wfdielen;
  289. #endif //CONFIG_WFD
  290. pattrib->last_txcmdsz = pattrib->pktlen;
  291. dump_mgntframe(padapter, pmgntframe);
  292. return;
  293. }
  294. static void issue_p2p_presence_resp(struct wifidirect_info *pwdinfo, u8 *da, u8 status, u8 dialogToken)
  295. {
  296. struct xmit_frame *pmgntframe;
  297. struct pkt_attrib *pattrib;
  298. unsigned char *pframe;
  299. struct rtw_ieee80211_hdr *pwlanhdr;
  300. unsigned short *fctrl;
  301. _adapter *padapter = pwdinfo->padapter;
  302. struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
  303. struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
  304. unsigned char category = RTW_WLAN_CATEGORY_P2P;//P2P action frame
  305. u32 p2poui = cpu_to_be32(P2POUI);
  306. u8 oui_subtype = P2P_PRESENCE_RESPONSE;
  307. u8 p2pie[ MAX_P2P_IE_LEN] = { 0x00 };
  308. u8 noa_attr_content[32] = { 0x00 };
  309. u32 p2pielen = 0;
  310. DBG_871X("[%s]\n", __FUNCTION__);
  311. if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
  312. {
  313. return;
  314. }
  315. //update attribute
  316. pattrib = &pmgntframe->attrib;
  317. update_mgntframe_attrib(padapter, pattrib);
  318. _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
  319. pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
  320. pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
  321. fctrl = &(pwlanhdr->frame_ctl);
  322. *(fctrl) = 0;
  323. _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
  324. _rtw_memcpy(pwlanhdr->addr2, pwdinfo->interface_addr, ETH_ALEN);
  325. _rtw_memcpy(pwlanhdr->addr3, pwdinfo->interface_addr, ETH_ALEN);
  326. SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
  327. pmlmeext->mgnt_seq++;
  328. SetFrameSubType(pframe, WIFI_ACTION);
  329. pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
  330. pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
  331. //Build P2P action frame header
  332. pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
  333. pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
  334. pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
  335. pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->pktlen));
  336. //Add P2P IE header
  337. // P2P OUI
  338. p2pielen = 0;
  339. p2pie[ p2pielen++ ] = 0x50;
  340. p2pie[ p2pielen++ ] = 0x6F;
  341. p2pie[ p2pielen++ ] = 0x9A;
  342. p2pie[ p2pielen++ ] = 0x09; // WFA P2P v1.0
  343. //Add Status attribute in P2P IE
  344. p2pielen += rtw_set_p2p_attr_content(&p2pie[p2pielen], P2P_ATTR_STATUS, 1, &status);
  345. //Add NoA attribute in P2P IE
  346. noa_attr_content[0] = 0x1;//index
  347. noa_attr_content[1] = 0x0;//CTWindow and OppPS Parameters
  348. //todo: Notice of Absence Descriptor(s)
  349. p2pielen += rtw_set_p2p_attr_content(&p2pie[p2pielen], P2P_ATTR_NOA, 2, noa_attr_content);
  350. pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, p2pie, &(pattrib->pktlen));
  351. pattrib->last_txcmdsz = pattrib->pktlen;
  352. dump_mgntframe(padapter, pmgntframe);
  353. }
  354. u32 build_beacon_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pbuf)
  355. {
  356. u8 p2pie[ MAX_P2P_IE_LEN] = { 0x00 };
  357. u16 capability=0;
  358. u32 len=0, p2pielen = 0;
  359. // P2P OUI
  360. p2pielen = 0;
  361. p2pie[ p2pielen++ ] = 0x50;
  362. p2pie[ p2pielen++ ] = 0x6F;
  363. p2pie[ p2pielen++ ] = 0x9A;
  364. p2pie[ p2pielen++ ] = 0x09; // WFA P2P v1.0
  365. // According to the P2P Specification, the beacon frame should contain 3 P2P attributes
  366. // 1. P2P Capability
  367. // 2. P2P Device ID
  368. // 3. Notice of Absence ( NOA )
  369. // P2P Capability ATTR
  370. // Type:
  371. // Length:
  372. // Value:
  373. // Device Capability Bitmap, 1 byte
  374. // Be able to participate in additional P2P Groups and
  375. // support the P2P Invitation Procedure
  376. // Group Capability Bitmap, 1 byte
  377. capability = P2P_DEVCAP_INVITATION_PROC|P2P_DEVCAP_CLIENT_DISCOVERABILITY;
  378. capability |= ((P2P_GRPCAP_GO | P2P_GRPCAP_INTRABSS) << 8);
  379. if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_PROVISIONING_ING))
  380. capability |= (P2P_GRPCAP_GROUP_FORMATION<<8);
  381. capability = cpu_to_le16(capability);
  382. p2pielen += rtw_set_p2p_attr_content(&p2pie[p2pielen], P2P_ATTR_CAPABILITY, 2, (u8*)&capability);
  383. // P2P Device ID ATTR
  384. p2pielen += rtw_set_p2p_attr_content(&p2pie[p2pielen], P2P_ATTR_DEVICE_ID, ETH_ALEN, pwdinfo->device_addr);
  385. // Notice of Absence ATTR
  386. // Type:
  387. // Length:
  388. // Value:
  389. //go_add_noa_attr(pwdinfo);
  390. pbuf = rtw_set_ie(pbuf, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &len);
  391. return len;
  392. }
  393. #ifdef CONFIG_WFD
  394. u32 build_beacon_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf)
  395. {
  396. u8 wfdie[ MAX_WFD_IE_LEN] = { 0x00 };
  397. u32 len=0, wfdielen = 0;
  398. _adapter *padapter = pwdinfo->padapter;
  399. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  400. struct wifi_display_info* pwfd_info = padapter->wdinfo.wfd_info;
  401. // WFD OUI
  402. wfdielen = 0;
  403. wfdie[ wfdielen++ ] = 0x50;
  404. wfdie[ wfdielen++ ] = 0x6F;
  405. wfdie[ wfdielen++ ] = 0x9A;
  406. wfdie[ wfdielen++ ] = 0x0A; // WFA WFD v1.0
  407. // Commented by Albert 20110812
  408. // According to the WFD Specification, the beacon frame should contain 4 WFD attributes
  409. // 1. WFD Device Information
  410. // 2. Associated BSSID
  411. // 3. Coupled Sink Information
  412. // WFD Device Information ATTR
  413. // Type:
  414. wfdie[ wfdielen++ ] = WFD_ATTR_DEVICE_INFO;
  415. // Length:
  416. // Note: In the WFD specification, the size of length field is 2.
  417. RTW_PUT_BE16(wfdie + wfdielen, 0x0006);
  418. wfdielen += 2;
  419. // Value1:
  420. // WFD device information
  421. if ( P2P_ROLE_GO == pwdinfo->role )
  422. {
  423. if ( is_any_client_associated( pwdinfo->padapter ) )
  424. {
  425. // WFD primary sink + WiFi Direct mode + WSD (WFD Service Discovery)
  426. RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->wfd_device_type | WFD_DEVINFO_WSD );
  427. }
  428. else
  429. {
  430. // WFD primary sink + available for WFD session + WiFi Direct mode + WSD (WFD Service Discovery)
  431. RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->wfd_device_type | WFD_DEVINFO_SESSION_AVAIL | WFD_DEVINFO_WSD );
  432. }
  433. }
  434. else
  435. {
  436. // WFD primary sink + available for WFD session + WiFi Direct mode + WSD ( WFD Service Discovery )
  437. RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->wfd_device_type | WFD_DEVINFO_SESSION_AVAIL | WFD_DEVINFO_WSD );
  438. }
  439. wfdielen += 2;
  440. // Value2:
  441. // Session Management Control Port
  442. // Default TCP port for RTSP messages is 554
  443. RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->rtsp_ctrlport );
  444. wfdielen += 2;
  445. // Value3:
  446. // WFD Device Maximum Throughput
  447. // 300Mbps is the maximum throughput
  448. RTW_PUT_BE16(wfdie + wfdielen, 300);
  449. wfdielen += 2;
  450. // Associated BSSID ATTR
  451. // Type:
  452. wfdie[ wfdielen++ ] = WFD_ATTR_ASSOC_BSSID;
  453. // Length:
  454. // Note: In the WFD specification, the size of length field is 2.
  455. RTW_PUT_BE16(wfdie + wfdielen, 0x0006);
  456. wfdielen += 2;
  457. // Value:
  458. // Associated BSSID
  459. if ( check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE )
  460. {
  461. _rtw_memcpy( wfdie + wfdielen, &pmlmepriv->assoc_bssid[ 0 ], ETH_ALEN );
  462. }
  463. else
  464. {
  465. _rtw_memset( wfdie + wfdielen, 0x00, ETH_ALEN );
  466. }
  467. wfdielen += ETH_ALEN;
  468. // Coupled Sink Information ATTR
  469. // Type:
  470. wfdie[ wfdielen++ ] = WFD_ATTR_COUPLED_SINK_INFO;
  471. // Length:
  472. // Note: In the WFD specification, the size of length field is 2.
  473. RTW_PUT_BE16(wfdie + wfdielen, 0x0007);
  474. wfdielen += 2;
  475. // Value:
  476. // Coupled Sink Status bitmap
  477. // Not coupled/available for Coupling
  478. wfdie[ wfdielen++ ] = 0;
  479. // MAC Addr.
  480. wfdie[ wfdielen++ ] = 0;
  481. wfdie[ wfdielen++ ] = 0;
  482. wfdie[ wfdielen++ ] = 0;
  483. wfdie[ wfdielen++ ] = 0;
  484. wfdie[ wfdielen++ ] = 0;
  485. wfdie[ wfdielen++ ] = 0;
  486. pbuf = rtw_set_ie(pbuf, _VENDOR_SPECIFIC_IE_, wfdielen, (unsigned char *) wfdie, &len);
  487. return len;
  488. }
  489. u32 build_probe_req_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf)
  490. {
  491. u8 wfdie[ MAX_WFD_IE_LEN] = { 0x00 };
  492. u32 len=0, wfdielen = 0;
  493. _adapter *padapter = pwdinfo->padapter;
  494. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  495. struct wifi_display_info* pwfd_info = padapter->wdinfo.wfd_info;
  496. // WFD OUI
  497. wfdielen = 0;
  498. wfdie[ wfdielen++ ] = 0x50;
  499. wfdie[ wfdielen++ ] = 0x6F;
  500. wfdie[ wfdielen++ ] = 0x9A;
  501. wfdie[ wfdielen++ ] = 0x0A; // WFA WFD v1.0
  502. // Commented by Albert 20110812
  503. // According to the WFD Specification, the probe request frame should contain 4 WFD attributes
  504. // 1. WFD Device Information
  505. // 2. Associated BSSID
  506. // 3. Coupled Sink Information
  507. // WFD Device Information ATTR
  508. // Type:
  509. wfdie[ wfdielen++ ] = WFD_ATTR_DEVICE_INFO;
  510. // Length:
  511. // Note: In the WFD specification, the size of length field is 2.
  512. RTW_PUT_BE16(wfdie + wfdielen, 0x0006);
  513. wfdielen += 2;
  514. // Value1:
  515. // WFD device information
  516. if ( 1 == pwdinfo->wfd_tdls_enable )
  517. {
  518. // WFD primary sink + available for WFD session + WiFi TDLS mode + WSC ( WFD Service Discovery )
  519. RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->wfd_device_type |
  520. WFD_DEVINFO_SESSION_AVAIL |
  521. WFD_DEVINFO_WSD |
  522. WFD_DEVINFO_PC_TDLS );
  523. }
  524. else
  525. {
  526. // WFD primary sink + available for WFD session + WiFi Direct mode + WSC ( WFD Service Discovery )
  527. RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->wfd_device_type |
  528. WFD_DEVINFO_SESSION_AVAIL |
  529. WFD_DEVINFO_WSD );
  530. }
  531. wfdielen += 2;
  532. // Value2:
  533. // Session Management Control Port
  534. // Default TCP port for RTSP messages is 554
  535. RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->rtsp_ctrlport );
  536. wfdielen += 2;
  537. // Value3:
  538. // WFD Device Maximum Throughput
  539. // 300Mbps is the maximum throughput
  540. RTW_PUT_BE16(wfdie + wfdielen, 300);
  541. wfdielen += 2;
  542. // Associated BSSID ATTR
  543. // Type:
  544. wfdie[ wfdielen++ ] = WFD_ATTR_ASSOC_BSSID;
  545. // Length:
  546. // Note: In the WFD specification, the size of length field is 2.
  547. RTW_PUT_BE16(wfdie + wfdielen, 0x0006);
  548. wfdielen += 2;
  549. // Value:
  550. // Associated BSSID
  551. if ( check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE )
  552. {
  553. _rtw_memcpy( wfdie + wfdielen, &pmlmepriv->assoc_bssid[ 0 ], ETH_ALEN );
  554. }
  555. else
  556. {
  557. _rtw_memset( wfdie + wfdielen, 0x00, ETH_ALEN );
  558. }
  559. wfdielen += ETH_ALEN;
  560. // Coupled Sink Information ATTR
  561. // Type:
  562. wfdie[ wfdielen++ ] = WFD_ATTR_COUPLED_SINK_INFO;
  563. // Length:
  564. // Note: In the WFD specification, the size of length field is 2.
  565. RTW_PUT_BE16(wfdie + wfdielen, 0x0007);
  566. wfdielen += 2;
  567. // Value:
  568. // Coupled Sink Status bitmap
  569. // Not coupled/available for Coupling
  570. wfdie[ wfdielen++ ] = 0;
  571. // MAC Addr.
  572. wfdie[ wfdielen++ ] = 0;
  573. wfdie[ wfdielen++ ] = 0;
  574. wfdie[ wfdielen++ ] = 0;
  575. wfdie[ wfdielen++ ] = 0;
  576. wfdie[ wfdielen++ ] = 0;
  577. wfdie[ wfdielen++ ] = 0;
  578. pbuf = rtw_set_ie(pbuf, _VENDOR_SPECIFIC_IE_, wfdielen, (unsigned char *) wfdie, &len);
  579. return len;
  580. }
  581. u32 build_probe_resp_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf, u8 tunneled)
  582. {
  583. u8 wfdie[ MAX_WFD_IE_LEN] = { 0x00 };
  584. u32 len=0, wfdielen = 0;
  585. _adapter *padapter = pwdinfo->padapter;
  586. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  587. struct wifi_display_info* pwfd_info = padapter->wdinfo.wfd_info;
  588. // WFD OUI
  589. wfdielen = 0;
  590. wfdie[ wfdielen++ ] = 0x50;
  591. wfdie[ wfdielen++ ] = 0x6F;
  592. wfdie[ wfdielen++ ] = 0x9A;
  593. wfdie[ wfdielen++ ] = 0x0A; // WFA WFD v1.0
  594. // Commented by Albert 20110812
  595. // According to the WFD Specification, the probe response frame should contain 4 WFD attributes
  596. // 1. WFD Device Information
  597. // 2. Associated BSSID
  598. // 3. Coupled Sink Information
  599. // 4. WFD Session Information
  600. // WFD Device Information ATTR
  601. // Type:
  602. wfdie[ wfdielen++ ] = WFD_ATTR_DEVICE_INFO;
  603. // Length:
  604. // Note: In the WFD specification, the size of length field is 2.
  605. RTW_PUT_BE16(wfdie + wfdielen, 0x0006);
  606. wfdielen += 2;
  607. // Value1:
  608. // WFD device information
  609. // WFD primary sink + available for WFD session + WiFi Direct mode
  610. if ( _TRUE == pwdinfo->session_available )
  611. {
  612. if ( P2P_ROLE_GO == pwdinfo->role )
  613. {
  614. if ( is_any_client_associated( pwdinfo->padapter ) )
  615. {
  616. if ( pwdinfo->wfd_tdls_enable )
  617. {
  618. // TDLS mode + WSD ( WFD Service Discovery )
  619. RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->wfd_device_type | WFD_DEVINFO_WSD | WFD_DEVINFO_PC_TDLS | WFD_DEVINFO_HDCP_SUPPORT);
  620. }
  621. else
  622. {
  623. // WiFi Direct mode + WSD ( WFD Service Discovery )
  624. RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->wfd_device_type | WFD_DEVINFO_WSD | WFD_DEVINFO_HDCP_SUPPORT);
  625. }
  626. }
  627. else
  628. {
  629. if ( pwdinfo->wfd_tdls_enable )
  630. {
  631. // available for WFD session + TDLS mode + WSD ( WFD Service Discovery )
  632. RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->wfd_device_type | WFD_DEVINFO_SESSION_AVAIL | WFD_DEVINFO_WSD | WFD_DEVINFO_PC_TDLS | WFD_DEVINFO_HDCP_SUPPORT);
  633. }
  634. else
  635. {
  636. // available for WFD session + WiFi Direct mode + WSD ( WFD Service Discovery )
  637. RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->wfd_device_type | WFD_DEVINFO_SESSION_AVAIL | WFD_DEVINFO_WSD | WFD_DEVINFO_HDCP_SUPPORT);
  638. }
  639. }
  640. }
  641. else
  642. {
  643. if ( pwdinfo->wfd_tdls_enable )
  644. {
  645. // available for WFD session + WiFi Direct mode + WSD ( WFD Service Discovery )
  646. RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->wfd_device_type | WFD_DEVINFO_SESSION_AVAIL | WFD_DEVINFO_WSD | WFD_DEVINFO_PC_TDLS | WFD_DEVINFO_HDCP_SUPPORT);
  647. }
  648. else
  649. {
  650. // available for WFD session + WiFi Direct mode + WSD ( WFD Service Discovery )
  651. RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->wfd_device_type | WFD_DEVINFO_SESSION_AVAIL | WFD_DEVINFO_WSD | WFD_DEVINFO_HDCP_SUPPORT);
  652. }
  653. }
  654. }
  655. else
  656. {
  657. if ( pwdinfo->wfd_tdls_enable )
  658. {
  659. RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->wfd_device_type | WFD_DEVINFO_WSD |WFD_DEVINFO_PC_TDLS | WFD_DEVINFO_HDCP_SUPPORT);
  660. }
  661. else
  662. {
  663. RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->wfd_device_type | WFD_DEVINFO_WSD | WFD_DEVINFO_HDCP_SUPPORT);
  664. }
  665. }
  666. wfdielen += 2;
  667. // Value2:
  668. // Session Management Control Port
  669. // Default TCP port for RTSP messages is 554
  670. RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->rtsp_ctrlport );
  671. wfdielen += 2;
  672. // Value3:
  673. // WFD Device Maximum Throughput
  674. // 300Mbps is the maximum throughput
  675. RTW_PUT_BE16(wfdie + wfdielen, 300);
  676. wfdielen += 2;
  677. // Associated BSSID ATTR
  678. // Type:
  679. wfdie[ wfdielen++ ] = WFD_ATTR_ASSOC_BSSID;
  680. // Length:
  681. // Note: In the WFD specification, the size of length field is 2.
  682. RTW_PUT_BE16(wfdie + wfdielen, 0x0006);
  683. wfdielen += 2;
  684. // Value:
  685. // Associated BSSID
  686. if ( check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE )
  687. {
  688. _rtw_memcpy( wfdie + wfdielen, &pmlmepriv->assoc_bssid[ 0 ], ETH_ALEN );
  689. }
  690. else
  691. {
  692. _rtw_memset( wfdie + wfdielen, 0x00, ETH_ALEN );
  693. }
  694. wfdielen += ETH_ALEN;
  695. // Coupled Sink Information ATTR
  696. // Type:
  697. wfdie[ wfdielen++ ] = WFD_ATTR_COUPLED_SINK_INFO;
  698. // Length:
  699. // Note: In the WFD specification, the size of length field is 2.
  700. RTW_PUT_BE16(wfdie + wfdielen, 0x0007);
  701. wfdielen += 2;
  702. // Value:
  703. // Coupled Sink Status bitmap
  704. // Not coupled/available for Coupling
  705. wfdie[ wfdielen++ ] = 0;
  706. // MAC Addr.
  707. wfdie[ wfdielen++ ] = 0;
  708. wfdie[ wfdielen++ ] = 0;
  709. wfdie[ wfdielen++ ] = 0;
  710. wfdie[ wfdielen++ ] = 0;
  711. wfdie[ wfdielen++ ] = 0;
  712. wfdie[ wfdielen++ ] = 0;
  713. if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
  714. {
  715. // WFD Session Information ATTR
  716. // Type:
  717. wfdie[ wfdielen++ ] = WFD_ATTR_SESSION_INFO;
  718. // Length:
  719. // Note: In the WFD specification, the size of length field is 2.
  720. RTW_PUT_BE16(wfdie + wfdielen, 0x0000);
  721. wfdielen += 2;
  722. // Todo: to add the list of WFD device info descriptor in WFD group.
  723. }
  724. #ifdef CONFIG_CONCURRENT_MODE
  725. #ifdef CONFIG_TDLS
  726. if ( ( tunneled == 0 ) && ( padapter->pbuddy_adapter->wdinfo.wfd_tdls_enable == 1 ) )
  727. {
  728. // Alternative MAC Address ATTR
  729. // Type:
  730. wfdie[ wfdielen++ ] = WFD_ATTR_ALTER_MAC;
  731. // Length:
  732. // Note: In the WFD specification, the size of length field is 2.
  733. RTW_PUT_BE16(wfdie + wfdielen, ETH_ALEN );
  734. wfdielen += 2;
  735. // Value:
  736. // Alternative MAC Address
  737. _rtw_memcpy( wfdie + wfdielen, &padapter->pbuddy_adapter->eeprompriv.mac_addr[ 0 ], ETH_ALEN );
  738. // This mac address is used to make the WFD session when TDLS is enable.
  739. wfdielen += ETH_ALEN;
  740. }
  741. #endif // CONFIG_TDLS
  742. #endif // CONFIG_CONCURRENT_MODE
  743. pbuf = rtw_set_ie(pbuf, _VENDOR_SPECIFIC_IE_, wfdielen, (unsigned char *) wfdie, &len);
  744. return len;
  745. }
  746. u32 build_assoc_req_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf)
  747. {
  748. u8 wfdie[ MAX_WFD_IE_LEN] = { 0x00 };
  749. u32 len=0, wfdielen = 0;
  750. _adapter *padapter = NULL;
  751. struct mlme_priv *pmlmepriv = NULL;
  752. struct wifi_display_info *pwfd_info = NULL;
  753. // WFD OUI
  754. if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) || rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE))
  755. {
  756. return 0;
  757. }
  758. padapter = pwdinfo->padapter;
  759. pmlmepriv = &padapter->mlmepriv;
  760. pwfd_info = padapter->wdinfo.wfd_info;
  761. wfdielen = 0;
  762. wfdie[ wfdielen++ ] = 0x50;
  763. wfdie[ wfdielen++ ] = 0x6F;
  764. wfdie[ wfdielen++ ] = 0x9A;
  765. wfdie[ wfdielen++ ] = 0x0A; // WFA WFD v1.0
  766. // Commented by Albert 20110812
  767. // According to the WFD Specification, the probe request frame should contain 4 WFD attributes
  768. // 1. WFD Device Information
  769. // 2. Associated BSSID
  770. // 3. Coupled Sink Information
  771. // WFD Device Information ATTR
  772. // Type:
  773. wfdie[ wfdielen++ ] = WFD_ATTR_DEVICE_INFO;
  774. // Length:
  775. // Note: In the WFD specification, the size of length field is 2.
  776. RTW_PUT_BE16(wfdie + wfdielen, 0x0006);
  777. wfdielen += 2;
  778. // Value1:
  779. // WFD device information
  780. // WFD primary sink + available for WFD session + WiFi Direct mode + WSD ( WFD Service Discovery )
  781. RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->wfd_device_type | WFD_DEVINFO_SESSION_AVAIL | WFD_DEVINFO_WSD );
  782. wfdielen += 2;
  783. // Value2:
  784. // Session Management Control Port
  785. // Default TCP port for RTSP messages is 554
  786. RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->rtsp_ctrlport );
  787. wfdielen += 2;
  788. // Value3:
  789. // WFD Device Maximum Throughput
  790. // 300Mbps is the maximum throughput
  791. RTW_PUT_BE16(wfdie + wfdielen, 300);
  792. wfdielen += 2;
  793. // Associated BSSID ATTR
  794. // Type:
  795. wfdie[ wfdielen++ ] = WFD_ATTR_ASSOC_BSSID;
  796. // Length:
  797. // Note: In the WFD specification, the size of length field is 2.
  798. RTW_PUT_BE16(wfdie + wfdielen, 0x0006);
  799. wfdielen += 2;
  800. // Value:
  801. // Associated BSSID
  802. if ( check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE )
  803. {
  804. _rtw_memcpy( wfdie + wfdielen, &pmlmepriv->assoc_bssid[ 0 ], ETH_ALEN );
  805. }
  806. else
  807. {
  808. _rtw_memset( wfdie + wfdielen, 0x00, ETH_ALEN );
  809. }
  810. wfdielen += ETH_ALEN;
  811. // Coupled Sink Information ATTR
  812. // Type:
  813. wfdie[ wfdielen++ ] = WFD_ATTR_COUPLED_SINK_INFO;
  814. // Length:
  815. // Note: In the WFD specification, the size of length field is 2.
  816. RTW_PUT_BE16(wfdie + wfdielen, 0x0007);
  817. wfdielen += 2;
  818. // Value:
  819. // Coupled Sink Status bitmap
  820. // Not coupled/available for Coupling
  821. wfdie[ wfdielen++ ] = 0;
  822. // MAC Addr.
  823. wfdie[ wfdielen++ ] = 0;
  824. wfdie[ wfdielen++ ] = 0;
  825. wfdie[ wfdielen++ ] = 0;
  826. wfdie[ wfdielen++ ] = 0;
  827. wfdie[ wfdielen++ ] = 0;
  828. wfdie[ wfdielen++ ] = 0;
  829. pbuf = rtw_set_ie(pbuf, _VENDOR_SPECIFIC_IE_, wfdielen, (unsigned char *) wfdie, &len);
  830. return len;
  831. }
  832. u32 build_assoc_resp_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf)
  833. {
  834. u8 wfdie[ MAX_WFD_IE_LEN] = { 0x00 };
  835. u32 len=0, wfdielen = 0;
  836. _adapter *padapter = pwdinfo->padapter;
  837. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  838. struct wifi_display_info* pwfd_info = padapter->wdinfo.wfd_info;
  839. // WFD OUI
  840. wfdielen = 0;
  841. wfdie[ wfdielen++ ] = 0x50;
  842. wfdie[ wfdielen++ ] = 0x6F;
  843. wfdie[ wfdielen++ ] = 0x9A;
  844. wfdie[ wfdielen++ ] = 0x0A; // WFA WFD v1.0
  845. // Commented by Albert 20110812
  846. // According to the WFD Specification, the probe request frame should contain 4 WFD attributes
  847. // 1. WFD Device Information
  848. // 2. Associated BSSID
  849. // 3. Coupled Sink Information
  850. // WFD Device Information ATTR
  851. // Type:
  852. wfdie[ wfdielen++ ] = WFD_ATTR_DEVICE_INFO;
  853. // Length:
  854. // Note: In the WFD specification, the size of length field is 2.
  855. RTW_PUT_BE16(wfdie + wfdielen, 0x0006);
  856. wfdielen += 2;
  857. // Value1:
  858. // WFD device information
  859. // WFD primary sink + available for WFD session + WiFi Direct mode + WSD ( WFD Service Discovery )
  860. RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->wfd_device_type | WFD_DEVINFO_SESSION_AVAIL | WFD_DEVINFO_WSD );
  861. wfdielen += 2;
  862. // Value2:
  863. // Session Management Control Port
  864. // Default TCP port for RTSP messages is 554
  865. RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->rtsp_ctrlport );
  866. wfdielen += 2;
  867. // Value3:
  868. // WFD Device Maximum Throughput
  869. // 300Mbps is the maximum throughput
  870. RTW_PUT_BE16(wfdie + wfdielen, 300);
  871. wfdielen += 2;
  872. // Associated BSSID ATTR
  873. // Type:
  874. wfdie[ wfdielen++ ] = WFD_ATTR_ASSOC_BSSID;
  875. // Length:
  876. // Note: In the WFD specification, the size of length field is 2.
  877. RTW_PUT_BE16(wfdie + wfdielen, 0x0006);
  878. wfdielen += 2;
  879. // Value:
  880. // Associated BSSID
  881. if ( check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE )
  882. {
  883. _rtw_memcpy( wfdie + wfdielen, &pmlmepriv->assoc_bssid[ 0 ], ETH_ALEN );
  884. }
  885. else
  886. {
  887. _rtw_memset( wfdie + wfdielen, 0x00, ETH_ALEN );
  888. }
  889. wfdielen += ETH_ALEN;
  890. // Coupled Sink Information ATTR
  891. // Type:
  892. wfdie[ wfdielen++ ] = WFD_ATTR_COUPLED_SINK_INFO;
  893. // Length:
  894. // Note: In the WFD specification, the size of length field is 2.
  895. RTW_PUT_BE16(wfdie + wfdielen, 0x0007);
  896. wfdielen += 2;
  897. // Value:
  898. // Coupled Sink Status bitmap
  899. // Not coupled/available for Coupling
  900. wfdie[ wfdielen++ ] = 0;
  901. // MAC Addr.
  902. wfdie[ wfdielen++ ] = 0;
  903. wfdie[ wfdielen++ ] = 0;
  904. wfdie[ wfdielen++ ] = 0;
  905. wfdie[ wfdielen++ ] = 0;
  906. wfdie[ wfdielen++ ] = 0;
  907. wfdie[ wfdielen++ ] = 0;
  908. pbuf = rtw_set_ie(pbuf, _VENDOR_SPECIFIC_IE_, wfdielen, (unsigned char *) wfdie, &len);
  909. return len;
  910. }
  911. u32 build_nego_req_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf)
  912. {
  913. u8 wfdie[ MAX_WFD_IE_LEN] = { 0x00 };
  914. u32 len=0, wfdielen = 0;
  915. _adapter *padapter = pwdinfo->padapter;
  916. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  917. struct wifi_display_info* pwfd_info = padapter->wdinfo.wfd_info;
  918. // WFD OUI
  919. wfdielen = 0;
  920. wfdie[ wfdielen++ ] = 0x50;
  921. wfdie[ wfdielen++ ] = 0x6F;
  922. wfdie[ wfdielen++ ] = 0x9A;
  923. wfdie[ wfdielen++ ] = 0x0A; // WFA WFD v1.0
  924. // Commented by Albert 20110825
  925. // According to the WFD Specification, the negotiation request frame should contain 3 WFD attributes
  926. // 1. WFD Device Information
  927. // 2. Associated BSSID ( Optional )
  928. // 3. Local IP Adress ( Optional )
  929. // WFD Device Information ATTR
  930. // Type:
  931. wfdie[ wfdielen++ ] = WFD_ATTR_DEVICE_INFO;
  932. // Length:
  933. // Note: In the WFD specification, the size of length field is 2.
  934. RTW_PUT_BE16(wfdie + wfdielen, 0x0006);
  935. wfdielen += 2;
  936. // Value1:
  937. // WFD device information
  938. // WFD primary sink + WiFi Direct mode + WSD ( WFD Service Discovery ) + WFD Session Available
  939. RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->wfd_device_type | WFD_DEVINFO_WSD | WFD_DEVINFO_SESSION_AVAIL);
  940. wfdielen += 2;
  941. // Value2:
  942. // Session Management Control Port
  943. // Default TCP port for RTSP messages is 554
  944. RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->rtsp_ctrlport );
  945. wfdielen += 2;
  946. // Value3:
  947. // WFD Device Maximum Throughput
  948. // 300Mbps is the maximum throughput
  949. RTW_PUT_BE16(wfdie + wfdielen, 300);
  950. wfdielen += 2;
  951. // Associated BSSID ATTR
  952. // Type:
  953. wfdie[ wfdielen++ ] = WFD_ATTR_ASSOC_BSSID;
  954. // Length:
  955. // Note: In the WFD specification, the size of length field is 2.
  956. RTW_PUT_BE16(wfdie + wfdielen, 0x0006);
  957. wfdielen += 2;
  958. // Value:
  959. // Associated BSSID
  960. if ( check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE )
  961. {
  962. _rtw_memcpy( wfdie + wfdielen, &pmlmepriv->assoc_bssid[ 0 ], ETH_ALEN );
  963. }
  964. else
  965. {
  966. _rtw_memset( wfdie + wfdielen, 0x00, ETH_ALEN );
  967. }
  968. wfdielen += ETH_ALEN;
  969. // Coupled Sink Information ATTR
  970. // Type:
  971. wfdie[ wfdielen++ ] = WFD_ATTR_COUPLED_SINK_INFO;
  972. // Length:
  973. // Note: In the WFD specification, the size of length field is 2.
  974. RTW_PUT_BE16(wfdie + wfdielen, 0x0007);
  975. wfdielen += 2;
  976. // Value:
  977. // Coupled Sink Status bitmap
  978. // Not coupled/available for Coupling
  979. wfdie[ wfdielen++ ] = 0;
  980. // MAC Addr.
  981. wfdie[ wfdielen++ ] = 0;
  982. wfdie[ wfdielen++ ] = 0;
  983. wfdie[ wfdielen++ ] = 0;
  984. wfdie[ wfdielen++ ] = 0;
  985. wfdie[ wfdielen++ ] = 0;
  986. wfdie[ wfdielen++ ] = 0;
  987. pbuf = rtw_set_ie(pbuf, _VENDOR_SPECIFIC_IE_, wfdielen, (unsigned char *) wfdie, &len);
  988. return len;
  989. }
  990. u32 build_nego_resp_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf)
  991. {
  992. u8 wfdie[ MAX_WFD_IE_LEN] = { 0x00 };
  993. u32 len=0, wfdielen = 0;
  994. _adapter *padapter = pwdinfo->padapter;
  995. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  996. struct wifi_display_info* pwfd_info = padapter->wdinfo.wfd_info;
  997. // WFD OUI
  998. wfdielen = 0;
  999. wfdie[ wfdielen++ ] = 0x50;
  1000. wfdie[ wfdielen++ ] = 0x6F;
  1001. wfdie[ wfdielen++ ] = 0x9A;
  1002. wfdie[ wfdielen++ ] = 0x0A; // WFA WFD v1.0
  1003. // Commented by Albert 20110825
  1004. // According to the WFD Specification, the negotiation request frame should contain 3 WFD attributes
  1005. // 1. WFD Device Information
  1006. // 2. Associated BSSID ( Optional )
  1007. // 3. Local IP Adress ( Optional )
  1008. // WFD Device Information ATTR
  1009. // Type:
  1010. wfdie[ wfdielen++ ] = WFD_ATTR_DEVICE_INFO;
  1011. // Length:
  1012. // Note: In the WFD specification, the size of length field is 2.
  1013. RTW_PUT_BE16(wfdie + wfdielen, 0x0006);
  1014. wfdielen += 2;
  1015. // Value1:
  1016. // WFD device information
  1017. // WFD primary sink + WiFi Direct mode + WSD ( WFD Service Discovery ) + WFD Session Available
  1018. RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->wfd_device_type | WFD_DEVINFO_WSD | WFD_DEVINFO_SESSION_AVAIL);
  1019. wfdielen += 2;
  1020. // Value2:
  1021. // Session Management Control Port
  1022. // Default TCP port for RTSP messages is 554
  1023. RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->rtsp_ctrlport );
  1024. wfdielen += 2;
  1025. // Value3:
  1026. // WFD Device Maximum Throughput
  1027. // 300Mbps is the maximum throughput
  1028. RTW_PUT_BE16(wfdie + wfdielen, 300);
  1029. wfdielen += 2;
  1030. // Associated BSSID ATTR
  1031. // Type:
  1032. wfdie[ wfdielen++ ] = WFD_ATTR_ASSOC_BSSID;
  1033. // Length:
  1034. // Note: In the WFD specification, the size of length field is 2.
  1035. RTW_PUT_BE16(wfdie + wfdielen, 0x0006);
  1036. wfdielen += 2;
  1037. // Value:
  1038. // Associated BSSID
  1039. if ( check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE )
  1040. {
  1041. _rtw_memcpy( wfdie + wfdielen, &pmlmepriv->assoc_bssid[ 0 ], ETH_ALEN );
  1042. }
  1043. else
  1044. {
  1045. _rtw_memset( wfdie + wfdielen, 0x00, ETH_ALEN );
  1046. }
  1047. wfdielen += ETH_ALEN;
  1048. // Coupled Sink Information ATTR
  1049. // Type:
  1050. wfdie[ wfdielen++ ] = WFD_ATTR_COUPLED_SINK_INFO;
  1051. // Length:
  1052. // Note: In the WFD specification, the size of length field is 2.
  1053. RTW_PUT_BE16(wfdie + wfdielen, 0x0007);
  1054. wfdielen += 2;
  1055. // Value:
  1056. // Coupled Sink Status bitmap
  1057. // Not coupled/available for Coupling
  1058. wfdie[ wfdielen++ ] = 0;
  1059. // MAC Addr.
  1060. wfdie[ wfdielen++ ] = 0;
  1061. wfdie[ wfdielen++ ] = 0;
  1062. wfdie[ wfdielen++ ] = 0;
  1063. wfdie[ wfdielen++ ] = 0;
  1064. wfdie[ wfdielen++ ] = 0;
  1065. wfdie[ wfdielen++ ] = 0;
  1066. pbuf = rtw_set_ie(pbuf, _VENDOR_SPECIFIC_IE_, wfdielen, (unsigned char *) wfdie, &len);
  1067. return len;
  1068. }
  1069. u32 build_nego_confirm_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf)
  1070. {
  1071. u8 wfdie[ MAX_WFD_IE_LEN] = { 0x00 };
  1072. u32 len=0, wfdielen = 0;
  1073. _adapter *padapter = pwdinfo->padapter;
  1074. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  1075. struct wifi_display_info* pwfd_info = padapter->wdinfo.wfd_info;
  1076. // WFD OUI
  1077. wfdielen = 0;
  1078. wfdie[ wfdielen++ ] = 0x50;
  1079. wfdie[ wfdielen++ ] = 0x6F;
  1080. wfdie[ wfdielen++ ] = 0x9A;
  1081. wfdie[ wfdielen++ ] = 0x0A; // WFA WFD v1.0
  1082. // Commented by Albert 20110825
  1083. // According to the WFD Specification, the negotiation request frame should contain 3 WFD attributes
  1084. // 1. WFD Device Information
  1085. // 2. Associated BSSID ( Optional )
  1086. // 3. Local IP Adress ( Optional )
  1087. // WFD Device Information ATTR
  1088. // Type:
  1089. wfdie[ wfdielen++ ] = WFD_ATTR_DEVICE_INFO;
  1090. // Length:
  1091. // Note: In the WFD specification, the size of length field is 2.
  1092. RTW_PUT_BE16(wfdie + wfdielen, 0x0006);
  1093. wfdielen += 2;
  1094. // Value1:
  1095. // WFD device information
  1096. // WFD primary sink + WiFi Direct mode + WSD ( WFD Service Discovery ) + WFD Session Available
  1097. RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->wfd_device_type | WFD_DEVINFO_WSD | WFD_DEVINFO_SESSION_AVAIL);
  1098. wfdielen += 2;
  1099. // Value2:
  1100. // Session Management Control Port
  1101. // Default TCP port for RTSP messages is 554
  1102. RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->rtsp_ctrlport );
  1103. wfdielen += 2;
  1104. // Value3:
  1105. // WFD Device Maximum Throughput
  1106. // 300Mbps is the maximum throughput
  1107. RTW_PUT_BE16(wfdie + wfdielen, 300);
  1108. wfdielen += 2;
  1109. // Associated BSSID ATTR
  1110. // Type:
  1111. wfdie[ wfdielen++ ] = WFD_ATTR_ASSOC_BSSID;
  1112. // Length:
  1113. // Note: In the WFD specification, the size of length field is 2.
  1114. RTW_PUT_BE16(wfdie + wfdielen, 0x0006);
  1115. wfdielen += 2;
  1116. // Value:
  1117. // Associated BSSID
  1118. if ( check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE )
  1119. {
  1120. _rtw_memcpy( wfdie + wfdielen, &pmlmepriv->assoc_bssid[ 0 ], ETH_ALEN );
  1121. }
  1122. else
  1123. {
  1124. _rtw_memset( wfdie + wfdielen, 0x00, ETH_ALEN );
  1125. }
  1126. wfdielen += ETH_ALEN;
  1127. // Coupled Sink Information ATTR
  1128. // Type:
  1129. wfdie[ wfdielen++ ] = WFD_ATTR_COUPLED_SINK_INFO;
  1130. // Length:
  1131. // Note: In the WFD specification, the size of length field is 2.
  1132. RTW_PUT_BE16(wfdie + wfdielen, 0x0007);
  1133. wfdielen += 2;
  1134. // Value:
  1135. // Coupled Sink Status bitmap
  1136. // Not coupled/available for Coupling
  1137. wfdie[ wfdielen++ ] = 0;
  1138. // MAC Addr.
  1139. wfdie[ wfdielen++ ] = 0;
  1140. wfdie[ wfdielen++ ] = 0;
  1141. wfdie[ wfdielen++ ] = 0;
  1142. wfdie[ wfdielen++ ] = 0;
  1143. wfdie[ wfdielen++ ] = 0;
  1144. wfdie[ wfdielen++ ] = 0;
  1145. pbuf = rtw_set_ie(pbuf, _VENDOR_SPECIFIC_IE_, wfdielen, (unsigned char *) wfdie, &len);
  1146. return len;
  1147. }
  1148. u32 build_invitation_req_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf)
  1149. {
  1150. u8 wfdie[ MAX_WFD_IE_LEN] = { 0x00 };
  1151. u32 len=0, wfdielen = 0;
  1152. _adapter *padapter = pwdinfo->padapter;
  1153. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  1154. struct wifi_display_info* pwfd_info = padapter->wdinfo.wfd_info;
  1155. // WFD OUI
  1156. wfdielen = 0;
  1157. wfdie[ wfdielen++ ] = 0x50;
  1158. wfdie[ wfdielen++ ] = 0x6F;
  1159. wfdie[ wfdielen++ ] = 0x9A;
  1160. wfdie[ wfdielen++ ] = 0x0A; // WFA WFD v1.0
  1161. // Commented by Albert 20110825
  1162. // According to the WFD Specification, the provision discovery request frame should contain 3 WFD attributes
  1163. // 1. WFD Device Information
  1164. // 2. Associated BSSID ( Optional )
  1165. // 3. Local IP Adress ( Optional )
  1166. // WFD Device Information ATTR
  1167. // Type:
  1168. wfdie[ wfdielen++ ] = WFD_ATTR_DEVICE_INFO;
  1169. // Length:
  1170. // Note: In the WFD specification, the size of length field is 2.
  1171. RTW_PUT_BE16(wfdie + wfdielen, 0x0006);
  1172. wfdielen += 2;
  1173. // Value1:
  1174. // WFD device information
  1175. // WFD primary sink + available for WFD session + WiFi Direct mode + WSD ( WFD Service Discovery )
  1176. RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->wfd_device_type | WFD_DEVINFO_SESSION_AVAIL | WFD_DEVINFO_WSD );
  1177. wfdielen += 2;
  1178. // Value2:
  1179. // Session Management Control Port
  1180. // Default TCP port for RTSP messages is 554
  1181. RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->rtsp_ctrlport );
  1182. wfdielen += 2;
  1183. // Value3:
  1184. // WFD Device Maximum Throughput
  1185. // 300Mbps is the maximum throughput
  1186. RTW_PUT_BE16(wfdie + wfdielen, 300);
  1187. wfdielen += 2;
  1188. // Associated BSSID ATTR
  1189. // Type:
  1190. wfdie[ wfdielen++ ] = WFD_ATTR_ASSOC_BSSID;
  1191. // Length:
  1192. // Note: In the WFD specification, the size of length field is 2.
  1193. RTW_PUT_BE16(wfdie + wfdielen, 0x0006);
  1194. wfdielen += 2;
  1195. // Value:
  1196. // Associated BSSID
  1197. if ( check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE )
  1198. {
  1199. _rtw_memcpy( wfdie + wfdielen, &pmlmepriv->assoc_bssid[ 0 ], ETH_ALEN );
  1200. }
  1201. else
  1202. {
  1203. _rtw_memset( wfdie + wfdielen, 0x00, ETH_ALEN );
  1204. }
  1205. wfdielen += ETH_ALEN;
  1206. // Coupled Sink Information ATTR
  1207. // Type:
  1208. wfdie[ wfdielen++ ] = WFD_ATTR_COUPLED_SINK_INFO;
  1209. // Length:
  1210. // Note: In the WFD specification, the size of length field is 2.
  1211. RTW_PUT_BE16(wfdie + wfdielen, 0x0007);
  1212. wfdielen += 2;
  1213. // Value:
  1214. // Coupled Sink Status bitmap
  1215. // Not coupled/available for Coupling
  1216. wfdie[ wfdielen++ ] = 0;
  1217. // MAC Addr.
  1218. wfdie[ wfdielen++ ] = 0;
  1219. wfdie[ wfdielen++ ] = 0;
  1220. wfdie[ wfdielen++ ] = 0;
  1221. wfdie[ wfdielen++ ] = 0;
  1222. wfdie[ wfdielen++ ] = 0;
  1223. wfdie[ wfdielen++ ] = 0;
  1224. if ( P2P_ROLE_GO == pwdinfo->role )
  1225. {
  1226. // WFD Session Information ATTR
  1227. // Type:
  1228. wfdie[ wfdielen++ ] = WFD_ATTR_SESSION_INFO;
  1229. // Length:
  1230. // Note: In the WFD specification, the size of length field is 2.
  1231. RTW_PUT_BE16(wfdie + wfdielen, 0x0000);
  1232. wfdielen += 2;
  1233. // Todo: to add the list of WFD device info descriptor in WFD group.
  1234. }
  1235. pbuf = rtw_set_ie(pbuf, _VENDOR_SPECIFIC_IE_, wfdielen, (unsigned char *) wfdie, &len);
  1236. return len;
  1237. }
  1238. u32 build_invitation_resp_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf)
  1239. {
  1240. u8 wfdie[ MAX_WFD_IE_LEN] = { 0x00 };
  1241. u32 len=0, wfdielen = 0;
  1242. _adapter *padapter = pwdinfo->padapter;
  1243. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  1244. struct wifi_display_info* pwfd_info = padapter->wdinfo.wfd_info;
  1245. // WFD OUI
  1246. wfdielen = 0;
  1247. wfdie[ wfdielen++ ] = 0x50;
  1248. wfdie[ wfdielen++ ] = 0x6F;
  1249. wfdie[ wfdielen++ ] = 0x9A;
  1250. wfdie[ wfdielen++ ] = 0x0A; // WFA WFD v1.0
  1251. // Commented by Albert 20110825
  1252. // According to the WFD Specification, the provision discovery request frame should contain 3 WFD attributes
  1253. // 1. WFD Device Information
  1254. // 2. Associated BSSID ( Optional )
  1255. // 3. Local IP Adress ( Optional )
  1256. // WFD Device Information ATTR
  1257. // Type:
  1258. wfdie[ wfdielen++ ] = WFD_ATTR_DEVICE_INFO;
  1259. // Length:
  1260. // Note: In the WFD specification, the size of length field is 2.
  1261. RTW_PUT_BE16(wfdie + wfdielen, 0x0006);
  1262. wfdielen += 2;
  1263. // Value1:
  1264. // WFD device information
  1265. // WFD primary sink + available for WFD session + WiFi Direct mode + WSD ( WFD Service Discovery )
  1266. RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->wfd_device_type | WFD_DEVINFO_SESSION_AVAIL | WFD_DEVINFO_WSD );
  1267. wfdielen += 2;
  1268. // Value2:
  1269. // Session Management Control Port
  1270. // Default TCP port for RTSP messages is 554
  1271. RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->rtsp_ctrlport );
  1272. wfdielen += 2;
  1273. // Value3:
  1274. // WFD Device Maximum Throughput
  1275. // 300Mbps is the maximum throughput
  1276. RTW_PUT_BE16(wfdie + wfdielen, 300);
  1277. wfdielen += 2;
  1278. // Associated BSSID ATTR
  1279. // Type:
  1280. wfdie[ wfdielen++ ] = WFD_ATTR_ASSOC_BSSID;
  1281. // Length:
  1282. // Note: In the WFD specification, the size of length field is 2.
  1283. RTW_PUT_BE16(wfdie + wfdielen, 0x0006);
  1284. wfdielen += 2;
  1285. // Value:
  1286. // Associated BSSID
  1287. if ( check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE )
  1288. {
  1289. _rtw_memcpy( wfdie + wfdielen, &pmlmepriv->assoc_bssid[ 0 ], ETH_ALEN );
  1290. }
  1291. else
  1292. {
  1293. _rtw_memset( wfdie + wfdielen, 0x00, ETH_ALEN );
  1294. }
  1295. wfdielen += ETH_ALEN;
  1296. // Coupled Sink Information ATTR
  1297. // Type:
  1298. wfdie[ wfdielen++ ] = WFD_ATTR_COUPLED_SINK_INFO;
  1299. // Length:
  1300. // Note: In the WFD specification, the size of length field is 2.
  1301. RTW_PUT_BE16(wfdie + wfdielen, 0x0007);
  1302. wfdielen += 2;
  1303. // Value:
  1304. // Coupled Sink Status bitmap
  1305. // Not coupled/available for Coupling
  1306. wfdie[ wfdielen++ ] = 0;
  1307. // MAC Addr.
  1308. wfdie[ wfdielen++ ] = 0;
  1309. wfdie[ wfdielen++ ] = 0;
  1310. wfdie[ wfdielen++ ] = 0;
  1311. wfdie[ wfdielen++ ] = 0;
  1312. wfdie[ wfdielen++ ] = 0;
  1313. wfdie[ wfdielen++ ] = 0;
  1314. if ( P2P_ROLE_GO == pwdinfo->role )
  1315. {
  1316. // WFD Session Information ATTR
  1317. // Type:
  1318. wfdie[ wfdielen++ ] = WFD_ATTR_SESSION_INFO;
  1319. // Length:
  1320. // Note: In the WFD specification, the size of length field is 2.
  1321. RTW_PUT_BE16(wfdie + wfdielen, 0x0000);
  1322. wfdielen += 2;
  1323. // Todo: to add the list of WFD device info descriptor in WFD group.
  1324. }
  1325. pbuf = rtw_set_ie(pbuf, _VENDOR_SPECIFIC_IE_, wfdielen, (unsigned char *) wfdie, &len);
  1326. return len;
  1327. }
  1328. u32 build_provdisc_req_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf)
  1329. {
  1330. u8 wfdie[ MAX_WFD_IE_LEN] = { 0x00 };
  1331. u32 len=0, wfdielen = 0;
  1332. _adapter *padapter = pwdinfo->padapter;
  1333. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  1334. struct wifi_display_info* pwfd_info = padapter->wdinfo.wfd_info;
  1335. // WFD OUI
  1336. wfdielen = 0;
  1337. wfdie[ wfdielen++ ] = 0x50;
  1338. wfdie[ wfdielen++ ] = 0x6F;
  1339. wfdie[ wfdielen++ ] = 0x9A;
  1340. wfdie[ wfdielen++ ] = 0x0A; // WFA WFD v1.0
  1341. // Commented by Albert 20110825
  1342. // According to the WFD Specification, the provision discovery request frame should contain 3 WFD attributes
  1343. // 1. WFD Device Information
  1344. // 2. Associated BSSID ( Optional )
  1345. // 3. Local IP Adress ( Optional )
  1346. // WFD Device Information ATTR
  1347. // Type:
  1348. wfdie[ wfdielen++ ] = WFD_ATTR_DEVICE_INFO;
  1349. // Length:
  1350. // Note: In the WFD specification, the size of length field is 2.
  1351. RTW_PUT_BE16(wfdie + wfdielen, 0x0006);
  1352. wfdielen += 2;
  1353. // Value1:
  1354. // WFD device information
  1355. // WFD primary sink + available for WFD session + WiFi Direct mode + WSD ( WFD Service Discovery )
  1356. RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->wfd_device_type | WFD_DEVINFO_SESSION_AVAIL | WFD_DEVINFO_WSD );
  1357. wfdielen += 2;
  1358. // Value2:
  1359. // Session Management Control Port
  1360. // Default TCP port for RTSP messages is 554
  1361. RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->rtsp_ctrlport );
  1362. wfdielen += 2;
  1363. // Value3:
  1364. // WFD Device Maximum Throughput
  1365. // 300Mbps is the maximum throughput
  1366. RTW_PUT_BE16(wfdie + wfdielen, 300);
  1367. wfdielen += 2;
  1368. // Associated BSSID ATTR
  1369. // Type:
  1370. wfdie[ wfdielen++ ] = WFD_ATTR_ASSOC_BSSID;
  1371. // Length:
  1372. // Note: In the WFD specification, the size of length field is 2.
  1373. RTW_PUT_BE16(wfdie + wfdielen, 0x0006);
  1374. wfdielen += 2;
  1375. // Value:
  1376. // Associated BSSID
  1377. if ( check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE )
  1378. {
  1379. _rtw_memcpy( wfdie + wfdielen, &pmlmepriv->assoc_bssid[ 0 ], ETH_ALEN );
  1380. }
  1381. else
  1382. {
  1383. _rtw_memset( wfdie + wfdielen, 0x00, ETH_ALEN );
  1384. }
  1385. wfdielen += ETH_ALEN;
  1386. // Coupled Sink Information ATTR
  1387. // Type:
  1388. wfdie[ wfdielen++ ] = WFD_ATTR_COUPLED_SINK_INFO;
  1389. // Length:
  1390. // Note: In the WFD specification, the size of length field is 2.
  1391. RTW_PUT_BE16(wfdie + wfdielen, 0x0007);
  1392. wfdielen += 2;
  1393. // Value:
  1394. // Coupled Sink Status bitmap
  1395. // Not coupled/available for Coupling
  1396. wfdie[ wfdielen++ ] = 0;
  1397. // MAC Addr.
  1398. wfdie[ wfdielen++ ] = 0;
  1399. wfdie[ wfdielen++ ] = 0;
  1400. wfdie[ wfdielen++ ] = 0;
  1401. wfdie[ wfdielen++ ] = 0;
  1402. wfdie[ wfdielen++ ] = 0;
  1403. wfdie[ wfdielen++ ] = 0;
  1404. pbuf = rtw_set_ie(pbuf, _VENDOR_SPECIFIC_IE_, wfdielen, (unsigned char *) wfdie, &len);
  1405. return len;
  1406. }
  1407. u32 build_provdisc_resp_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf)
  1408. {
  1409. u8 wfdie[ MAX_WFD_IE_LEN] = { 0x00 };
  1410. u32 len=0, wfdielen = 0;
  1411. _adapter *padapter = pwdinfo->padapter;
  1412. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  1413. struct wifi_display_info* pwfd_info = padapter->wdinfo.wfd_info;
  1414. // WFD OUI
  1415. wfdielen = 0;
  1416. wfdie[ wfdielen++ ] = 0x50;
  1417. wfdie[ wfdielen++ ] = 0x6F;
  1418. wfdie[ wfdielen++ ] = 0x9A;
  1419. wfdie[ wfdielen++ ] = 0x0A; // WFA WFD v1.0
  1420. // Commented by Albert 20110825
  1421. // According to the WFD Specification, the provision discovery response frame should contain 3 WFD attributes
  1422. // 1. WFD Device Information
  1423. // 2. Associated BSSID ( Optional )
  1424. // 3. Local IP Adress ( Optional )
  1425. // WFD Device Information ATTR
  1426. // Type:
  1427. wfdie[ wfdielen++ ] = WFD_ATTR_DEVICE_INFO;
  1428. // Length:
  1429. // Note: In the WFD specification, the size of length field is 2.
  1430. RTW_PUT_BE16(wfdie + wfdielen, 0x0006);
  1431. wfdielen += 2;
  1432. // Value1:
  1433. // WFD device information
  1434. // WFD primary sink + available for WFD session + WiFi Direct mode + WSD ( WFD Service Discovery )
  1435. RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->wfd_device_type | WFD_DEVINFO_SESSION_AVAIL | WFD_DEVINFO_WSD );
  1436. wfdielen += 2;
  1437. // Value2:
  1438. // Session Management Control Port
  1439. // Default TCP port for RTSP messages is 554
  1440. RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->rtsp_ctrlport );
  1441. wfdielen += 2;
  1442. // Value3:
  1443. // WFD Device Maximum Throughput
  1444. // 300Mbps is the maximum throughput
  1445. RTW_PUT_BE16(wfdie + wfdielen, 300);
  1446. wfdielen += 2;
  1447. // Associated BSSID ATTR
  1448. // Type:
  1449. wfdie[ wfdielen++ ] = WFD_ATTR_ASSOC_BSSID;
  1450. // Length:
  1451. // Note: In the WFD specification, the size of length field is 2.
  1452. RTW_PUT_BE16(wfdie + wfdielen, 0x0006);
  1453. wfdielen += 2;
  1454. // Value:
  1455. // Associated BSSID
  1456. if ( check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE )
  1457. {
  1458. _rtw_memcpy( wfdie + wfdielen, &pmlmepriv->assoc_bssid[ 0 ], ETH_ALEN );
  1459. }
  1460. else
  1461. {
  1462. _rtw_memset( wfdie + wfdielen, 0x00, ETH_ALEN );
  1463. }
  1464. wfdielen += ETH_ALEN;
  1465. // Coupled Sink Information ATTR
  1466. // Type:
  1467. wfdie[ wfdielen++ ] = WFD_ATTR_COUPLED_SINK_INFO;
  1468. // Length:
  1469. // Note: In the WFD specification, the size of length field is 2.
  1470. RTW_PUT_BE16(wfdie + wfdielen, 0x0007);
  1471. wfdielen += 2;
  1472. // Value:
  1473. // Coupled Sink Status bitmap
  1474. // Not coupled/available for Coupling
  1475. wfdie[ wfdielen++ ] = 0;
  1476. // MAC Addr.
  1477. wfdie[ wfdielen++ ] = 0;
  1478. wfdie[ wfdielen++ ] = 0;
  1479. wfdie[ wfdielen++ ] = 0;
  1480. wfdie[ wfdielen++ ] = 0;
  1481. wfdie[ wfdielen++ ] = 0;
  1482. wfdie[ wfdielen++ ] = 0;
  1483. pbuf = rtw_set_ie(pbuf, _VENDOR_SPECIFIC_IE_, wfdielen, (unsigned char *) wfdie, &len);
  1484. return len;
  1485. }
  1486. #endif //CONFIG_WFD
  1487. u32 build_probe_resp_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pbuf)
  1488. {
  1489. u8 p2pie[ MAX_P2P_IE_LEN] = { 0x00 };
  1490. u32 len=0, p2pielen = 0;
  1491. #ifdef CONFIG_INTEL_WIDI
  1492. u8 zero_array_check[L2SDTA_SERVICE_VE_LEN] = { 0x00 };
  1493. #endif //CONFIG_INTEL_WIDI
  1494. // P2P OUI
  1495. p2pielen = 0;
  1496. p2pie[ p2pielen++ ] = 0x50;
  1497. p2pie[ p2pielen++ ] = 0x6F;
  1498. p2pie[ p2pielen++ ] = 0x9A;
  1499. p2pie[ p2pielen++ ] = 0x09; // WFA P2P v1.0
  1500. // Commented by Albert 20100907
  1501. // According to the P2P Specification, the probe response frame should contain 5 P2P attributes
  1502. // 1. P2P Capability
  1503. // 2. Extended Listen Timing
  1504. // 3. Notice of Absence ( NOA ) ( Only GO needs this )
  1505. // 4. Device Info
  1506. // 5. Group Info ( Only GO need this )
  1507. // P2P Capability ATTR
  1508. // Type:
  1509. p2pie[ p2pielen++ ] = P2P_ATTR_CAPABILITY;
  1510. // Length:
  1511. //*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
  1512. RTW_PUT_LE16(p2pie + p2pielen, 0x0002);
  1513. p2pielen += 2;
  1514. // Value:
  1515. // Device Capability Bitmap, 1 byte
  1516. p2pie[ p2pielen++ ] = DMP_P2P_DEVCAP_SUPPORT;
  1517. // Group Capability Bitmap, 1 byte
  1518. if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
  1519. {
  1520. p2pie[ p2pielen ] = (P2P_GRPCAP_GO | P2P_GRPCAP_INTRABSS);
  1521. if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_PROVISIONING_ING))
  1522. p2pie[ p2pielen ] |= P2P_GRPCAP_GROUP_FORMATION;
  1523. p2pielen++;
  1524. }
  1525. else if ( rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE) )
  1526. {
  1527. // Group Capability Bitmap, 1 byte
  1528. if ( pwdinfo->persistent_supported )
  1529. p2pie[ p2pielen++ ] = P2P_GRPCAP_PERSISTENT_GROUP | DMP_P2P_GRPCAP_SUPPORT;
  1530. else
  1531. p2pie[ p2pielen++ ] = DMP_P2P_GRPCAP_SUPPORT;
  1532. }
  1533. // Extended Listen Timing ATTR
  1534. // Type:
  1535. p2pie[ p2pielen++ ] = P2P_ATTR_EX_LISTEN_TIMING;
  1536. // Length:
  1537. //*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0004 );
  1538. RTW_PUT_LE16(p2pie + p2pielen, 0x0004);
  1539. p2pielen += 2;
  1540. // Value:
  1541. // Availability Period
  1542. //*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF );
  1543. RTW_PUT_LE16(p2pie + p2pielen, 0xFFFF);
  1544. p2pielen += 2;
  1545. // Availability Interval
  1546. //*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF );
  1547. RTW_PUT_LE16(p2pie + p2pielen, 0xFFFF);
  1548. p2pielen += 2;
  1549. // Notice of Absence ATTR
  1550. // Type:
  1551. // Length:
  1552. // Value:
  1553. if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
  1554. {
  1555. //go_add_noa_attr(pwdinfo);
  1556. }
  1557. // Device Info ATTR
  1558. // Type:
  1559. p2pie[ p2pielen++ ] = P2P_ATTR_DEVICE_INFO;
  1560. // Length:
  1561. // 21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes)
  1562. // + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes)
  1563. //*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 21 + pwdinfo->device_name_len );
  1564. #ifdef CONFIG_INTEL_WIDI
  1565. if( _rtw_memcmp( pwdinfo->padapter->mlmepriv.sa_ext, zero_array_check, L2SDTA_SERVICE_VE_LEN ) == _FALSE )
  1566. {
  1567. RTW_PUT_LE16(p2pie + p2pielen, 21 + 8 + pwdinfo->device_name_len);
  1568. }
  1569. else
  1570. #endif //CONFIG_INTEL_WIDI
  1571. RTW_PUT_LE16(p2pie + p2pielen, 21 + pwdinfo->device_name_len);
  1572. p2pielen += 2;
  1573. // Value:
  1574. // P2P Device Address
  1575. _rtw_memcpy( p2pie + p2pielen, pwdinfo->device_addr, ETH_ALEN );
  1576. p2pielen += ETH_ALEN;
  1577. // Config Method
  1578. // This field should be big endian. Noted by P2P specification.
  1579. //*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( pwdinfo->supported_wps_cm );
  1580. RTW_PUT_BE16(p2pie + p2pielen, pwdinfo->supported_wps_cm);
  1581. p2pielen += 2;
  1582. // Primary Device Type
  1583. // Category ID
  1584. //*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA );
  1585. RTW_PUT_BE16(p2pie + p2pielen, WPS_PDT_CID_MULIT_MEDIA);
  1586. p2pielen += 2;
  1587. // OUI
  1588. //*(u32*) ( p2pie + p2pielen ) = cpu_to_be32( WPSOUI );
  1589. RTW_PUT_BE32(p2pie + p2pielen, WPSOUI);
  1590. p2pielen += 4;
  1591. // Sub Category ID
  1592. //*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER );
  1593. RTW_PUT_BE16(p2pie + p2pielen, WPS_PDT_SCID_MEDIA_SERVER);
  1594. p2pielen += 2;
  1595. // Number of Secondary Device Types
  1596. #ifdef CONFIG_INTEL_WIDI
  1597. if( _rtw_memcmp( pwdinfo->padapter->mlmepriv.sa_ext, zero_array_check, L2SDTA_SERVICE_VE_LEN ) == _FALSE )
  1598. {
  1599. p2pie[ p2pielen++ ] = 0x01;
  1600. RTW_PUT_BE16(p2pie + p2pielen, WPS_PDT_CID_DISPLAYS);
  1601. p2pielen += 2;
  1602. RTW_PUT_BE32(p2pie + p2pielen, INTEL_DEV_TYPE_OUI);
  1603. p2pielen += 4;
  1604. RTW_PUT_BE16(p2pie + p2pielen, P2P_SCID_WIDI_CONSUMER_SINK);
  1605. p2pielen += 2;
  1606. }
  1607. else
  1608. #endif //CONFIG_INTEL_WIDI
  1609. p2pie[ p2pielen++ ] = 0x00; // No Secondary Device Type List
  1610. // Device Name
  1611. // Type:
  1612. //*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
  1613. RTW_PUT_BE16(p2pie + p2pielen, WPS_ATTR_DEVICE_NAME);
  1614. p2pielen += 2;
  1615. // Length:
  1616. //*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( pwdinfo->device_name_len );
  1617. RTW_PUT_BE16(p2pie + p2pielen, pwdinfo->device_name_len);
  1618. p2pielen += 2;
  1619. // Value:
  1620. _rtw_memcpy( p2pie + p2pielen, pwdinfo->device_name, pwdinfo->device_name_len );
  1621. p2pielen += pwdinfo->device_name_len;
  1622. // Group Info ATTR
  1623. // Type:
  1624. // Length:
  1625. // Value:
  1626. if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
  1627. {
  1628. p2pielen += go_add_group_info_attr(pwdinfo, p2pie + p2pielen);
  1629. }
  1630. pbuf = rtw_set_ie(pbuf, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &len);
  1631. return len;
  1632. }
  1633. u32 build_prov_disc_request_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pbuf, u8* pssid, u8 ussidlen, u8* pdev_raddr )
  1634. {
  1635. u8 p2pie[ MAX_P2P_IE_LEN] = { 0x00 };
  1636. u32 len=0, p2pielen = 0;
  1637. // P2P OUI
  1638. p2pielen = 0;
  1639. p2pie[ p2pielen++ ] = 0x50;
  1640. p2pie[ p2pielen++ ] = 0x6F;
  1641. p2pie[ p2pielen++ ] = 0x9A;
  1642. p2pie[ p2pielen++ ] = 0x09; // WFA P2P v1.0
  1643. // Commented by Albert 20110301
  1644. // According to the P2P Specification, the provision discovery request frame should contain 3 P2P attributes
  1645. // 1. P2P Capability
  1646. // 2. Device Info
  1647. // 3. Group ID ( When joining an operating P2P Group )
  1648. // P2P Capability ATTR
  1649. // Type:
  1650. p2pie[ p2pielen++ ] = P2P_ATTR_CAPABILITY;
  1651. // Length:
  1652. //*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
  1653. RTW_PUT_LE16(p2pie + p2pielen, 0x0002);
  1654. p2pielen += 2;
  1655. // Value:
  1656. // Device Capability Bitmap, 1 byte
  1657. p2pie[ p2pielen++ ] = DMP_P2P_DEVCAP_SUPPORT;
  1658. // Group Capability Bitmap, 1 byte
  1659. if ( pwdinfo->persistent_supported )
  1660. p2pie[ p2pielen++ ] = P2P_GRPCAP_PERSISTENT_GROUP | DMP_P2P_GRPCAP_SUPPORT;
  1661. else
  1662. p2pie[ p2pielen++ ] = DMP_P2P_GRPCAP_SUPPORT;
  1663. // Device Info ATTR
  1664. // Type:
  1665. p2pie[ p2pielen++ ] = P2P_ATTR_DEVICE_INFO;
  1666. // Length:
  1667. // 21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes)
  1668. // + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes)
  1669. //*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 21 + pwdinfo->device_name_len );
  1670. RTW_PUT_LE16(p2pie + p2pielen, 21 + pwdinfo->device_name_len);
  1671. p2pielen += 2;
  1672. // Value:
  1673. // P2P Device Address
  1674. _rtw_memcpy( p2pie + p2pielen, pwdinfo->device_addr, ETH_ALEN );
  1675. p2pielen += ETH_ALEN;
  1676. // Config Method
  1677. // This field should be big endian. Noted by P2P specification.
  1678. if ( pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_PBC )
  1679. {
  1680. //*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_CONFIG_METHOD_PBC );
  1681. RTW_PUT_BE16(p2pie + p2pielen, WPS_CONFIG_METHOD_PBC);
  1682. }
  1683. else
  1684. {
  1685. //*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_CONFIG_METHOD_DISPLAY );
  1686. RTW_PUT_BE16(p2pie + p2pielen, WPS_CONFIG_METHOD_DISPLAY);
  1687. }
  1688. p2pielen += 2;
  1689. // Primary Device Type
  1690. // Category ID
  1691. //*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA );
  1692. RTW_PUT_BE16(p2pie + p2pielen, WPS_PDT_CID_MULIT_MEDIA);
  1693. p2pielen += 2;
  1694. // OUI
  1695. //*(u32*) ( p2pie + p2pielen ) = cpu_to_be32( WPSOUI );
  1696. RTW_PUT_BE32(p2pie + p2pielen, WPSOUI);
  1697. p2pielen += 4;
  1698. // Sub Category ID
  1699. //*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER );
  1700. RTW_PUT_BE16(p2pie + p2pielen, WPS_PDT_SCID_MEDIA_SERVER);
  1701. p2pielen += 2;
  1702. // Number of Secondary Device Types
  1703. p2pie[ p2pielen++ ] = 0x00; // No Secondary Device Type List
  1704. // Device Name
  1705. // Type:
  1706. //*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
  1707. RTW_PUT_BE16(p2pie + p2pielen, WPS_ATTR_DEVICE_NAME);
  1708. p2pielen += 2;
  1709. // Length:
  1710. //*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( pwdinfo->device_name_len );
  1711. RTW_PUT_BE16(p2pie + p2pielen, pwdinfo->device_name_len);
  1712. p2pielen += 2;
  1713. // Value:
  1714. _rtw_memcpy( p2pie + p2pielen, pwdinfo->device_name, pwdinfo->device_name_len );
  1715. p2pielen += pwdinfo->device_name_len;
  1716. if ( rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) )
  1717. {
  1718. // Added by Albert 2011/05/19
  1719. // In this case, the pdev_raddr is the device address of the group owner.
  1720. // P2P Group ID ATTR
  1721. // Type:
  1722. p2pie[ p2pielen++ ] = P2P_ATTR_GROUP_ID;
  1723. // Length:
  1724. //*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( ETH_ALEN + ussidlen );
  1725. RTW_PUT_LE16(p2pie + p2pielen, ETH_ALEN + ussidlen);
  1726. p2pielen += 2;
  1727. // Value:
  1728. _rtw_memcpy( p2pie + p2pielen, pdev_raddr, ETH_ALEN );
  1729. p2pielen += ETH_ALEN;
  1730. _rtw_memcpy( p2pie + p2pielen, pssid, ussidlen );
  1731. p2pielen += ussidlen;
  1732. }
  1733. pbuf = rtw_set_ie(pbuf, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &len);
  1734. return len;
  1735. }
  1736. u32 build_assoc_resp_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pbuf, u8 status_code)
  1737. {
  1738. u8 p2pie[ MAX_P2P_IE_LEN] = { 0x00 };
  1739. u32 len=0, p2pielen = 0;
  1740. // P2P OUI
  1741. p2pielen = 0;
  1742. p2pie[ p2pielen++ ] = 0x50;
  1743. p2pie[ p2pielen++ ] = 0x6F;
  1744. p2pie[ p2pielen++ ] = 0x9A;
  1745. p2pie[ p2pielen++ ] = 0x09; // WFA P2P v1.0
  1746. // According to the P2P Specification, the Association response frame should contain 2 P2P attributes
  1747. // 1. Status
  1748. // 2. Extended Listen Timing (optional)
  1749. // Status ATTR
  1750. p2pielen += rtw_set_p2p_attr_content(&p2pie[p2pielen], P2P_ATTR_STATUS, 1, &status_code);
  1751. // Extended Listen Timing ATTR
  1752. // Type:
  1753. // Length:
  1754. // Value:
  1755. pbuf = rtw_set_ie(pbuf, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &len);
  1756. return len;
  1757. }
  1758. u32 build_deauth_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pbuf)
  1759. {
  1760. u32 len=0;
  1761. return len;
  1762. }
  1763. u32 process_probe_req_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pframe, uint len)
  1764. {
  1765. u8 *p;
  1766. u32 ret=_FALSE;
  1767. u8 *p2pie;
  1768. u32 p2pielen = 0;
  1769. int ssid_len=0, rate_cnt = 0;
  1770. p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_, _SUPPORTEDRATES_IE_, (int *)&rate_cnt,
  1771. len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_);
  1772. if ( rate_cnt <= 4 )
  1773. {
  1774. int i, g_rate =0;
  1775. for( i = 0; i < rate_cnt; i++ )
  1776. {
  1777. if ( ( ( *( p + 2 + i ) & 0xff ) != 0x02 ) &&
  1778. ( ( *( p + 2 + i ) & 0xff ) != 0x04 ) &&
  1779. ( ( *( p + 2 + i ) & 0xff ) != 0x0B ) &&
  1780. ( ( *( p + 2 + i ) & 0xff ) != 0x16 ) )
  1781. {
  1782. g_rate = 1;
  1783. }
  1784. }
  1785. if ( g_rate == 0 )
  1786. {
  1787. // There is no OFDM rate included in SupportedRates IE of this probe request frame
  1788. // The driver should response this probe request.
  1789. return ret;
  1790. }
  1791. }
  1792. else
  1793. {
  1794. // rate_cnt > 4 means the SupportRates IE contains the OFDM rate because the count of CCK rates are 4.
  1795. // We should proceed the following check for this probe request.
  1796. }
  1797. // Added comments by Albert 20100906
  1798. // There are several items we should check here.
  1799. // 1. This probe request frame must contain the P2P IE. (Done)
  1800. // 2. This probe request frame must contain the wildcard SSID. (Done)
  1801. // 3. Wildcard BSSID. (Todo)
  1802. // 4. Destination Address. ( Done in mgt_dispatcher function )
  1803. // 5. Requested Device Type in WSC IE. (Todo)
  1804. // 6. Device ID attribute in P2P IE. (Todo)
  1805. p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_, _SSID_IE_, (int *)&ssid_len,
  1806. len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_);
  1807. ssid_len &= 0xff; // Just last 1 byte is valid for ssid len of the probe request
  1808. if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE) || rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
  1809. {
  1810. if((p2pie=rtw_get_p2p_ie( pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_ , len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_ , NULL, &p2pielen)))
  1811. {
  1812. if ( (p != NULL) && _rtw_memcmp( ( void * ) ( p+2 ), ( void * ) pwdinfo->p2p_wildcard_ssid , 7 ))
  1813. {
  1814. //todo:
  1815. //Check Requested Device Type attributes in WSC IE.
  1816. //Check Device ID attribute in P2P IE
  1817. ret = _TRUE;
  1818. }
  1819. else if ( (p != NULL) && ( ssid_len == 0 ) )
  1820. {
  1821. ret = _TRUE;
  1822. }
  1823. }
  1824. else
  1825. {
  1826. //non -p2p device
  1827. }
  1828. }
  1829. return ret;
  1830. }
  1831. u32 process_assoc_req_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pframe, uint len, struct sta_info *psta)
  1832. {
  1833. u8 status_code = P2P_STATUS_SUCCESS;
  1834. u8 *pbuf, *pattr_content=NULL;
  1835. u32 attr_contentlen = 0;
  1836. u16 cap_attr=0;
  1837. unsigned short frame_type, ie_offset=0;
  1838. u8 * ies;
  1839. u32 ies_len;
  1840. u8 * p2p_ie;
  1841. u32 p2p_ielen = 0;
  1842. if(!rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
  1843. return P2P_STATUS_FAIL_REQUEST_UNABLE;
  1844. frame_type = GetFrameSubType(pframe);
  1845. if (frame_type == WIFI_ASSOCREQ)
  1846. {
  1847. ie_offset = _ASOCREQ_IE_OFFSET_;
  1848. }
  1849. else // WIFI_REASSOCREQ
  1850. {
  1851. ie_offset = _REASOCREQ_IE_OFFSET_;
  1852. }
  1853. ies = pframe + WLAN_HDR_A3_LEN + ie_offset;
  1854. ies_len = len - WLAN_HDR_A3_LEN - ie_offset;
  1855. p2p_ie = rtw_get_p2p_ie(ies , ies_len , NULL, &p2p_ielen);
  1856. if ( !p2p_ie )
  1857. {
  1858. DBG_8192C( "[%s] P2P IE not Found!!\n", __FUNCTION__ );
  1859. status_code = P2P_STATUS_FAIL_INVALID_PARAM;
  1860. }
  1861. else
  1862. {
  1863. DBG_8192C( "[%s] P2P IE Found!!\n", __FUNCTION__ );
  1864. }
  1865. while ( p2p_ie )
  1866. {
  1867. //Check P2P Capability ATTR
  1868. if( rtw_get_p2p_attr_content( p2p_ie, p2p_ielen, P2P_ATTR_CAPABILITY, (u8*)&cap_attr, (uint*) &attr_contentlen) )
  1869. {
  1870. DBG_8192C( "[%s] Got P2P Capability Attr!!\n", __FUNCTION__ );
  1871. cap_attr = le16_to_cpu(cap_attr);
  1872. psta->dev_cap = cap_attr&0xff;
  1873. }
  1874. //Check Extended Listen Timing ATTR
  1875. //Check P2P Device Info ATTR
  1876. if(rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_DEVICE_INFO, NULL, (uint*)&attr_contentlen))
  1877. {
  1878. DBG_8192C( "[%s] Got P2P DEVICE INFO Attr!!\n", __FUNCTION__ );
  1879. pattr_content = pbuf = rtw_zmalloc(attr_contentlen);
  1880. if(pattr_content)
  1881. {
  1882. u8 num_of_secdev_type;
  1883. u16 dev_name_len;
  1884. rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_DEVICE_INFO , pattr_content, (uint*)&attr_contentlen);
  1885. _rtw_memcpy(psta->dev_addr, pattr_content, ETH_ALEN);//P2P Device Address
  1886. pattr_content += ETH_ALEN;
  1887. _rtw_memcpy(&psta->config_methods, pattr_content, 2);//Config Methods
  1888. psta->config_methods = be16_to_cpu(psta->config_methods);
  1889. pattr_content += 2;
  1890. _rtw_memcpy(psta->primary_dev_type, pattr_content, 8);
  1891. pattr_content += 8;
  1892. num_of_secdev_type = *pattr_content;
  1893. pattr_content += 1;
  1894. if(num_of_secdev_type==0)
  1895. {
  1896. psta->num_of_secdev_type = 0;
  1897. }
  1898. else
  1899. {
  1900. u32 len;
  1901. psta->num_of_secdev_type = num_of_secdev_type;
  1902. len = (sizeof(psta->secdev_types_list)<(num_of_secdev_type*8)) ? (sizeof(psta->secdev_types_list)) : (num_of_secdev_type*8);
  1903. _rtw_memcpy(psta->secdev_types_list, pattr_content, len);
  1904. pattr_content += (num_of_secdev_type*8);
  1905. }
  1906. //dev_name_len = attr_contentlen - ETH_ALEN - 2 - 8 - 1 - (num_of_secdev_type*8);
  1907. psta->dev_name_len=0;
  1908. if(WPS_ATTR_DEVICE_NAME == be16_to_cpu(*(u16*)pattr_content))
  1909. {
  1910. dev_name_len = be16_to_cpu(*(u16*)(pattr_content+2));
  1911. psta->dev_name_len = (sizeof(psta->dev_name)<dev_name_len) ? sizeof(psta->dev_name):dev_name_len;
  1912. _rtw_memcpy(psta->dev_name, pattr_content+4, psta->dev_name_len);
  1913. }
  1914. rtw_mfree(pbuf, attr_contentlen);
  1915. }
  1916. }
  1917. //Get the next P2P IE
  1918. p2p_ie = rtw_get_p2p_ie(p2p_ie+p2p_ielen, ies_len -(p2p_ie -ies + p2p_ielen), NULL, &p2p_ielen);
  1919. }
  1920. return status_code;
  1921. }
  1922. u32 process_p2p_devdisc_req(struct wifidirect_info *pwdinfo, u8 *pframe, uint len)
  1923. {
  1924. u8 *frame_body;
  1925. u8 status, dialogToken;
  1926. struct sta_info *psta = NULL;
  1927. _adapter *padapter = pwdinfo->padapter;
  1928. struct sta_priv *pstapriv = &padapter->stapriv;
  1929. u8 *p2p_ie;
  1930. u32 p2p_ielen = 0;
  1931. frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
  1932. dialogToken = frame_body[7];
  1933. status = P2P_STATUS_FAIL_UNKNOWN_P2PGROUP;
  1934. if ( (p2p_ie=rtw_get_p2p_ie( frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, NULL, &p2p_ielen)) )
  1935. {
  1936. u8 groupid[ 38 ] = { 0x00 };
  1937. u8 dev_addr[ETH_ALEN] = { 0x00 };
  1938. u32 attr_contentlen = 0;
  1939. if(rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_GROUP_ID, groupid, &attr_contentlen))
  1940. {
  1941. if(_rtw_memcmp(pwdinfo->device_addr, groupid, ETH_ALEN) &&
  1942. _rtw_memcmp(pwdinfo->p2p_group_ssid, groupid+ETH_ALEN, pwdinfo->p2p_group_ssid_len))
  1943. {
  1944. attr_contentlen=0;
  1945. if(rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_DEVICE_ID, dev_addr, &attr_contentlen))
  1946. {
  1947. _irqL irqL;
  1948. _list *phead, *plist;
  1949. _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
  1950. phead = &pstapriv->asoc_list;
  1951. plist = get_next(phead);
  1952. //look up sta asoc_queue
  1953. while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)
  1954. {
  1955. psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
  1956. plist = get_next(plist);
  1957. if(psta->is_p2p_device && (psta->dev_cap&P2P_DEVCAP_CLIENT_DISCOVERABILITY) &&
  1958. _rtw_memcmp(psta->dev_addr, dev_addr, ETH_ALEN))
  1959. {
  1960. //_exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
  1961. //issue GO Discoverability Request
  1962. issue_group_disc_req(pwdinfo, psta->hwaddr);
  1963. //_enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
  1964. status = P2P_STATUS_SUCCESS;
  1965. break;
  1966. }
  1967. else
  1968. {
  1969. status = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
  1970. }
  1971. }
  1972. _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
  1973. }
  1974. else
  1975. {
  1976. status = P2P_STATUS_FAIL_INVALID_PARAM;
  1977. }
  1978. }
  1979. else
  1980. {
  1981. status = P2P_STATUS_FAIL_INVALID_PARAM;
  1982. }
  1983. }
  1984. }
  1985. //issue Device Discoverability Response
  1986. issue_p2p_devdisc_resp(pwdinfo, GetAddr2Ptr(pframe), status, dialogToken);
  1987. return (status==P2P_STATUS_SUCCESS) ? _TRUE:_FALSE;
  1988. }
  1989. u32 process_p2p_devdisc_resp(struct wifidirect_info *pwdinfo, u8 *pframe, uint len)
  1990. {
  1991. return _TRUE;
  1992. }
  1993. u8 process_p2p_provdisc_req(struct wifidirect_info *pwdinfo, u8 *pframe, uint len )
  1994. {
  1995. u8 *frame_body;
  1996. u8 *wpsie;
  1997. uint wps_ielen = 0, attr_contentlen = 0;
  1998. u16 uconfig_method = 0;
  1999. frame_body = (pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
  2000. if ( (wpsie=rtw_get_wps_ie( frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, NULL, &wps_ielen)) )
  2001. {
  2002. if ( rtw_get_wps_attr_content( wpsie, wps_ielen, WPS_ATTR_CONF_METHOD , ( u8* ) &uconfig_method, &attr_contentlen) )
  2003. {
  2004. uconfig_method = be16_to_cpu( uconfig_method );
  2005. switch( uconfig_method )
  2006. {
  2007. case WPS_CM_DISPLYA:
  2008. {
  2009. _rtw_memcpy( pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "dis", 3 );
  2010. break;
  2011. }
  2012. case WPS_CM_LABEL:
  2013. {
  2014. _rtw_memcpy( pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "lab", 3 );
  2015. break;
  2016. }
  2017. case WPS_CM_PUSH_BUTTON:
  2018. {
  2019. _rtw_memcpy( pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "pbc", 3 );
  2020. break;
  2021. }
  2022. case WPS_CM_KEYPAD:
  2023. {
  2024. _rtw_memcpy( pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "pad", 3 );
  2025. break;
  2026. }
  2027. }
  2028. issue_p2p_provision_resp( pwdinfo, GetAddr2Ptr(pframe), frame_body, uconfig_method);
  2029. }
  2030. }
  2031. DBG_871X( "[%s] config method = %s\n", __FUNCTION__, pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req );
  2032. return _TRUE;
  2033. }
  2034. u8 process_p2p_provdisc_resp(struct wifidirect_info *pwdinfo, u8 *pframe)
  2035. {
  2036. return _TRUE;
  2037. }
  2038. u8 rtw_p2p_get_peer_ch_list(struct wifidirect_info *pwdinfo, u8 *ch_content, u8 ch_cnt, u8 *peer_ch_list)
  2039. {
  2040. u8 i = 0, j = 0;
  2041. u8 temp = 0;
  2042. u8 ch_no = 0;
  2043. ch_content += 3;
  2044. ch_cnt -= 3;
  2045. while( ch_cnt > 0)
  2046. {
  2047. ch_content += 1;
  2048. ch_cnt -= 1;
  2049. temp = *ch_content;
  2050. for( i = 0 ; i < temp ; i++, j++ )
  2051. {
  2052. peer_ch_list[j] = *( ch_content + 1 + i );
  2053. }
  2054. ch_content += (temp + 1);
  2055. ch_cnt -= (temp + 1);
  2056. ch_no += temp ;
  2057. }
  2058. return ch_no;
  2059. }
  2060. u8 rtw_p2p_check_peer_oper_ch(struct mlme_ext_priv *pmlmeext, u8 ch)
  2061. {
  2062. u8 i = 0;
  2063. for( i = 0; i < pmlmeext->max_chan_nums; i++ )
  2064. {
  2065. if ( pmlmeext->channel_set[ i ].ChannelNum == ch )
  2066. {
  2067. return _SUCCESS;
  2068. }
  2069. }
  2070. return _FAIL;
  2071. }
  2072. u8 rtw_p2p_ch_inclusion(struct mlme_ext_priv *pmlmeext, u8 *peer_ch_list, u8 peer_ch_num, u8 *ch_list_inclusioned)
  2073. {
  2074. int i = 0, j = 0, temp = 0;
  2075. u8 ch_no = 0;
  2076. for( i = 0; i < peer_ch_num; i++ )
  2077. {
  2078. for( j = temp; j < pmlmeext->max_chan_nums; j++ )
  2079. {
  2080. if( *( peer_ch_list + i ) == pmlmeext->channel_set[ j ].ChannelNum )
  2081. {
  2082. ch_list_inclusioned[ ch_no++ ] = *( peer_ch_list + i );
  2083. temp = j;
  2084. break;
  2085. }
  2086. }
  2087. }
  2088. return ch_no;
  2089. }
  2090. u8 process_p2p_group_negotation_req( struct wifidirect_info *pwdinfo, u8 *pframe, uint len )
  2091. {
  2092. _adapter *padapter = pwdinfo->padapter;
  2093. u8 result = P2P_STATUS_SUCCESS;
  2094. u32 p2p_ielen = 0, wps_ielen = 0;
  2095. u8 * ies;
  2096. u32 ies_len;
  2097. u8 *p2p_ie;
  2098. u8 *wpsie;
  2099. u16 wps_devicepassword_id = 0x0000;
  2100. uint wps_devicepassword_id_len = 0;
  2101. #ifdef CONFIG_WFD
  2102. u8 wfd_ie[ 128 ] = { 0x00 };
  2103. u32 wfd_ielen = 0;
  2104. #ifdef CONFIG_TDLS
  2105. struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
  2106. #endif // CONFIG_TDLS
  2107. #endif // CONFIG_WFD
  2108. #ifdef CONFIG_CONCURRENT_MODE
  2109. _adapter *pbuddy_adapter = pwdinfo->padapter->pbuddy_adapter;
  2110. struct wifidirect_info *pbuddy_wdinfo = &pbuddy_adapter->wdinfo;
  2111. struct mlme_priv *pbuddy_mlmepriv = &pbuddy_adapter->mlmepriv;
  2112. struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
  2113. #endif
  2114. if ( (wpsie=rtw_get_wps_ie( pframe + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, NULL, &wps_ielen)) )
  2115. {
  2116. // Commented by Kurt 20120113
  2117. // If some device wants to do p2p handshake without sending prov_disc_req
  2118. // We have to get peer_req_cm from here.
  2119. if(_rtw_memcmp( pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "000", 3) )
  2120. {
  2121. rtw_get_wps_attr_content( wpsie, wps_ielen, WPS_ATTR_DEVICE_PWID, (u8*) &wps_devicepassword_id, &wps_devicepassword_id_len);
  2122. wps_devicepassword_id = be16_to_cpu( wps_devicepassword_id );
  2123. if ( wps_devicepassword_id == WPS_DPID_USER_SPEC )
  2124. {
  2125. _rtw_memcpy( pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "dis", 3 );
  2126. }
  2127. else if ( wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC )
  2128. {
  2129. _rtw_memcpy( pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "pad", 3 );
  2130. }
  2131. else
  2132. {
  2133. _rtw_memcpy( pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "pbc", 3 );
  2134. }
  2135. }
  2136. }
  2137. else
  2138. {
  2139. DBG_871X( "[%s] WPS IE not Found!!\n", __FUNCTION__ );
  2140. result = P2P_STATUS_FAIL_INCOMPATIBLE_PARAM;
  2141. rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL);
  2142. return( result );
  2143. }
  2144. if ( pwdinfo->ui_got_wps_info == P2P_NO_WPSINFO )
  2145. {
  2146. result = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
  2147. rtw_p2p_set_state(pwdinfo, P2P_STATE_TX_INFOR_NOREADY);
  2148. return( result );
  2149. }
  2150. ies = pframe + _PUBLIC_ACTION_IE_OFFSET_;
  2151. ies_len = len - _PUBLIC_ACTION_IE_OFFSET_;
  2152. p2p_ie = rtw_get_p2p_ie( ies, ies_len, NULL, &p2p_ielen );
  2153. if ( !p2p_ie )
  2154. {
  2155. DBG_871X( "[%s] P2P IE not Found!!\n", __FUNCTION__ );
  2156. result = P2P_STATUS_FAIL_INCOMPATIBLE_PARAM;
  2157. rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL);
  2158. }
  2159. while ( p2p_ie )
  2160. {
  2161. u8 attr_content = 0x00;
  2162. u32 attr_contentlen = 0;
  2163. u8 ch_content[100] = { 0x00 };
  2164. uint ch_cnt = 0;
  2165. u8 peer_ch_list[100] = { 0x00 };
  2166. u8 peer_ch_num = 0;
  2167. u8 ch_list_inclusioned[100] = { 0x00 };
  2168. u8 ch_num_inclusioned = 0;
  2169. u16 cap_attr;
  2170. rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_ING);
  2171. //Check P2P Capability ATTR
  2172. if(rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_CAPABILITY, (u8*)&cap_attr, (uint*)&attr_contentlen) )
  2173. {
  2174. cap_attr = le16_to_cpu(cap_attr);
  2175. #if defined(CONFIG_WFD) && defined(CONFIG_TDLS)
  2176. if(!(cap_attr & P2P_GRPCAP_INTRABSS) )
  2177. ptdlsinfo->ap_prohibited = _TRUE;
  2178. #endif //defined(CONFIG_WFD) && defined(CONFIG_TDLS)
  2179. }
  2180. if ( rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_GO_INTENT , &attr_content, &attr_contentlen) )
  2181. {
  2182. DBG_871X( "[%s] GO Intent = %d, tie = %d\n", __FUNCTION__, attr_content >> 1, attr_content & 0x01 );
  2183. pwdinfo->peer_intent = attr_content; // include both intent and tie breaker values.
  2184. if ( pwdinfo->intent == ( pwdinfo->peer_intent >> 1 ) )
  2185. {
  2186. // Try to match the tie breaker value
  2187. if ( pwdinfo->intent == P2P_MAX_INTENT )
  2188. {
  2189. rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
  2190. result = P2P_STATUS_FAIL_BOTH_GOINTENT_15;
  2191. }
  2192. else
  2193. {
  2194. if ( attr_content & 0x01 )
  2195. {
  2196. rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
  2197. }
  2198. else
  2199. {
  2200. rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO);
  2201. }
  2202. }
  2203. }
  2204. else if ( pwdinfo->intent > ( pwdinfo->peer_intent >> 1 ) )
  2205. {
  2206. rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO);
  2207. }
  2208. else
  2209. {
  2210. rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
  2211. }
  2212. if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
  2213. {
  2214. // Store the group id information.
  2215. _rtw_memcpy( pwdinfo->groupid_info.go_device_addr, pwdinfo->device_addr, ETH_ALEN );
  2216. _rtw_memcpy( pwdinfo->groupid_info.ssid, pwdinfo->nego_ssid, pwdinfo->nego_ssidlen );
  2217. }
  2218. }
  2219. attr_contentlen = 0;
  2220. if ( rtw_get_p2p_attr_content( p2p_ie, p2p_ielen, P2P_ATTR_INTENTED_IF_ADDR, pwdinfo->p2p_peer_interface_addr, &attr_contentlen ) )
  2221. {
  2222. if ( attr_contentlen != ETH_ALEN )
  2223. {
  2224. _rtw_memset( pwdinfo->p2p_peer_interface_addr, 0x00, ETH_ALEN );
  2225. }
  2226. }
  2227. if ( rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_CH_LIST, ch_content, &ch_cnt) )
  2228. {
  2229. peer_ch_num = rtw_p2p_get_peer_ch_list(pwdinfo, ch_content, ch_cnt, peer_ch_list);
  2230. ch_num_inclusioned = rtw_p2p_ch_inclusion(&padapter->mlmeextpriv, peer_ch_list, peer_ch_num, ch_list_inclusioned);
  2231. if( ch_num_inclusioned == 0)
  2232. {
  2233. DBG_871X( "[%s] No common channel in channel list!\n", __FUNCTION__ );
  2234. result = P2P_STATUS_FAIL_NO_COMMON_CH;
  2235. rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL);
  2236. break;
  2237. }
  2238. if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
  2239. {
  2240. if ( !rtw_p2p_is_channel_list_ok( pwdinfo->operating_channel,
  2241. ch_list_inclusioned, ch_num_inclusioned) )
  2242. {
  2243. #ifdef CONFIG_CONCURRENT_MODE
  2244. if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
  2245. {
  2246. DBG_871X( "[%s] desired channel NOT Found!\n", __FUNCTION__ );
  2247. result = P2P_STATUS_FAIL_NO_COMMON_CH;
  2248. rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL);
  2249. break;
  2250. }
  2251. else
  2252. #endif //CONFIG_CONCURRENT_MODE
  2253. {
  2254. u8 operatingch_info[5] = { 0x00 }, peer_operating_ch = 0;
  2255. attr_contentlen = 0;
  2256. if ( rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, operatingch_info, &attr_contentlen) )
  2257. {
  2258. peer_operating_ch = operatingch_info[4];
  2259. }
  2260. if ( rtw_p2p_is_channel_list_ok( peer_operating_ch,
  2261. ch_list_inclusioned, ch_num_inclusioned) )
  2262. {
  2263. /**
  2264. * Change our operating channel as peer's for compatibility.
  2265. */
  2266. pwdinfo->operating_channel = peer_operating_ch;
  2267. DBG_871X( "[%s] Change op ch to %02x as peer's\n", __FUNCTION__, pwdinfo->operating_channel);
  2268. }
  2269. else
  2270. {
  2271. // Take first channel of ch_list_inclusioned as operating channel
  2272. pwdinfo->operating_channel = ch_list_inclusioned[0];
  2273. DBG_871X( "[%s] Change op ch to %02x\n", __FUNCTION__, pwdinfo->operating_channel);
  2274. }
  2275. }
  2276. }
  2277. }
  2278. }
  2279. //Get the next P2P IE
  2280. p2p_ie = rtw_get_p2p_ie(p2p_ie+p2p_ielen, ies_len -(p2p_ie -ies + p2p_ielen), NULL, &p2p_ielen);
  2281. }
  2282. #ifdef CONFIG_WFD
  2283. // Added by Albert 20110823
  2284. // Try to get the TCP port information when receiving the negotiation request.
  2285. if ( rtw_get_wfd_ie( pframe + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, wfd_ie, &wfd_ielen ) )
  2286. {
  2287. u8 attr_content[ 10 ] = { 0x00 };
  2288. u32 attr_contentlen = 0;
  2289. DBG_871X( "[%s] WFD IE Found!!\n", __FUNCTION__ );
  2290. rtw_get_wfd_attr_content( wfd_ie, wfd_ielen, WFD_ATTR_DEVICE_INFO, attr_content, &attr_contentlen);
  2291. if ( attr_contentlen )
  2292. {
  2293. pwdinfo->wfd_info->peer_rtsp_ctrlport = RTW_GET_BE16( attr_content + 2 );
  2294. DBG_871X( "[%s] Peer PORT NUM = %d\n", __FUNCTION__, pwdinfo->wfd_info->peer_rtsp_ctrlport );
  2295. }
  2296. }
  2297. #endif // CONFIG_WFD
  2298. return( result );
  2299. }
  2300. u8 process_p2p_group_negotation_resp( struct wifidirect_info *pwdinfo, u8 *pframe, uint len )
  2301. {
  2302. _adapter *padapter = pwdinfo->padapter;
  2303. u8 result = P2P_STATUS_SUCCESS;
  2304. u32 p2p_ielen, wps_ielen;
  2305. u8 * ies;
  2306. u32 ies_len;
  2307. u8 * p2p_ie;
  2308. #ifdef CONFIG_WFD
  2309. u8 wfd_ie[ 128 ] = { 0x00 };
  2310. u32 wfd_ielen = 0;
  2311. #ifdef CONFIG_TDLS
  2312. struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
  2313. #endif // CONFIG_TDLS
  2314. #endif // CONFIG_WFD
  2315. ies = pframe + _PUBLIC_ACTION_IE_OFFSET_;
  2316. ies_len = len - _PUBLIC_ACTION_IE_OFFSET_;
  2317. // Be able to know which one is the P2P GO and which one is P2P client.
  2318. if ( rtw_get_wps_ie( ies, ies_len, NULL, &wps_ielen) )
  2319. {
  2320. }
  2321. else
  2322. {
  2323. DBG_871X( "[%s] WPS IE not Found!!\n", __FUNCTION__ );
  2324. result = P2P_STATUS_FAIL_INCOMPATIBLE_PARAM;
  2325. rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL);
  2326. }
  2327. p2p_ie = rtw_get_p2p_ie( ies, ies_len, NULL, &p2p_ielen );
  2328. if ( !p2p_ie )
  2329. {
  2330. rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
  2331. rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL);
  2332. result = P2P_STATUS_FAIL_INCOMPATIBLE_PARAM;
  2333. }
  2334. else
  2335. {
  2336. u8 attr_content = 0x00;
  2337. u32 attr_contentlen = 0;
  2338. u8 operatingch_info[5] = { 0x00 };
  2339. uint ch_cnt = 0;
  2340. u8 ch_content[100] = { 0x00 };
  2341. u8 groupid[ 38 ];
  2342. u16 cap_attr;
  2343. u8 peer_ch_list[100] = { 0x00 };
  2344. u8 peer_ch_num = 0;
  2345. u8 ch_list_inclusioned[100] = { 0x00 };
  2346. u8 ch_num_inclusioned = 0;
  2347. while ( p2p_ie ) // Found the P2P IE.
  2348. {
  2349. //Check P2P Capability ATTR
  2350. if(rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_CAPABILITY, (u8*)&cap_attr, (uint*)&attr_contentlen) )
  2351. {
  2352. cap_attr = le16_to_cpu(cap_attr);
  2353. #ifdef CONFIG_TDLS
  2354. if(!(cap_attr & P2P_GRPCAP_INTRABSS) )
  2355. ptdlsinfo->ap_prohibited = _TRUE;
  2356. #endif // CONFIG_TDLS
  2357. }
  2358. rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_STATUS, &attr_content, &attr_contentlen);
  2359. if ( attr_contentlen == 1 )
  2360. {
  2361. DBG_871X( "[%s] Status = %d\n", __FUNCTION__, attr_content );
  2362. if ( attr_content == P2P_STATUS_SUCCESS )
  2363. {
  2364. // Do nothing.
  2365. }
  2366. else
  2367. {
  2368. if ( P2P_STATUS_FAIL_INFO_UNAVAILABLE == attr_content ) {
  2369. rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_INFOR_NOREADY);
  2370. } else {
  2371. rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL);
  2372. }
  2373. rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
  2374. result = attr_content;
  2375. break;
  2376. }
  2377. }
  2378. // Try to get the peer's interface address
  2379. attr_contentlen = 0;
  2380. if ( rtw_get_p2p_attr_content( p2p_ie, p2p_ielen, P2P_ATTR_INTENTED_IF_ADDR, pwdinfo->p2p_peer_interface_addr, &attr_contentlen ) )
  2381. {
  2382. if ( attr_contentlen != ETH_ALEN )
  2383. {
  2384. _rtw_memset( pwdinfo->p2p_peer_interface_addr, 0x00, ETH_ALEN );
  2385. }
  2386. }
  2387. // Try to get the peer's intent and tie breaker value.
  2388. attr_content = 0x00;
  2389. attr_contentlen = 0;
  2390. if ( rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_GO_INTENT , &attr_content, &attr_contentlen) )
  2391. {
  2392. DBG_871X( "[%s] GO Intent = %d, tie = %d\n", __FUNCTION__, attr_content >> 1, attr_content & 0x01 );
  2393. pwdinfo->peer_intent = attr_content; // include both intent and tie breaker values.
  2394. if ( pwdinfo->intent == ( pwdinfo->peer_intent >> 1 ) )
  2395. {
  2396. // Try to match the tie breaker value
  2397. if ( pwdinfo->intent == P2P_MAX_INTENT )
  2398. {
  2399. rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
  2400. result = P2P_STATUS_FAIL_BOTH_GOINTENT_15;
  2401. rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL);
  2402. }
  2403. else
  2404. {
  2405. rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK);
  2406. rtw_p2p_set_pre_state(pwdinfo, P2P_STATE_GONEGO_OK);
  2407. if ( attr_content & 0x01 )
  2408. {
  2409. rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
  2410. }
  2411. else
  2412. {
  2413. rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO);
  2414. }
  2415. }
  2416. }
  2417. else if ( pwdinfo->intent > ( pwdinfo->peer_intent >> 1 ) )
  2418. {
  2419. rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK);
  2420. rtw_p2p_set_pre_state(pwdinfo, P2P_STATE_GONEGO_OK);
  2421. rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO);
  2422. }
  2423. else
  2424. {
  2425. rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK);
  2426. rtw_p2p_set_pre_state(pwdinfo, P2P_STATE_GONEGO_OK);
  2427. rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
  2428. }
  2429. if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
  2430. {
  2431. // Store the group id information.
  2432. _rtw_memcpy( pwdinfo->groupid_info.go_device_addr, pwdinfo->device_addr, ETH_ALEN );
  2433. _rtw_memcpy( pwdinfo->groupid_info.ssid, pwdinfo->nego_ssid, pwdinfo->nego_ssidlen );
  2434. }
  2435. }
  2436. // Try to get the operation channel information
  2437. attr_contentlen = 0;
  2438. if ( rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, operatingch_info, &attr_contentlen))
  2439. {
  2440. DBG_871X( "[%s] Peer's operating channel = %d\n", __FUNCTION__, operatingch_info[4] );
  2441. pwdinfo->peer_operating_ch = operatingch_info[4];
  2442. }
  2443. // Try to get the channel list information
  2444. if ( rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_CH_LIST, pwdinfo->channel_list_attr, &pwdinfo->channel_list_attr_len ) )
  2445. {
  2446. DBG_871X( "[%s] channel list attribute found, len = %d\n", __FUNCTION__, pwdinfo->channel_list_attr_len );
  2447. peer_ch_num = rtw_p2p_get_peer_ch_list(pwdinfo, pwdinfo->channel_list_attr, pwdinfo->channel_list_attr_len, peer_ch_list);
  2448. ch_num_inclusioned = rtw_p2p_ch_inclusion(&padapter->mlmeextpriv, peer_ch_list, peer_ch_num, ch_list_inclusioned);
  2449. if( ch_num_inclusioned == 0)
  2450. {
  2451. DBG_871X( "[%s] No common channel in channel list!\n", __FUNCTION__ );
  2452. result = P2P_STATUS_FAIL_NO_COMMON_CH;
  2453. rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL);
  2454. break;
  2455. }
  2456. if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
  2457. {
  2458. if ( !rtw_p2p_is_channel_list_ok( pwdinfo->operating_channel,
  2459. ch_list_inclusioned, ch_num_inclusioned) )
  2460. {
  2461. #ifdef CONFIG_CONCURRENT_MODE
  2462. if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
  2463. {
  2464. DBG_871X( "[%s] desired channel NOT Found!\n", __FUNCTION__ );
  2465. result = P2P_STATUS_FAIL_NO_COMMON_CH;
  2466. rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL);
  2467. break;
  2468. }
  2469. else
  2470. #endif //CONFIG_CONCURRENT_MODE
  2471. {
  2472. u8 operatingch_info[5] = { 0x00 }, peer_operating_ch = 0;
  2473. attr_contentlen = 0;
  2474. if ( rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, operatingch_info, &attr_contentlen) )
  2475. {
  2476. peer_operating_ch = operatingch_info[4];
  2477. }
  2478. if ( rtw_p2p_is_channel_list_ok( peer_operating_ch,
  2479. ch_list_inclusioned, ch_num_inclusioned) )
  2480. {
  2481. /**
  2482. * Change our operating channel as peer's for compatibility.
  2483. */
  2484. pwdinfo->operating_channel = peer_operating_ch;
  2485. DBG_871X( "[%s] Change op ch to %02x as peer's\n", __FUNCTION__, pwdinfo->operating_channel);
  2486. }
  2487. else
  2488. {
  2489. // Take first channel of ch_list_inclusioned as operating channel
  2490. pwdinfo->operating_channel = ch_list_inclusioned[0];
  2491. DBG_871X( "[%s] Change op ch to %02x\n", __FUNCTION__, pwdinfo->operating_channel);
  2492. }
  2493. }
  2494. }
  2495. }
  2496. }
  2497. else
  2498. {
  2499. DBG_871X( "[%s] channel list attribute not found!\n", __FUNCTION__);
  2500. }
  2501. // Try to get the group id information if peer is GO
  2502. attr_contentlen = 0;
  2503. _rtw_memset( groupid, 0x00, 38 );
  2504. if ( rtw_get_p2p_attr_content( p2p_ie, p2p_ielen, P2P_ATTR_GROUP_ID, groupid, &attr_contentlen) )
  2505. {
  2506. _rtw_memcpy( pwdinfo->groupid_info.go_device_addr, &groupid[0], ETH_ALEN );
  2507. _rtw_memcpy( pwdinfo->groupid_info.ssid, &groupid[6], attr_contentlen - ETH_ALEN );
  2508. }
  2509. //Get the next P2P IE
  2510. p2p_ie = rtw_get_p2p_ie(p2p_ie+p2p_ielen, ies_len -(p2p_ie -ies + p2p_ielen), NULL, &p2p_ielen);
  2511. }
  2512. }
  2513. #ifdef CONFIG_WFD
  2514. // Added by Albert 20111122
  2515. // Try to get the TCP port information when receiving the negotiation response.
  2516. if ( rtw_get_wfd_ie( pframe + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, wfd_ie, &wfd_ielen ) )
  2517. {
  2518. u8 attr_content[ 10 ] = { 0x00 };
  2519. u32 attr_contentlen = 0;
  2520. DBG_8192C( "[%s] WFD IE Found!!\n", __FUNCTION__ );
  2521. rtw_get_wfd_attr_content( wfd_ie, wfd_ielen, WFD_ATTR_DEVICE_INFO, attr_content, &attr_contentlen);
  2522. if ( attr_contentlen )
  2523. {
  2524. pwdinfo->wfd_info->peer_rtsp_ctrlport = RTW_GET_BE16( attr_content + 2 );
  2525. DBG_8192C( "[%s] Peer PORT NUM = %d\n", __FUNCTION__, pwdinfo->wfd_info->peer_rtsp_ctrlport );
  2526. }
  2527. }
  2528. #endif // CONFIG_WFD
  2529. return( result );
  2530. }
  2531. u8 process_p2p_group_negotation_confirm( struct wifidirect_info *pwdinfo, u8 *pframe, uint len )
  2532. {
  2533. u8 * ies;
  2534. u32 ies_len;
  2535. u8 * p2p_ie;
  2536. u32 p2p_ielen = 0;
  2537. u8 result = P2P_STATUS_SUCCESS;
  2538. ies = pframe + _PUBLIC_ACTION_IE_OFFSET_;
  2539. ies_len = len - _PUBLIC_ACTION_IE_OFFSET_;
  2540. p2p_ie = rtw_get_p2p_ie( ies, ies_len, NULL, &p2p_ielen );
  2541. while ( p2p_ie ) // Found the P2P IE.
  2542. {
  2543. u8 attr_content = 0x00, operatingch_info[5] = { 0x00 };
  2544. u8 groupid[ 38 ] = { 0x00 };
  2545. u32 attr_contentlen = 0;
  2546. pwdinfo->negotiation_dialog_token = 1;
  2547. rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_STATUS, &attr_content, &attr_contentlen);
  2548. if ( attr_contentlen == 1 )
  2549. {
  2550. DBG_871X( "[%s] Status = %d\n", __FUNCTION__, attr_content );
  2551. result = attr_content;
  2552. if ( attr_content == P2P_STATUS_SUCCESS )
  2553. {
  2554. u8 bcancelled = 0;
  2555. _cancel_timer( &pwdinfo->restore_p2p_state_timer, &bcancelled );
  2556. // Commented by Albert 20100911
  2557. // Todo: Need to handle the case which both Intents are the same.
  2558. rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK);
  2559. rtw_p2p_set_pre_state(pwdinfo, P2P_STATE_GONEGO_OK);
  2560. if ( ( pwdinfo->intent ) > ( pwdinfo->peer_intent >> 1 ) )
  2561. {
  2562. rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO);
  2563. }
  2564. else if ( ( pwdinfo->intent ) < ( pwdinfo->peer_intent >> 1 ) )
  2565. {
  2566. rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
  2567. }
  2568. else
  2569. {
  2570. // Have to compare the Tie Breaker
  2571. if ( pwdinfo->peer_intent & 0x01 )
  2572. {
  2573. rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
  2574. }
  2575. else
  2576. {
  2577. rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO);
  2578. }
  2579. }
  2580. #ifdef CONFIG_CONCURRENT_MODE
  2581. if ( check_buddy_fwstate(pwdinfo->padapter , _FW_LINKED ) )
  2582. {
  2583. // Switch back to the AP channel soon.
  2584. _set_timer( &pwdinfo->ap_p2p_switch_timer, 100 );
  2585. }
  2586. #endif
  2587. }
  2588. else
  2589. {
  2590. rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
  2591. rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL);
  2592. break;
  2593. }
  2594. }
  2595. // Try to get the group id information
  2596. attr_contentlen = 0;
  2597. _rtw_memset( groupid, 0x00, 38 );
  2598. if ( rtw_get_p2p_attr_content( p2p_ie, p2p_ielen, P2P_ATTR_GROUP_ID, groupid, &attr_contentlen) )
  2599. {
  2600. DBG_871X( "[%s] Ssid = %s, ssidlen = %zu\n", __FUNCTION__, &groupid[ETH_ALEN], strlen(&groupid[ETH_ALEN]) );
  2601. _rtw_memcpy( pwdinfo->groupid_info.go_device_addr, &groupid[0], ETH_ALEN );
  2602. _rtw_memcpy( pwdinfo->groupid_info.ssid, &groupid[6], attr_contentlen - ETH_ALEN );
  2603. }
  2604. attr_contentlen = 0;
  2605. if ( rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, operatingch_info, &attr_contentlen) )
  2606. {
  2607. DBG_871X( "[%s] Peer's operating channel = %d\n", __FUNCTION__, operatingch_info[4] );
  2608. pwdinfo->peer_operating_ch = operatingch_info[4];
  2609. }
  2610. //Get the next P2P IE
  2611. p2p_ie = rtw_get_p2p_ie(p2p_ie+p2p_ielen, ies_len -(p2p_ie -ies + p2p_ielen), NULL, &p2p_ielen);
  2612. }
  2613. return( result );
  2614. }
  2615. u8 process_p2p_presence_req(struct wifidirect_info *pwdinfo, u8 *pframe, uint len)
  2616. {
  2617. u8 *frame_body;
  2618. u8 dialogToken=0;
  2619. u8 status = P2P_STATUS_SUCCESS;
  2620. frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
  2621. dialogToken = frame_body[6];
  2622. //todo: check NoA attribute
  2623. issue_p2p_presence_resp(pwdinfo, GetAddr2Ptr(pframe), status, dialogToken);
  2624. return _TRUE;
  2625. }
  2626. void find_phase_handler( _adapter* padapter )
  2627. {
  2628. struct wifidirect_info *pwdinfo = &padapter->wdinfo;
  2629. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  2630. NDIS_802_11_SSID ssid;
  2631. _irqL irqL;
  2632. u8 _status = 0;
  2633. _func_enter_;
  2634. _rtw_memset((unsigned char*)&ssid, 0, sizeof(NDIS_802_11_SSID));
  2635. _rtw_memcpy(ssid.Ssid, pwdinfo->p2p_wildcard_ssid, P2P_WILDCARD_SSID_LEN );
  2636. ssid.SsidLength = P2P_WILDCARD_SSID_LEN;
  2637. rtw_p2p_set_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH);
  2638. _enter_critical_bh(&pmlmepriv->lock, &irqL);
  2639. _status = rtw_sitesurvey_cmd(padapter, &ssid, 1, NULL, 0);
  2640. _exit_critical_bh(&pmlmepriv->lock, &irqL);
  2641. _func_exit_;
  2642. }
  2643. void p2p_concurrent_handler( _adapter* padapter );
  2644. void restore_p2p_state_handler( _adapter* padapter )
  2645. {
  2646. struct wifidirect_info *pwdinfo = &padapter->wdinfo;
  2647. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  2648. _func_enter_;
  2649. if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING) || rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_FAIL))
  2650. {
  2651. rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
  2652. }
  2653. #ifdef CONFIG_CONCURRENT_MODE
  2654. if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
  2655. {
  2656. _adapter *pbuddy_adapter = padapter->pbuddy_adapter;
  2657. struct mlme_priv *pbuddy_mlmepriv = &pbuddy_adapter->mlmepriv;
  2658. struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
  2659. if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ) || rtw_p2p_chk_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_RSP))
  2660. {
  2661. set_channel_bwmode(padapter, pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode);
  2662. issue_nulldata(pbuddy_adapter, NULL, 0, 3, 500);
  2663. }
  2664. }
  2665. #endif
  2666. rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
  2667. if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE))
  2668. {
  2669. #ifdef CONFIG_CONCURRENT_MODE
  2670. p2p_concurrent_handler( padapter );
  2671. #else
  2672. // In the P2P client mode, the driver should not switch back to its listen channel
  2673. // because this P2P client should stay at the operating channel of P2P GO.
  2674. set_channel_bwmode( padapter, pwdinfo->listen_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
  2675. #endif
  2676. }
  2677. _func_exit_;
  2678. }
  2679. void pre_tx_invitereq_handler( _adapter* padapter )
  2680. {
  2681. struct wifidirect_info *pwdinfo = &padapter->wdinfo;
  2682. u8 val8 = 1;
  2683. _func_enter_;
  2684. set_channel_bwmode(padapter, pwdinfo->invitereq_info.peer_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
  2685. padapter->HalFunc.SetHwRegHandler(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
  2686. issue_probereq_p2p(padapter, NULL);
  2687. _set_timer( &pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT );
  2688. _func_exit_;
  2689. }
  2690. void pre_tx_provdisc_handler( _adapter* padapter )
  2691. {
  2692. struct wifidirect_info *pwdinfo = &padapter->wdinfo;
  2693. u8 val8 = 1;
  2694. _func_enter_;
  2695. set_channel_bwmode(padapter, pwdinfo->tx_prov_disc_info.peer_channel_num[0], HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
  2696. rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
  2697. issue_probereq_p2p(padapter, NULL);
  2698. _set_timer( &pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT );
  2699. _func_exit_;
  2700. }
  2701. void pre_tx_negoreq_handler( _adapter* padapter )
  2702. {
  2703. struct wifidirect_info *pwdinfo = &padapter->wdinfo;
  2704. u8 val8 = 1;
  2705. _func_enter_;
  2706. set_channel_bwmode(padapter, pwdinfo->nego_req_info.peer_channel_num[0], HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
  2707. rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
  2708. issue_probereq_p2p(padapter, NULL);
  2709. _set_timer( &pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT );
  2710. _func_exit_;
  2711. }
  2712. #ifdef CONFIG_CONCURRENT_MODE
  2713. void p2p_concurrent_handler( _adapter* padapter )
  2714. {
  2715. struct wifidirect_info *pwdinfo = &padapter->wdinfo;
  2716. //_adapter *pbuddy_adapter = padapter->pbuddy_adapter;
  2717. //struct wifidirect_info *pbuddy_wdinfo = &pbuddy_adapter->wdinfo;
  2718. //struct mlme_priv *pbuddy_mlmepriv = &pbuddy_adapter->mlmepriv;
  2719. //struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
  2720. u8 val8;
  2721. _func_enter_;
  2722. if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
  2723. {
  2724. PADAPTER pbuddy_adapter = padapter->pbuddy_adapter;
  2725. struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
  2726. pwdinfo->operating_channel = pbuddy_mlmeext->cur_channel;
  2727. if( pwdinfo->driver_interface == DRIVER_CFG80211 )
  2728. {
  2729. DBG_871X("%s, switch ch back to buddy's cur_channel=%d\n", __func__, pbuddy_mlmeext->cur_channel);
  2730. set_channel_bwmode(padapter, pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode);
  2731. issue_nulldata(pbuddy_adapter, NULL, 0, 3, 500);
  2732. }
  2733. else if( pwdinfo->driver_interface == DRIVER_WEXT )
  2734. {
  2735. if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE))
  2736. {
  2737. // Now, the driver stays on the AP's channel.
  2738. // If the pwdinfo->ext_listen_period = 0, that means the P2P listen state is not available on listen channel.
  2739. if ( pwdinfo->ext_listen_period > 0 )
  2740. {
  2741. DBG_8192C( "[%s] P2P_STATE_IDLE, ext_listen_period = %d\n", __FUNCTION__, pwdinfo->ext_listen_period );
  2742. if ( pbuddy_mlmeext->cur_channel != pwdinfo->listen_channel )
  2743. {
  2744. // Will switch to listen channel so that need to send the NULL data with PW bit to AP.
  2745. issue_nulldata(pbuddy_adapter, NULL, 1, 3, 500);
  2746. set_channel_bwmode(padapter, pwdinfo->listen_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
  2747. }
  2748. rtw_p2p_set_state(pwdinfo, P2P_STATE_LISTEN);
  2749. val8 = 1;
  2750. rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
  2751. // Todo: To check the value of pwdinfo->ext_listen_period is equal to 0 or not.
  2752. _set_timer( &pwdinfo->ap_p2p_switch_timer, pwdinfo->ext_listen_period );
  2753. }
  2754. }
  2755. else if ( rtw_p2p_chk_state(pwdinfo, P2P_STATE_LISTEN) ||
  2756. rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_FAIL) ||
  2757. ( rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING) && pwdinfo->nego_req_info.benable == _FALSE ) ||
  2758. rtw_p2p_chk_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_REQ) )
  2759. {
  2760. // Now, the driver is in the listen state of P2P mode.
  2761. DBG_8192C( "[%s] P2P_STATE_IDLE, ext_listen_interval = %d\n", __FUNCTION__, pwdinfo->ext_listen_interval );
  2762. // Commented by Albert 2012/11/01
  2763. // If the AP's channel is the same as the listen channel, we should still be in the listen state
  2764. // Other P2P device is still able to find this device out even this device is in the AP's channel.
  2765. // So, configure this device to be able to receive the probe request frame and set it to listen state.
  2766. if ( pbuddy_mlmeext->cur_channel != pwdinfo->listen_channel )
  2767. {
  2768. set_channel_bwmode(padapter, pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode);
  2769. val8 = 0;
  2770. padapter->HalFunc.SetHwRegHandler(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
  2771. rtw_p2p_set_state(pwdinfo, P2P_STATE_IDLE);
  2772. issue_nulldata(pbuddy_adapter, NULL, 0, 3, 500);
  2773. }
  2774. // Todo: To check the value of pwdinfo->ext_listen_interval is equal to 0 or not.
  2775. _set_timer( &pwdinfo->ap_p2p_switch_timer, pwdinfo->ext_listen_interval );
  2776. }
  2777. else if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_OK))
  2778. {
  2779. // The driver had finished the P2P handshake successfully.
  2780. val8 = 0;
  2781. rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
  2782. set_channel_bwmode(padapter, pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode);
  2783. issue_nulldata(pbuddy_adapter, NULL, 0, 3, 500);
  2784. }
  2785. else if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ))
  2786. {
  2787. val8 = 1;
  2788. set_channel_bwmode(padapter, pwdinfo->tx_prov_disc_info.peer_channel_num[0], HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
  2789. rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
  2790. issue_probereq_p2p(padapter, NULL);
  2791. _set_timer( &pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT );
  2792. }
  2793. else if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING) && pwdinfo->nego_req_info.benable == _TRUE)
  2794. {
  2795. val8 = 1;
  2796. set_channel_bwmode(padapter, pwdinfo->nego_req_info.peer_channel_num[0], HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
  2797. rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
  2798. issue_probereq_p2p(padapter, NULL);
  2799. _set_timer( &pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT );
  2800. }
  2801. else if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_INVITE_REQ ) && pwdinfo->invitereq_info.benable == _TRUE)
  2802. {
  2803. /*
  2804. val8 = 1;
  2805. set_channel_bwmode(padapter, , HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
  2806. rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
  2807. issue_probereq_p2p(padapter, NULL);
  2808. _set_timer( &pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT );
  2809. */
  2810. }
  2811. }
  2812. }
  2813. else
  2814. {
  2815. set_channel_bwmode( padapter, pwdinfo->listen_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
  2816. }
  2817. _func_exit_;
  2818. }
  2819. #endif
  2820. #ifdef CONFIG_IOCTL_CFG80211
  2821. static void ro_ch_handler(_adapter *padapter)
  2822. {
  2823. struct cfg80211_wifidirect_info *pcfg80211_wdinfo = &padapter->cfg80211_wdinfo;
  2824. struct wifidirect_info *pwdinfo = &padapter->wdinfo;
  2825. struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
  2826. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  2827. _func_enter_;
  2828. {
  2829. #ifdef CONFIG_CONCURRENT_MODE
  2830. if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
  2831. {
  2832. PADAPTER pbuddy_adapter = padapter->pbuddy_adapter;
  2833. struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
  2834. DBG_871X("%s, switch ch back to buddy's cur_channel=%d\n", __func__, pbuddy_mlmeext->cur_channel);
  2835. set_channel_bwmode(padapter, pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode);
  2836. pmlmeext->cur_channel = pbuddy_mlmeext->cur_channel;
  2837. }else
  2838. #endif //CONFIG_CONCURRENT_MODE
  2839. if( pcfg80211_wdinfo->restore_channel != pmlmeext->cur_channel )
  2840. {
  2841. if ( !check_fwstate(&padapter->mlmepriv, _FW_LINKED ) )
  2842. pmlmeext->cur_channel = pcfg80211_wdinfo->restore_channel;
  2843. set_channel_bwmode(padapter, pmlmeext->cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
  2844. }
  2845. rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
  2846. #ifdef CONFIG_DEBUG_CFG80211
  2847. DBG_871X("%s, role=%d, p2p_state=%d\n", __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo));
  2848. #endif
  2849. }
  2850. pcfg80211_wdinfo->is_ro_ch = _FALSE;
  2851. DBG_871X("cfg80211_remain_on_channel_expired\n");
  2852. rtw_cfg80211_remain_on_channel_expired(padapter,
  2853. pcfg80211_wdinfo->remain_on_ch_cookie,
  2854. &pcfg80211_wdinfo->remain_on_ch_channel,
  2855. pcfg80211_wdinfo->remain_on_ch_type, GFP_KERNEL);
  2856. _func_exit_;
  2857. }
  2858. static void ro_ch_timer_process (void *FunctionContext)
  2859. {
  2860. _adapter *adapter = (_adapter *)FunctionContext;
  2861. struct rtw_wdev_priv *pwdev_priv = wdev_to_priv(adapter->rtw_wdev);
  2862. //printk("%s \n", __FUNCTION__);
  2863. #ifdef CONFIG_CONCURRENT_MODE
  2864. ATOMIC_SET(&pwdev_priv->ro_ch_to, 1);
  2865. #endif
  2866. p2p_protocol_wk_cmd( adapter, P2P_RO_CH_WK);
  2867. }
  2868. static void rtw_change_p2pie_op_ch(_adapter *padapter, const u8 *frame_body, u32 len, u8 ch)
  2869. {
  2870. u8 *ies, *p2p_ie;
  2871. u32 ies_len, p2p_ielen;
  2872. PADAPTER pbuddy_adapter = padapter->pbuddy_adapter;
  2873. struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
  2874. ies = (u8*)(frame_body + _PUBLIC_ACTION_IE_OFFSET_);
  2875. ies_len = len - _PUBLIC_ACTION_IE_OFFSET_;
  2876. p2p_ie = rtw_get_p2p_ie( ies, ies_len, NULL, &p2p_ielen );
  2877. while ( p2p_ie ) {
  2878. u32 attr_contentlen = 0;
  2879. u8 *pattr = NULL;
  2880. //Check P2P_ATTR_OPERATING_CH
  2881. attr_contentlen = 0;
  2882. pattr = NULL;
  2883. if((pattr = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, NULL, (uint*)&attr_contentlen))!=NULL)
  2884. {
  2885. *(pattr+4) = ch;
  2886. }
  2887. //Get the next P2P IE
  2888. p2p_ie = rtw_get_p2p_ie(p2p_ie+p2p_ielen, ies_len -(p2p_ie -ies + p2p_ielen), NULL, &p2p_ielen);
  2889. }
  2890. }
  2891. static void rtw_change_p2pie_ch_list(_adapter *padapter, const u8 *frame_body, u32 len, u8 ch)
  2892. {
  2893. u8 *ies, *p2p_ie;
  2894. u32 ies_len, p2p_ielen;
  2895. PADAPTER pbuddy_adapter = padapter->pbuddy_adapter;
  2896. struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
  2897. ies = (u8*)(frame_body + _PUBLIC_ACTION_IE_OFFSET_);
  2898. ies_len = len - _PUBLIC_ACTION_IE_OFFSET_;
  2899. p2p_ie = rtw_get_p2p_ie( ies, ies_len, NULL, &p2p_ielen );
  2900. while (p2p_ie) {
  2901. u32 attr_contentlen = 0;
  2902. u8 *pattr = NULL;
  2903. //Check P2P_ATTR_CH_LIST
  2904. if ((pattr=rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_CH_LIST, NULL, (uint*)&attr_contentlen))!=NULL) {
  2905. int i;
  2906. u32 num_of_ch;
  2907. u8 *pattr_temp = pattr + 3 ;
  2908. attr_contentlen -= 3;
  2909. while (attr_contentlen>0) {
  2910. num_of_ch = *(pattr_temp+1);
  2911. for(i=0; i<num_of_ch; i++)
  2912. *(pattr_temp+2+i) = ch;
  2913. pattr_temp += (2+num_of_ch);
  2914. attr_contentlen -= (2+num_of_ch);
  2915. }
  2916. }
  2917. //Get the next P2P IE
  2918. p2p_ie = rtw_get_p2p_ie(p2p_ie+p2p_ielen, ies_len -(p2p_ie -ies + p2p_ielen), NULL, &p2p_ielen);
  2919. }
  2920. }
  2921. static bool rtw_chk_p2pie_ch_list_with_buddy(_adapter *padapter, const u8 *frame_body, u32 len)
  2922. {
  2923. bool fit = _FALSE;
  2924. #ifdef CONFIG_CONCURRENT_MODE
  2925. u8 *ies, *p2p_ie;
  2926. u32 ies_len, p2p_ielen;
  2927. PADAPTER pbuddy_adapter = padapter->pbuddy_adapter;
  2928. struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
  2929. u8 buddy_ch = pbuddy_mlmeext->cur_channel;
  2930. ies = (u8*)(frame_body + _PUBLIC_ACTION_IE_OFFSET_);
  2931. ies_len = len - _PUBLIC_ACTION_IE_OFFSET_;
  2932. p2p_ie = rtw_get_p2p_ie( ies, ies_len, NULL, &p2p_ielen );
  2933. while (p2p_ie) {
  2934. u32 attr_contentlen = 0;
  2935. u8 *pattr = NULL;
  2936. //Check P2P_ATTR_CH_LIST
  2937. if ((pattr=rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_CH_LIST, NULL, (uint*)&attr_contentlen))!=NULL) {
  2938. int i;
  2939. u32 num_of_ch;
  2940. u8 *pattr_temp = pattr + 3 ;
  2941. attr_contentlen -= 3;
  2942. while (attr_contentlen>0) {
  2943. num_of_ch = *(pattr_temp+1);
  2944. for(i=0; i<num_of_ch; i++) {
  2945. if (*(pattr_temp+2+i) == buddy_ch) {
  2946. DBG_871X(FUNC_ADPT_FMT" ch_list fit buddy_ch:%u\n", FUNC_ADPT_ARG(padapter), buddy_ch);
  2947. fit = _TRUE;
  2948. break;
  2949. }
  2950. }
  2951. pattr_temp += (2+num_of_ch);
  2952. attr_contentlen -= (2+num_of_ch);
  2953. }
  2954. }
  2955. //Get the next P2P IE
  2956. p2p_ie = rtw_get_p2p_ie(p2p_ie+p2p_ielen, ies_len -(p2p_ie -ies + p2p_ielen), NULL, &p2p_ielen);
  2957. }
  2958. #endif
  2959. return fit;
  2960. }
  2961. static bool rtw_chk_p2pie_op_ch_with_buddy(_adapter *padapter, const u8 *frame_body, u32 len)
  2962. {
  2963. bool fit = _FALSE;
  2964. #ifdef CONFIG_CONCURRENT_MODE
  2965. u8 *ies, *p2p_ie;
  2966. u32 ies_len, p2p_ielen;
  2967. PADAPTER pbuddy_adapter = padapter->pbuddy_adapter;
  2968. struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
  2969. u8 buddy_ch = pbuddy_mlmeext->cur_channel;
  2970. ies = (u8*)(frame_body + _PUBLIC_ACTION_IE_OFFSET_);
  2971. ies_len = len - _PUBLIC_ACTION_IE_OFFSET_;
  2972. p2p_ie = rtw_get_p2p_ie( ies, ies_len, NULL, &p2p_ielen );
  2973. while (p2p_ie) {
  2974. u32 attr_contentlen = 0;
  2975. u8 *pattr = NULL;
  2976. //Check P2P_ATTR_OPERATING_CH
  2977. attr_contentlen = 0;
  2978. pattr = NULL;
  2979. if((pattr = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, NULL, (uint*)&attr_contentlen))!=NULL) {
  2980. if (*(pattr+4) == buddy_ch) {
  2981. DBG_871X(FUNC_ADPT_FMT" op_ch fit buddy_ch:%u\n", FUNC_ADPT_ARG(padapter), buddy_ch);
  2982. }
  2983. }
  2984. //Get the next P2P IE
  2985. p2p_ie = rtw_get_p2p_ie(p2p_ie+p2p_ielen, ies_len -(p2p_ie -ies + p2p_ielen), NULL, &p2p_ielen);
  2986. }
  2987. #endif
  2988. return fit;
  2989. }
  2990. static void rtw_cfg80211_adjust_p2pie_channel(_adapter *padapter, const u8 *frame_body, u32 len)
  2991. {
  2992. #ifdef CONFIG_CONCURRENT_MODE
  2993. u8 *ies, *p2p_ie;
  2994. u32 ies_len, p2p_ielen;
  2995. PADAPTER pbuddy_adapter = padapter->pbuddy_adapter;
  2996. struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
  2997. ies = (u8*)(frame_body + _PUBLIC_ACTION_IE_OFFSET_);
  2998. ies_len = len - _PUBLIC_ACTION_IE_OFFSET_;
  2999. p2p_ie = rtw_get_p2p_ie( ies, ies_len, NULL, &p2p_ielen );
  3000. while ( p2p_ie )
  3001. {
  3002. u32 attr_contentlen = 0;
  3003. u8 *pattr = NULL;
  3004. //Check P2P_ATTR_CH_LIST
  3005. if((pattr=rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_CH_LIST, NULL, (uint*)&attr_contentlen))!=NULL)
  3006. {
  3007. int i;
  3008. u32 num_of_ch;
  3009. u8 *pattr_temp = pattr + 3 ;
  3010. attr_contentlen -= 3;
  3011. while(attr_contentlen>0)
  3012. {
  3013. num_of_ch = *(pattr_temp+1);
  3014. for(i=0; i<num_of_ch; i++)
  3015. *(pattr_temp+2+i) = pbuddy_mlmeext->cur_channel;//forcing to the same channel
  3016. pattr_temp += (2+num_of_ch);
  3017. attr_contentlen -= (2+num_of_ch);
  3018. }
  3019. }
  3020. //Check P2P_ATTR_OPERATING_CH
  3021. attr_contentlen = 0;
  3022. pattr = NULL;
  3023. if((pattr = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, NULL, (uint*)&attr_contentlen))!=NULL)
  3024. {
  3025. *(pattr+4) = pbuddy_mlmeext->cur_channel;//forcing to the same channel
  3026. }
  3027. //Get the next P2P IE
  3028. p2p_ie = rtw_get_p2p_ie(p2p_ie+p2p_ielen, ies_len -(p2p_ie -ies + p2p_ielen), NULL, &p2p_ielen);
  3029. }
  3030. #endif
  3031. }
  3032. #ifdef CONFIG_WFD
  3033. void rtw_append_wfd_ie(_adapter *padapter, u8 *buf, u32* len)
  3034. {
  3035. unsigned char *frame_body;
  3036. u8 category, action, OUI_Subtype, dialogToken=0;
  3037. u32 wfdielen = 0;
  3038. struct rtw_wdev_priv *pwdev_priv = wdev_to_priv(padapter->rtw_wdev);
  3039. frame_body = (unsigned char *)(buf + sizeof(struct rtw_ieee80211_hdr_3addr));
  3040. category = frame_body[0];
  3041. if(category == RTW_WLAN_CATEGORY_PUBLIC)
  3042. {
  3043. action = frame_body[1];
  3044. if (action == ACT_PUBLIC_VENDOR
  3045. && _rtw_memcmp(frame_body+2, P2P_OUI, 4) == _TRUE
  3046. )
  3047. {
  3048. OUI_Subtype = frame_body[6];
  3049. dialogToken = frame_body[7];
  3050. switch( OUI_Subtype )//OUI Subtype
  3051. {
  3052. case P2P_GO_NEGO_REQ:
  3053. {
  3054. wfdielen = build_nego_req_wfd_ie( &padapter->wdinfo, buf + ( *len ) );
  3055. (*len) += wfdielen;
  3056. break;
  3057. }
  3058. case P2P_GO_NEGO_RESP:
  3059. {
  3060. wfdielen = build_nego_resp_wfd_ie( &padapter->wdinfo, buf + ( *len ) );
  3061. (*len) += wfdielen;
  3062. break;
  3063. }
  3064. case P2P_GO_NEGO_CONF:
  3065. {
  3066. wfdielen = build_nego_confirm_wfd_ie( &padapter->wdinfo, buf + ( *len ) );
  3067. (*len) += wfdielen;
  3068. break;
  3069. }
  3070. case P2P_INVIT_REQ:
  3071. {
  3072. wfdielen = build_invitation_req_wfd_ie( &padapter->wdinfo, buf + ( *len ) );
  3073. (*len) += wfdielen;
  3074. break;
  3075. }
  3076. case P2P_INVIT_RESP:
  3077. {
  3078. wfdielen = build_invitation_resp_wfd_ie( &padapter->wdinfo, buf + ( *len ) );
  3079. (*len) += wfdielen;
  3080. break;
  3081. }
  3082. case P2P_DEVDISC_REQ:
  3083. break;
  3084. case P2P_DEVDISC_RESP:
  3085. break;
  3086. case P2P_PROVISION_DISC_REQ:
  3087. {
  3088. wfdielen = build_provdisc_req_wfd_ie( &padapter->wdinfo, buf + ( *len ) );
  3089. (*len) += wfdielen;
  3090. break;
  3091. }
  3092. case P2P_PROVISION_DISC_RESP:
  3093. {
  3094. wfdielen = build_provdisc_resp_wfd_ie( &padapter->wdinfo, buf + ( *len ) );
  3095. (*len) += wfdielen;
  3096. break;
  3097. }
  3098. default:
  3099. break;
  3100. }
  3101. }
  3102. }
  3103. else if(category == RTW_WLAN_CATEGORY_P2P)
  3104. {
  3105. OUI_Subtype = frame_body[5];
  3106. dialogToken = frame_body[6];
  3107. #ifdef CONFIG_DEBUG_CFG80211
  3108. DBG_871X("ACTION_CATEGORY_P2P: OUI=0x%x, OUI_Subtype=%d, dialogToken=%d\n",
  3109. cpu_to_be32( *( ( u32* ) ( frame_body + 1 ) ) ), OUI_Subtype, dialogToken);
  3110. #endif
  3111. switch(OUI_Subtype)
  3112. {
  3113. case P2P_NOTICE_OF_ABSENCE:
  3114. break;
  3115. case P2P_PRESENCE_REQUEST:
  3116. break;
  3117. case P2P_PRESENCE_RESPONSE:
  3118. break;
  3119. case P2P_GO_DISC_REQUEST:
  3120. break;
  3121. default:
  3122. break;
  3123. }
  3124. }
  3125. else
  3126. {
  3127. DBG_871X("%s, action frame category=%d\n", __func__, category);
  3128. //is_p2p_frame = (-1);
  3129. }
  3130. return;
  3131. }
  3132. #endif
  3133. u8 *dump_p2p_attr_ch_list(u8 *p2p_ie, uint p2p_ielen, u8 *buf, u32 buf_len)
  3134. {
  3135. uint attr_contentlen = 0;
  3136. u8 *pattr = NULL;
  3137. int w_sz = 0;
  3138. u8 ch_cnt = 0;
  3139. u8 ch_list[40];
  3140. bool continuous = _FALSE;
  3141. if ((pattr=rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_CH_LIST, NULL, &attr_contentlen))!=NULL) {
  3142. int i, j;
  3143. u32 num_of_ch;
  3144. u8 *pattr_temp = pattr + 3 ;
  3145. attr_contentlen -= 3;
  3146. _rtw_memset(ch_list, 0, 40);
  3147. while (attr_contentlen>0) {
  3148. num_of_ch = *(pattr_temp+1);
  3149. for(i=0; i<num_of_ch; i++) {
  3150. for (j=0;j<ch_cnt;j++) {
  3151. if (ch_list[j] == *(pattr_temp+2+i))
  3152. break;
  3153. }
  3154. if (j>=ch_cnt)
  3155. ch_list[ch_cnt++] = *(pattr_temp+2+i);
  3156. }
  3157. pattr_temp += (2+num_of_ch);
  3158. attr_contentlen -= (2+num_of_ch);
  3159. }
  3160. for (j=0;j<ch_cnt;j++) {
  3161. if (j == 0) {
  3162. w_sz += snprintf(buf+w_sz, buf_len-w_sz, "%u", ch_list[j]);
  3163. } else if (ch_list[j] - ch_list[j-1] != 1) {
  3164. w_sz += snprintf(buf+w_sz, buf_len-w_sz, ", %u", ch_list[j]);
  3165. } else if (j != ch_cnt-1 && ch_list[j+1] - ch_list[j] == 1) {
  3166. /* empty */
  3167. } else {
  3168. w_sz += snprintf(buf+w_sz, buf_len-w_sz, "-%u", ch_list[j]);
  3169. }
  3170. }
  3171. }
  3172. return buf;
  3173. }
  3174. int rtw_p2p_check_frames(_adapter *padapter, const u8 *buf, u32 len, u8 tx)
  3175. {
  3176. int is_p2p_frame = (-1);
  3177. unsigned char *frame_body;
  3178. u8 category, action, OUI_Subtype, dialogToken=0;
  3179. u8 *p2p_ie = NULL;
  3180. uint p2p_ielen = 0;
  3181. struct rtw_wdev_priv *pwdev_priv = wdev_to_priv(padapter->rtw_wdev);
  3182. int status = -1;
  3183. u8 ch_list_buf[128] = {'\0'};
  3184. int op_ch = -1;
  3185. u8 intent = 0;
  3186. frame_body = (unsigned char *)(buf + sizeof(struct rtw_ieee80211_hdr_3addr));
  3187. category = frame_body[0];
  3188. //just for check
  3189. if(category == RTW_WLAN_CATEGORY_PUBLIC)
  3190. {
  3191. action = frame_body[1];
  3192. if (action == ACT_PUBLIC_VENDOR
  3193. && _rtw_memcmp(frame_body+2, P2P_OUI, 4) == _TRUE
  3194. )
  3195. {
  3196. OUI_Subtype = frame_body[6];
  3197. dialogToken = frame_body[7];
  3198. is_p2p_frame = OUI_Subtype;
  3199. #ifdef CONFIG_DEBUG_CFG80211
  3200. DBG_871X("ACTION_CATEGORY_PUBLIC: ACT_PUBLIC_VENDOR, OUI=0x%x, OUI_Subtype=%d, dialogToken=%d\n",
  3201. cpu_to_be32( *( ( u32* ) ( frame_body + 2 ) ) ), OUI_Subtype, dialogToken);
  3202. #endif
  3203. p2p_ie = rtw_get_p2p_ie(
  3204. (u8 *)buf+sizeof(struct rtw_ieee80211_hdr_3addr)+_PUBLIC_ACTION_IE_OFFSET_,
  3205. len-sizeof(struct rtw_ieee80211_hdr_3addr)-_PUBLIC_ACTION_IE_OFFSET_,
  3206. NULL, &p2p_ielen);
  3207. switch( OUI_Subtype )//OUI Subtype
  3208. {
  3209. u8 *cont;
  3210. uint cont_len;
  3211. case P2P_GO_NEGO_REQ:
  3212. if (tx) {
  3213. #ifdef CONFIG_DRV_ISSUE_PROV_REQ // IOT FOR S2
  3214. if(pwdev_priv->provdisc_req_issued == _FALSE)
  3215. rtw_cfg80211_issue_p2p_provision_request(padapter, buf, len);
  3216. #endif //CONFIG_DRV_ISSUE_PROV_REQ
  3217. //pwdev_priv->provdisc_req_issued = _FALSE;
  3218. #ifdef CONFIG_CONCURRENT_MODE
  3219. if(check_buddy_fwstate(padapter, _FW_LINKED))
  3220. rtw_cfg80211_adjust_p2pie_channel(padapter, frame_body, len-sizeof(struct rtw_ieee80211_hdr_3addr));
  3221. #endif
  3222. }
  3223. if ((cont = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, NULL, &cont_len)))
  3224. op_ch = *(cont+4);
  3225. if ((cont = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_GO_INTENT, NULL, &cont_len)))
  3226. intent = *cont;
  3227. dump_p2p_attr_ch_list(p2p_ie, p2p_ielen, ch_list_buf, 128);
  3228. DBG_871X("RTW_%s:P2P_GO_NEGO_REQ, dialogToken=%d, intent:%u%s, op_ch:%d, ch_list:%s\n",
  3229. (tx==_TRUE)?"Tx":"Rx", dialogToken, (intent>>1), intent&0x1 ? "+" : "-", op_ch, ch_list_buf);
  3230. if (!tx) {
  3231. #ifdef CONFIG_CONCURRENT_MODE
  3232. if(check_buddy_fwstate(padapter, _FW_LINKED)
  3233. && rtw_chk_p2pie_ch_list_with_buddy(padapter, frame_body, len-sizeof(struct rtw_ieee80211_hdr_3addr)) == _FALSE)
  3234. {
  3235. DBG_871X(FUNC_ADPT_FMT" ch_list has no intersect with buddy\n", FUNC_ADPT_ARG(padapter));
  3236. rtw_change_p2pie_ch_list(padapter, frame_body, len-sizeof(struct rtw_ieee80211_hdr_3addr), 0);
  3237. }
  3238. #endif
  3239. }
  3240. break;
  3241. case P2P_GO_NEGO_RESP:
  3242. if (tx) {
  3243. #ifdef CONFIG_CONCURRENT_MODE
  3244. if(check_buddy_fwstate(padapter, _FW_LINKED))
  3245. rtw_cfg80211_adjust_p2pie_channel(padapter, frame_body, len-sizeof(struct rtw_ieee80211_hdr_3addr));
  3246. #endif
  3247. }
  3248. if ((cont = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, NULL, &cont_len)))
  3249. op_ch = *(cont+4);
  3250. if ((cont = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_GO_INTENT, NULL, &cont_len)))
  3251. intent = *cont;
  3252. if ((cont = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_STATUS, NULL, &cont_len)))
  3253. status = *cont;
  3254. dump_p2p_attr_ch_list(p2p_ie, p2p_ielen, ch_list_buf, 128);
  3255. DBG_871X("RTW_%s:P2P_GO_NEGO_RESP, dialogToken=%d, intent:%u%s, status:%d, op_ch:%d, ch_list:%s\n",
  3256. (tx==_TRUE)?"Tx":"Rx", dialogToken, (intent>>1), intent&0x1 ? "+" : "-", status, op_ch, ch_list_buf);
  3257. if (!tx) {
  3258. pwdev_priv->provdisc_req_issued = _FALSE;
  3259. #ifdef CONFIG_CONCURRENT_MODE
  3260. if(check_buddy_fwstate(padapter, _FW_LINKED)
  3261. && rtw_chk_p2pie_ch_list_with_buddy(padapter, frame_body, len-sizeof(struct rtw_ieee80211_hdr_3addr)) == _FALSE)
  3262. {
  3263. DBG_871X(FUNC_ADPT_FMT" ch_list has no intersect with buddy\n", FUNC_ADPT_ARG(padapter));
  3264. rtw_change_p2pie_ch_list(padapter, frame_body, len-sizeof(struct rtw_ieee80211_hdr_3addr), 0);
  3265. }
  3266. #endif
  3267. }
  3268. break;
  3269. case P2P_GO_NEGO_CONF:
  3270. if (tx) {
  3271. #ifdef CONFIG_CONCURRENT_MODE
  3272. if(check_buddy_fwstate(padapter, _FW_LINKED))
  3273. rtw_cfg80211_adjust_p2pie_channel(padapter, frame_body, len-sizeof(struct rtw_ieee80211_hdr_3addr));
  3274. #endif
  3275. }
  3276. if ((cont = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, NULL, &cont_len)))
  3277. op_ch = *(cont+4);
  3278. if ((cont = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_STATUS, NULL, &cont_len)))
  3279. status = *cont;
  3280. dump_p2p_attr_ch_list(p2p_ie, p2p_ielen, ch_list_buf, 128);
  3281. DBG_871X("RTW_%s:P2P_GO_NEGO_CONF, dialogToken=%d, status:%d, op_ch:%d, ch_list:%s\n",
  3282. (tx==_TRUE)?"Tx":"Rx", dialogToken, status, op_ch, ch_list_buf);
  3283. if (!tx) {
  3284. }
  3285. break;
  3286. case P2P_INVIT_REQ:
  3287. {
  3288. struct rtw_wdev_invit_info* invit_info = &pwdev_priv->invit_info;
  3289. int flags = -1;
  3290. if (tx) {
  3291. #ifdef CONFIG_CONCURRENT_MODE
  3292. if(check_buddy_fwstate(padapter, _FW_LINKED))
  3293. rtw_cfg80211_adjust_p2pie_channel(padapter, frame_body, len-sizeof(struct rtw_ieee80211_hdr_3addr));
  3294. #endif
  3295. }
  3296. if ((cont = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_INVITATION_FLAGS, NULL, &cont_len)))
  3297. flags = *cont;
  3298. if ((cont = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, NULL, &cont_len)))
  3299. op_ch = *(cont+4);
  3300. if (invit_info->token != dialogToken)
  3301. rtw_wdev_invit_info_init(invit_info);
  3302. invit_info->token = dialogToken;
  3303. invit_info->flags = (flags==-1) ? 0x0 : flags;
  3304. invit_info->req_op_ch= op_ch;
  3305. dump_p2p_attr_ch_list(p2p_ie, p2p_ielen, ch_list_buf, 128);
  3306. DBG_871X("RTW_%s:P2P_INVIT_REQ, dialogToken=%d, flags:0x%02x, op_ch:%d, ch_list:%s\n",
  3307. (tx==_TRUE)?"Tx":"Rx", dialogToken, flags, op_ch, ch_list_buf);
  3308. if (!tx) {
  3309. #ifdef CONFIG_CONCURRENT_MODE
  3310. if(check_buddy_fwstate(padapter, _FW_LINKED)
  3311. && rtw_chk_p2pie_ch_list_with_buddy(padapter, frame_body, len-sizeof(struct rtw_ieee80211_hdr_3addr)) == _FALSE)
  3312. {
  3313. DBG_871X(FUNC_ADPT_FMT" ch_list has no intersect with buddy\n", FUNC_ADPT_ARG(padapter));
  3314. rtw_change_p2pie_ch_list(padapter, frame_body, len-sizeof(struct rtw_ieee80211_hdr_3addr), 0);
  3315. }
  3316. #endif
  3317. }
  3318. break;
  3319. }
  3320. case P2P_INVIT_RESP:
  3321. {
  3322. struct rtw_wdev_invit_info* invit_info = &pwdev_priv->invit_info;
  3323. if (tx) {
  3324. #ifdef CONFIG_CONCURRENT_MODE
  3325. if(check_buddy_fwstate(padapter, _FW_LINKED))
  3326. rtw_cfg80211_adjust_p2pie_channel(padapter, frame_body, len-sizeof(struct rtw_ieee80211_hdr_3addr));
  3327. #endif
  3328. }
  3329. if ((cont = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_STATUS, NULL, &cont_len)))
  3330. status = *cont;
  3331. if ((cont = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, NULL, &cont_len)))
  3332. op_ch = *(cont+4);
  3333. if (invit_info->token != dialogToken) {
  3334. rtw_wdev_invit_info_init(invit_info);
  3335. } else {
  3336. invit_info->token = 0;
  3337. invit_info->status = (status==-1) ? 0xff : status;
  3338. invit_info->rsp_op_ch= op_ch;
  3339. }
  3340. dump_p2p_attr_ch_list(p2p_ie, p2p_ielen, ch_list_buf, 128);
  3341. DBG_871X("RTW_%s:P2P_INVIT_RESP, dialogToken=%d, status:%d, op_ch:%d, ch_list:%s\n",
  3342. (tx==_TRUE)?"Tx":"Rx", dialogToken, status, op_ch, ch_list_buf);
  3343. if (!tx) {
  3344. }
  3345. break;
  3346. }
  3347. case P2P_DEVDISC_REQ:
  3348. DBG_871X("RTW_%s:P2P_DEVDISC_REQ, dialogToken=%d\n", (tx==_TRUE)?"Tx":"Rx", dialogToken);
  3349. break;
  3350. case P2P_DEVDISC_RESP:
  3351. cont = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_STATUS, NULL, &cont_len);
  3352. DBG_871X("RTW_%s:P2P_DEVDISC_RESP, dialogToken=%d, status:%d\n", (tx==_TRUE)?"Tx":"Rx", dialogToken, cont?*cont:-1);
  3353. break;
  3354. case P2P_PROVISION_DISC_REQ:
  3355. {
  3356. size_t frame_body_len = len - sizeof(struct rtw_ieee80211_hdr_3addr);
  3357. u8 *p2p_ie;
  3358. uint p2p_ielen = 0;
  3359. uint contentlen = 0;
  3360. DBG_871X("RTW_%s:P2P_PROVISION_DISC_REQ, dialogToken=%d\n", (tx==_TRUE)?"Tx":"Rx", dialogToken);
  3361. //if(tx)
  3362. {
  3363. pwdev_priv->provdisc_req_issued = _FALSE;
  3364. if( (p2p_ie=rtw_get_p2p_ie( frame_body + _PUBLIC_ACTION_IE_OFFSET_, frame_body_len - _PUBLIC_ACTION_IE_OFFSET_, NULL, &p2p_ielen)))
  3365. {
  3366. if(rtw_get_p2p_attr_content( p2p_ie, p2p_ielen, P2P_ATTR_GROUP_ID, NULL, &contentlen))
  3367. {
  3368. pwdev_priv->provdisc_req_issued = _FALSE;//case: p2p_client join p2p GO
  3369. }
  3370. else
  3371. {
  3372. #ifdef CONFIG_DEBUG_CFG80211
  3373. DBG_871X("provdisc_req_issued is _TRUE\n");
  3374. #endif //CONFIG_DEBUG_CFG80211
  3375. pwdev_priv->provdisc_req_issued = _TRUE;//case: p2p_devices connection before Nego req.
  3376. }
  3377. }
  3378. }
  3379. }
  3380. break;
  3381. case P2P_PROVISION_DISC_RESP:
  3382. DBG_871X("RTW_%s:P2P_PROVISION_DISC_RESP, dialogToken=%d\n", (tx==_TRUE)?"Tx":"Rx", dialogToken);
  3383. break;
  3384. default:
  3385. DBG_871X("RTW_%s:OUI_Subtype=%d, dialogToken=%d\n", (tx==_TRUE)?"Tx":"Rx", OUI_Subtype, dialogToken);
  3386. break;
  3387. }
  3388. }
  3389. }
  3390. else if(category == RTW_WLAN_CATEGORY_P2P)
  3391. {
  3392. OUI_Subtype = frame_body[5];
  3393. dialogToken = frame_body[6];
  3394. #ifdef CONFIG_DEBUG_CFG80211
  3395. DBG_871X("ACTION_CATEGORY_P2P: OUI=0x%x, OUI_Subtype=%d, dialogToken=%d\n",
  3396. cpu_to_be32( *( ( u32* ) ( frame_body + 1 ) ) ), OUI_Subtype, dialogToken);
  3397. #endif
  3398. is_p2p_frame = OUI_Subtype;
  3399. switch(OUI_Subtype)
  3400. {
  3401. case P2P_NOTICE_OF_ABSENCE:
  3402. DBG_871X("RTW_%s:P2P_NOTICE_OF_ABSENCE, dialogToken=%d\n", (tx==_TRUE)?"TX":"RX", dialogToken);
  3403. break;
  3404. case P2P_PRESENCE_REQUEST:
  3405. DBG_871X("RTW_%s:P2P_PRESENCE_REQUEST, dialogToken=%d\n", (tx==_TRUE)?"TX":"RX", dialogToken);
  3406. break;
  3407. case P2P_PRESENCE_RESPONSE:
  3408. DBG_871X("RTW_%s:P2P_PRESENCE_RESPONSE, dialogToken=%d\n", (tx==_TRUE)?"TX":"RX", dialogToken);
  3409. break;
  3410. case P2P_GO_DISC_REQUEST:
  3411. DBG_871X("RTW_%s:P2P_GO_DISC_REQUEST, dialogToken=%d\n", (tx==_TRUE)?"TX":"RX", dialogToken);
  3412. break;
  3413. default:
  3414. DBG_871X("RTW_%s:OUI_Subtype=%d, dialogToken=%d\n", (tx==_TRUE)?"TX":"RX", OUI_Subtype, dialogToken);
  3415. break;
  3416. }
  3417. }
  3418. else
  3419. {
  3420. DBG_871X("RTW_%s:action frame category=%d\n", (tx==_TRUE)?"TX":"RX", category);
  3421. //is_p2p_frame = (-1);
  3422. }
  3423. return is_p2p_frame;
  3424. }
  3425. void rtw_init_cfg80211_wifidirect_info( _adapter* padapter)
  3426. {
  3427. struct cfg80211_wifidirect_info *pcfg80211_wdinfo = &padapter->cfg80211_wdinfo;
  3428. _rtw_memset(pcfg80211_wdinfo, 0x00, sizeof(struct cfg80211_wifidirect_info) );
  3429. _init_timer( &pcfg80211_wdinfo->remain_on_ch_timer, padapter->pnetdev, ro_ch_timer_process, padapter );
  3430. }
  3431. #endif //CONFIG_IOCTL_CFG80211
  3432. void p2p_protocol_wk_hdl(_adapter *padapter, int intCmdType)
  3433. {
  3434. struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
  3435. _func_enter_;
  3436. switch(intCmdType)
  3437. {
  3438. case P2P_FIND_PHASE_WK:
  3439. {
  3440. find_phase_handler( padapter );
  3441. break;
  3442. }
  3443. case P2P_RESTORE_STATE_WK:
  3444. {
  3445. restore_p2p_state_handler( padapter );
  3446. break;
  3447. }
  3448. case P2P_PRE_TX_PROVDISC_PROCESS_WK:
  3449. {
  3450. #ifdef CONFIG_CONCURRENT_MODE
  3451. if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
  3452. {
  3453. p2p_concurrent_handler( padapter );
  3454. }
  3455. else
  3456. {
  3457. pre_tx_provdisc_handler( padapter );
  3458. }
  3459. #else
  3460. pre_tx_provdisc_handler( padapter );
  3461. #endif
  3462. break;
  3463. }
  3464. case P2P_PRE_TX_INVITEREQ_PROCESS_WK:
  3465. {
  3466. #ifdef CONFIG_CONCURRENT_MODE
  3467. if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
  3468. {
  3469. p2p_concurrent_handler( padapter );
  3470. }
  3471. else
  3472. {
  3473. pre_tx_invitereq_handler( padapter );
  3474. }
  3475. #else
  3476. pre_tx_invitereq_handler( padapter );
  3477. #endif
  3478. break;
  3479. }
  3480. case P2P_PRE_TX_NEGOREQ_PROCESS_WK:
  3481. {
  3482. #ifdef CONFIG_CONCURRENT_MODE
  3483. if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
  3484. {
  3485. p2p_concurrent_handler( padapter );
  3486. }
  3487. else
  3488. {
  3489. pre_tx_negoreq_handler( padapter );
  3490. }
  3491. #else
  3492. pre_tx_negoreq_handler( padapter );
  3493. #endif
  3494. break;
  3495. }
  3496. #ifdef CONFIG_P2P
  3497. #ifdef CONFIG_CONCURRENT_MODE
  3498. case P2P_AP_P2P_CH_SWITCH_PROCESS_WK:
  3499. {
  3500. p2p_concurrent_handler( padapter );
  3501. break;
  3502. }
  3503. #endif
  3504. #endif
  3505. #ifdef CONFIG_IOCTL_CFG80211
  3506. case P2P_RO_CH_WK:
  3507. {
  3508. ro_ch_handler( padapter );
  3509. break;
  3510. }
  3511. #endif //CONFIG_IOCTL_CFG80211
  3512. }
  3513. _func_exit_;
  3514. }
  3515. #ifdef CONFIG_P2P_PS
  3516. void process_p2p_ps_ie(PADAPTER padapter, u8 *IEs, u32 IELength)
  3517. {
  3518. u8 * ies;
  3519. u32 ies_len;
  3520. u8 * p2p_ie;
  3521. u32 p2p_ielen = 0;
  3522. u8 noa_attr[MAX_P2P_IE_LEN] = { 0x00 };// NoA length should be n*(13) + 2
  3523. u32 attr_contentlen = 0;
  3524. struct wifidirect_info *pwdinfo = &( padapter->wdinfo );
  3525. u8 find_p2p = _FALSE, find_p2p_ps = _FALSE;
  3526. u8 noa_offset, noa_num, noa_index;
  3527. _func_enter_;
  3528. if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
  3529. {
  3530. return;
  3531. }
  3532. #ifdef CONFIG_CONCURRENT_MODE
  3533. if(padapter->iface_type != IFACE_PORT0)
  3534. return;
  3535. #endif
  3536. if(IELength <= _BEACON_IE_OFFSET_)
  3537. return;
  3538. ies = IEs + _BEACON_IE_OFFSET_;
  3539. ies_len = IELength - _BEACON_IE_OFFSET_;
  3540. p2p_ie = rtw_get_p2p_ie( ies, ies_len, NULL, &p2p_ielen);
  3541. while(p2p_ie)
  3542. {
  3543. find_p2p = _TRUE;
  3544. // Get Notice of Absence IE.
  3545. if(rtw_get_p2p_attr_content( p2p_ie, p2p_ielen, P2P_ATTR_NOA, noa_attr, &attr_contentlen))
  3546. {
  3547. find_p2p_ps = _TRUE;
  3548. noa_index = noa_attr[0];
  3549. if( (pwdinfo->p2p_ps_mode == P2P_PS_NONE) ||
  3550. (noa_index != pwdinfo->noa_index) )// if index change, driver should reconfigure related setting.
  3551. {
  3552. pwdinfo->noa_index = noa_index;
  3553. pwdinfo->opp_ps = noa_attr[1] >> 7;
  3554. pwdinfo->ctwindow = noa_attr[1] & 0x7F;
  3555. noa_offset = 2;
  3556. noa_num = 0;
  3557. // NoA length should be n*(13) + 2
  3558. if(attr_contentlen > 2)
  3559. {
  3560. while(noa_offset < attr_contentlen)
  3561. {
  3562. //_rtw_memcpy(&wifidirect_info->noa_count[noa_num], &noa_attr[noa_offset], 1);
  3563. pwdinfo->noa_count[noa_num] = noa_attr[noa_offset];
  3564. noa_offset += 1;
  3565. _rtw_memcpy(&pwdinfo->noa_duration[noa_num], &noa_attr[noa_offset], 4);
  3566. noa_offset += 4;
  3567. _rtw_memcpy(&pwdinfo->noa_interval[noa_num], &noa_attr[noa_offset], 4);
  3568. noa_offset += 4;
  3569. _rtw_memcpy(&pwdinfo->noa_start_time[noa_num], &noa_attr[noa_offset], 4);
  3570. noa_offset += 4;
  3571. noa_num++;
  3572. }
  3573. }
  3574. pwdinfo->noa_num = noa_num;
  3575. if( pwdinfo->opp_ps == 1 )
  3576. {
  3577. pwdinfo->p2p_ps_mode = P2P_PS_CTWINDOW;
  3578. // driver should wait LPS for entering CTWindow
  3579. if(padapter->pwrctrlpriv.bFwCurrentInPSMode == _TRUE)
  3580. {
  3581. p2p_ps_wk_cmd(padapter, P2P_PS_ENABLE, 1);
  3582. }
  3583. }
  3584. else if( pwdinfo->noa_num > 0 )
  3585. {
  3586. pwdinfo->p2p_ps_mode = P2P_PS_NOA;
  3587. p2p_ps_wk_cmd(padapter, P2P_PS_ENABLE, 1);
  3588. }
  3589. else if( pwdinfo->p2p_ps_mode > P2P_PS_NONE)
  3590. {
  3591. p2p_ps_wk_cmd(padapter, P2P_PS_DISABLE, 1);
  3592. }
  3593. }
  3594. break; // find target, just break.
  3595. }
  3596. //Get the next P2P IE
  3597. p2p_ie = rtw_get_p2p_ie(p2p_ie+p2p_ielen, ies_len -(p2p_ie -ies + p2p_ielen), NULL, &p2p_ielen);
  3598. }
  3599. if(find_p2p == _TRUE)
  3600. {
  3601. if( (pwdinfo->p2p_ps_mode > P2P_PS_NONE) && (find_p2p_ps == _FALSE) )
  3602. {
  3603. p2p_ps_wk_cmd(padapter, P2P_PS_DISABLE, 1);
  3604. }
  3605. }
  3606. _func_exit_;
  3607. }
  3608. void p2p_ps_wk_hdl(_adapter *padapter, u8 p2p_ps_state)
  3609. {
  3610. struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
  3611. struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
  3612. _func_enter_;
  3613. // Pre action for p2p state
  3614. switch(p2p_ps_state)
  3615. {
  3616. case P2P_PS_DISABLE:
  3617. pwdinfo->p2p_ps_state = p2p_ps_state;
  3618. rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_P2P_PS_OFFLOAD, (u8 *)(&p2p_ps_state));
  3619. pwdinfo->noa_index = 0;
  3620. pwdinfo->ctwindow = 0;
  3621. pwdinfo->opp_ps = 0;
  3622. pwdinfo->noa_num = 0;
  3623. pwdinfo->p2p_ps_mode = P2P_PS_NONE;
  3624. if(padapter->pwrctrlpriv.bFwCurrentInPSMode == _TRUE)
  3625. {
  3626. if(pwrpriv->smart_ps == 0)
  3627. {
  3628. pwrpriv->smart_ps = 2;
  3629. rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&(padapter->pwrctrlpriv.pwr_mode)));
  3630. }
  3631. }
  3632. break;
  3633. case P2P_PS_ENABLE:
  3634. if (pwdinfo->p2p_ps_mode > P2P_PS_NONE) {
  3635. pwdinfo->p2p_ps_state = p2p_ps_state;
  3636. if( pwdinfo->ctwindow > 0 )
  3637. {
  3638. if(pwrpriv->smart_ps != 0)
  3639. {
  3640. pwrpriv->smart_ps = 0;
  3641. DBG_871X("%s(): Enter CTW, change SmartPS\n", __FUNCTION__);
  3642. rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&(padapter->pwrctrlpriv.pwr_mode)));
  3643. }
  3644. }
  3645. rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_P2P_PS_OFFLOAD, (u8 *)(&p2p_ps_state));
  3646. }
  3647. break;
  3648. case P2P_PS_SCAN:
  3649. case P2P_PS_SCAN_DONE:
  3650. case P2P_PS_ALLSTASLEEP:
  3651. if (pwdinfo->p2p_ps_mode > P2P_PS_NONE) {
  3652. pwdinfo->p2p_ps_state = p2p_ps_state;
  3653. rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_P2P_PS_OFFLOAD, (u8 *)(&p2p_ps_state));
  3654. }
  3655. break;
  3656. default:
  3657. break;
  3658. }
  3659. _func_exit_;
  3660. }
  3661. u8 p2p_ps_wk_cmd(_adapter*padapter, u8 p2p_ps_state, u8 enqueue)
  3662. {
  3663. struct cmd_obj *ph2c;
  3664. struct drvextra_cmd_parm *pdrvextra_cmd_parm;
  3665. struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
  3666. struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
  3667. u8 res = _SUCCESS;
  3668. _func_enter_;
  3669. if ( rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)
  3670. #ifdef CONFIG_CONCURRENT_MODE
  3671. || (padapter->iface_type != IFACE_PORT0)
  3672. #endif
  3673. )
  3674. {
  3675. return res;
  3676. }
  3677. if(enqueue)
  3678. {
  3679. ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
  3680. if(ph2c==NULL){
  3681. res= _FAIL;
  3682. goto exit;
  3683. }
  3684. pdrvextra_cmd_parm = (struct drvextra_cmd_parm*)rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
  3685. if(pdrvextra_cmd_parm==NULL){
  3686. rtw_mfree((unsigned char *)ph2c, sizeof(struct cmd_obj));
  3687. res= _FAIL;
  3688. goto exit;
  3689. }
  3690. pdrvextra_cmd_parm->ec_id = P2P_PS_WK_CID;
  3691. pdrvextra_cmd_parm->type_size = p2p_ps_state;
  3692. pdrvextra_cmd_parm->pbuf = NULL;
  3693. init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra));
  3694. res = rtw_enqueue_cmd(pcmdpriv, ph2c);
  3695. }
  3696. else
  3697. {
  3698. p2p_ps_wk_hdl(padapter, p2p_ps_state);
  3699. }
  3700. exit:
  3701. _func_exit_;
  3702. return res;
  3703. }
  3704. #endif // CONFIG_P2P_PS
  3705. static void reset_ch_sitesurvey_timer_process (void *FunctionContext)
  3706. {
  3707. _adapter *adapter = (_adapter *)FunctionContext;
  3708. struct wifidirect_info *pwdinfo = &adapter->wdinfo;
  3709. if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
  3710. return;
  3711. DBG_871X( "[%s] In\n", __FUNCTION__ );
  3712. // Reset the operation channel information
  3713. pwdinfo->rx_invitereq_info.operation_ch[0] = 0;
  3714. pwdinfo->rx_invitereq_info.scan_op_ch_only = 0;
  3715. }
  3716. static void reset_ch_sitesurvey_timer_process2 (void *FunctionContext)
  3717. {
  3718. _adapter *adapter = (_adapter *)FunctionContext;
  3719. struct wifidirect_info *pwdinfo = &adapter->wdinfo;
  3720. if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
  3721. return;
  3722. DBG_871X( "[%s] In\n", __FUNCTION__ );
  3723. // Reset the operation channel information
  3724. pwdinfo->p2p_info.operation_ch[0] = 0;
  3725. pwdinfo->p2p_info.scan_op_ch_only = 0;
  3726. }
  3727. static void restore_p2p_state_timer_process (void *FunctionContext)
  3728. {
  3729. _adapter *adapter = (_adapter *)FunctionContext;
  3730. struct wifidirect_info *pwdinfo = &adapter->wdinfo;
  3731. if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
  3732. return;
  3733. p2p_protocol_wk_cmd( adapter, P2P_RESTORE_STATE_WK );
  3734. }
  3735. static void pre_tx_scan_timer_process (void *FunctionContext)
  3736. {
  3737. _adapter *adapter = (_adapter *) FunctionContext;
  3738. struct wifidirect_info *pwdinfo = &adapter->wdinfo;
  3739. _irqL irqL;
  3740. struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
  3741. u8 _status = 0;
  3742. if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
  3743. return;
  3744. _enter_critical_bh(&pmlmepriv->lock, &irqL);
  3745. if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ))
  3746. {
  3747. if ( _TRUE == pwdinfo->tx_prov_disc_info.benable ) // the provision discovery request frame is trigger to send or not
  3748. {
  3749. p2p_protocol_wk_cmd( adapter, P2P_PRE_TX_PROVDISC_PROCESS_WK );
  3750. //issue_probereq_p2p(adapter, NULL);
  3751. //_set_timer( &pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT );
  3752. }
  3753. }
  3754. else if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING))
  3755. {
  3756. if ( _TRUE == pwdinfo->nego_req_info.benable )
  3757. {
  3758. p2p_protocol_wk_cmd( adapter, P2P_PRE_TX_NEGOREQ_PROCESS_WK );
  3759. }
  3760. }
  3761. else if ( rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_INVITE_REQ ) )
  3762. {
  3763. if ( _TRUE == pwdinfo->invitereq_info.benable )
  3764. {
  3765. p2p_protocol_wk_cmd( adapter, P2P_PRE_TX_INVITEREQ_PROCESS_WK );
  3766. }
  3767. }
  3768. else
  3769. {
  3770. DBG_8192C( "[%s] p2p_state is %d, ignore!!\n", __FUNCTION__, rtw_p2p_state(pwdinfo) );
  3771. }
  3772. _exit_critical_bh(&pmlmepriv->lock, &irqL);
  3773. }
  3774. static void find_phase_timer_process (void *FunctionContext)
  3775. {
  3776. _adapter *adapter = (_adapter *)FunctionContext;
  3777. struct wifidirect_info *pwdinfo = &adapter->wdinfo;
  3778. if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
  3779. return;
  3780. adapter->wdinfo.find_phase_state_exchange_cnt++;
  3781. p2p_protocol_wk_cmd( adapter, P2P_FIND_PHASE_WK );
  3782. }
  3783. #ifdef CONFIG_CONCURRENT_MODE
  3784. void ap_p2p_switch_timer_process (void *FunctionContext)
  3785. {
  3786. _adapter *adapter = (_adapter *)FunctionContext;
  3787. struct wifidirect_info *pwdinfo = &adapter->wdinfo;
  3788. #ifdef CONFIG_IOCTL_CFG80211
  3789. struct rtw_wdev_priv *pwdev_priv = wdev_to_priv(adapter->rtw_wdev);
  3790. #endif
  3791. if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
  3792. return;
  3793. #ifdef CONFIG_IOCTL_CFG80211
  3794. ATOMIC_SET(&pwdev_priv->switch_ch_to, 1);
  3795. #endif
  3796. p2p_protocol_wk_cmd( adapter, P2P_AP_P2P_CH_SWITCH_PROCESS_WK );
  3797. }
  3798. #endif
  3799. void reset_global_wifidirect_info( _adapter* padapter )
  3800. {
  3801. struct wifidirect_info *pwdinfo;
  3802. pwdinfo = &padapter->wdinfo;
  3803. pwdinfo->persistent_supported = 0;
  3804. pwdinfo->session_available = _TRUE;
  3805. pwdinfo->wfd_tdls_enable = 0;
  3806. pwdinfo->wfd_tdls_weaksec = 0;
  3807. }
  3808. #ifdef CONFIG_WFD
  3809. int rtw_init_wifi_display_info(_adapter* padapter)
  3810. {
  3811. int res = _SUCCESS;
  3812. struct wifi_display_info *pwfd_info = &padapter->wfd_info;
  3813. // Used in P2P and TDLS
  3814. pwfd_info->rtsp_ctrlport = 554;
  3815. pwfd_info->peer_rtsp_ctrlport = 0; // Reset to 0
  3816. pwfd_info->wfd_enable = _FALSE;
  3817. pwfd_info->wfd_device_type = WFD_DEVINFO_PSINK;
  3818. pwfd_info->scan_result_type = SCAN_RESULT_P2P_ONLY;
  3819. // Used in P2P
  3820. pwfd_info->peer_session_avail = _TRUE;
  3821. pwfd_info->wfd_pc = _FALSE;
  3822. // Used in TDLS
  3823. _rtw_memset( pwfd_info->ip_address, 0x00, 4 );
  3824. _rtw_memset( pwfd_info->peer_ip_address, 0x00, 4 );
  3825. return res;
  3826. }
  3827. #endif //CONFIG_WFD
  3828. void rtw_init_wifidirect_timers(_adapter* padapter)
  3829. {
  3830. struct wifidirect_info *pwdinfo = &padapter->wdinfo;
  3831. _init_timer( &pwdinfo->find_phase_timer, padapter->pnetdev, find_phase_timer_process, padapter );
  3832. _init_timer( &pwdinfo->restore_p2p_state_timer, padapter->pnetdev, restore_p2p_state_timer_process, padapter );
  3833. _init_timer( &pwdinfo->pre_tx_scan_timer, padapter->pnetdev, pre_tx_scan_timer_process, padapter );
  3834. _init_timer( &pwdinfo->reset_ch_sitesurvey, padapter->pnetdev, reset_ch_sitesurvey_timer_process, padapter );
  3835. _init_timer( &pwdinfo->reset_ch_sitesurvey2, padapter->pnetdev, reset_ch_sitesurvey_timer_process2, padapter );
  3836. #ifdef CONFIG_CONCURRENT_MODE
  3837. _init_timer( &pwdinfo->ap_p2p_switch_timer, padapter->pnetdev, ap_p2p_switch_timer_process, padapter );
  3838. #endif
  3839. }
  3840. void rtw_init_wifidirect_addrs(_adapter* padapter, u8 *dev_addr, u8 *iface_addr)
  3841. {
  3842. #ifdef CONFIG_P2P
  3843. struct wifidirect_info *pwdinfo = &padapter->wdinfo;
  3844. /*init device&interface address */
  3845. if (dev_addr) {
  3846. _rtw_memcpy(pwdinfo->device_addr, dev_addr, ETH_ALEN);
  3847. }
  3848. if (iface_addr) {
  3849. _rtw_memcpy(pwdinfo->interface_addr, iface_addr, ETH_ALEN);
  3850. }
  3851. #endif
  3852. }
  3853. void init_wifidirect_info( _adapter* padapter, enum P2P_ROLE role)
  3854. {
  3855. struct wifidirect_info *pwdinfo;
  3856. #ifdef CONFIG_WFD
  3857. struct wifi_display_info *pwfd_info = &padapter->wfd_info;
  3858. #endif
  3859. #ifdef CONFIG_CONCURRENT_MODE
  3860. _adapter *pbuddy_adapter = padapter->pbuddy_adapter;
  3861. struct wifidirect_info *pbuddy_wdinfo;
  3862. struct mlme_priv *pbuddy_mlmepriv;
  3863. struct mlme_ext_priv *pbuddy_mlmeext;
  3864. #endif
  3865. pwdinfo = &padapter->wdinfo;
  3866. pwdinfo->padapter = padapter;
  3867. // 1, 6, 11 are the social channel defined in the WiFi Direct specification.
  3868. pwdinfo->social_chan[0] = 1;
  3869. pwdinfo->social_chan[1] = 6;
  3870. pwdinfo->social_chan[2] = 11;
  3871. pwdinfo->social_chan[3] = 0; // channel 0 for scanning ending in site survey function.
  3872. #ifdef CONFIG_CONCURRENT_MODE
  3873. if (pbuddy_adapter) {
  3874. pbuddy_wdinfo = &pbuddy_adapter->wdinfo;
  3875. pbuddy_mlmepriv = &pbuddy_adapter->mlmepriv;
  3876. pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
  3877. }
  3878. if ( ( check_buddy_fwstate(padapter, _FW_LINKED ) == _TRUE ) &&
  3879. ( ( pbuddy_mlmeext->cur_channel == 1) || ( pbuddy_mlmeext->cur_channel == 6 ) || ( pbuddy_mlmeext->cur_channel == 11 ) )
  3880. )
  3881. {
  3882. // Use the AP's channel as the listen channel
  3883. // This will avoid the channel switch between AP's channel and listen channel.
  3884. pwdinfo->listen_channel = pbuddy_mlmeext->cur_channel;
  3885. }
  3886. else
  3887. #endif //CONFIG_CONCURRENT_MODE
  3888. {
  3889. // Use the channel 11 as the listen channel
  3890. pwdinfo->listen_channel = 11;
  3891. }
  3892. if (role == P2P_ROLE_DEVICE)
  3893. {
  3894. rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
  3895. #ifdef CONFIG_CONCURRENT_MODE
  3896. if ( check_buddy_fwstate(padapter, _FW_LINKED ) == _TRUE )
  3897. {
  3898. rtw_p2p_set_state(pwdinfo, P2P_STATE_IDLE);
  3899. }
  3900. else
  3901. #endif
  3902. {
  3903. rtw_p2p_set_state(pwdinfo, P2P_STATE_LISTEN);
  3904. }
  3905. pwdinfo->intent = 1;
  3906. rtw_p2p_set_pre_state(pwdinfo, P2P_STATE_LISTEN);
  3907. }
  3908. else if (role == P2P_ROLE_CLIENT)
  3909. {
  3910. rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
  3911. rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK);
  3912. pwdinfo->intent = 1;
  3913. rtw_p2p_set_pre_state(pwdinfo, P2P_STATE_GONEGO_OK);
  3914. }
  3915. else if (role == P2P_ROLE_GO)
  3916. {
  3917. rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO);
  3918. rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK);
  3919. pwdinfo->intent = 15;
  3920. rtw_p2p_set_pre_state(pwdinfo, P2P_STATE_GONEGO_OK);
  3921. }
  3922. // Use the OFDM rate in the P2P probe response frame. ( 6(B), 9(B), 12, 18, 24, 36, 48, 54 )
  3923. pwdinfo->support_rate[0] = 0x8c; // 6(B)
  3924. pwdinfo->support_rate[1] = 0x92; // 9(B)
  3925. pwdinfo->support_rate[2] = 0x18; // 12
  3926. pwdinfo->support_rate[3] = 0x24; // 18
  3927. pwdinfo->support_rate[4] = 0x30; // 24
  3928. pwdinfo->support_rate[5] = 0x48; // 36
  3929. pwdinfo->support_rate[6] = 0x60; // 48
  3930. pwdinfo->support_rate[7] = 0x6c; // 54
  3931. _rtw_memcpy( ( void* ) pwdinfo->p2p_wildcard_ssid, "DIRECT-", 7 );
  3932. _rtw_memset( pwdinfo->device_name, 0x00, WPS_MAX_DEVICE_NAME_LEN );
  3933. pwdinfo->device_name_len = 0;
  3934. _rtw_memset( &pwdinfo->invitereq_info, 0x00, sizeof( struct tx_invite_req_info ) );
  3935. pwdinfo->invitereq_info.token = 3; // Token used for P2P invitation request frame.
  3936. _rtw_memset( &pwdinfo->inviteresp_info, 0x00, sizeof( struct tx_invite_resp_info ) );
  3937. pwdinfo->inviteresp_info.token = 0;
  3938. pwdinfo->profileindex = 0;
  3939. _rtw_memset( &pwdinfo->profileinfo[ 0 ], 0x00, sizeof( struct profile_info ) * P2P_MAX_PERSISTENT_GROUP_NUM );
  3940. rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_NONE);
  3941. pwdinfo->listen_dwell = ( u8 ) (( rtw_get_current_time() % 3 ) + 1);
  3942. //DBG_8192C( "[%s] listen_dwell time is %d00ms\n", __FUNCTION__, pwdinfo->listen_dwell );
  3943. _rtw_memset( &pwdinfo->tx_prov_disc_info, 0x00, sizeof( struct tx_provdisc_req_info ) );
  3944. pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_NONE;
  3945. _rtw_memset( &pwdinfo->nego_req_info, 0x00, sizeof( struct tx_nego_req_info ) );
  3946. pwdinfo->device_password_id_for_nego = WPS_DPID_PBC;
  3947. pwdinfo->negotiation_dialog_token = 1;
  3948. _rtw_memset( pwdinfo->nego_ssid, 0x00, WLAN_SSID_MAXLEN );
  3949. pwdinfo->nego_ssidlen = 0;
  3950. pwdinfo->ui_got_wps_info = P2P_NO_WPSINFO;
  3951. #ifdef CONFIG_WFD
  3952. pwdinfo->supported_wps_cm = WPS_CONFIG_METHOD_DISPLAY | WPS_CONFIG_METHOD_PBC;
  3953. pwdinfo->wfd_info = pwfd_info;
  3954. #else
  3955. pwdinfo->supported_wps_cm = WPS_CONFIG_METHOD_DISPLAY | WPS_CONFIG_METHOD_PBC | WPS_CONFIG_METHOD_KEYPAD;
  3956. #endif //CONFIG_WFD
  3957. pwdinfo->channel_list_attr_len = 0;
  3958. _rtw_memset( pwdinfo->channel_list_attr, 0x00, 100 );
  3959. _rtw_memset( pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, 0x00, 4 );
  3960. _rtw_memset( pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, '0', 3 );
  3961. _rtw_memset( &pwdinfo->groupid_info, 0x00, sizeof( struct group_id_info ) );
  3962. #ifdef CONFIG_CONCURRENT_MODE
  3963. #ifdef CONFIG_IOCTL_CFG80211
  3964. pwdinfo->ext_listen_interval = 1000; //The interval to be available with legacy AP during p2p0-find/scan
  3965. pwdinfo->ext_listen_period = 3000; //The time period to be available for P2P during nego
  3966. #else //!CONFIG_IOCTL_CFG80211
  3967. //pwdinfo->ext_listen_interval = 3000;
  3968. //pwdinfo->ext_listen_period = 400;
  3969. pwdinfo->ext_listen_interval = 1000;
  3970. pwdinfo->ext_listen_period = 1000;
  3971. #endif //!CONFIG_IOCTL_CFG80211
  3972. #endif
  3973. // Commented by Kurt 20130319
  3974. // For WiDi purpose: Use CFG80211 interface but controled WFD/RDS frame by driver itself.
  3975. #ifdef CONFIG_IOCTL_CFG80211
  3976. pwdinfo->driver_interface = DRIVER_CFG80211;
  3977. #else
  3978. pwdinfo->driver_interface = DRIVER_WEXT;
  3979. #endif //CONFIG_IOCTL_CFG80211
  3980. pwdinfo->wfd_tdls_enable = 0;
  3981. _rtw_memset( pwdinfo->p2p_peer_interface_addr, 0x00, ETH_ALEN );
  3982. _rtw_memset( pwdinfo->p2p_peer_device_addr, 0x00, ETH_ALEN );
  3983. pwdinfo->rx_invitereq_info.operation_ch[0] = 0;
  3984. pwdinfo->rx_invitereq_info.operation_ch[1] = 0; // Used to indicate the scan end in site survey function
  3985. pwdinfo->rx_invitereq_info.scan_op_ch_only = 0;
  3986. pwdinfo->p2p_info.operation_ch[0] = 0;
  3987. pwdinfo->p2p_info.operation_ch[1] = 0; // Used to indicate the scan end in site survey function
  3988. pwdinfo->p2p_info.scan_op_ch_only = 0;
  3989. }
  3990. #ifdef CONFIG_DBG_P2P
  3991. char * p2p_role_str[] = {
  3992. "P2P_ROLE_DISABLE",
  3993. "P2P_ROLE_DEVICE",
  3994. "P2P_ROLE_CLIENT",
  3995. "P2P_ROLE_GO"
  3996. };
  3997. char * p2p_state_str[] = {
  3998. "P2P_STATE_NONE",
  3999. "P2P_STATE_IDLE",
  4000. "P2P_STATE_LISTEN",
  4001. "P2P_STATE_SCAN",
  4002. "P2P_STATE_FIND_PHASE_LISTEN",
  4003. "P2P_STATE_FIND_PHASE_SEARCH",
  4004. "P2P_STATE_TX_PROVISION_DIS_REQ",
  4005. "P2P_STATE_RX_PROVISION_DIS_RSP",
  4006. "P2P_STATE_RX_PROVISION_DIS_REQ",
  4007. "P2P_STATE_GONEGO_ING",
  4008. "P2P_STATE_GONEGO_OK",
  4009. "P2P_STATE_GONEGO_FAIL",
  4010. "P2P_STATE_RECV_INVITE_REQ_MATCH",
  4011. "P2P_STATE_PROVISIONING_ING",
  4012. "P2P_STATE_PROVISIONING_DONE",
  4013. "P2P_STATE_RECV_INVITE_REQ_DISMATCH",
  4014. "P2P_STATE_RECV_INVITE_REQ_GO"
  4015. };
  4016. void dbg_rtw_p2p_set_state(struct wifidirect_info *wdinfo, enum P2P_STATE state, const char *caller, int line)
  4017. {
  4018. if(!_rtw_p2p_chk_state(wdinfo, state)) {
  4019. enum P2P_STATE old_state = _rtw_p2p_state(wdinfo);
  4020. _rtw_p2p_set_state(wdinfo, state);
  4021. DBG_871X("[CONFIG_DBG_P2P]%s:%d set_state from %s to %s\n", caller, line
  4022. , p2p_state_str[old_state], p2p_state_str[_rtw_p2p_state(wdinfo)]
  4023. );
  4024. } else {
  4025. DBG_871X("[CONFIG_DBG_P2P]%s:%d set_state to same state %s\n", caller, line
  4026. , p2p_state_str[_rtw_p2p_state(wdinfo)]
  4027. );
  4028. }
  4029. }
  4030. void dbg_rtw_p2p_set_pre_state(struct wifidirect_info *wdinfo, enum P2P_STATE state, const char *caller, int line)
  4031. {
  4032. if(_rtw_p2p_pre_state(wdinfo) != state) {
  4033. enum P2P_STATE old_state = _rtw_p2p_pre_state(wdinfo);
  4034. _rtw_p2p_set_pre_state(wdinfo, state);
  4035. DBG_871X("[CONFIG_DBG_P2P]%s:%d set_pre_state from %s to %s\n", caller, line
  4036. , p2p_state_str[old_state], p2p_state_str[_rtw_p2p_pre_state(wdinfo)]
  4037. );
  4038. } else {
  4039. DBG_871X("[CONFIG_DBG_P2P]%s:%d set_pre_state to same state %s\n", caller, line
  4040. , p2p_state_str[_rtw_p2p_pre_state(wdinfo)]
  4041. );
  4042. }
  4043. }
  4044. #if 0
  4045. void dbg_rtw_p2p_restore_state(struct wifidirect_info *wdinfo, const char *caller, int line)
  4046. {
  4047. if(wdinfo->pre_p2p_state != -1) {
  4048. DBG_871X("[CONFIG_DBG_P2P]%s:%d restore from %s to %s\n", caller, line
  4049. , p2p_state_str[wdinfo->p2p_state], p2p_state_str[wdinfo->pre_p2p_state]
  4050. );
  4051. _rtw_p2p_restore_state(wdinfo);
  4052. } else {
  4053. DBG_871X("[CONFIG_DBG_P2P]%s:%d restore no pre state, cur state %s\n", caller, line
  4054. , p2p_state_str[wdinfo->p2p_state]
  4055. );
  4056. }
  4057. }
  4058. #endif
  4059. void dbg_rtw_p2p_set_role(struct wifidirect_info *wdinfo, enum P2P_ROLE role, const char *caller, int line)
  4060. {
  4061. if(wdinfo->role != role) {
  4062. enum P2P_ROLE old_role = wdinfo->role;
  4063. _rtw_p2p_set_role(wdinfo, role);
  4064. DBG_871X("[CONFIG_DBG_P2P]%s:%d set_role from %s to %s\n", caller, line
  4065. , p2p_role_str[old_role], p2p_role_str[wdinfo->role]
  4066. );
  4067. } else {
  4068. DBG_871X("[CONFIG_DBG_P2P]%s:%d set_role to same role %s\n", caller, line
  4069. , p2p_role_str[wdinfo->role]
  4070. );
  4071. }
  4072. }
  4073. #endif //CONFIG_DBG_P2P
  4074. int rtw_p2p_enable(_adapter *padapter, enum P2P_ROLE role)
  4075. {
  4076. int ret = _SUCCESS;
  4077. struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
  4078. struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
  4079. if (role == P2P_ROLE_DEVICE || role == P2P_ROLE_CLIENT|| role == P2P_ROLE_GO)
  4080. {
  4081. u8 channel, ch_offset;
  4082. u16 bwmode;
  4083. #ifdef CONFIG_CONCURRENT_MODE
  4084. _adapter *pbuddy_adapter = padapter->pbuddy_adapter;
  4085. struct wifidirect_info *pbuddy_wdinfo = &pbuddy_adapter->wdinfo;
  4086. // Commented by Albert 2011/12/30
  4087. // The driver just supports 1 P2P group operation.
  4088. // So, this function will do nothing if the buddy adapter had enabled the P2P function.
  4089. if(!rtw_p2p_chk_state(pbuddy_wdinfo, P2P_STATE_NONE))
  4090. {
  4091. // The buddy adapter had enabled the P2P function.
  4092. return ret;
  4093. }
  4094. #endif //CONFIG_CONCURRENT_MODE
  4095. //leave IPS/Autosuspend
  4096. if (_FAIL == rtw_pwr_wakeup(padapter)) {
  4097. ret = _FAIL;
  4098. goto exit;
  4099. }
  4100. // Added by Albert 2011/03/22
  4101. // In the P2P mode, the driver should not support the b mode.
  4102. // So, the Tx packet shouldn't use the CCK rate
  4103. update_tx_basic_rate(padapter, WIRELESS_11AGN);
  4104. //Enable P2P function
  4105. init_wifidirect_info(padapter, role);
  4106. rtw_hal_set_odm_var(padapter,HAL_ODM_P2P_STATE,NULL,_TRUE);
  4107. #ifdef CONFIG_WFD
  4108. rtw_hal_set_odm_var(padapter,HAL_ODM_WIFI_DISPLAY_STATE,NULL,_TRUE);
  4109. #endif
  4110. }
  4111. else if (role == P2P_ROLE_DISABLE)
  4112. {
  4113. if (_FAIL == rtw_pwr_wakeup(padapter)) {
  4114. ret = _FAIL;
  4115. goto exit;
  4116. }
  4117. //Disable P2P function
  4118. if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
  4119. {
  4120. _cancel_timer_ex( &pwdinfo->find_phase_timer );
  4121. _cancel_timer_ex( &pwdinfo->restore_p2p_state_timer );
  4122. _cancel_timer_ex( &pwdinfo->pre_tx_scan_timer);
  4123. _cancel_timer_ex( &pwdinfo->reset_ch_sitesurvey);
  4124. _cancel_timer_ex( &pwdinfo->reset_ch_sitesurvey2);
  4125. reset_ch_sitesurvey_timer_process( padapter );
  4126. reset_ch_sitesurvey_timer_process2( padapter );
  4127. #ifdef CONFIG_CONCURRENT_MODE
  4128. _cancel_timer_ex( &pwdinfo->ap_p2p_switch_timer);
  4129. #endif
  4130. rtw_p2p_set_state(pwdinfo, P2P_STATE_NONE);
  4131. rtw_p2p_set_role(pwdinfo, P2P_ROLE_DISABLE);
  4132. _rtw_memset(&pwdinfo->rx_prov_disc_info, 0x00, sizeof(struct rx_provdisc_req_info));
  4133. }
  4134. rtw_hal_set_odm_var(padapter,HAL_ODM_P2P_STATE,NULL,_FALSE);
  4135. #ifdef CONFIG_WFD
  4136. rtw_hal_set_odm_var(padapter,HAL_ODM_WIFI_DISPLAY_STATE,NULL,_FALSE);
  4137. #endif
  4138. //Restore to initial setting.
  4139. update_tx_basic_rate(padapter, padapter->registrypriv.wireless_mode);
  4140. //For WiDi purpose.
  4141. #ifdef CONFIG_IOCTL_CFG80211
  4142. pwdinfo->driver_interface = DRIVER_CFG80211;
  4143. #else
  4144. pwdinfo->driver_interface = DRIVER_WEXT;
  4145. #endif //CONFIG_IOCTL_CFG80211
  4146. }
  4147. exit:
  4148. return ret;
  4149. }
  4150. #endif //CONFIG_P2P