mongoose.h 221 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024
  1. // Copyright (c) 2004-2013 Sergey Lyubka
  2. // Copyright (c) 2013-2025 Cesanta Software Limited
  3. // All rights reserved
  4. //
  5. // This software is dual-licensed: you can redistribute it and/or modify
  6. // it under the terms of the GNU General Public License version 2 as
  7. // published by the Free Software Foundation. For the terms of this
  8. // license, see http://www.gnu.org/licenses/
  9. //
  10. // You are free to use this software under the terms of the GNU General
  11. // Public License, but WITHOUT ANY WARRANTY; without even the implied
  12. // warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  13. // See the GNU General Public License for more details.
  14. //
  15. // Alternatively, you can license this software under a commercial
  16. // license, as set out in https://www.mongoose.ws/licensing/
  17. //
  18. // SPDX-License-Identifier: GPL-2.0-only or commercial
  19. #ifndef MONGOOSE_H
  20. #define MONGOOSE_H
  21. #define MG_VERSION "7.23"
  22. #ifdef __cplusplus
  23. extern "C" {
  24. #endif
  25. #define MG_ARCH_CUSTOM 0 // User creates its own mongoose_config.h
  26. #define MG_ARCH_UNIX 1 // Linux, BSD, Mac, ...
  27. #define MG_ARCH_WIN32 2 // Windows
  28. #define MG_ARCH_ESP32 3 // ESP32
  29. #define MG_ARCH_ESP8266 4 // ESP8266
  30. #define MG_ARCH_FREERTOS 5 // FreeRTOS <-- DEPRECATED !!!
  31. #define MG_ARCH_THREADX 6 // Eclipse ThreadX (former MS Azure RTOS)
  32. #define MG_ARCH_ZEPHYR 7 // Zephyr RTOS
  33. #define MG_ARCH_ARMGCC 8 // Plain ARM GCC
  34. #define MG_ARCH_CMSIS_RTOS1 9 // CMSIS-RTOS API v1 (Keil RTX)
  35. #define MG_ARCH_TIRTOS 10 // Texas Semi TI-RTOS
  36. #define MG_ARCH_PICOSDK 11 // Raspberry Pi Pico-SDK (RP2040, RP2350)
  37. #define MG_ARCH_ARMCC 12 // Keil MDK-Core with Configuration Wizard
  38. #define MG_ARCH_CMSIS_RTOS2 13 // CMSIS-RTOS API v2 (Keil RTX5, FreeRTOS)
  39. #define MG_ARCH_RTTHREAD 14 // RT-Thread RTOS
  40. #define MG_ARCH_ARMCGT 15 // Texas Semi ARM-CGT
  41. #define MG_ARCH_CUBE 16 // STM32Cube environment
  42. #define MG_ARCH_MCUXPRESSO 17 // MCUXpresso environment
  43. #define MG_ARCH_NEWLIB MG_ARCH_ARMGCC // Alias, deprecate in 2025
  44. #if !defined(MG_ARCH)
  45. #if defined(__unix__) || defined(__APPLE__)
  46. #define MG_ARCH MG_ARCH_UNIX
  47. #elif defined(_WIN32)
  48. #define MG_ARCH MG_ARCH_WIN32
  49. #endif
  50. #endif // !defined(MG_ARCH)
  51. #if !defined(MG_ARCH) || (MG_ARCH == MG_ARCH_CUSTOM)
  52. #include "mongoose_config.h" // keep this include
  53. #endif
  54. #if !defined(MG_ARCH)
  55. #error "MG_ARCH is not specified and we couldn't guess it. Define MG_ARCH=... in mongoose_config.h"
  56. #elif MG_ARCH == MG_ARCH_FREERTOS
  57. #error "MG_ARCH_FREERTOS has been deprecated, set MG_ARCH=your_build_environment and MG_ENABLE_FREERTOS=1 instead"
  58. #undef MG_ARCH // avoid errors piling up, provide a clean environment so the error above is seen
  59. #define MG_ARCH MG_ARCH_ARMGCC
  60. #define MG_ENABLE_FREERTOS 1
  61. #endif
  62. // http://esr.ibiblio.org/?p=5095
  63. #define MG_BIG_ENDIAN (*(uint16_t *) "\0\xff" < 0x100)
  64. #if MG_ARCH == MG_ARCH_ARMCGT
  65. #include <ctype.h>
  66. #include <errno.h>
  67. #include <stdarg.h>
  68. #include <stdbool.h>
  69. #include <stdio.h>
  70. #include <stdlib.h>
  71. #include <string.h>
  72. #include <sys/types.h>
  73. #include <time.h>
  74. #define MG_PATH_MAX 100
  75. #define MG_ENABLE_DIRLIST 0
  76. #endif
  77. #if MG_ARCH == MG_ARCH_ARMGCC
  78. #define _POSIX_TIMERS
  79. #include <ctype.h>
  80. #if !defined(MG_ENABLE_LWIP) || !MG_ENABLE_LWIP
  81. #include <errno.h>
  82. #endif
  83. #include <stdarg.h>
  84. #include <stdbool.h>
  85. #include <stdio.h>
  86. #include <stdlib.h>
  87. #include <string.h>
  88. #include <sys/stat.h>
  89. #include <sys/time.h>
  90. #include <sys/types.h>
  91. #include <time.h>
  92. #include <unistd.h>
  93. #define MG_PATH_MAX 100
  94. #define MG_ENABLE_DIRLIST 0
  95. #endif
  96. #if MG_ARCH == MG_ARCH_CUBE
  97. #include <ctype.h>
  98. #if !defined(MG_ENABLE_LWIP) || !MG_ENABLE_LWIP
  99. #include <errno.h>
  100. #endif
  101. #include <stdarg.h>
  102. #include <stdbool.h>
  103. #include <stdio.h>
  104. #include <stdlib.h>
  105. #include <string.h>
  106. #include <sys/stat.h>
  107. #include <sys/time.h>
  108. #include <sys/types.h>
  109. #include <time.h>
  110. #include <unistd.h>
  111. // Cube-generated header, includes ST Cube HAL
  112. // NOTE: use angle brackets to prevent amalgamator ditching it
  113. #include <main.h>
  114. #ifndef MG_PATH_MAX
  115. #define MG_PATH_MAX 100
  116. #endif
  117. #ifndef MG_ENABLE_DIRLIST
  118. #define MG_ENABLE_DIRLIST 0
  119. #endif
  120. #ifndef MG_ENABLE_TCPIP
  121. #define MG_ENABLE_TCPIP 1 // Enable built-in TCP/IP stack
  122. #endif
  123. #if MG_ENABLE_TCPIP && !defined(MG_ENABLE_DRIVER_STM32F) && \
  124. !defined(MG_ENABLE_DRIVER_STM32H) && !defined(MG_ENABLE_DRIVER_STM32N) && \
  125. !defined(MG_ENABLE_DRIVER_CYW) && !defined(MG_ENABLE_DRIVER_CYW_SDIO) && \
  126. !defined(MG_ENABLE_DRIVER_ST67W6)
  127. #if defined(STM32F1) || defined(STM32F2) || defined(STM32F4) || defined(STM32F7)
  128. #define MG_ENABLE_DRIVER_STM32F 1
  129. #elif defined(STM32H5) || defined(STM32H7)
  130. #define MG_ENABLE_DRIVER_STM32H 1
  131. #elif defined(STM32N6)
  132. #define MG_ENABLE_DRIVER_STM32N 1
  133. #else
  134. #error Select a driver in mongoose_config.h
  135. #endif
  136. #endif
  137. #ifndef MG_TLS
  138. #define MG_TLS MG_TLS_BUILTIN
  139. #endif
  140. #if !defined(MG_OTA) && defined(STM32F1) || defined(STM32F2) || \
  141. defined(STM32F4) || defined(STM32F7)
  142. #define MG_OTA MG_OTA_STM32F
  143. #elif !defined(MG_OTA) && defined(STM32H5)
  144. #define MG_OTA MG_OTA_STM32H5
  145. #elif !defined(MG_OTA) && defined(STM32H7)
  146. #define MG_OTA MG_OTA_STM32H7
  147. #endif
  148. // OTA rollback timer via IWDG. Fixed 10 s hang-detection window (prescaler
  149. // /1024, LSI ~32 kHz: reload = 10 * 32000 / 1024 = 312). mg_ota_poll() feeds
  150. // the watchdog every 500 ms while in MG_OTA_TESTING state; if the event loop
  151. // hangs for 10 s, the IWDG fires and the device rolls back.
  152. // STM32H7 names the peripheral IWDG1; all others use IWDG.
  153. // The total evaluation period is set by MG_OTA_ROLLBACK_TIMEOUT_SECONDS.
  154. // STM32H7 names the watchdog peripheral IWDG1; all other families use IWDG.
  155. #if defined(IWDG1) && !defined(IWDG)
  156. #define MG_IWDG IWDG1
  157. #else
  158. #define MG_IWDG IWDG
  159. #endif
  160. // PR=6 → /256 prescaler, RLR=1250 → ~10 s at LSI 32 kHz.
  161. // Works on F4/F7/H5/H7; uses direct register writes so it is safe before HAL_Init().
  162. #ifndef MG_OTA_ROLLBACK_TIMER_START
  163. #define MG_OTA_ROLLBACK_TIMER_START() \
  164. do { \
  165. MG_IWDG->KR = 0xCCCCU; /* start + LSI */ \
  166. MG_IWDG->KR = 0x5555U; /* unlock PR/RLR */ \
  167. MG_IWDG->PR = 6U; /* /256 */ \
  168. MG_IWDG->RLR = 1250U; /* 10 s */ \
  169. while (MG_IWDG->SR & (IWDG_SR_PVU | IWDG_SR_RVU)) (void) 0; \
  170. MG_IWDG->KR = 0xAAAAU; /* reload */ \
  171. } while (0)
  172. #endif
  173. // Feed (reload) the IWDG. Called from mg_ota_poll() every 500 ms.
  174. #ifndef MG_OTA_ROLLBACK_TIMER_FEED
  175. #define MG_OTA_ROLLBACK_TIMER_FEED() (MG_IWDG->KR = 0xAAAAU)
  176. #endif
  177. // OTA state in a backup register that survives warm resets but clears on POR.
  178. // STATE_GET reads work without any setup. STATE_SET enables the RTC APB clock
  179. // and unlocks backup domain write access via direct register writes, so it is
  180. // safe to call from any context (before or after HAL_Init).
  181. // H5 (TAMP->BKP0R), H7 (RTC->BKP0R), F4/F7 (RTC->BKP0R).
  182. #ifndef MG_OTA_STATE_GET
  183. #if defined(PWR_DBPCR_DBP)
  184. #define MG_OTA_DBP_ENABLE() (PWR->DBPCR |= PWR_DBPCR_DBP)
  185. #elif defined(PWR_CR1_DBP)
  186. #define MG_OTA_DBP_ENABLE() (PWR->CR1 |= PWR_CR1_DBP)
  187. #else
  188. #define MG_OTA_DBP_ENABLE() (PWR->CR |= PWR_CR_DBP)
  189. #endif
  190. #if defined(TAMP)
  191. #define MG_OTA_STATE_GET() \
  192. (RCC->APB3ENR |= RCC_APB3ENR_RTCAPBEN, TAMP->BKP0R)
  193. #define MG_OTA_STATE_SET(v) \
  194. (RCC->APB3ENR |= RCC_APB3ENR_RTCAPBEN, MG_OTA_DBP_ENABLE(), \
  195. (TAMP->BKP0R = (uint32_t) (v)), TAMP->BKP0R)
  196. #elif defined(RCC_APB4ENR_RTCAPBEN)
  197. #define MG_OTA_STATE_GET() (RTC->BKP0R)
  198. #define MG_OTA_STATE_SET(v) \
  199. (RCC->APB4ENR |= RCC_APB4ENR_RTCAPBEN, MG_OTA_DBP_ENABLE(), \
  200. (RTC->BKP0R = (uint32_t) (v)))
  201. #else
  202. #define MG_OTA_STATE_GET() (RTC->BKP0R)
  203. #define MG_OTA_STATE_SET(v) \
  204. (RCC->APB1ENR |= RCC_APB1ENR_PWREN, MG_OTA_DBP_ENABLE(), \
  205. (RTC->BKP0R = (uint32_t) (v)))
  206. #endif
  207. #endif
  208. // use HAL-defined execute-in-ram section
  209. #ifndef MG_IRAM
  210. #define MG_IRAM __attribute__((section(".RamFunc")))
  211. #endif
  212. #ifndef MG_ETH_RAM
  213. #define MG_ETH_RAM __attribute__((section(".eth_ram")))
  214. #endif
  215. #ifndef HAL_ICACHE_MODULE_ENABLED
  216. #define HAL_ICACHE_IsEnabled() 0
  217. #define HAL_ICACHE_Enable() (void) 0
  218. #define HAL_ICACHE_Disable() (void) 0
  219. #endif
  220. #ifndef MG_SET_MAC_ADDRESS
  221. // Construct MAC address from UUID
  222. #define MGUID ((uint32_t *) UID_BASE) // Unique 96-bit chip ID
  223. #define MG_SET_MAC_ADDRESS(mac) \
  224. do { \
  225. int icache_enabled_ = HAL_ICACHE_IsEnabled(); \
  226. if (icache_enabled_) HAL_ICACHE_Disable(); \
  227. mac[0] = 42; \
  228. mac[1] = ((MGUID[0] >> 0) & 255) ^ ((MGUID[2] >> 19) & 255); \
  229. mac[2] = ((MGUID[0] >> 10) & 255) ^ ((MGUID[1] >> 10) & 255); \
  230. mac[3] = (MGUID[0] >> 19) & 255; \
  231. mac[4] = ((MGUID[1] >> 0) & 255) ^ ((MGUID[2] >> 10) & 255); \
  232. mac[5] = ((MGUID[2] >> 0) & 255) ^ ((MGUID[1] >> 19) & 255); \
  233. if (icache_enabled_) HAL_ICACHE_Enable(); \
  234. } while (0)
  235. #endif
  236. #endif
  237. #if MG_ARCH == MG_ARCH_ESP32
  238. #include <ctype.h>
  239. #include <dirent.h>
  240. #include <errno.h>
  241. #include <fcntl.h>
  242. #include <limits.h>
  243. #include <netdb.h>
  244. #include <stdarg.h>
  245. #include <stddef.h>
  246. #include <stdio.h>
  247. #include <stdlib.h>
  248. #include <string.h>
  249. #include <sys/stat.h>
  250. #include <sys/types.h>
  251. #include <time.h>
  252. #include <esp_ota_ops.h> // Use angle brackets to avoid
  253. #include <esp_timer.h> // amalgamation ditching them
  254. #include <esp_system.h>
  255. #include <esp_mac.h>
  256. #include <esp_idf_version.h>
  257. #include <esp_ota_ops.h>
  258. #include <esp_task_wdt.h>
  259. #include <soc/soc.h>
  260. #include <soc/rtc_cntl_reg.h>
  261. #define MG_PATH_MAX 128
  262. #ifndef MG_ENABLE_POSIX_FS
  263. #define MG_ENABLE_POSIX_FS 1
  264. #endif
  265. #ifndef MG_ENABLE_DIRLIST
  266. #define MG_ENABLE_DIRLIST 1
  267. #endif
  268. #ifndef MG_OTA_ESP32_WDT_TIMEOUT_MS
  269. #define MG_OTA_ESP32_WDT_TIMEOUT_MS 10000U
  270. #endif
  271. static inline void mg_ota_esp32_timer_start(void) {
  272. #if ESP_IDF_VERSION_MAJOR >= 5
  273. esp_task_wdt_config_t cfg = {0};
  274. esp_err_t err;
  275. cfg.timeout_ms = MG_OTA_ESP32_WDT_TIMEOUT_MS;
  276. cfg.idle_core_mask = 0;
  277. cfg.trigger_panic = true;
  278. err = esp_task_wdt_init(&cfg);
  279. if (err == ESP_ERR_INVALID_STATE) esp_task_wdt_reconfigure(&cfg);
  280. #else
  281. esp_task_wdt_init(MG_OTA_ESP32_WDT_TIMEOUT_MS / 1000U, true);
  282. #endif
  283. esp_task_wdt_add(NULL);
  284. esp_task_wdt_reset();
  285. }
  286. static inline uint32_t mg_ota_esp32_state_set(uint32_t state) {
  287. if (state == 0) esp_ota_mark_app_valid_cancel_rollback();
  288. REG_WRITE(RTC_CNTL_STORE0_REG, state);
  289. return REG_READ(RTC_CNTL_STORE0_REG);
  290. }
  291. #define MG_OTA_STATE_GET() \
  292. REG_READ(RTC_CNTL_STORE0_REG)
  293. #define MG_OTA_STATE_SET(v) mg_ota_esp32_state_set((uint32_t) (v))
  294. #ifndef MG_OTA_ROLLBACK_TIMER_START
  295. #define MG_OTA_ROLLBACK_TIMER_START() mg_ota_esp32_timer_start()
  296. #endif
  297. #ifndef MG_OTA_ROLLBACK_TIMER_FEED
  298. #define MG_OTA_ROLLBACK_TIMER_FEED() \
  299. do { \
  300. (void) esp_task_wdt_reset(); \
  301. } while (0)
  302. #endif
  303. #ifndef MG_OTA_ROLLBACK
  304. #define MG_OTA_ROLLBACK() \
  305. do { \
  306. (void) esp_ota_mark_app_invalid_rollback_and_reboot(); \
  307. } while (0)
  308. #endif
  309. #endif
  310. #if MG_ARCH == MG_ARCH_ESP8266
  311. #include <ctype.h>
  312. #include <dirent.h>
  313. #include <errno.h>
  314. #include <fcntl.h>
  315. #include <limits.h>
  316. #include <netdb.h>
  317. #include <stdarg.h>
  318. #include <stdbool.h>
  319. #include <stddef.h>
  320. #include <stdio.h>
  321. #include <stdlib.h>
  322. #include <string.h>
  323. #include <sys/stat.h>
  324. #include <sys/time.h>
  325. #include <sys/types.h>
  326. #include <time.h>
  327. #include <esp_system.h>
  328. #define MG_PATH_MAX 128
  329. #endif
  330. #if MG_ARCH == MG_ARCH_MCUXPRESSO
  331. #define _POSIX_TIMERS
  332. #include <ctype.h>
  333. #if !defined(MG_ENABLE_LWIP) || !MG_ENABLE_LWIP
  334. #include <errno.h>
  335. #endif
  336. #include <stdarg.h>
  337. #include <stdbool.h>
  338. #include <stdint.h>
  339. #include <stdio.h>
  340. #include <stdlib.h>
  341. #include <string.h>
  342. #include <sys/stat.h>
  343. #include <sys/time.h>
  344. #include <sys/types.h>
  345. #include <time.h>
  346. #include <unistd.h>
  347. // MCUXpresso-generated header, includes the SoC peripheral definitions.
  348. // NOTE: use angle brackets to prevent amalgamator ditching it
  349. #include <fsl_device_registers.h>
  350. #ifndef MG_PATH_MAX
  351. #define MG_PATH_MAX 100
  352. #endif
  353. #ifndef MG_ENABLE_DIRLIST
  354. #define MG_ENABLE_DIRLIST 0
  355. #endif
  356. #ifndef MG_ENABLE_TCPIP
  357. #define MG_ENABLE_TCPIP 1 // Enable built-in TCP/IP stack
  358. #endif
  359. #if MG_ENABLE_TCPIP && !defined(MG_ENABLE_DRIVER_IMXRT10) && \
  360. !defined(MG_ENABLE_DRIVER_IMXRT11)
  361. #if defined(CPU_MIMXRT1021DAG5A) || defined(CPU_MIMXRT1024DAG5A) || \
  362. defined(CPU_MIMXRT1042XJM5B) || defined(CPU_MIMXRT1052DVL6B) || \
  363. defined(CPU_MIMXRT1062DVL6B) || defined(CPU_MIMXRT1064DVL6B) || \
  364. defined(CPU_MIMXRT1062DVL6A) || defined(CPU_MIMXRT1064DVL6A) || \
  365. defined(CPU_MIMXRT1062DVMAA_cm7) || defined(CPU_MIMXRT1062DVL6A_cm7) || \
  366. defined(CPU_MIMXRT1062DVL6B_cm7) || defined(_MIMXRT1021_H_) || \
  367. defined(_MIMXRT1024_H_) || defined(_MIMXRT1042_H_) || \
  368. defined(_MIMXRT1052_H_) || defined(_MIMXRT1062_H_) || \
  369. defined(_MIMXRT1064_H_)
  370. #define MG_ENABLE_DRIVER_IMXRT10 1
  371. #elif defined(CPU_MIMXRT1176DVMAA_cm7) || defined(CPU_MIMXRT1176DVMAA_cm4) || \
  372. defined(_MIMXRT1176_cm7_H_) || defined(_MIMXRT1176_cm4_H_) || \
  373. defined(_MIMXRT1176_H_)
  374. #define MG_ENABLE_DRIVER_IMXRT11 1
  375. #else
  376. #error Select an Ethernet driver in mongoose_config.h
  377. #endif
  378. #endif
  379. #ifndef MG_TLS
  380. #define MG_TLS MG_TLS_BUILTIN
  381. #endif
  382. #if !defined(MG_OTA) && \
  383. (defined(CPU_MIMXRT1021DAG5A) || defined(CPU_MIMXRT1024DAG5A) || \
  384. defined(_MIMXRT1021_H_) || defined(_MIMXRT1024_H_))
  385. #define MG_OTA MG_OTA_RT1020
  386. #elif !defined(MG_OTA) && \
  387. (defined(CPU_MIMXRT1052DVL6B) || defined(_MIMXRT1052_H_))
  388. #define MG_OTA MG_OTA_RT1050
  389. #elif !defined(MG_OTA) && \
  390. (defined(CPU_MIMXRT1062DVL6B) || defined(CPU_MIMXRT1062DVL6A) || \
  391. defined(CPU_MIMXRT1042XJM5B) || defined(_MIMXRT1042_H_) || \
  392. defined(CPU_MIMXRT1062DVMAA_cm7) || defined(CPU_MIMXRT1062DVL6A_cm7) || \
  393. defined(CPU_MIMXRT1062DVL6B_cm7) || defined(_MIMXRT1062_H_))
  394. #define MG_OTA MG_OTA_RT1060
  395. #elif !defined(MG_OTA) && \
  396. (defined(CPU_MIMXRT1064DVL6B) || defined(CPU_MIMXRT1064DVL6A) || \
  397. defined(_MIMXRT1064_H_))
  398. #define MG_OTA MG_OTA_RT1064
  399. #elif !defined(MG_OTA) && \
  400. (defined(CPU_MIMXRT1176DVMAA_cm7) || defined(CPU_MIMXRT1176DVMAA_cm4) || \
  401. defined(_MIMXRT1176_cm7_H_) || defined(_MIMXRT1176_cm4_H_) || \
  402. defined(_MIMXRT1176_H_))
  403. #define MG_OTA MG_OTA_RT1170
  404. #endif
  405. #ifndef MG_IRAM
  406. #define MG_IRAM __attribute__((noinline, section(".data_RAM2")))
  407. #endif
  408. #ifndef MG_SET_MAC_ADDRESS
  409. #if defined(MG_ENABLE_DRIVER_IMXRT11) && MG_ENABLE_DRIVER_IMXRT11
  410. #define MG_OCOTP_FUSES ((volatile uint32_t *) 0x40cac900)
  411. #else
  412. #define MG_OCOTP_FUSES ((volatile uint32_t *) 0x401f4410)
  413. #endif
  414. #define MG_SET_MAC_ADDRESS(mac) \
  415. do { \
  416. mac[0] = 2; \
  417. mac[1] = (MG_OCOTP_FUSES[0] >> 0) & 255; \
  418. mac[2] = (MG_OCOTP_FUSES[0] >> 10) & 255; \
  419. mac[3] = ((MG_OCOTP_FUSES[0] >> 19) ^ (MG_OCOTP_FUSES[4] >> 19)) & 255; \
  420. mac[4] = (MG_OCOTP_FUSES[4] >> 10) & 255; \
  421. mac[5] = (MG_OCOTP_FUSES[4] >> 0) & 255; \
  422. } while (0)
  423. #endif
  424. #ifndef MG_IMXRT_WDOG1_TIMEOUT_MS
  425. #define MG_IMXRT_WDOG1_TIMEOUT_MS 10000
  426. #endif
  427. #define MG_IMXRT_WDOG1_FEED() \
  428. do { \
  429. WDOG1->WSR = 0x5555; \
  430. WDOG1->WSR = 0xaaaa; \
  431. } while (0)
  432. #ifndef MG_OTA_ROLLBACK_TIMER_START
  433. #define MG_OTA_ROLLBACK_TIMER_START() \
  434. do { \
  435. uint16_t wt_ = (uint16_t) ((MG_IMXRT_WDOG1_TIMEOUT_MS / 500) - 1); \
  436. if ((WDOG1->WCR & WDOG_WCR_WDE_MASK) == 0) { \
  437. WDOG1->WMCR = 0; \
  438. WDOG1->WCR = (uint16_t) (WDOG_WCR_WDZST_MASK | WDOG_WCR_WDBG_MASK | \
  439. WDOG_WCR_WDE_MASK | WDOG_WCR_WDT_MASK | \
  440. WDOG_WCR_SRS_MASK | WDOG_WCR_WDW_MASK | \
  441. WDOG_WCR_WT(wt_)); \
  442. } \
  443. MG_IMXRT_WDOG1_FEED(); \
  444. } while (0)
  445. #endif
  446. #ifndef MG_OTA_ROLLBACK_TIMER_FEED
  447. #define MG_OTA_ROLLBACK_TIMER_FEED() MG_IMXRT_WDOG1_FEED()
  448. #endif
  449. #ifndef MG_OTA_STATE_GET
  450. #define MG_OTA_STATE_GET() SNVS->LPGPR[0]
  451. #endif
  452. #ifndef MG_OTA_STATE_SET
  453. #define MG_OTA_STATE_SET(v) \
  454. do { \
  455. if (SNVS->LPSR & (1u << 3)) { \
  456. SNVS->LPLVDR = 0x41736166u; \
  457. SNVS->LPSR = 1u << 3; \
  458. } \
  459. SNVS->LPGPR[0] = (uint32_t) (v); \
  460. } while (0)
  461. #endif
  462. #endif
  463. #if MG_ARCH == MG_ARCH_PICOSDK
  464. #if !defined(MG_ENABLE_LWIP) || !MG_ENABLE_LWIP
  465. #include <errno.h>
  466. #endif
  467. #include <stdarg.h>
  468. #include <stdbool.h>
  469. #include <stdint.h>
  470. #include <stdio.h>
  471. #include <stdlib.h>
  472. #include <string.h>
  473. #include <time.h>
  474. #include <pico/stdlib.h>
  475. #include <pico/rand.h>
  476. #include <pico/unique_id.h>
  477. int mkdir(const char *, mode_t);
  478. #if MG_OTA == MG_OTA_PICOSDK
  479. #include <hardware/flash.h>
  480. #include <hardware/watchdog.h>
  481. #include <hardware/structs/watchdog.h>
  482. #include <pico/bootrom.h>
  483. #ifndef MG_OTA_WATCHDOG_MS
  484. #if PICO_RP2040
  485. #define MG_OTA_WATCHDOG_MS 8000U // max delay on RP2040 is 8.3 seconds
  486. #else
  487. #define MG_OTA_WATCHDOG_MS 10000U // max delay on RP2350 is 16 seconds
  488. #endif
  489. #endif
  490. #ifndef MG_OTA_ROLLBACK_TIMER_START
  491. #define MG_OTA_ROLLBACK_TIMER_START() watchdog_enable(MG_OTA_WATCHDOG_MS, false)
  492. #endif
  493. #ifndef MG_OTA_ROLLBACK_TIMER_FEED
  494. #define MG_OTA_ROLLBACK_TIMER_FEED() watchdog_update()
  495. #endif
  496. #define MG_OTA_STATE_GET() ((uint32_t) watchdog_hw->scratch[0])
  497. #define MG_OTA_STATE_SET(v) \
  498. (watchdog_hw->scratch[0] = (uint32_t) (v), (uint32_t) watchdog_hw->scratch[0])
  499. #if PICO_RP2040
  500. #define MG_OTA_ROLLBACK() \
  501. do { \
  502. mg_flash->swap_fn(); \
  503. *(volatile unsigned long *) 0xe000ed0c = 0x5fa0004; \
  504. } while (0)
  505. #else
  506. #define MG_OTA_ROLLBACK() \
  507. do { \
  508. mg_flash->swap_fn(); \
  509. ((rom_reboot_fn) rom_func_lookup(ROM_FUNC_REBOOT))( \
  510. BOOT_TYPE_NORMAL | 0x100, 1, 0, 0); \
  511. } while (0)
  512. #endif
  513. #endif
  514. #endif
  515. #if MG_ARCH == MG_ARCH_RTTHREAD
  516. #include <rtthread.h>
  517. #include <ctype.h>
  518. #include <errno.h>
  519. #include <fcntl.h>
  520. #include <sys/socket.h>
  521. #include <sys/select.h>
  522. #include <stdarg.h>
  523. #include <stdbool.h>
  524. #include <stdint.h>
  525. #include <stdio.h>
  526. #include <stdlib.h>
  527. #include <string.h>
  528. #include <sys/types.h>
  529. #include <time.h>
  530. #ifndef MG_IO_SIZE
  531. #define MG_IO_SIZE 1460
  532. #endif
  533. #endif // MG_ARCH == MG_ARCH_RTTHREAD
  534. #if MG_ARCH == MG_ARCH_ARMCC || MG_ARCH == MG_ARCH_CMSIS_RTOS1 || \
  535. MG_ARCH == MG_ARCH_CMSIS_RTOS2
  536. #include <ctype.h>
  537. #include <errno.h>
  538. #include <stdarg.h>
  539. #include <stdbool.h>
  540. #include <stddef.h>
  541. #include <stdint.h>
  542. #include <stdio.h>
  543. #include <stdlib.h>
  544. #include <alloca.h>
  545. #include <string.h>
  546. #include <time.h>
  547. #if MG_ARCH == MG_ARCH_CMSIS_RTOS1
  548. #include "cmsis_os.h" // keep this include
  549. // https://developer.arm.com/documentation/ka003821/latest
  550. extern uint32_t rt_time_get(void);
  551. #elif MG_ARCH == MG_ARCH_CMSIS_RTOS2
  552. #include "cmsis_os2.h" // keep this include
  553. #endif
  554. #define strdup(s) ((char *) mg_strdup(mg_str(s)).buf)
  555. #if defined(__ARMCC_VERSION)
  556. #define mode_t size_t
  557. #if !defined(MG_ENABLE_POSIX_FS) || !MG_ENABLE_POSIX_FS
  558. #else
  559. #define mkdir(a, b) mg_mkdir(a, b)
  560. static inline int mg_mkdir(const char *path, mode_t mode) {
  561. (void) path, (void) mode;
  562. return -1;
  563. }
  564. #endif
  565. #endif
  566. #if (MG_ARCH == MG_ARCH_CMSIS_RTOS1 || MG_ARCH == MG_ARCH_CMSIS_RTOS2) && \
  567. !defined MG_ENABLE_RL && (!defined(MG_ENABLE_LWIP) || !MG_ENABLE_LWIP) && \
  568. (!defined(MG_ENABLE_TCPIP) || !MG_ENABLE_TCPIP)
  569. #define MG_ENABLE_RL 1
  570. #ifndef MG_SOCK_LISTEN_BACKLOG_SIZE
  571. #define MG_SOCK_LISTEN_BACKLOG_SIZE 3
  572. #endif
  573. #endif
  574. #endif
  575. #if MG_ARCH == MG_ARCH_THREADX
  576. #include <stdarg.h>
  577. #include <stdbool.h>
  578. #include <stdint.h>
  579. #include <string.h>
  580. // Do not include time.h and stdlib.h, since they conflict with nxd_bsd.h
  581. // extern time_t time(time_t *);
  582. #include <nxd_bsd.h>
  583. #define MG_DIRSEP '\\'
  584. #undef FOPEN_MAX
  585. #ifndef MG_PATH_MAX
  586. #define MG_PATH_MAX 32
  587. #endif
  588. #ifndef MG_SOCK_LISTEN_BACKLOG_SIZE
  589. #define MG_SOCK_LISTEN_BACKLOG_SIZE 3
  590. #endif
  591. #ifndef MG_ENABLE_IPV6
  592. #define MG_ENABLE_IPV6 0
  593. #endif
  594. #define socklen_t int
  595. #define closesocket(x) soc_close(x)
  596. // In order to enable BSD support in NetxDuo, do the following (assuming Cube):
  597. // 1. Add nxd_bsd.h and nxd_bsd.c to the repo:
  598. // https://github.com/eclipse-threadx/netxduo/blob/v6.1.12_rel/addons/BSD/nxd_bsd.c
  599. // https://github.com/eclipse-threadx/netxduo/blob/v6.1.12_rel/addons/BSD/nxd_bsd.h
  600. // 2. Add to tx_user.h
  601. // #define TX_THREAD_USER_EXTENSION int bsd_errno;
  602. // 3. Add to nx_user.h
  603. // #define NX_ENABLE_EXTENDED_NOTIFY_SUPPORT
  604. // 4. Add __CCRX__ build preprocessor constant
  605. // Project -> Properties -> C/C++ -> Settings -> MCU Compiler -> Preprocessor
  606. #endif
  607. #if MG_ARCH == MG_ARCH_TIRTOS
  608. #include <stdlib.h>
  609. #include <ctype.h>
  610. #include <stdarg.h>
  611. #include <stdbool.h>
  612. #include <stdint.h>
  613. #include <stdio.h>
  614. #include <string.h>
  615. #include <time.h>
  616. #include <serrno.h>
  617. #include <sys/socket.h>
  618. #include <ti/sysbios/knl/Clock.h>
  619. #endif
  620. #if MG_ARCH == MG_ARCH_UNIX
  621. #define _DARWIN_UNLIMITED_SELECT 1 // No limit on file descriptors
  622. #if defined(__APPLE__)
  623. #include <mach/mach_time.h>
  624. #endif
  625. #if !defined(MG_ENABLE_EPOLL) && defined(__linux__)
  626. #define MG_ENABLE_EPOLL 1
  627. #elif !defined(MG_ENABLE_POLL)
  628. #define MG_ENABLE_POLL 1
  629. #endif
  630. #include <arpa/inet.h>
  631. #include <ctype.h>
  632. #include <dirent.h>
  633. #if !defined(MG_ENABLE_LWIP) || !MG_ENABLE_LWIP
  634. #include <errno.h>
  635. #endif
  636. #include <fcntl.h>
  637. #include <inttypes.h>
  638. #include <limits.h>
  639. #include <netdb.h>
  640. #include <netinet/in.h>
  641. #include <netinet/tcp.h>
  642. #include <signal.h>
  643. #include <stdarg.h>
  644. #include <stdbool.h>
  645. #include <stddef.h>
  646. #include <stdint.h>
  647. #include <stdio.h>
  648. #include <stdlib.h>
  649. #include <string.h>
  650. #if defined(MG_ENABLE_EPOLL) && MG_ENABLE_EPOLL
  651. #include <sys/epoll.h>
  652. #elif defined(MG_ENABLE_POLL) && MG_ENABLE_POLL
  653. #include <poll.h>
  654. #else
  655. #include <sys/select.h>
  656. #endif
  657. #include <sys/socket.h>
  658. #include <sys/stat.h>
  659. #include <sys/time.h>
  660. #include <sys/types.h>
  661. #include <time.h>
  662. #include <unistd.h>
  663. #ifndef MG_ENABLE_DIRLIST
  664. #define MG_ENABLE_DIRLIST 1
  665. #endif
  666. #ifndef MG_PATH_MAX
  667. #define MG_PATH_MAX FILENAME_MAX
  668. #endif
  669. #ifndef MG_ENABLE_POSIX_FS
  670. #define MG_ENABLE_POSIX_FS 1
  671. #endif
  672. #ifndef MG_IO_SIZE
  673. #define MG_IO_SIZE 16384
  674. #endif
  675. #endif
  676. #if MG_ARCH == MG_ARCH_WIN32
  677. // Avoid name clashing; (macro expansion producing 'defined' has undefined
  678. // behaviour). See config.h for user options
  679. #ifndef MG_ENABLE_WINSOCK
  680. #if (!defined(MG_ENABLE_TCPIP) || !MG_ENABLE_TCPIP) && \
  681. (!defined(MG_ENABLE_LWIP) || !MG_ENABLE_LWIP) && \
  682. (!defined(MG_ENABLE_FREERTOS_TCP) || !MG_ENABLE_FREERTOS_TCP)
  683. #define MG_ENABLE_WINSOCK 1
  684. #else
  685. #define MG_ENABLE_WINSOCK 0
  686. #endif
  687. #endif
  688. #ifndef _CRT_RAND_S
  689. #define _CRT_RAND_S
  690. #endif
  691. #ifndef _WIN32_WINNT
  692. #if defined(_MSC_VER) && _MSC_VER < 1700
  693. #define _WIN32_WINNT 0x0400 // Let vc98 pick up wincrypt.h
  694. #else
  695. #define _WIN32_WINNT 0x0600
  696. #endif
  697. #endif
  698. #ifndef WINVER
  699. #define WINVER _WIN32_WINNT
  700. #endif
  701. #ifndef WIN32_LEAN_AND_MEAN
  702. #define WIN32_LEAN_AND_MEAN
  703. #endif
  704. #ifndef _CRT_SECURE_NO_WARNINGS
  705. #define _CRT_SECURE_NO_WARNINGS
  706. #endif
  707. #ifndef _WINSOCK_DEPRECATED_NO_WARNINGS
  708. #define _WINSOCK_DEPRECATED_NO_WARNINGS
  709. #endif
  710. #include <ctype.h>
  711. #include <direct.h>
  712. #if !defined(MG_ENABLE_LWIP) || !MG_ENABLE_LWIP
  713. #include <errno.h>
  714. #endif
  715. #include <fcntl.h>
  716. #include <limits.h>
  717. #include <signal.h>
  718. #include <stdarg.h>
  719. #include <stddef.h>
  720. #include <stdio.h>
  721. #include <stdlib.h>
  722. #include <string.h>
  723. #include <sys/stat.h>
  724. #include <sys/types.h>
  725. #include <time.h>
  726. #include <winsock2.h> // fix missing macros and types
  727. #if defined(_MSC_VER) && _MSC_VER < 1700
  728. #define __func__ ""
  729. typedef __int64 int64_t;
  730. typedef unsigned __int64 uint64_t;
  731. typedef unsigned char uint8_t;
  732. typedef char int8_t;
  733. typedef unsigned short uint16_t;
  734. typedef short int16_t;
  735. typedef unsigned int uint32_t;
  736. typedef int int32_t;
  737. typedef enum { false = 0, true = 1 } bool;
  738. #define inline __inline
  739. #else
  740. #include <stdbool.h>
  741. #include <stdint.h>
  742. #if MG_ENABLE_WINSOCK
  743. #include <ws2tcpip.h>
  744. #endif
  745. #endif
  746. #include <process.h>
  747. #include <winerror.h>
  748. // For mg_random()
  749. #if defined(_MSC_VER) && _MSC_VER < 1700
  750. #include <wincrypt.h>
  751. #pragma comment(lib, "advapi32.lib")
  752. #endif
  753. #if defined(_MSC_VER) && _MSC_VER <= 1200
  754. #ifndef IPPROTO_IP
  755. #define IPPROTO_IP 0
  756. #endif
  757. #ifndef IP_ADD_MEMBERSHIP
  758. struct ip_mreq {
  759. struct in_addr imr_multiaddr;
  760. struct in_addr imr_interface;
  761. };
  762. #define IP_ADD_MEMBERSHIP 12
  763. #endif
  764. #endif
  765. // Protect from calls like std::snprintf in app code
  766. // See https://github.com/cesanta/mongoose/issues/1047
  767. #ifndef __cplusplus
  768. #define snprintf _snprintf
  769. #define vsnprintf _vsnprintf
  770. #ifndef strdup // For MSVC with _DEBUG, see #1359
  771. #define strdup(x) _strdup(x)
  772. #endif
  773. #endif
  774. #if defined(MG_ENABLE_POLL) && MG_ENABLE_POLL && (!defined(MG_ENABLE_LWIP) || !MG_ENABLE_LWIP)
  775. typedef unsigned long nfds_t; // see #3388
  776. #endif
  777. #if defined(_MSC_VER)
  778. #if MG_ENABLE_WINSOCK
  779. #pragma comment(lib, "ws2_32.lib")
  780. #endif
  781. #ifndef alloca
  782. #define alloca(a) _alloca(a)
  783. #endif
  784. #endif
  785. #define MG_DIRSEP '\\'
  786. #ifndef MG_PATH_MAX
  787. #define MG_PATH_MAX FILENAME_MAX
  788. #endif
  789. #if MG_ENABLE_WINSOCK
  790. #define MG_INVALID_SOCKET INVALID_SOCKET
  791. #define MG_SOCKET_TYPE SOCKET
  792. #define poll(a, b, c) WSAPoll((a), (b), (c))
  793. #define closesocket(x) closesocket(x)
  794. typedef int socklen_t;
  795. #ifndef SO_EXCLUSIVEADDRUSE
  796. #define SO_EXCLUSIVEADDRUSE ((int) (~SO_REUSEADDR))
  797. #endif
  798. #define MG_SOCK_ERR(errcode) ((errcode) < 0 ? WSAGetLastError() : 0)
  799. #define MG_SOCK_PENDING(errcode) \
  800. (((errcode) < 0) && \
  801. (WSAGetLastError() == WSAEINTR || WSAGetLastError() == WSAEINPROGRESS || \
  802. WSAGetLastError() == WSAEWOULDBLOCK))
  803. #define MG_SOCK_RESET(errcode) \
  804. (((errcode) < 0) && (WSAGetLastError() == WSAECONNRESET))
  805. #endif // MG_ENABLE_WINSOCK
  806. #define realpath(a, b) _fullpath((b), (a), MG_PATH_MAX)
  807. #define sleep(x) Sleep((x) *1000)
  808. #define mkdir(a, b) _mkdir(a)
  809. #define rmdir(a) _rmdir(a)
  810. #define timegm(x) _mkgmtime(x)
  811. #ifndef S_ISDIR
  812. #define S_ISDIR(x) (((x) &_S_IFMT) == _S_IFDIR)
  813. #endif
  814. #ifndef MG_ENABLE_DIRLIST
  815. #define MG_ENABLE_DIRLIST 1
  816. #endif
  817. #ifndef SIGPIPE
  818. #define SIGPIPE 0
  819. #endif
  820. #ifndef MG_ENABLE_POSIX_FS
  821. #define MG_ENABLE_POSIX_FS 1
  822. #endif
  823. #ifndef MG_IO_SIZE
  824. #define MG_IO_SIZE 16384
  825. #endif
  826. #endif
  827. #if MG_ARCH == MG_ARCH_ZEPHYR
  828. #include <zephyr/kernel.h>
  829. #include <zephyr/net/socket.h>
  830. // #include <zephyr/posix/dirent.h>
  831. #include <zephyr/posix/fcntl.h>
  832. #include <zephyr/posix/sys/select.h>
  833. #include <zephyr/random/random.h>
  834. #include <zephyr/version.h>
  835. #include <ctype.h>
  836. #include <errno.h>
  837. #include <stdarg.h>
  838. #include <stdbool.h>
  839. #include <stdint.h>
  840. #include <stdio.h>
  841. #include <stdlib.h>
  842. #include <string.h>
  843. #include <sys/types.h>
  844. #include <time.h>
  845. #define MG_PUTCHAR(x) printk("%c", x)
  846. #ifndef strdup
  847. #define strdup(s) ((char *) mg_strdup(mg_str(s)).buf)
  848. #endif
  849. #define strerror(x) zsock_gai_strerror(x)
  850. #ifndef FD_CLOEXEC
  851. #define FD_CLOEXEC 0
  852. #endif
  853. #ifndef F_SETFD
  854. #define F_SETFD 0
  855. #endif
  856. #define MG_ENABLE_SSI 0
  857. int rand(void);
  858. int sscanf(const char *, const char *, ...);
  859. #endif
  860. #if defined(MG_ENABLE_FREERTOS) && MG_ENABLE_FREERTOS
  861. #include <FreeRTOS.h>
  862. #include <task.h>
  863. #define MG_ENABLE_CUSTOM_CALLOC 1
  864. static inline void mg_free(void *ptr) {
  865. vPortFree(ptr);
  866. }
  867. // Re-route calloc/free to FreeRTOS functions, don't use stdlib
  868. static inline void *mg_calloc(size_t cnt, size_t size) {
  869. void *p = pvPortMalloc(cnt * size);
  870. if (p != NULL) memset(p, 0, size * cnt);
  871. return p;
  872. }
  873. #endif // MG_ENABLE_FREERTOS
  874. #if defined(MG_ENABLE_FREERTOS_TCP) && MG_ENABLE_FREERTOS_TCP
  875. #include <limits.h>
  876. #include <list.h>
  877. #include <FreeRTOS_IP.h>
  878. #include <FreeRTOS_Sockets.h>
  879. #define MG_SOCKET_TYPE Socket_t
  880. #define MG_INVALID_SOCKET FREERTOS_INVALID_SOCKET
  881. // Why FreeRTOS-TCP did not implement a clean BSD API, but its own thing
  882. // with FreeRTOS_ prefix, is beyond me
  883. #define IPPROTO_TCP FREERTOS_IPPROTO_TCP
  884. #define IPPROTO_UDP FREERTOS_IPPROTO_UDP
  885. #define AF_INET FREERTOS_AF_INET
  886. #define SOCK_STREAM FREERTOS_SOCK_STREAM
  887. #define SOCK_DGRAM FREERTOS_SOCK_DGRAM
  888. #define SO_BROADCAST 0
  889. #define SO_ERROR 0
  890. #define SOL_SOCKET 0
  891. #define SO_REUSEADDR 0
  892. #define MG_SOCK_ERR(errcode) ((errcode) < 0 ? (errcode) : 0)
  893. #define MG_SOCK_PENDING(errcode) \
  894. ((errcode) == -pdFREERTOS_ERRNO_EWOULDBLOCK || \
  895. (errcode) == -pdFREERTOS_ERRNO_EISCONN || \
  896. (errcode) == -pdFREERTOS_ERRNO_EINPROGRESS || \
  897. (errcode) == -pdFREERTOS_ERRNO_EAGAIN || \
  898. (errcode) == -pdFREERTOS_ERRNO_ENOSPC)
  899. #define MG_SOCK_RESET(errcode) ((errcode) == -pdFREERTOS_ERRNO_ENOTCONN)
  900. // actually only if optional timeout is enabled
  901. #define MG_SOCK_INTR(fd) (fd == NULL)
  902. #define sockaddr_in freertos_sockaddr
  903. #define sockaddr freertos_sockaddr
  904. #if ipFR_TCP_VERSION_MAJOR >= 4
  905. #define sin_addr sin_address.ulIP_IPv4
  906. #endif
  907. #define accept(a, b, c) FreeRTOS_accept((a), (b), (c))
  908. #define connect(a, b, c) FreeRTOS_connect((a), (b), (c))
  909. #define bind(a, b, c) FreeRTOS_bind((a), (b), (c))
  910. #define listen(a, b) FreeRTOS_listen((a), (b))
  911. #define socket(a, b, c) FreeRTOS_socket((a), (b), (c))
  912. #define send(a, b, c, d) FreeRTOS_send((a), (b), (c), (d))
  913. #define recv(a, b, c, d) FreeRTOS_recv((a), (b), (c), (d))
  914. #define setsockopt(a, b, c, d, e) FreeRTOS_setsockopt((a), (b), (c), (d), (e))
  915. #define sendto(a, b, c, d, e, f) FreeRTOS_sendto((a), (b), (c), (d), (e), (f))
  916. #define recvfrom(a, b, c, d, e, f) \
  917. FreeRTOS_recvfrom((a), (b), (c), (d), (e), (f))
  918. #define closesocket(x) FreeRTOS_closesocket(x)
  919. #define gethostbyname(x) FreeRTOS_gethostbyname(x)
  920. #define getsockname(a, b, c) mg_getsockname((a), (b), (c))
  921. #define getpeername(a, b, c) mg_getpeername((a), (b), (c))
  922. static inline int mg_getsockname(MG_SOCKET_TYPE fd, void *buf, socklen_t *len) {
  923. (void) fd, (void) buf, (void) len;
  924. return -1;
  925. }
  926. static inline int mg_getpeername(MG_SOCKET_TYPE fd, void *buf, socklen_t *len) {
  927. (void) fd, (void) buf, (void) len;
  928. return 0;
  929. }
  930. #endif
  931. #if defined(MG_ENABLE_LWIP) && MG_ENABLE_LWIP
  932. #if defined(__GNUC__) && !defined(__ARMCC_VERSION)
  933. #include <sys/stat.h>
  934. #endif
  935. struct timeval;
  936. #include <lwip/sockets.h>
  937. #if !LWIP_TIMEVAL_PRIVATE
  938. #if defined(__GNUC__) && !defined(__ARMCC_VERSION) // armclang sets both
  939. #include <sys/time.h>
  940. #else
  941. struct timeval {
  942. time_t tv_sec;
  943. long tv_usec;
  944. };
  945. #endif
  946. #endif
  947. #if LWIP_SOCKET != 1
  948. // Sockets support disabled in LWIP by default
  949. #error Set LWIP_SOCKET variable to 1 (in lwipopts.h)
  950. #endif
  951. #endif
  952. #if defined(MG_ENABLE_RL) && MG_ENABLE_RL
  953. #include <rl_net.h>
  954. #define closesocket(x) closesocket(x)
  955. #define TCP_NODELAY SO_KEEPALIVE
  956. #define MG_SOCK_ERR(errcode) ((errcode) < 0 ? (errcode) : 0)
  957. #define MG_SOCK_PENDING(errcode) \
  958. ((errcode) == BSD_EWOULDBLOCK || (errcode) == BSD_EALREADY || \
  959. (errcode) == BSD_EINPROGRESS)
  960. #define MG_SOCK_RESET(errcode) \
  961. ((errcode) == BSD_ECONNABORTED || (errcode) == BSD_ECONNRESET)
  962. // In blocking mode, which is enabled by default, accept() waits for a
  963. // connection request. In non blocking mode, you must call accept()
  964. // again if the error code BSD_EWOULDBLOCK is returned.
  965. #define MG_SOCK_INTR(fd) (fd == BSD_EWOULDBLOCK)
  966. #define socklen_t int
  967. #endif
  968. #ifndef MG_ENABLE_LOG
  969. #define MG_ENABLE_LOG 1
  970. #endif
  971. #ifndef MG_ENABLE_CUSTOM_CALLOC
  972. #define MG_ENABLE_CUSTOM_CALLOC 0
  973. #endif
  974. #ifndef MG_ENABLE_CUSTOM_LOG
  975. #define MG_ENABLE_CUSTOM_LOG 0 // Let user define their own MG_LOG
  976. #endif
  977. #ifndef MG_ENABLE_FREERTOS
  978. #define MG_ENABLE_FREERTOS 0 // FreeRTOS RTOS
  979. #endif
  980. #ifndef MG_ENABLE_TCPIP
  981. #define MG_ENABLE_TCPIP 0 // Mongoose built-in network stack
  982. #endif
  983. #ifndef MG_ENABLE_BSD_SOCKETS
  984. #define MG_ENABLE_BSD_SOCKETS 0 // BSD API support for built-in stack
  985. #endif
  986. #ifndef MG_ENABLE_BSD_PROTOTYPES
  987. #define MG_ENABLE_BSD_PROTOTYPES 1
  988. #endif
  989. #ifndef MG_ENABLE_LWIP
  990. #define MG_ENABLE_LWIP 0 // lwIP network stack
  991. #endif
  992. #ifndef MG_ENABLE_FREERTOS_TCP
  993. #define MG_ENABLE_FREERTOS_TCP 0 // Amazon FreeRTOS-TCP network stack
  994. #endif
  995. #ifndef MG_ENABLE_RL
  996. #define MG_ENABLE_RL 0 // ARM MDK network stack
  997. #endif
  998. #ifndef MG_ENABLE_SOCKET
  999. #define MG_ENABLE_SOCKET !MG_ENABLE_TCPIP
  1000. #endif
  1001. #ifndef MG_ENABLE_POLL
  1002. #define MG_ENABLE_POLL 0
  1003. #endif
  1004. #ifndef MG_ENABLE_EPOLL
  1005. #define MG_ENABLE_EPOLL 0
  1006. #endif
  1007. #ifndef MG_ENABLE_FATFS
  1008. #define MG_ENABLE_FATFS 0
  1009. #endif
  1010. #ifndef MG_ENABLE_LFS
  1011. #define MG_ENABLE_LFS 0
  1012. #endif
  1013. #ifndef MG_ENABLE_SSI
  1014. #define MG_ENABLE_SSI 0
  1015. #endif
  1016. #ifndef MG_ENABLE_IPV6
  1017. #define MG_ENABLE_IPV6 0
  1018. #endif
  1019. #ifndef MG_IPV6_V6ONLY
  1020. #define MG_IPV6_V6ONLY 0 // IPv6 socket binds only to V6, not V4 address
  1021. #endif
  1022. #ifndef MG_ENABLE_MD5
  1023. #define MG_ENABLE_MD5 1
  1024. #endif
  1025. // Set MG_ENABLE_WINSOCK=0 for Win32 builds with other external IP stack not
  1026. // mentioned in arch_win32.h
  1027. #ifndef MG_ENABLE_WINSOCK
  1028. #define MG_ENABLE_WINSOCK 1
  1029. #endif
  1030. #ifndef MG_ENABLE_DIRLIST
  1031. #define MG_ENABLE_DIRLIST 0
  1032. #endif
  1033. #ifndef MG_ENABLE_CUSTOM_RANDOM
  1034. #define MG_ENABLE_CUSTOM_RANDOM 0
  1035. #endif
  1036. #ifndef MG_ENABLE_CUSTOM_MILLIS
  1037. #define MG_ENABLE_CUSTOM_MILLIS 0
  1038. #endif
  1039. #ifndef MG_ENABLE_ASSERT
  1040. #define MG_ENABLE_ASSERT 0
  1041. #endif
  1042. #ifndef MG_IO_SIZE
  1043. #define MG_IO_SIZE 512 // Granularity of the send/recv IO buffer growth
  1044. #endif
  1045. #ifndef MG_MAX_RECV_SIZE
  1046. #define MG_MAX_RECV_SIZE (3UL * 1024UL * 1024UL) // Maximum recv IO buffer size
  1047. #endif
  1048. #ifndef MG_DATA_SIZE
  1049. #define MG_DATA_SIZE 32 // struct mg_connection :: data size
  1050. #endif
  1051. #ifndef MG_MAX_HTTP_HEADERS
  1052. #define MG_MAX_HTTP_HEADERS 30
  1053. #endif
  1054. #ifndef MG_HTTP_INDEX
  1055. #define MG_HTTP_INDEX "index.html"
  1056. #endif
  1057. #ifndef MG_PATH_MAX
  1058. #ifdef PATH_MAX
  1059. #define MG_PATH_MAX PATH_MAX
  1060. #else
  1061. #define MG_PATH_MAX 128
  1062. #endif
  1063. #endif
  1064. #ifndef MG_SOCK_LISTEN_BACKLOG_SIZE
  1065. #define MG_SOCK_LISTEN_BACKLOG_SIZE 128
  1066. #endif
  1067. #ifndef MG_DIRSEP
  1068. #define MG_DIRSEP '/'
  1069. #endif
  1070. #ifndef MG_ENABLE_POSIX_FS
  1071. #define MG_ENABLE_POSIX_FS 0
  1072. #endif
  1073. #ifndef MG_INVALID_SOCKET
  1074. #define MG_INVALID_SOCKET (-1)
  1075. #endif
  1076. #ifndef MG_SOCKET_TYPE
  1077. #define MG_SOCKET_TYPE int
  1078. #endif
  1079. #ifndef MG_SOCKET_ERRNO
  1080. #define MG_SOCKET_ERRNO errno
  1081. #endif
  1082. #if MG_ENABLE_EPOLL
  1083. #define MG_EPOLL_ADD(c) \
  1084. do { \
  1085. struct epoll_event ev = {EPOLLIN | EPOLLERR | EPOLLHUP, {c}}; \
  1086. epoll_ctl(c->mgr->epoll_fd, EPOLL_CTL_ADD, (int) (size_t) c->fd, &ev); \
  1087. } while (0)
  1088. #define MG_EPOLL_MOD(c, wr) \
  1089. do { \
  1090. struct epoll_event ev = {EPOLLIN | EPOLLERR | EPOLLHUP, {c}}; \
  1091. if (wr) ev.events |= EPOLLOUT; \
  1092. epoll_ctl(c->mgr->epoll_fd, EPOLL_CTL_MOD, (int) (size_t) c->fd, &ev); \
  1093. } while (0)
  1094. #else
  1095. #define MG_EPOLL_ADD(c)
  1096. #define MG_EPOLL_MOD(c, wr)
  1097. #endif
  1098. #ifndef MG_ENABLE_PROFILE
  1099. #define MG_ENABLE_PROFILE 0
  1100. #endif
  1101. #ifndef MG_ENABLE_TCPIP_DRIVER_INIT // mg_mgr_init() will also initialize
  1102. #define MG_ENABLE_TCPIP_DRIVER_INIT 1 // enabled built-in driver for
  1103. #endif // Mongoose built-in network stack
  1104. #ifndef MG_TCPIP_IP // e.g. MG_IPV4(192, 168, 0, 223)
  1105. #define MG_TCPIP_IP MG_IPV4(0, 0, 0, 0) // Default is 0.0.0.0 (DHCP)
  1106. #endif
  1107. #ifndef MG_TCPIP_MASK
  1108. #define MG_TCPIP_MASK MG_IPV4(0, 0, 0, 0) // Default is 0.0.0.0 (DHCP)
  1109. #endif
  1110. #ifndef MG_TCPIP_GW
  1111. #define MG_TCPIP_GW MG_IPV4(0, 0, 0, 0) // Default is 0.0.0.0 (DHCP)
  1112. #endif
  1113. #if MG_ENABLE_IPV6
  1114. #ifndef MG_TCPIP_GLOBAL
  1115. #define MG_TCPIP_GLOBAL MG_IPV6(0, 0, 0, 0, 0, 0, 0, 0)
  1116. #endif
  1117. #ifndef MG_TCPIP_IPV6_LINKLOCAL
  1118. #define MG_TCPIP_IPV6_LINKLOCAL MG_IPV6(0, 0, 0, 0, 0, 0, 0, 0)
  1119. #endif
  1120. #ifndef MG_TCPIP_PREFIX_LEN
  1121. #define MG_TCPIP_PREFIX_LEN 0
  1122. #endif
  1123. #ifndef MG_TCPIP_GW6
  1124. #define MG_TCPIP_GW6 MG_IPV6(0, 0, 0, 0, 0, 0, 0, 0)
  1125. #endif
  1126. #endif
  1127. #ifndef MG_SET_MAC_ADDRESS
  1128. #define MG_SET_MAC_ADDRESS(mac)
  1129. #endif
  1130. #ifndef MG_TCPIP_DHCPNAME_SIZE
  1131. #define MG_TCPIP_DHCPNAME_SIZE 18 // struct mg_tcpip_if :: dhcp_name size
  1132. #endif
  1133. #ifndef MG_SET_WIFI_CONFIG
  1134. #define MG_SET_WIFI_CONFIG(ifp, driver_data)
  1135. #endif
  1136. #ifndef MG_ENABLE_TCPIP_PRINT_DEBUG_STATS
  1137. #define MG_ENABLE_TCPIP_PRINT_DEBUG_STATS 0
  1138. #endif
  1139. #ifndef MG_ENABLE_CHACHA20
  1140. #define MG_ENABLE_CHACHA20 1 // When set to 0, GCM is used. For MG_TLS_BUILTIN
  1141. #endif
  1142. // Macros to record timestamped events that happens with a connection.
  1143. // They are saved into a c->prof IO buffer, each event is a name and a 32-bit
  1144. // timestamp in milliseconds since connection init time.
  1145. //
  1146. // Test (run in two separate terminals):
  1147. // make -C tutorials/http/http-server/ CFLAGS_EXTRA=-DMG_ENABLE_PROFILE=1
  1148. // curl localhost:8000
  1149. // Output:
  1150. // 1ea1f1e7 2 net.c:150:mg_close_conn 3 profile:
  1151. // 1ea1f1e8 2 net.c:150:mg_close_conn 1ea1f1e6 init
  1152. // 1ea1f1e8 2 net.c:150:mg_close_conn 0 EV_OPEN
  1153. // 1ea1f1e8 2 net.c:150:mg_close_conn 0 EV_ACCEPT
  1154. // 1ea1f1e8 2 net.c:150:mg_close_conn 0 EV_READ
  1155. // 1ea1f1e8 2 net.c:150:mg_close_conn 0 EV_HTTP_MSG
  1156. // 1ea1f1e8 2 net.c:150:mg_close_conn 0 EV_WRITE
  1157. // 1ea1f1e8 2 net.c:150:mg_close_conn 1 EV_CLOSE
  1158. //
  1159. // Usage:
  1160. // Enable profiling by setting MG_ENABLE_PROFILE=1
  1161. // Invoke MG_PROF_ADD(c, "MY_EVENT_1") in the places you'd like to measure
  1162. #if MG_ENABLE_PROFILE
  1163. struct mg_profitem {
  1164. const char *name; // Event name
  1165. uint32_t timestamp; // Milliseconds since connection creation (MG_EV_OPEN)
  1166. };
  1167. #define MG_PROFILE_ALLOC_GRANULARITY 256 // Can save 32 items wih to realloc
  1168. // Adding a profile item to the c->prof. Must be as fast as possible.
  1169. // Reallocation of the c->prof iobuf is not desirable here, that's why we
  1170. // pre-allocate c->prof with MG_PROFILE_ALLOC_GRANULARITY.
  1171. // This macro just inits and copies 8 bytes, and calls mg_millis(),
  1172. // which should be fast enough.
  1173. #define MG_PROF_ADD(c, name_) \
  1174. do { \
  1175. struct mg_iobuf *io = &c->prof; \
  1176. uint32_t inittime = ((struct mg_profitem *) io->buf)->timestamp; \
  1177. struct mg_profitem item = {name_, (uint32_t) mg_millis() - inittime}; \
  1178. mg_iobuf_add(io, io->len, &item, sizeof(item)); \
  1179. } while (0)
  1180. // Initialising profile for a new connection. Not time sensitive
  1181. #define MG_PROF_INIT(c) \
  1182. do { \
  1183. struct mg_profitem first = {"init", (uint32_t) mg_millis()}; \
  1184. mg_iobuf_init(&(c)->prof, 0, MG_PROFILE_ALLOC_GRANULARITY); \
  1185. mg_iobuf_add(&c->prof, c->prof.len, &first, sizeof(first)); \
  1186. } while (0)
  1187. #define MG_PROF_FREE(c) mg_iobuf_free(&(c)->prof)
  1188. // Dumping the profile. Not time sensitive
  1189. #define MG_PROF_DUMP(c) \
  1190. do { \
  1191. struct mg_iobuf *io = &c->prof; \
  1192. struct mg_profitem *p = (struct mg_profitem *) io->buf; \
  1193. struct mg_profitem *e = &p[io->len / sizeof(*p)]; \
  1194. MG_INFO(("%lu profile:", c->id)); \
  1195. while (p < e) { \
  1196. MG_INFO(("%5lx %s", (unsigned long) p->timestamp, p->name)); \
  1197. p++; \
  1198. } \
  1199. } while (0)
  1200. #else
  1201. #define MG_PROF_INIT(c)
  1202. #define MG_PROF_FREE(c)
  1203. #define MG_PROF_ADD(c, name)
  1204. #define MG_PROF_DUMP(c)
  1205. #endif
  1206. // A non-owning view of an arbitrary byte buffer. Not NUL-terminated in general.
  1207. // Use mg_str() or mg_str_n() to construct; use mg_strdup() for an owned copy.
  1208. struct mg_str {
  1209. char *buf; // Pointer to the data (not necessarily NUL-terminated)
  1210. size_t len; // Number of bytes
  1211. };
  1212. // Using macro to avoid shadowing the C++ struct constructor, see #1298
  1213. #define mg_str(s) mg_str_s(s)
  1214. // Creates an mg_str from a NUL-terminated C string. Computes length via
  1215. // strlen. Returns {NULL, 0} when s is NULL.
  1216. struct mg_str mg_str(const char *s);
  1217. // Creates an mg_str from a pointer and explicit byte count. s need not be
  1218. // NUL-terminated. Does not copy the data.
  1219. struct mg_str mg_str_n(const char *s, size_t n);
  1220. // Case-insensitive strcmp for NUL-terminated C strings.
  1221. // Returns 0 if equal, <0 if s1 < s2, >0 if s1 > s2.
  1222. int mg_casecmp(const char *s1, const char *s2);
  1223. // Compares two mg_str by content and length. Returns 0 if identical,
  1224. // -1 if str1 < str2, 1 if str1 > str2. Length is used as a tiebreaker
  1225. // when one string is a prefix of the other.
  1226. int mg_strcmp(const struct mg_str str1, const struct mg_str str2);
  1227. // Case-insensitive mg_strcmp.
  1228. int mg_strcasecmp(const struct mg_str str1, const struct mg_str str2);
  1229. // Returns a heap-allocated, NUL-terminated copy of s.
  1230. // Returns {NULL, 0} on OOM or if s.buf is NULL or s.len is 0.
  1231. // Caller must mg_free(result.buf) when done.
  1232. struct mg_str mg_strdup(const struct mg_str s);
  1233. // Matches a string against a glob pattern.
  1234. //
  1235. // Returns:
  1236. // True if the whole str matches pattern.
  1237. // Example:
  1238. // if (mg_match(hm->uri, mg_str("/api/#"), NULL)) { ... }
  1239. // Full examples:
  1240. // tutorials/http/http-server, tutorials/http/link-checker,
  1241. // tutorials/websocket/websocket-server
  1242. // Related APIs:
  1243. // mg_str(), mg_str_n(), mg_span(), mg_strcmp(), mg_strcasecmp()
  1244. // Notes:
  1245. // Pattern wildcards: ? matches one character, * matches any sequence except
  1246. // '/', and # matches any sequence including '/'. If caps is not NULL, each
  1247. // wildcard capture is stored as a zero-copy mg_str slice into str. Pass
  1248. // caps=NULL when captures are not needed. The caps array size should be
  1249. // at least the number of wildcards in a pattern plus one. The last cap
  1250. // is initialised to an empty string.
  1251. // Attention: the pattern must consume the whole str in order to match.
  1252. bool mg_match(struct mg_str str, struct mg_str pattern, struct mg_str *caps);
  1253. // Splits s at the first occurrence of sep. Sets *a to the part before sep
  1254. // and *b to the part after it (sep is not included in either). Both slices
  1255. // are zero-copy views into s. a or b may be NULL if that half is not needed.
  1256. // If sep is not found, *a is the whole string and *b is empty.
  1257. // Returns false if s is empty or s.buf is NULL.
  1258. // Example - scan comma-separated key=value pairs:
  1259. // ```c
  1260. // struct mg_str entry, key, val;
  1261. // struct mg_str s = mg_str("a=333,b=777,hello");
  1262. //
  1263. // while (mg_span(s, &entry, &s, ',')) {
  1264. // mg_span(entry, &key, &val, '=');
  1265. // printf("key: %.*s, val: %.*s\n", (int) key.len, key.buf, (int) val.len, val.buf);
  1266. // }
  1267. // ```
  1268. bool mg_span(struct mg_str s, struct mg_str *a, struct mg_str *b, char sep);
  1269. // Parses str as an unsigned integer into the val_len-byte value at *val.
  1270. // val_len must be 1, 2, 4, or 8 (for uint8_t, uint16_t, uint32_t, uint64_t).
  1271. // base must be 2, 10, or 16; pass 0 to auto-detect from a "0b" or "0x" prefix.
  1272. // The entire string must consist of valid digits with no trailing characters.
  1273. // Returns false on overflow, invalid input, unsupported base, or unsupported val_len.
  1274. bool mg_str_to_num(struct mg_str str, int base, void *val, size_t val_len);
  1275. // Lock-free, single-producer / single-consumer (SPSC) message queue.
  1276. // Safe to write from an ISR and read from the main loop without locking,
  1277. // as long as only one context writes and one context reads at a time.
  1278. // Each message is stored with an internal 32-bit length prefix; the buf
  1279. // pointers returned by mg_queue_book() and mg_queue_next() already skip it.
  1280. //
  1281. // Producer pattern:
  1282. // char buf[1024];
  1283. // if (mg_queue_book(&q, &buf, len) >= len) {
  1284. // memcpy(buf, data, len);
  1285. // mg_queue_add(&q, len);
  1286. // }
  1287. //
  1288. // Consumer pattern:
  1289. // char *buf;
  1290. // size_t len = mg_queue_next(&q, &buf);
  1291. // if (len > 0) { process(buf, len); mg_queue_del(&q, len); }
  1292. struct mg_queue {
  1293. char *buf; // Caller-supplied backing buffer
  1294. size_t size; // Size of buf in bytes
  1295. volatile size_t tail; // Read offset; updated by the consumer
  1296. volatile size_t head; // Write offset; updated by the producer
  1297. };
  1298. // Initialises q to use the caller-supplied buf/size. buf must remain valid
  1299. // for the lifetime of the queue.
  1300. void mg_queue_init(struct mg_queue *q, char *buf, size_t size);
  1301. // Reserves space for a message of len bytes. Sets *buf to the write location.
  1302. // Returns the number of bytes available (>= len means the reservation
  1303. // succeeded). Does NOT commit the message; call mg_queue_add() after writing.
  1304. size_t mg_queue_book(struct mg_queue *q, char **buf, size_t len);
  1305. // Commits the most recently reserved message of len bytes. Must be called
  1306. // with the same len passed to the preceding mg_queue_book() call, after
  1307. // the data has been written into the buffer it returned.
  1308. void mg_queue_add(struct mg_queue *q, size_t len);
  1309. // Returns the length of the oldest unconsumed message and sets *buf to its
  1310. // start. Returns 0 if the queue is empty. Does NOT remove the message;
  1311. // call mg_queue_del() after processing to advance the read position.
  1312. size_t mg_queue_next(struct mg_queue *q, char **buf);
  1313. // Removes the oldest message of len bytes. Must be called with the same len
  1314. // returned by the preceding mg_queue_next() call.
  1315. void mg_queue_del(struct mg_queue *q, size_t len);
  1316. // Character output function. Called once per output character by mg_xprintf/mg_vxprintf.
  1317. // arg is an arbitrary user pointer passed through from the caller.
  1318. typedef void (*mg_pfn_t)(char, void *arg);
  1319. // Custom %M/%m printer. Reads its own arguments from ap and writes via fn.
  1320. // Returns the number of characters printed (excluding the quotes added by %m).
  1321. typedef size_t (*mg_pm_t)(mg_pfn_t fn, void *arg, va_list *);
  1322. // Formats fmt with printf-like specifiers, calling fn for each output character.
  1323. // Returns the total number of characters printed. Supported specifiers:
  1324. // - %c - expect char
  1325. // - %f, %g - expect double
  1326. // - %hhd, %hd, %d, %ld, %lld - for char, short, int, long, int64_t
  1327. // - %hhu, %hu, %u, %lu, %llu - same but for unsigned variants
  1328. // - %hhx, %hx, %x, %lx, %llx - same, unsigned and hex output
  1329. // - %p - expects any pointer, prints 0x..... hex value
  1330. // - %s - expects char *
  1331. // - %% - prints the % character itself
  1332. // - %X.Y - optional width and precision modifiers (e.g.: %1.2d)
  1333. // - %.* - optional precision modifier, expected as int argument (e.g.: %.*d)
  1334. // - %M - (EXTENSION) expects a pointer to a custom print function and its arguments
  1335. // - %m - (EXTENSION) exactly like %M but double-quotes the output
  1336. // - %M/%m (custom mg_pm_t printer; %m additionally wraps the output in quotes).
  1337. //
  1338. // There are higher level wrappers around these functions that use
  1339. // predefined output functions, and can print to char buffer, or connection
  1340. // send iobuffer, etc etc. - for example, mg_snrptinf(). The %M/%m non-standard
  1341. // specifier allows to use custom formtter. There are several pre-defined
  1342. // formatters:
  1343. // - mg_print_base64 - prints a buffer as a base64-encoded string
  1344. // - mg_print_esc - prints a JSON-escaped string
  1345. // - mg_print_hex - prints a buffer as a hex string
  1346. // - mg_print_ip - prints an IP address in a struct mg_str
  1347. // - mg_print_ip_port - prints IP address and port in a struct mg_str
  1348. // - mg_print_ip4 - prints an IPv4 address
  1349. // - mg_print_ip6 - prints an IPv6 address
  1350. // - mg_print_mac - prints a MAC address
  1351. //
  1352. // Usage example:
  1353. //
  1354. // ```c
  1355. // struct a { int a, b; };
  1356. //
  1357. // size_t print_a(mg_pfn_t fn, void *arg, va_list *ap) {
  1358. // struct a *p = va_arg(*ap, struct a *);
  1359. // return mg_xprintf(fn, arg, "{%m:%d}", MG_ESC("a"), p->a);
  1360. // }
  1361. //
  1362. // struct a temp = { 42, 43 };
  1363. // char buf[100];
  1364. //
  1365. // mg_snprintf(buf, sizeof(buf), "%M", print_a, &temp); // {"a":42}
  1366. // ```
  1367. size_t mg_vxprintf(mg_pfn_t fn, void *arg, const char *fmt, va_list *);
  1368. size_t mg_xprintf(mg_pfn_t fn, void *arg, const char *fmt, ...);
  1369. // Formats data into a caller-supplied buffer.
  1370. //
  1371. // Returns:
  1372. // Number of bytes that would be written if buf were large enough, like
  1373. // snprintf().
  1374. // Example:
  1375. // char buf[20];
  1376. // mg_snprintf(buf, sizeof(buf), "{%m:%d}", MG_ESC("status"), 1);
  1377. // Full examples:
  1378. // tutorials/http/link-checker, tutorials/http/redirect-to-https,
  1379. // tutorials/mqtt/mqtt-dashboard/device
  1380. // Related APIs:
  1381. // mg_xprintf(), mg_printf(), mg_mprintf(), MG_ESC
  1382. // Notes:
  1383. // These functions are just wrappers around mg_xprintf().
  1384. // Call with buf=NULL and len=0 to measure. NUL-terminates if the result fits
  1385. // (return value < len). Supports mg_xprintf specifiers, including custom
  1386. // %M/%m printers. Use MG_ESC when printing JSON strings.
  1387. size_t mg_vsnprintf(char *buf, size_t len, const char *fmt, va_list *ap);
  1388. size_t mg_snprintf(char *buf, size_t len, const char *fmt, ...);
  1389. // Formats into a heap-allocated NUL-terminated string. Caller must mg_free() it.
  1390. char *mg_vmprintf(const char *fmt, va_list *ap);
  1391. char *mg_mprintf(const char *fmt, ...);
  1392. // Formats into a mg_queue slot. Returns bytes written, or 0 if no space.
  1393. size_t mg_queue_printf(struct mg_queue *, const char *fmt, ...);
  1394. // Built-in %M/%m printer functions. Each reads its argument(s) from ap.
  1395. size_t mg_print_base64(mg_pfn_t, void *arg, va_list *ap); // expects: const void *buf, size_t len
  1396. size_t mg_print_esc(mg_pfn_t, void *arg, va_list *ap); // expects: int len, const char *str -- use MG_ESC()
  1397. size_t mg_print_hex(mg_pfn_t, void *arg, va_list *ap); // expects: const void *buf, size_t len
  1398. size_t mg_print_ip(mg_pfn_t, void *arg, va_list *ap); // expects: const struct mg_addr *
  1399. size_t mg_print_ip_port(mg_pfn_t, void *arg, va_list *ap); // expects: const struct mg_addr *
  1400. size_t mg_print_ip4(mg_pfn_t, void *arg, va_list *ap); // expects: uint32_t *ipv4
  1401. size_t mg_print_ip6(mg_pfn_t, void *arg, va_list *ap); // expects: uint8_t[16] ipv6
  1402. size_t mg_print_mac(mg_pfn_t, void *arg, va_list *ap); // expects: uint8_t[6] mac
  1403. size_t mg_print_ieee64(mg_pfn_t, void *arg, va_list *ap); // expects: uint64_t
  1404. size_t mg_print_l2addr(mg_pfn_t, void *arg, va_list *ap); // expects: uint8_t l2, uint8_t[n] n-byte l2-dependent address
  1405. size_t mg_print_html_esc(mg_pfn_t, void *arg, va_list *ap); // expects: int len, const char *str -- use MG_ESC()
  1406. // Output functions for use as the fn argument to mg_xprintf/mg_vxprintf.
  1407. void mg_pfn_iobuf(char ch, void *param); // param: struct mg_iobuf * (resizes as needed)
  1408. void mg_pfn_iobuf_noresize(char ch, void *param); // param: struct mg_iobuf * (fixed buffer, no resize)
  1409. void mg_pfn_stdout(char c, void *param); // param: ignored, writes to stdout
  1410. // Expands to the three arguments for %m to JSON-escape a string literal.
  1411. // Example: mg_snprintf(buf, len, "%m", MG_ESC("hello")) -> "\"hello\""
  1412. #define MG_ESC(str) mg_print_esc, 0, (str)
  1413. // Logging
  1414. //
  1415. // Mongoose provides a set of functions and macros for logging. The application can
  1416. // use these functions for its own purposes as well as the rest of Mongoose API.
  1417. // Log levels
  1418. enum { MG_LL_NONE, MG_LL_ERROR, MG_LL_INFO, MG_LL_DEBUG, MG_LL_VERBOSE };
  1419. // Set Mongoose logging level. Example: `mg_log_set(MG_LL_INFO);`
  1420. extern int mg_log_level; // Current log level, one of MG_LL_*
  1421. #define mg_log_set(level_) mg_log_level = (level_)
  1422. void mg_log(const char *fmt, ...);
  1423. void mg_log_prefix(int ll, const char *file, int line, const char *fname);
  1424. // Log a hex dump of binary data `buf`, `len`.
  1425. void mg_hexdump(const void *buf, size_t len);
  1426. // Set log printer function which prints one byte. Example:
  1427. //
  1428. // ```c
  1429. // static void print_char(char ch, void *param) {
  1430. // hal_uart_write_char(param, ch);
  1431. // }
  1432. // ...
  1433. // mg_log_set_fn(print_char, USART3);
  1434. // ```
  1435. void mg_log_set_fn(mg_pfn_t fn, void *param);
  1436. #if MG_ENABLE_LOG
  1437. #if !defined(_MSC_VER) && \
  1438. (!defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L)
  1439. #define MG___FUNC__ ""
  1440. #else
  1441. #define MG___FUNC__ __func__ // introduced in C99
  1442. #endif
  1443. #define MG_LOG(level, args) \
  1444. do { \
  1445. if ((level) <= mg_log_level) { \
  1446. mg_log_prefix((level), __FILE__, __LINE__, MG___FUNC__); \
  1447. mg_log args; \
  1448. } \
  1449. } while (0)
  1450. #else
  1451. #define MG_LOG(level, args) \
  1452. do { \
  1453. if (0) mg_log args; \
  1454. } while (0)
  1455. #endif
  1456. // Logging macros. Note: the argument is exactly like for mg_snprintf(),
  1457. // and it should be enclosed in double parenthesis. Example:
  1458. // ```c
  1459. // MG_INFO(("Conn %lu, recv buf: %.*s", c->id, c->recv.len, c->recv.buf));
  1460. // ```
  1461. #define MG_ERROR(args) MG_LOG(MG_LL_ERROR, args)
  1462. #define MG_INFO(args) MG_LOG(MG_LL_INFO, args)
  1463. #define MG_DEBUG(args) MG_LOG(MG_LL_DEBUG, args)
  1464. #define MG_VERBOSE(args) MG_LOG(MG_LL_VERBOSE, args)
  1465. struct mg_timer {
  1466. uint64_t period_ms; // Timer period in milliseconds
  1467. uint64_t expire; // Expiration timestamp in milliseconds
  1468. unsigned flags; // Possible flags values below
  1469. #define MG_TIMER_ONCE 0 // Call function once
  1470. #define MG_TIMER_REPEAT 1 // Call function periodically
  1471. #define MG_TIMER_RUN_NOW 2 // Call immediately when timer is set
  1472. #define MG_TIMER_CALLED 4 // Timer function was called at least once
  1473. #define MG_TIMER_AUTODELETE 8 // mg_free() timer when done
  1474. void (*fn)(void *); // Function to call
  1475. void *arg; // Function argument
  1476. struct mg_timer *next; // Linkage
  1477. };
  1478. void mg_timer_init(struct mg_timer **head, struct mg_timer *timer,
  1479. uint64_t milliseconds, unsigned flags, void (*fn)(void *),
  1480. void *arg);
  1481. void mg_timer_free(struct mg_timer **head, struct mg_timer *);
  1482. void mg_timer_poll(struct mg_timer **head, uint64_t new_ms);
  1483. // Flags returned by mg_fs.st() and passed to mg_fs.open().
  1484. enum { MG_FS_READ = 1, MG_FS_WRITE = 2, MG_FS_DIR = 4, MG_FS_EXCL = 8 };
  1485. // Filesystem abstraction. Implement all function pointers to plug in a custom
  1486. // filesystem. Short UNIX-style names are used deliberately to avoid conflicts
  1487. // with libraries that define macros for stat(), read(), write(), etc.
  1488. struct mg_fs {
  1489. int (*st)(const char *path, size_t *size, time_t *mtime); // Stat: return MG_FS_* flags; size/mtime may be NULL
  1490. void (*ls)(const char *path, void (*fn)(const char *, void *), void *); // List dir: call fn(name, arg) per entry
  1491. void *(*op)(const char *path, int flags); // Open file; return opaque fd, or NULL on error
  1492. void (*cl)(void *fd); // Close file
  1493. size_t (*rd)(void *fd, void *buf, size_t len); // Read up to len bytes; return bytes read
  1494. size_t (*wr)(void *fd, const void *buf, size_t len); // Write len bytes; return bytes written
  1495. size_t (*sk)(void *fd, size_t offset); // Seek to offset from start; return new position
  1496. bool (*mv)(const char *from, const char *to); // Rename/move file
  1497. bool (*rm)(const char *path); // Delete file
  1498. bool (*mkd)(const char *path); // Create directory
  1499. };
  1500. extern struct mg_fs mg_fs_posix; // POSIX filesystem (open/close/read/write/seek)
  1501. extern struct mg_fs mg_fs_packed; // Read-only packed filesystem (see tutorials/core/embedded-filesystem)
  1502. extern struct mg_fs mg_fs_fat; // FAT filesystem
  1503. // Open file descriptor returned by mg_fs_open(). Bundles the raw fd with its fs.
  1504. struct mg_fd {
  1505. void *fd; // Opaque file handle from fs->op()
  1506. struct mg_fs *fs; // Filesystem that owns fd
  1507. };
  1508. // Opens path with the given MG_FS_* flags. Returns NULL on error.
  1509. struct mg_fd *mg_fs_open(struct mg_fs *fs, const char *path, int flags);
  1510. // Closes fd and frees the mg_fd struct. Safe to call with NULL.
  1511. void mg_fs_close(struct mg_fd *fd);
  1512. // Sequential directory iterator. Call repeatedly with the same buf/len;
  1513. // each call fills buf with the next entry name. Returns false when done.
  1514. bool mg_fs_ls(struct mg_fs *fs, const char *path, char *buf, size_t len);
  1515. // Reads the entire file into a heap-allocated buffer. The returned mg_str is
  1516. // NUL-terminated. Caller must mg_free(result.buf). Returns {NULL,0} on error.
  1517. struct mg_str mg_file_read(struct mg_fs *fs, const char *path);
  1518. // Atomically writes buf/len to path (via a temp file + rename). Returns false on error.
  1519. bool mg_file_write(struct mg_fs *fs, const char *path, const void *buf, size_t len);
  1520. // Formats a string and atomically writes it to path. Returns false on error.
  1521. bool mg_file_printf(struct mg_fs *fs, const char *path, const char *fmt, ...);
  1522. // A file stored in memory (flash or RAM), used by mg_fs_packed.
  1523. struct mg_mem_file {
  1524. const char *path; // Virtual file path, e.g. "/web_root/index.html"
  1525. const unsigned char *data; // Pointer to file content
  1526. size_t size; // Content size in bytes
  1527. time_t mtime; // Modification time (may be 0)
  1528. };
  1529. // Pointer to a NULL-path-terminated array of in-memory files for mg_fs_packed.
  1530. // Override to serve a custom set of files:
  1531. // static const struct mg_mem_file my_files[] = {
  1532. // {"/index.html", data, sizeof(data), 0},
  1533. // {NULL, NULL, 0, 0},
  1534. // };
  1535. // mg_mem_files = my_files;
  1536. extern const struct mg_mem_file *mg_mem_files;
  1537. // Looks up path in the packed file array. Returns an mg_str pointing directly
  1538. // into the stored data (zero-copy). Returns {NULL,0} if not found.
  1539. struct mg_str mg_unpacked(const char *path);
  1540. // Array of packed files generated by the "pack" utility into packed_fs.c.
  1541. // Activate by assigning: mg_mem_files = mg_packed_files;
  1542. extern const struct mg_mem_file mg_packed_files[];
  1543. #if MG_ENABLE_ASSERT
  1544. #include <assert.h>
  1545. #elif !defined(assert)
  1546. #define assert(x)
  1547. #endif
  1548. // Wrappers around calloc/free. Override by defining MG_ENABLE_CUSTOM_CALLOC=1
  1549. // and providing your own implementations.
  1550. void *mg_calloc(size_t count, size_t size);
  1551. void mg_free(void *ptr);
  1552. // Zeroes len bytes at buf using a volatile write loop that the compiler cannot
  1553. // elide. Safe to call with buf=NULL. Use instead of memset() for clearing
  1554. // sensitive data (keys, passwords).
  1555. void mg_bzero(volatile unsigned char *buf, size_t len);
  1556. // Fixed-length constant-time byte equality. Use for MACs, tags, signatures.
  1557. bool mg_memeq(const void *a, const void *b, size_t n);
  1558. // Fills buf with len cryptographically random bytes. Uses the best available
  1559. // hardware or OS source (hardware RNG, /dev/urandom, CryptGenRandom, etc.).
  1560. // Falls back to rand() with an error log if no strong source is available.
  1561. // Returns true when a strong source was used, false on fallback to rand().
  1562. // Override by defining MG_ENABLE_CUSTOM_RANDOM=1 and providing your own impl.
  1563. bool mg_random(void *buf, size_t len);
  1564. // Fills buf with len-1 random alphanumeric characters ([a-zA-Z0-9]) and
  1565. // NUL-terminates. Returns buf.
  1566. char *mg_random_str(char *buf, size_t len);
  1567. // Computes CRC32 (polynomial 0xEDB88320) over buf/len. Pass crc=0 to start
  1568. // a new checksum; pass the result of a prior call to extend over more data.
  1569. uint32_t mg_crc32(uint32_t crc, const char *buf, size_t len);
  1570. // Computes CRC16 (HDLC, polynomial 0x8408) over buf/len. Pass crc=0 to start
  1571. // a new checksum; pass the result of a prior call to extend over more data.
  1572. uint16_t mg_crc16(uint16_t crc, const char *buf, size_t len);
  1573. // Returns true if path is safe to serve from the filesystem. Rejects paths
  1574. // that start with '~' or '..', or contain a '/../' component, to prevent
  1575. // directory traversal attacks.
  1576. bool mg_path_is_sane(const struct mg_str path);
  1577. // Busy-waits for at least ms milliseconds using mg_millis(). Blocks the
  1578. // calling context; avoid in event handlers.
  1579. void mg_delayms(unsigned int ms);
  1580. uint64_t mg_timegm(unsigned int year, unsigned int month, unsigned int day,
  1581. unsigned int hour, unsigned int min, unsigned int sec);
  1582. // Packs four byte values into a uint32_t in big-endian order.
  1583. // MG_U32(1, 2, 3, 4) == 0x01020304
  1584. #define MG_U32(a, b, c, d) \
  1585. (((uint32_t) ((a) &255) << 24) | ((uint32_t) ((b) &255) << 16) | \
  1586. ((uint32_t) ((c) &255) << 8) | (uint32_t) ((d) &255))
  1587. // Constructs an IPv4 address in network byte order from four decimal octets.
  1588. // Usage: uint32_t ip = MG_IPV4(192, 168, 1, 1);
  1589. #define MG_IPV4(a, b, c, d) mg_htonl(MG_U32(a, b, c, d))
  1590. // Expands to a brace-enclosed byte initialiser for a 16-byte IPv6 address.
  1591. // Arguments are the eight 16-bit groups in the address, e.g.:
  1592. // uint8_t ip6[16] = MG_IPV6(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1);
  1593. #define MG_IPV6(a, b, c, d, e, f, g ,h) \
  1594. { (uint8_t)((a)>>8),(uint8_t)(a), \
  1595. (uint8_t)((b)>>8),(uint8_t)(b), \
  1596. (uint8_t)((c)>>8),(uint8_t)(c), \
  1597. (uint8_t)((d)>>8),(uint8_t)(d), \
  1598. (uint8_t)((e)>>8),(uint8_t)(e), \
  1599. (uint8_t)((f)>>8),(uint8_t)(f), \
  1600. (uint8_t)((g)>>8),(uint8_t)(g), \
  1601. (uint8_t)((h)>>8),(uint8_t)(h) }
  1602. // For printing IPv4 addresses: printf("%d.%d.%d.%d\n", MG_IPADDR_PARTS(&ip))
  1603. #define MG_U8P(ADDR) ((uint8_t *) (ADDR))
  1604. #define MG_IPADDR_PARTS(ADDR) \
  1605. MG_U8P(ADDR)[0], MG_U8P(ADDR)[1], MG_U8P(ADDR)[2], MG_U8P(ADDR)[3]
  1606. // Read an unaligned big-endian value from byte pointer p into a native integer.
  1607. // Safe on architectures that forbid unaligned access (e.g. Cortex-M0).
  1608. #define MG_LOAD_BE16(p) \
  1609. ((uint16_t) (((uint16_t) MG_U8P(p)[0] << 8U) | MG_U8P(p)[1]))
  1610. #define MG_LOAD_BE24(p) \
  1611. ((uint32_t) (((uint32_t) MG_U8P(p)[0] << 16U) | \
  1612. ((uint32_t) MG_U8P(p)[1] << 8U) | MG_U8P(p)[2]))
  1613. #define MG_LOAD_BE32(p) \
  1614. ((uint32_t) (((uint32_t) MG_U8P(p)[0] << 24U) | \
  1615. ((uint32_t) MG_U8P(p)[1] << 16U) | \
  1616. ((uint32_t) MG_U8P(p)[2] << 8U) | MG_U8P(p)[3]))
  1617. #define MG_LOAD_BE64(p) \
  1618. ((uint64_t) (((uint64_t) MG_U8P(p)[0] << 56U) | \
  1619. ((uint64_t) MG_U8P(p)[1] << 48U) | \
  1620. ((uint64_t) MG_U8P(p)[2] << 40U) | \
  1621. ((uint64_t) MG_U8P(p)[3] << 32U) | \
  1622. ((uint64_t) MG_U8P(p)[4] << 24U) | \
  1623. ((uint64_t) MG_U8P(p)[5] << 16U) | \
  1624. ((uint64_t) MG_U8P(p)[6] << 8U) | MG_U8P(p)[7]))
  1625. // Write a native integer to byte pointer p in big-endian byte order.
  1626. // Safe on architectures that forbid unaligned access.
  1627. #define MG_STORE_BE16(p, n) \
  1628. do { \
  1629. MG_U8P(p)[0] = (uint8_t) ((n) >> 8U); \
  1630. MG_U8P(p)[1] = (uint8_t) (n); \
  1631. } while (0)
  1632. #define MG_STORE_BE24(p, n) \
  1633. do { \
  1634. MG_U8P(p)[0] = (uint8_t) ((n) >> 16U); \
  1635. MG_U8P(p)[1] = (uint8_t) ((n) >> 8U); \
  1636. MG_U8P(p)[2] = (uint8_t) (n); \
  1637. } while (0)
  1638. #define MG_STORE_BE32(p, n) \
  1639. do { \
  1640. MG_U8P(p)[0] = (uint8_t) ((n) >> 24U); \
  1641. MG_U8P(p)[1] = (uint8_t) ((n) >> 16U); \
  1642. MG_U8P(p)[2] = (uint8_t) ((n) >> 8U); \
  1643. MG_U8P(p)[3] = (uint8_t) (n); \
  1644. } while (0)
  1645. #define MG_STORE_BE64(p, n) \
  1646. do { \
  1647. MG_U8P(p)[0] = (uint8_t) ((n) >> 56U); \
  1648. MG_U8P(p)[1] = (uint8_t) ((n) >> 48U); \
  1649. MG_U8P(p)[2] = (uint8_t) ((n) >> 40U); \
  1650. MG_U8P(p)[3] = (uint8_t) ((n) >> 32U); \
  1651. MG_U8P(p)[4] = (uint8_t) ((n) >> 24U); \
  1652. MG_U8P(p)[5] = (uint8_t) ((n) >> 16U); \
  1653. MG_U8P(p)[6] = (uint8_t) ((n) >> 8U); \
  1654. MG_U8P(p)[7] = (uint8_t) (n); \
  1655. } while (0)
  1656. // Network / host byte-order conversion (big-endian <-> native).
  1657. // mg_htons/mg_htonl/mg_htonll are aliases for the same operation (symmetric).
  1658. uint16_t mg_ntohs(uint16_t net);
  1659. uint32_t mg_ntohl(uint32_t net);
  1660. uint64_t mg_ntohll(uint64_t net);
  1661. #define mg_htons(x) mg_ntohs(x)
  1662. #define mg_htonl(x) mg_ntohl(x)
  1663. #define mg_htonll(x) mg_ntohll(x)
  1664. // Memory-mapped register access: reads/writes a volatile uint32_t at address x.
  1665. #define MG_REG(x) ((volatile uint32_t *) (x))[0]
  1666. // Produces a uint32_t with bit x set. x must be 0-31.
  1667. #define MG_BIT(x) (((uint32_t) 1U) << (x))
  1668. // Clears bits in CLRMASK and sets bits in SETMASK in register R atomically
  1669. // (read-modify-write). Example: MG_SET_BITS(MG_REG(addr), 0xF, 0x3);
  1670. #define MG_SET_BITS(R, CLRMASK, SETMASK) (R) = ((R) & ~(CLRMASK)) | (SETMASK)
  1671. // Round x up / down to the nearest multiple of a. Returns x when a is 0.
  1672. #define MG_ROUND_UP(x, a) ((a) == 0 ? (x) : ((((x) + (a) -1) / (a)) * (a)))
  1673. #define MG_ROUND_DOWN(x, a) ((a) == 0 ? (x) : (((x) / (a)) * (a)))
  1674. #if defined(__GNUC__) && defined(__arm__)
  1675. #ifdef __ZEPHYR__
  1676. #define MG_ARM_DISABLE_IRQ() __asm__ __volatile__("cpsid i" : : : "memory")
  1677. #define MG_ARM_ENABLE_IRQ() __asm__ __volatile__("cpsie i" : : : "memory")
  1678. #else
  1679. #define MG_ARM_DISABLE_IRQ() asm volatile("cpsid i" : : : "memory")
  1680. #define MG_ARM_ENABLE_IRQ() asm volatile("cpsie i" : : : "memory")
  1681. #endif // !ZEPHYR
  1682. #elif defined(__CCRH__)
  1683. #define MG_RH850_DISABLE_IRQ() __DI()
  1684. #define MG_RH850_ENABLE_IRQ() __EI()
  1685. #else
  1686. #define MG_ARM_DISABLE_IRQ()
  1687. #define MG_ARM_ENABLE_IRQ()
  1688. #endif
  1689. #if defined(__CC_ARM)
  1690. #define MG_DSB() __dsb(0xf)
  1691. #elif defined(__ARMCC_VERSION)
  1692. #define MG_DSB() __builtin_arm_dsb(0xf)
  1693. #elif defined(__GNUC__) && defined(__arm__) && defined(__thumb__)
  1694. #ifdef __ZEPHYR__
  1695. #define MG_DSB() __asm__("DSB 0xf")
  1696. #else
  1697. #define MG_DSB() asm("DSB 0xf")
  1698. #endif // !ZEPHYR
  1699. #elif defined(__ICCARM__)
  1700. #define MG_DSB() __iar_builtin_DSB()
  1701. #else
  1702. #define MG_DSB()
  1703. #endif
  1704. struct mg_addr;
  1705. int mg_check_ip_acl(struct mg_str acl, struct mg_addr *remote_ip);
  1706. // Linked list management macros
  1707. #define LIST_ADD_HEAD(type_, head_, elem_) \
  1708. do { \
  1709. (elem_)->next = (*head_); \
  1710. *(head_) = (elem_); \
  1711. } while (0)
  1712. #define LIST_ADD_TAIL(type_, head_, elem_) \
  1713. do { \
  1714. type_ **h = head_; \
  1715. while (*h != NULL) h = &(*h)->next; \
  1716. *h = (elem_); \
  1717. } while (0)
  1718. #define LIST_DELETE(type_, head_, elem_) \
  1719. do { \
  1720. type_ **h = head_; \
  1721. while (*h != (elem_)) h = &(*h)->next; \
  1722. *h = (elem_)->next; \
  1723. } while (0)
  1724. // Returns the port from url. Uses scheme defaults when no port is explicit:
  1725. // http/ws=80, https/wss=443, mqtt=1883, mqtts=8883. Returns 0 if unknown.
  1726. unsigned short mg_url_port(const char *url);
  1727. // Returns true if url uses a TLS scheme (https, wss, mqtts, ssl, tls, tcps).
  1728. bool mg_url_is_ssl(const char *url);
  1729. // Returns the hostname from url as mg_str, without port or brackets.
  1730. // E.g. "http://foo.com:8080/x" -> "foo.com". Not NUL-terminated.
  1731. struct mg_str mg_url_host(const char *url);
  1732. // Returns the username from url (user:pass@host form) as mg_str.
  1733. // Returns an empty mg_str if no credentials are present. Not NUL-terminated.
  1734. struct mg_str mg_url_user(const char *url);
  1735. // Returns the password from url (user:pass@host form) as mg_str.
  1736. // Returns an empty mg_str if no credentials are present. Not NUL-terminated.
  1737. struct mg_str mg_url_pass(const char *url);
  1738. // Returns a pointer to the URI path in url (e.g. "/api/v1").
  1739. // Returns "/" if the url has no path. Points into the original url string.
  1740. const char *mg_url_uri(const char *url);
  1741. // Dynamically-sized I/O buffer. len <= size always holds.
  1742. struct mg_iobuf {
  1743. unsigned char *buf; // Heap-allocated data buffer
  1744. size_t size; // Allocated capacity (rounded up to align)
  1745. size_t len; // Number of bytes currently stored
  1746. size_t align; // Allocation granularity; capacity is always a multiple of this
  1747. };
  1748. // Initializes io to empty, then allocates size bytes with the given alignment.
  1749. // Returns false on allocation failure.
  1750. bool mg_iobuf_init(struct mg_iobuf *io, size_t size, size_t align);
  1751. // Resizes the buffer to new_size (rounded up to io->align). new_size=0 frees
  1752. // the buffer. Uses mg_calloc+mg_free (not realloc) so old memory is zeroed on release.
  1753. // Returns false on allocation failure.
  1754. bool mg_iobuf_resize(struct mg_iobuf *io, size_t new_size);
  1755. // Frees the buffer and zeroes the struct. Equivalent to mg_iobuf_resize(io, 0).
  1756. void mg_iobuf_free(struct mg_iobuf *io);
  1757. // Inserts len bytes from buf at offset ofs, shifting existing data right.
  1758. // Pass buf=NULL to reserve space without writing. Returns bytes inserted, 0 on OOM.
  1759. size_t mg_iobuf_add(struct mg_iobuf *io, size_t ofs, const void *buf, size_t len);
  1760. // Removes len bytes at ofs, shifting remaining data left. Clamps to available data.
  1761. // Returns bytes actually removed.
  1762. size_t mg_iobuf_del(struct mg_iobuf *io, size_t ofs, size_t len);
  1763. size_t mg_base64_update(unsigned char input_byte, char *buf, size_t len);
  1764. size_t mg_base64_final(char *buf, size_t len);
  1765. size_t mg_base64_encode(const unsigned char *p, size_t n, char *buf, size_t);
  1766. size_t mg_base64_decode(const char *src, size_t n, char *dst, size_t);
  1767. size_t mg_base64url_encode(const unsigned char *p, size_t n, char *buf,
  1768. size_t);
  1769. size_t mg_base64url_decode(const char *src, size_t n, char *dst, size_t);
  1770. typedef struct {
  1771. uint32_t buf[4];
  1772. uint32_t bits[2];
  1773. unsigned char in[64];
  1774. } mg_md5_ctx;
  1775. void mg_md5_init(mg_md5_ctx *c);
  1776. void mg_md5_update(mg_md5_ctx *c, const unsigned char *data, size_t len);
  1777. void mg_md5_final(mg_md5_ctx *c, unsigned char[16]);
  1778. typedef struct {
  1779. uint32_t state[5];
  1780. uint32_t count[2];
  1781. unsigned char buffer[64];
  1782. } mg_sha1_ctx;
  1783. void mg_sha1_init(mg_sha1_ctx *);
  1784. void mg_sha1_update(mg_sha1_ctx *, const unsigned char *data, size_t len);
  1785. void mg_sha1_final(unsigned char digest[20], mg_sha1_ctx *);
  1786. // https://github.com/B-Con/crypto-algorithms
  1787. // Author: Brad Conte (brad AT bradconte.com)
  1788. // Disclaimer: This code is presented "as is" without any guarantees.
  1789. // Details: Defines the API for the corresponding SHA1 implementation.
  1790. // Copyright: public domain
  1791. typedef struct {
  1792. uint32_t state[8];
  1793. uint64_t bits;
  1794. uint32_t len;
  1795. unsigned char buffer[64];
  1796. } mg_sha256_ctx;
  1797. void mg_sha256_init(mg_sha256_ctx *);
  1798. void mg_sha256_update(mg_sha256_ctx *, const unsigned char *data, size_t len);
  1799. void mg_sha256_final(unsigned char digest[32], mg_sha256_ctx *);
  1800. void mg_sha256(uint8_t dst[32], uint8_t *data, size_t datasz);
  1801. void mg_hmac_sha256(uint8_t dst[32], uint8_t *key, size_t keysz, uint8_t *data,
  1802. size_t datasz);
  1803. typedef struct {
  1804. uint64_t state[8];
  1805. uint8_t buffer[128];
  1806. uint64_t bitlen[2];
  1807. uint32_t datalen;
  1808. } mg_sha384_ctx;
  1809. void mg_sha384_init(mg_sha384_ctx *ctx);
  1810. void mg_sha384_update(mg_sha384_ctx *ctx, const uint8_t *data, size_t len);
  1811. void mg_sha384_final(uint8_t digest[48], mg_sha384_ctx *ctx);
  1812. void mg_sha384(uint8_t dst[48], uint8_t *data, size_t datasz);
  1813. struct mg_connection;
  1814. // User-supplied event handler. ev is enum mg_event; ev_data type depends on
  1815. // the event (see enum below). c->fn_data is the user pointer passed to
  1816. // mg_listen(), mg_connect(), mg_*_listen(), mg_*_connect().
  1817. typedef void (*mg_event_handler_t)(struct mg_connection *, int ev,
  1818. void *ev_data);
  1819. // Fires ev on connection c, invoking c->fn and c->pfn with ev_data.
  1820. void mg_call(struct mg_connection *c, int ev, void *ev_data);
  1821. // Sets c->is_closing and fires MG_EV_ERROR with a printf-formatted message.
  1822. void mg_error(struct mg_connection *c, const char *fmt, ...);
  1823. // Event codes passed to mg_event_handler_t. Each entry shows the type of
  1824. // ev_data cast to use inside the handler, e.g.: char *msg = (char *) ev_data;
  1825. enum mg_event {
  1826. // Event Meaning ev_data type
  1827. MG_EV_ERROR, // Error char *error_message
  1828. MG_EV_OPEN, // Connection created NULL
  1829. MG_EV_POLL, // mg_mgr_poll iteration uint64_t *uptime_millis
  1830. MG_EV_RESOLVE, // Host name is resolved NULL
  1831. MG_EV_CONNECT, // Connection established NULL
  1832. MG_EV_ACCEPT, // Connection accepted NULL
  1833. MG_EV_TLS_HS, // TLS handshake succeeded NULL
  1834. MG_EV_READ, // Data received from socket long *bytes_read
  1835. MG_EV_WRITE, // Data written to socket long *bytes_written
  1836. MG_EV_CLOSE, // Connection closed NULL
  1837. MG_EV_HTTP_HDRS, // HTTP headers struct mg_http_message *
  1838. MG_EV_HTTP_MSG, // Full HTTP request/response struct mg_http_message *
  1839. MG_EV_WS_OPEN, // Websocket handshake done struct mg_http_message *
  1840. MG_EV_WS_MSG, // Websocket msg, text or bin struct mg_ws_message *
  1841. MG_EV_WS_CTL, // Websocket control msg struct mg_ws_message *
  1842. MG_EV_MQTT_CMD, // MQTT low-level command struct mg_mqtt_message *
  1843. MG_EV_MQTT_MSG, // MQTT PUBLISH received struct mg_mqtt_message *
  1844. MG_EV_MQTT_OPEN, // MQTT CONNACK received int *connack_status_code
  1845. MG_EV_SNTP_TIME, // SNTP time received uint64_t *epoch_millis
  1846. MG_EV_WAKEUP, // mg_wakeup() data received struct mg_str *data
  1847. MG_EV_MDNS_REQ, // mDNS request struct mg_mdns_req *
  1848. MG_EV_MDNS_RESP, // mDNS response struct mg_mdns_resp *
  1849. MG_EV_MODBUS_REQ, // Modbus TCP request struct mg_modbus_req *
  1850. MG_EV_USER // Starting ID for user events
  1851. };
  1852. // DNS server configuration used by struct mg_mgr.
  1853. struct mg_dns {
  1854. const char *url; // DNS server URL, e.g. "udp://8.8.8.8:53"
  1855. struct mg_connection *c; // Active DNS connection; NULL when idle
  1856. };
  1857. // Network address: IPv4 or IPv6 address plus port. All values in network byte order.
  1858. struct mg_addr {
  1859. union { // IP address bytes in network byte order
  1860. uint8_t ip[16]; // Raw 16-byte buffer; IPv4 uses the first 4 bytes
  1861. uint32_t ip4; // IPv4 address alias (same storage as ip[0..3])
  1862. uint64_t ip6[2]; // IPv6 address as two 64-bit words
  1863. } addr;
  1864. uint16_t port; // TCP or UDP port in network byte order
  1865. uint8_t scope_id; // IPv6 scope ID (from the %N suffix in the address)
  1866. bool is_ip6; // True when this address holds an IPv6 address
  1867. };
  1868. union mg_pipe {
  1869. MG_SOCKET_TYPE fd;
  1870. void *q;
  1871. };
  1872. // Central event manager. Zero-initialise with mg_mgr_init() before use.
  1873. struct mg_mgr {
  1874. struct mg_connection *conns; // Linked list of all open connections
  1875. struct mg_dns dns4; // IPv4 DNS server (default: 8.8.8.8:53)
  1876. struct mg_dns dns6; // IPv6 DNS server (default: [2001:4860:4860::8888]:53)
  1877. struct mg_connection *mdns; // mDNS listener connection, or NULL
  1878. int dnstimeout; // DNS resolve timeout in ms (default: 3000)
  1879. bool use_dns6; // If true, prefer DNS6 for hostname resolution
  1880. unsigned long nextid; // Auto-incrementing counter for connection IDs
  1881. void *userdata; // Arbitrary user pointer
  1882. void *tls_ctx; // Shared TLS context for all TLS connections
  1883. uint16_t mqtt_id; // Packet ID counter for MQTT pub/sub
  1884. void *active_dns_requests; // Pending DNS queries (internal)
  1885. void *active_mdns_requests; // Pending mDNS resolver queries (internal)
  1886. struct mg_timer *timers; // Linked list of active timers
  1887. int epoll_fd; // epoll file descriptor; -1 when unused (MG_EPOLL_ENABLE=1)
  1888. struct mg_tcpip_if *ifp; // Builtin TCP/IP stack: network interface pointer
  1889. size_t extraconnsize; // Builtin TCP/IP stack: extra bytes allocated per connection
  1890. union mg_pipe pipe; // Socketpair write-end / queue, used by mg_wakeup()
  1891. #if MG_ENABLE_FREERTOS_TCP
  1892. SocketSet_t ss; // FreeRTOS-TCP socket set
  1893. #endif
  1894. };
  1895. // A single network connection. Do not allocate directly; use mg_connect() or
  1896. // mg_listen(). Each connection has an event handler fn called for every event.
  1897. struct mg_connection {
  1898. struct mg_connection *next; // Next connection in mgr->conns linked list
  1899. struct mg_mgr *mgr; // Manager that owns this connection
  1900. struct mg_addr loc; // Local address (IP + port)
  1901. struct mg_addr rem; // Remote address (IP + port)
  1902. void *fd; // OS socket handle or LWIP PCB pointer
  1903. unsigned long id; // Unique, auto-incrementing connection ID
  1904. struct mg_iobuf recv; // Received data; consume in MG_EV_READ handler
  1905. struct mg_iobuf send; // Data to send; append with mg_send() / mg_printf()
  1906. struct mg_iobuf prof; // Profiling data (MG_ENABLE_PROFILE only)
  1907. struct mg_iobuf rtls; // TLS only: encrypted data buffered before decryption
  1908. mg_event_handler_t fn; // User event handler
  1909. void *fn_data; // User-supplied argument passed to fn
  1910. mg_event_handler_t pfn; // Protocol-level handler (set by protocol modules)
  1911. void *pfn_data; // Protocol-level handler argument
  1912. char data[MG_DATA_SIZE]; // Scratch space for protocol state; freely readable
  1913. void *tls; // TLS state (internal)
  1914. unsigned dscp : 6; // Differentiated Services Code Point
  1915. #define MG_DSCP_CS(class_) ((class_) << 3)
  1916. #define MG_DSCP_AF(class_, drop_) (((class_) << 3) | ((drop_) << 1))
  1917. #define MG_DSCP_EF 46
  1918. unsigned is_listening : 1; // Listening connection; accepts inbound connections
  1919. unsigned is_client : 1; // Outbound connection created by mg_connect()
  1920. unsigned is_accepted : 1; // Inbound connection accepted from a listener
  1921. unsigned is_resolving : 1; // DNS resolution is in progress
  1922. unsigned is_arplooking : 1; // ARP resolution is in progress (builtin TCP/IP)
  1923. unsigned is_connecting : 1; // Non-blocking TCP connect is in progress
  1924. unsigned is_tls : 1; // TLS connection
  1925. unsigned is_tls_hs : 1; // TLS handshake is in progress
  1926. unsigned is_udp : 1; // UDP connection (not TCP)
  1927. unsigned is_websocket : 1; // WebSocket connection
  1928. unsigned is_mqtt5 : 1; // MQTT5 connection (set by mg_mqtt_login)
  1929. unsigned is_hexdumping : 1; // Log hex dump of all in/out traffic
  1930. unsigned is_draining : 1; // Flush send buffer, then close
  1931. unsigned is_closing : 1; // Close and free immediately on next poll
  1932. unsigned is_full : 1; // Pause incoming reads until cleared
  1933. unsigned is_tls_throttled : 1; // TLS write was throttled; retry pending
  1934. unsigned is_resp : 1; // HTTP: response is still being generated
  1935. unsigned is_readable : 1; // Socket is ready to read (epoll/select)
  1936. unsigned is_writable : 1; // Socket is ready to write (epoll/select)
  1937. };
  1938. // Runs one iteration of the event loop.
  1939. //
  1940. // Example:
  1941. // while (keep_running) mg_mgr_poll(&mgr, 50);
  1942. // Full examples:
  1943. // tutorials/http/http-server, tutorials/mqtt/mqtt-client,
  1944. // tutorials/websocket/websocket-server, tutorials/core/timers
  1945. // Related APIs:
  1946. // mg_mgr_init(), mg_mgr_free(), mg_timer_add(), mg_wakeup()
  1947. // Notes:
  1948. // Waits up to ms milliseconds for I/O events; use ms=0 to return
  1949. // immediately. Calls event handlers for ready connections and fires expired
  1950. // timers. Call repeatedly from the main loop or a dedicated network task.
  1951. void mg_mgr_poll(struct mg_mgr *, int ms);
  1952. // Initialises an event manager before use.
  1953. //
  1954. // Example:
  1955. // struct mg_mgr mgr;
  1956. // mg_mgr_init(&mgr);
  1957. // Full examples:
  1958. // tutorials/http/http-server, tutorials/mqtt/mqtt-client,
  1959. // tutorials/websocket/websocket-server, tutorials/core/embedded-filesystem
  1960. // Related APIs:
  1961. // mg_mgr_poll(), mg_mgr_free(), mg_http_listen(), mg_connect()
  1962. // Notes:
  1963. // Sets safe defaults such as DNS servers, DNS timeout, epoll/SIGPIPE setup,
  1964. // and TLS context. Call before creating connections, listeners, or timers.
  1965. // Set mgr.userdata after this call if your application needs it.
  1966. // On embedded systems, if the built-in TCP/IP stack is enabled
  1967. // (MG_ENABLE_TCPIP=1) and one built-in driver is selected, e.g.
  1968. // MG_ENABLE_DRIVER_STM32H=1, mg_mgr_init() also calls mg_tcpip_init().
  1969. // If no driver is selected, automatic driver init is disabled, or multiple
  1970. // interfaces are intended, call mg_tcpip_init() separately.
  1971. void mg_mgr_init(struct mg_mgr *);
  1972. // Closes all connections, frees all timers, and releases the TLS context.
  1973. // Safe to call on a partially initialised mgr.
  1974. void mg_mgr_free(struct mg_mgr *);
  1975. // Creates a listening connection on url (e.g. "tcp://0.0.0.0:8080").
  1976. // Fires MG_EV_OPEN on the listener, then MG_EV_ACCEPT for each new client.
  1977. // Returns NULL on error.
  1978. struct mg_connection *mg_listen(struct mg_mgr *, const char *url,
  1979. mg_event_handler_t fn, void *fn_data);
  1980. // Opens an outbound connection to url (e.g. "tcp://example.com:80").
  1981. // DNS resolution is asynchronous. Fires MG_EV_RESOLVE, then MG_EV_CONNECT
  1982. // when the connection is established (or MG_EV_ERROR on failure).
  1983. // Returns NULL on error (OOM, network down, null url).
  1984. struct mg_connection *mg_connect(struct mg_mgr *, const char *url,
  1985. mg_event_handler_t fn, void *fn_data);
  1986. // Wraps an existing OS file descriptor in a Mongoose connection.
  1987. // The connection is added to mgr and fires MG_EV_OPEN immediately.
  1988. // Useful for integrating pre-opened sockets (e.g. stdin, accept() fd).
  1989. struct mg_connection *mg_wrapfd(struct mg_mgr *mgr, int fd,
  1990. mg_event_handler_t fn, void *fn_data);
  1991. // Sets the 6-bit Differentiated Services Code Point for outgoing datagrams.
  1992. // Call on MG_EV_OPEN for UDP listeners, MG_EV_CONNECT for clients, or
  1993. // MG_EV_ACCEPT for TCP servers, before sending application data.
  1994. bool mg_dscp(struct mg_connection *, uint8_t dscp);
  1995. // Called internally after DNS resolution completes to create the OS socket
  1996. // and initiate the TCP/IP connect. Normally not called by user code.
  1997. void mg_connect_resolved(struct mg_connection *);
  1998. // Appends buf/len to c->send. Returns true on success, false on OOM
  1999. // (which also fires MG_EV_ERROR and schedules the connection for close).
  2000. // Data is sent asynchronously by the next mg_mgr_poll() call.
  2001. bool mg_send(struct mg_connection *, const void *, size_t);
  2002. // Formats data and appends it to a connection send buffer.
  2003. //
  2004. // Returns:
  2005. // Number of bytes appended, or 0 on OOM.
  2006. // Example:
  2007. // mg_printf(c, "GET / HTTP/1.0\r\nHost: %.*s\r\n\r\n",
  2008. // (int) host.len, host.buf);
  2009. // Full examples:
  2010. // tutorials/http/http-client, tutorials/http/http-proxy-client,
  2011. // tutorials/http/http-restful-server
  2012. // Related APIs:
  2013. // mg_send(), mg_snprintf(), mg_http_reply(), mg_ws_printf()
  2014. // Notes:
  2015. // Data is sent asynchronously by a later mg_mgr_poll() call. Supports
  2016. // mg_xprintf specifiers, including custom %M/%m printers. See src/fmt.h for
  2017. // the full specifier list.
  2018. size_t mg_printf(struct mg_connection *, const char *fmt, ...);
  2019. size_t mg_vprintf(struct mg_connection *, const char *fmt, va_list *ap);
  2020. // Parses an IP address string str into addr. Handles "localhost", plain IPv4
  2021. // (e.g. "1.2.3.4"), IPv6 with optional brackets and scope ID, and
  2022. // IPv4-mapped IPv6 (::ffff:1.2.3.4). Does NOT parse the port.
  2023. // Returns true on success; addr->is_ip6 and addr->addr are set.
  2024. bool mg_aton(struct mg_str str, struct mg_addr *addr);
  2025. // Low-level functions for integrating with custom network stacks.
  2026. // Allocates a new connection struct with mgr->extraconnsize extra bytes.
  2027. // Returns NULL on OOM.
  2028. struct mg_connection *mg_alloc_conn(struct mg_mgr *);
  2029. // Fires MG_EV_CLOSE, frees all buffers (recv/send/rtls), removes c from
  2030. // mgr->conns, and calls mg_free(c). Do not use c after this call.
  2031. void mg_close_conn(struct mg_connection *c);
  2032. // Creates and binds the OS socket for a listening connection c at url.
  2033. // Called internally by mg_listen(); expose for custom network stack use.
  2034. // Returns false on error.
  2035. bool mg_open_listener(struct mg_connection *c, const char *url);
  2036. // Thread-safe wakeup: fires MG_EV_WAKEUP on the connection whose id matches,
  2037. // with ev_data pointing to an mg_str containing buf/len.
  2038. // Requires mg_wakeup_init() to have been called first.
  2039. // Returns false if the pipe is not initialised or conn_id is 0.
  2040. // Safe to call from any thread or interrupt context.
  2041. bool mg_wakeup(struct mg_mgr *, unsigned long id, const void *buf, size_t len);
  2042. // Initialises the internal socketpair used by mg_wakeup(). Call once after
  2043. // mg_mgr_init() if you intend to wake the event loop from another thread.
  2044. // Returns false on failure (e.g. socketpair creation failed).
  2045. bool mg_wakeup_init(struct mg_mgr *);
  2046. // Deprecated API, do not expose. Use mg_timer_expired instead
  2047. struct mg_timer *mg_timer_add(struct mg_mgr *mgr, uint64_t milliseconds,
  2048. unsigned flags, void (*fn)(void *), void *arg);
  2049. // Like mg_connect() but also sets a protocol-level handler pfn/pfn_data.
  2050. // Used internally by protocol modules (MQTT, WebSocket, etc.).
  2051. struct mg_connection *mg_connect_svc(struct mg_mgr *mgr, const char *url,
  2052. mg_event_handler_t fn, void *fn_data,
  2053. mg_event_handler_t pfn, void *pfn_data);
  2054. // Restores c->rem from a saved address buffer written by the caller, then
  2055. // maps the IP back through the builtin TCP/IP stack. Used after a UDP
  2056. // multicast send to restore the connection's original remote address.
  2057. void mg_multicast_restore(struct mg_connection *c, uint8_t *from);
  2058. // A single HTTP header name/value pair.
  2059. struct mg_http_header {
  2060. struct mg_str name; // Header name, e.g. "Content-Type"
  2061. struct mg_str value; // Header value, e.g. "text/html"
  2062. };
  2063. // Parsed HTTP request or response.
  2064. // Passed as ev_data in MG_EV_HTTP_MSG and MG_EV_HTTP_HDRS.
  2065. // For requests: method="GET", uri="/path", proto="a=1&b=2", proto="HTTP/1.1"
  2066. // For responses: method="HTTP/1.0", uri="200", query="", proto="OK"
  2067. struct mg_http_message {
  2068. struct mg_str method, uri, query, proto; // Request/response line
  2069. struct mg_http_header headers[MG_MAX_HTTP_HEADERS]; // Parsed headers array
  2070. struct mg_str body; // Request or response body
  2071. struct mg_str head; // Raw bytes: request/status line + headers, no body
  2072. struct mg_str message; // Raw bytes: head + body
  2073. };
  2074. // Options for mg_http_serve_dir() and mg_http_serve_file().
  2075. struct mg_http_serve_opts {
  2076. const char *root_dir; // Root directory for serving files, e.g. "/web"
  2077. const char *ssi_pattern; // Pattern for Server-Side Include files, e.g. "#.shtml". NULL disables SSI
  2078. const char *extra_headers; // Extra response headers, e.g. "A: b\r\nC: d\r\n". NULL for none
  2079. const char *mime_types; // Additional MIME types: "ext1=type1,ext2=type2". NULL for defaults only
  2080. const char *page404; // Path to a custom 404 page, e.g. "/404.html". NULL for built-in
  2081. struct mg_fs *fs; // Filesystem to use. NULL defaults to POSIX
  2082. };
  2083. // A single part of a multipart/form-data body, filled by mg_http_next_multipart().
  2084. struct mg_http_part {
  2085. struct mg_str name; // Form field name, from Content-Disposition: name="..."
  2086. struct mg_str filename; // Original filename for file uploads, empty for plain fields
  2087. struct mg_str body; // Part contents, points into the original message buffer
  2088. };
  2089. // Parses HTTP request or response in buffer s/len into hm.
  2090. // Returns number of bytes consumed, 0 if incomplete, -1 on error.
  2091. int mg_http_parse(const char *s, size_t len, struct mg_http_message *);
  2092. // Returns the byte length of HTTP headers in buf (i.e. offset of the body).
  2093. // Returns 0 if headers are incomplete, -1 on error.
  2094. int mg_http_get_request_len(const unsigned char *buf, size_t buf_len);
  2095. // Sends one chunk in HTTP chunked transfer encoding using printf-style fmt.
  2096. // Call with empty fmt ("") to send the terminating zero-length chunk.
  2097. void mg_http_printf_chunk(struct mg_connection *cnn, const char *fmt, ...);
  2098. // Sends one chunk in HTTP chunked transfer encoding from a raw buffer.
  2099. // Call with len=0 to send the terminating zero-length chunk.
  2100. void mg_http_write_chunk(struct mg_connection *c, const char *buf, size_t len);
  2101. // Creates an HTTP server on url, e.g. "http://0.0.0.0:8000".
  2102. //
  2103. // Returns:
  2104. // Listening connection, or NULL on error.
  2105. // Example:
  2106. // mg_http_listen(&mgr, "http://0.0.0.0:8000", fn, NULL);
  2107. // Full examples:
  2108. // tutorials/http/http-server, tutorials/http/*
  2109. // Related APIs:
  2110. // mg_http_reply(), mg_http_serve_dir(), mg_match()
  2111. // Notes:
  2112. // Call mg_mgr_poll() in the main loop. The user-supplied fn event handler
  2113. // receives normal connection events. It also receives MG_EV_HTTP_HDRS when
  2114. // headers are received and MG_EV_HTTP_MSG when the full request is received.
  2115. // ev_data for both HTTP events is struct mg_http_message *.
  2116. struct mg_connection *mg_http_listen(struct mg_mgr *, const char *url,
  2117. mg_event_handler_t fn, void *fn_data);
  2118. // Opens an HTTP client connection to url, e.g. "http://example.org".
  2119. //
  2120. // Returns:
  2121. // Client connection, or NULL on error.
  2122. // Example:
  2123. // mg_http_connect(&mgr, "http://example.org", fn, NULL);
  2124. // Full examples:
  2125. // tutorials/http/http-client, tutorials/http/huge-response
  2126. // Related APIs:
  2127. // mg_printf(), mg_http_status(), mg_http_get_header()
  2128. // Notes:
  2129. // In the user-supplied fn event handler, send the HTTP request on
  2130. // MG_EV_CONNECT. The handler receives normal connection events. It also
  2131. // receives MG_EV_HTTP_HDRS when headers are received and MG_EV_HTTP_MSG when
  2132. // the full response is received. ev_data for both HTTP events is struct
  2133. // mg_http_message *.
  2134. struct mg_connection *mg_http_connect(struct mg_mgr *, const char *url,
  2135. mg_event_handler_t fn, void *fn_data);
  2136. // Serves static files from a directory.
  2137. //
  2138. // Example:
  2139. // struct mg_http_serve_opts o = {.root_dir = "web_root", .fs = &mg_fs_posix};
  2140. // mg_http_serve_dir(c, hm, &o);
  2141. // Full examples:
  2142. // tutorials/http/http-server, tutorials/core/embedded-filesystem
  2143. // Related APIs:
  2144. // mg_http_listen(), mg_http_serve_file(), mg_http_reply(), mg_match()
  2145. // Notes:
  2146. // Call from an MG_EV_HTTP_MSG handler. The uri in hm is mapped under
  2147. // opts->root_dir. Directory listing depends on MG_ENABLE_DIRLIST; SSI uses
  2148. // opts->ssi_pattern when configured.
  2149. void mg_http_serve_dir(struct mg_connection *, struct mg_http_message *hm,
  2150. const struct mg_http_serve_opts *);
  2151. // Serves a single file at path. Call from an MG_EV_HTTP_MSG handler.
  2152. void mg_http_serve_file(struct mg_connection *, struct mg_http_message *hm,
  2153. const char *path, const struct mg_http_serve_opts *);
  2154. // Sends a complete HTTP response with Content-Length.
  2155. //
  2156. // Example:
  2157. // mg_http_reply(c, 200, "Content-Type: application/json\r\n",
  2158. // "{%m:%d}", MG_ESC("temperature"), 123);
  2159. // Full examples:
  2160. // tutorials/http/http-server, tutorials/http/http-restful-server,
  2161. // tutorials/http/device-dashboard
  2162. // Related APIs:
  2163. // mg_http_listen(), mg_printf(), mg_http_printf_chunk(), MG_ESC
  2164. // Notes:
  2165. // headers must end with "\r\n"; pass "" or NULL for no extra headers.
  2166. // body_fmt is printf-style and supports %M/%m custom printers. Use MG_ESC
  2167. // when printing JSON strings.
  2168. void mg_http_reply(struct mg_connection *, int status_code, const char *headers,
  2169. const char *body_fmt, ...);
  2170. // Looks up a request header by name (case-insensitive).
  2171. // Returns a pointer to the mg_str value, or NULL if not found.
  2172. struct mg_str *mg_http_get_header(struct mg_http_message *, const char *name);
  2173. // Extracts a named variable from a query string or form-encoded body (buf).
  2174. // Returns the raw (URL-encoded) value as mg_str, or an empty mg_str if not found.
  2175. // Not NUL-terminated. Use mg_url_decode() to get a decoded string.
  2176. struct mg_str mg_http_var(struct mg_str buf, struct mg_str name);
  2177. // URL-decodes variable name from query string or form body into a NUL-terminated buffer.
  2178. // Returns the length of the decoded value, or negative if not found / buffer too small.
  2179. int mg_http_get_var(const struct mg_str *, const char *name, char *, size_t);
  2180. // URL-decodes s/n into to/to_len. Set form=1 to also decode '+' as space.
  2181. // Returns number of bytes written, or -1 if to buffer is too small.
  2182. int mg_url_decode(const char *s, size_t n, char *to, size_t to_len, int form);
  2183. // URL-encodes s/n into buf/len. Returns number of bytes written.
  2184. size_t mg_url_encode(const char *s, size_t n, char *buf, size_t len);
  2185. // Extracts HTTP credentials into caller-supplied buffers.
  2186. // For Basic auth: fills user (buf1) and password (buf2).
  2187. // For Bearer auth: fills buf1 with "" and buf2 with the token.
  2188. void mg_http_creds(struct mg_http_message *, char *, size_t, char *, size_t);
  2189. // Deprecated API, do not expose
  2190. long mg_http_upload(struct mg_connection *c, struct mg_http_message *hm,
  2191. struct mg_fs *fs, const char *dir, size_t max_size);
  2192. // Streams the raw request body into dir/name via fs. Non-blocking: installs an
  2193. // internal handler and returns immediately. fn is called with NULL on success
  2194. // or an error string on failure.
  2195. void mg_http_start_upload(struct mg_connection *c, struct mg_http_message *hm,
  2196. struct mg_str name, struct mg_str dir,
  2197. struct mg_fs *fs,
  2198. void (*fn)(struct mg_connection *, const char *));
  2199. // Starts an OTA firmware update from an HTTP POST upload.
  2200. // Calls mg_ota_begin/write/end internally; fn is called with NULL on success,
  2201. // or an error string on failure.
  2202. void mg_http_start_ota(struct mg_connection *c, struct mg_http_message *hm,
  2203. void (*fn)(struct mg_connection *, const char *));
  2204. // Sends a 401 Unauthorized response with a Basic Auth WWW-Authenticate challenge.
  2205. void mg_http_bauth(struct mg_connection *, const char *user, const char *pass);
  2206. // Extracts a named parameter from a header value string s.
  2207. // E.g. for s="multipart/form-data; boundary=abc", v="boundary" returns "abc".
  2208. struct mg_str mg_http_get_header_var(struct mg_str s, struct mg_str v);
  2209. // Iterates over parts of a multipart/form-data body.
  2210. //
  2211. // Returns:
  2212. // Offset for the next call, or 0 when there are no more parts.
  2213. // Example:
  2214. // size_t ofs = 0;
  2215. // struct mg_http_part part;
  2216. // while ((ofs = mg_http_next_multipart(hm->body, ofs, &part)) > 0) { ... }
  2217. // Full examples:
  2218. // tutorials/http/file-upload-html-form, tutorials/http/http-server
  2219. // Related APIs:
  2220. // mg_http_listen(), mg_http_start_upload()
  2221. // Notes:
  2222. // Call from an MG_EV_HTTP_MSG handler after the full request body is
  2223. // received. part.name, part.filename, and part.body are zero-copy slices into
  2224. // hm->body and are not NUL-terminated.
  2225. size_t mg_http_next_multipart(struct mg_str, size_t, struct mg_http_part *);
  2226. // Returns the HTTP status code from a parsed response message (e.g. 200, 404).
  2227. int mg_http_status(const struct mg_http_message *hm);
  2228. void mg_http_serve_ssi(struct mg_connection *c, const char *root,
  2229. const char *fullpath);
  2230. // TLS / Security
  2231. // Available TLS backend libraries
  2232. #define MG_TLS_NONE 0 // No TLS support
  2233. #define MG_TLS_MBED 1 // mbedTLS
  2234. #define MG_TLS_OPENSSL 2 // OpenSSL
  2235. #define MG_TLS_WOLFSSL 5 // WolfSSL (based on OpenSSL)
  2236. #define MG_TLS_BUILTIN 3 // Built-in
  2237. #define MG_TLS_CUSTOM 4 // Custom implementation
  2238. #ifndef MG_TLS
  2239. // mongoose_config.h setting. Set MG_TLS to one of the MG_TLS_* values above to
  2240. // select a TLS backend. Defaults to MG_TLS_NONE (no TLS).
  2241. #define MG_TLS MG_TLS_NONE
  2242. #endif
  2243. // TLS options structure passed to mg_tls_init(). All cert/key fields accept
  2244. // PEM strings or DER binary.
  2245. //
  2246. // One-way TLS:
  2247. // server sets `cert` + `key`,
  2248. // client sets `ca` + optionally `name` for hostname verification.
  2249. //
  2250. // Two-way (mutual) TLS: both sides set `ca` + `cert` + `key`.
  2251. //
  2252. // - `ca`: CA certificate. Verifies the peer's certificate.
  2253. // Set on clients to authenticate the server. Set on servers to require
  2254. // and verify a client certificate. If empty, peer is not verified.
  2255. // - `cert`: Our certificate. Required on servers. Also set on clients for
  2256. // mutual TLS.
  2257. // - `key`: Our private key. May equal `cert` when PEM bundles both.
  2258. // - `name`: Server name for SNI and hostname verification. Set on clients.
  2259. // Empty disables hostname verification.
  2260. // - `skip_verification`: Skip certificate and hostname verification.
  2261. // Useful during development; do not use in production.
  2262. struct mg_tls_opts {
  2263. struct mg_str ca; // CA certificate, PEM or DER
  2264. struct mg_str cert; // Our certificate, PEM or DER
  2265. struct mg_str key; // Our private key, PEM or DER
  2266. struct mg_str name; // Server name for SNI + hostname verification
  2267. bool skip_verification; // Skip certificate and hostname verification
  2268. };
  2269. // Initialises TLS on a connection.
  2270. //
  2271. // Example:
  2272. // ```c
  2273. // // Server: one-way TLS
  2274. // if (ev == MG_EV_ACCEPT) {
  2275. // struct mg_tls_opts opts = {.cert = mg_str(s_tls_cert),
  2276. // .key = mg_str(s_tls_key)};
  2277. // mg_tls_init(c, &opts);
  2278. // }
  2279. //
  2280. // // Client: verify server certificate and hostname
  2281. // if (ev == MG_EV_CONNECT) {
  2282. // struct mg_tls_opts opts = {.ca = mg_str(s_tls_ca),
  2283. // .name = mg_str("hostname")};
  2284. // mg_tls_init(c, &opts);
  2285. // }
  2286. // ```
  2287. // Full examples:
  2288. // tutorials/http/http-server, tutorials/http/http-client,
  2289. // tutorials/mqtt/mqtt-client-aws-iot, tutorials/websocket/websocket-client
  2290. // Related APIs:
  2291. // mg_http_listen(), mg_http_connect(), mg_ws_connect(), mg_mqtt_connect()
  2292. // Notes:
  2293. // Call from the user-supplied event handler on MG_EV_ACCEPT for servers or
  2294. // MG_EV_CONNECT for clients, before application data is sent. Servers usually
  2295. // set cert and key. Clients usually set ca and name; name enables SNI and
  2296. // hostname verification.
  2297. void mg_tls_init(struct mg_connection *c, const struct mg_tls_opts *opts);
  2298. // Private API, do not expose
  2299. void mg_tls_free(struct mg_connection *);
  2300. long mg_tls_send(struct mg_connection *, const void *buf, size_t len);
  2301. long mg_tls_recv(struct mg_connection *, void *buf, size_t len);
  2302. size_t mg_tls_pending(struct mg_connection *);
  2303. void mg_tls_flush(struct mg_connection *);
  2304. void mg_tls_handshake(struct mg_connection *);
  2305. void mg_tls_ctx_init(struct mg_mgr *);
  2306. void mg_tls_ctx_free(struct mg_mgr *);
  2307. #define MG_IS_DER(buf) (((uint8_t *) (buf))[0] == 0x30) // DER begins with 0x30
  2308. #if MG_TLS == MG_TLS_BUILTIN
  2309. // Extracts a 32-byte P-256 private scalar from EC PRIVATE KEY or PKCS#8 PRIVATE
  2310. // KEY input. Accepts PEM or DER. Returns key size, or 0 on error.
  2311. size_t mg_uecc_parse_private_key(struct mg_str key, uint8_t *buf, size_t len);
  2312. #endif
  2313. // Low-level IO primitives used by TLS layer
  2314. enum { MG_IO_ERR = -1, MG_IO_WAIT = -2 };
  2315. long mg_io_send(struct mg_connection *c, const void *buf, size_t len);
  2316. long mg_io_recv(struct mg_connection *c, void *buf, size_t len);
  2317. #ifndef TLS_X15519_H
  2318. #define TLS_X15519_H
  2319. #define X25519_BYTES 32
  2320. extern const uint8_t X25519_BASE_POINT[X25519_BYTES];
  2321. int mg_tls_x25519(uint8_t out[X25519_BYTES], const uint8_t scalar[X25519_BYTES],
  2322. const uint8_t x1[X25519_BYTES], int clamp);
  2323. #endif /* TLS_X15519_H */
  2324. /******************************************************************************
  2325. *
  2326. * THIS SOURCE CODE IS HEREBY PLACED INTO THE PUBLIC DOMAIN FOR THE GOOD OF ALL
  2327. *
  2328. * This is a simple and straightforward implementation of AES-GCM authenticated
  2329. * encryption. The focus of this work was correctness & accuracy. It is written
  2330. * in straight 'C' without any particular focus upon optimization or speed. It
  2331. * should be endian (memory byte order) neutral since the few places that care
  2332. * are handled explicitly.
  2333. *
  2334. * This implementation of AES-GCM was created by Steven M. Gibson of GRC.com.
  2335. *
  2336. * It is intended for general purpose use, but was written in support of GRC's
  2337. * reference implementation of the SQRL (Secure Quick Reliable Login) client.
  2338. *
  2339. * See: http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf
  2340. * http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/ \
  2341. * gcm/gcm-revised-spec.pdf
  2342. *
  2343. * NO COPYRIGHT IS CLAIMED IN THIS WORK, HOWEVER, NEITHER IS ANY WARRANTY MADE
  2344. * REGARDING ITS FITNESS FOR ANY PARTICULAR PURPOSE. USE IT AT YOUR OWN RISK.
  2345. *
  2346. *******************************************************************************/
  2347. #ifndef TLS_AES128_H
  2348. #define TLS_AES128_H
  2349. /******************************************************************************
  2350. * AES_CONTEXT : cipher context / holds inter-call data
  2351. ******************************************************************************/
  2352. typedef struct {
  2353. int mode; // 1 for Encryption, 0 for Decryption
  2354. int rounds; // keysize-based rounds count
  2355. uint32_t *rk; // pointer to current round key
  2356. uint32_t buf[68]; // key expansion buffer
  2357. } aes_context;
  2358. #define GCM_AUTH_FAILURE 0x55555555 // authentication failure
  2359. /******************************************************************************
  2360. * GCM_CONTEXT : MUST be called once before ANY use of this library
  2361. ******************************************************************************/
  2362. int mg_gcm_initialize(void);
  2363. //
  2364. // aes-gcm.h
  2365. // MKo
  2366. //
  2367. // Created by Markus Kosmal on 20/11/14.
  2368. //
  2369. //
  2370. int mg_aes_gcm_encrypt(unsigned char *output, const unsigned char *input,
  2371. size_t input_length, const unsigned char *key,
  2372. const size_t key_len, const unsigned char *iv,
  2373. const size_t iv_len, unsigned char *aead,
  2374. size_t aead_len, unsigned char *tag,
  2375. const size_t tag_len);
  2376. int mg_aes_gcm_decrypt(unsigned char *output, const unsigned char *input,
  2377. size_t input_length, const unsigned char *key,
  2378. const size_t key_len, const unsigned char *iv,
  2379. const size_t iv_len, unsigned char *aead,
  2380. size_t aead_len, const unsigned char *tag,
  2381. const size_t tag_len);
  2382. #endif /* TLS_AES128_H */
  2383. // End of aes128 PD
  2384. /* Copyright 2014, Kenneth MacKay. Licensed under the BSD 2-clause license. */
  2385. #ifndef _UECC_H_
  2386. #define _UECC_H_
  2387. /* Platform selection options.
  2388. If MG_UECC_PLATFORM is not defined, the code will try to guess it based on
  2389. compiler macros. Possible values for MG_UECC_PLATFORM are defined below: */
  2390. #define mg_uecc_arch_other 0
  2391. #define mg_uecc_x86 1
  2392. #define mg_uecc_x86_64 2
  2393. #define mg_uecc_arm 3
  2394. #define mg_uecc_arm_thumb 4
  2395. #define mg_uecc_arm_thumb2 5
  2396. #define mg_uecc_arm64 6
  2397. #define mg_uecc_avr 7
  2398. /* If desired, you can define MG_UECC_WORD_SIZE as appropriate for your platform
  2399. (1, 4, or 8 bytes). If MG_UECC_WORD_SIZE is not explicitly defined then it will
  2400. be automatically set based on your platform. */
  2401. /* Optimization level; trade speed for code size.
  2402. Larger values produce code that is faster but larger.
  2403. Currently supported values are 0 - 4; 0 is unusably slow for most
  2404. applications. Optimization level 4 currently only has an effect ARM platforms
  2405. where more than one curve is enabled. */
  2406. #ifndef MG_UECC_OPTIMIZATION_LEVEL
  2407. #define MG_UECC_OPTIMIZATION_LEVEL 2
  2408. #endif
  2409. /* MG_UECC_SQUARE_FUNC - If enabled (defined as nonzero), this will cause a
  2410. specific function to be used for (scalar) squaring instead of the generic
  2411. multiplication function. This can make things faster somewhat faster, but
  2412. increases the code size. */
  2413. #ifndef MG_UECC_SQUARE_FUNC
  2414. #define MG_UECC_SQUARE_FUNC 0
  2415. #endif
  2416. /* MG_UECC_VLI_NATIVE_LITTLE_ENDIAN - If enabled (defined as nonzero), this will
  2417. switch to native little-endian format for *all* arrays passed in and out of the
  2418. public API. This includes public and private keys, shared secrets, signatures
  2419. and message hashes. Using this switch reduces the amount of call stack memory
  2420. used by uECC, since less intermediate translations are required. Note that this
  2421. will *only* work on native little-endian processors and it will treat the
  2422. uint8_t arrays passed into the public API as word arrays, therefore requiring
  2423. the provided byte arrays to be word aligned on architectures that do not support
  2424. unaligned accesses. IMPORTANT: Keys and signatures generated with
  2425. MG_UECC_VLI_NATIVE_LITTLE_ENDIAN=1 are incompatible with keys and signatures
  2426. generated with MG_UECC_VLI_NATIVE_LITTLE_ENDIAN=0; all parties must use the same
  2427. endianness. */
  2428. #ifndef MG_UECC_VLI_NATIVE_LITTLE_ENDIAN
  2429. #define MG_UECC_VLI_NATIVE_LITTLE_ENDIAN 0
  2430. #endif
  2431. /* Curve support selection. Set to 0 to remove that curve. */
  2432. #ifndef MG_UECC_SUPPORTS_secp160r1
  2433. #define MG_UECC_SUPPORTS_secp160r1 0
  2434. #endif
  2435. #ifndef MG_UECC_SUPPORTS_secp192r1
  2436. #define MG_UECC_SUPPORTS_secp192r1 0
  2437. #endif
  2438. #ifndef MG_UECC_SUPPORTS_secp224r1
  2439. #define MG_UECC_SUPPORTS_secp224r1 0
  2440. #endif
  2441. #ifndef MG_UECC_SUPPORTS_secp256r1
  2442. #define MG_UECC_SUPPORTS_secp256r1 1
  2443. #endif
  2444. #ifndef MG_UECC_SUPPORTS_secp256k1
  2445. #define MG_UECC_SUPPORTS_secp256k1 0
  2446. #endif
  2447. #ifndef MG_UECC_SUPPORTS_secp384r1
  2448. #define MG_UECC_SUPPORTS_secp384r1 1
  2449. #endif
  2450. /* Specifies whether compressed point format is supported.
  2451. Set to 0 to disable point compression/decompression functions. */
  2452. #ifndef MG_UECC_SUPPORT_COMPRESSED_POINT
  2453. #define MG_UECC_SUPPORT_COMPRESSED_POINT 1
  2454. #endif
  2455. struct MG_UECC_Curve_t;
  2456. typedef const struct MG_UECC_Curve_t *MG_UECC_Curve;
  2457. #ifdef __cplusplus
  2458. extern "C" {
  2459. #endif
  2460. #if MG_UECC_SUPPORTS_secp160r1
  2461. MG_UECC_Curve mg_uecc_secp160r1(void);
  2462. #endif
  2463. #if MG_UECC_SUPPORTS_secp192r1
  2464. MG_UECC_Curve mg_uecc_secp192r1(void);
  2465. #endif
  2466. #if MG_UECC_SUPPORTS_secp224r1
  2467. MG_UECC_Curve mg_uecc_secp224r1(void);
  2468. #endif
  2469. #if MG_UECC_SUPPORTS_secp256r1
  2470. MG_UECC_Curve mg_uecc_secp256r1(void);
  2471. #endif
  2472. #if MG_UECC_SUPPORTS_secp256k1
  2473. MG_UECC_Curve mg_uecc_secp256k1(void);
  2474. #endif
  2475. #if MG_UECC_SUPPORTS_secp384r1
  2476. MG_UECC_Curve mg_uecc_secp384r1(void);
  2477. #endif
  2478. /* MG_UECC_RNG_Function type
  2479. The RNG function should fill 'size' random bytes into 'dest'. It should return 1
  2480. if 'dest' was filled with random data, or 0 if the random data could not be
  2481. generated. The filled-in values should be either truly random, or from a
  2482. cryptographically-secure PRNG.
  2483. A correctly functioning RNG is required before calling mg_uecc_make_key() or
  2484. mg_uecc_sign().
  2485. Setting a correctly functioning RNG function improves the resistance to
  2486. side-channel attacks for mg_uecc_shared_secret() and
  2487. mg_uecc_sign_deterministic().
  2488. */
  2489. typedef int (*MG_UECC_RNG_Function)(uint8_t *dest, unsigned size);
  2490. // Mongoose: mg_uecc_make_key() and mg_uecc_sign() use mg_random() when no
  2491. // explicit uECC RNG is installed. If mg_random() cannot provide a strong source,
  2492. // those operations fail. Deterministic signing works without RNG, but only an
  2493. // explicit uECC RNG enables its optional side-channel blinding.
  2494. /* mg_uecc_set_rng() function.
  2495. Set the function that will be used to generate random bytes. The RNG function
  2496. should return 1 if the random data was generated, or 0 if the random data could
  2497. not be generated.
  2498. Mongoose: this overrides the default mg_random() fallback used by
  2499. mg_uecc_make_key() and mg_uecc_sign(). Do not call mg_uecc_set_rng() unless the
  2500. application must provide its own cryptographic RNG.
  2501. Inputs:
  2502. rng_function - The function that will be used to generate random bytes.
  2503. */
  2504. void mg_uecc_set_rng(MG_UECC_RNG_Function rng_function);
  2505. /* mg_uecc_get_rng() function.
  2506. Returns the function that will be used to generate random bytes.
  2507. */
  2508. MG_UECC_RNG_Function mg_uecc_get_rng(void);
  2509. /* mg_uecc_curve_private_key_size() function.
  2510. Returns the size of a private key for the curve in bytes.
  2511. */
  2512. int mg_uecc_curve_private_key_size(MG_UECC_Curve curve);
  2513. /* mg_uecc_curve_public_key_size() function.
  2514. Returns the size of a public key for the curve in bytes.
  2515. */
  2516. int mg_uecc_curve_public_key_size(MG_UECC_Curve curve);
  2517. /* mg_uecc_make_key() function.
  2518. Create a public/private key pair.
  2519. Outputs:
  2520. public_key - Will be filled in with the public key. Must be at least 2 *
  2521. the curve size (in bytes) long. For example, if the curve is secp256r1,
  2522. public_key must be 64 bytes long. private_key - Will be filled in with the
  2523. private key. Must be as long as the curve order; this is typically the same as
  2524. the curve size, except for secp160r1. For example, if the curve is secp256r1,
  2525. private_key must be 32 bytes long.
  2526. For secp160r1, private_key must be 21 bytes long! Note that
  2527. the first byte will almost always be 0 (there is about a 1 in 2^80 chance of it
  2528. being non-zero).
  2529. Returns 1 if the key pair was generated successfully, 0 if an error occurred.
  2530. */
  2531. int mg_uecc_make_key(uint8_t *public_key, uint8_t *private_key,
  2532. MG_UECC_Curve curve);
  2533. /* mg_uecc_shared_secret() function.
  2534. Compute a shared secret given your secret key and someone else's public key. If
  2535. the public key is not from a trusted source and has not been previously
  2536. verified, you should verify it first using mg_uecc_valid_public_key(). Note: It
  2537. is recommended that you hash the result of mg_uecc_shared_secret() before using
  2538. it for symmetric encryption or HMAC.
  2539. Inputs:
  2540. public_key - The public key of the remote party.
  2541. private_key - Your private key.
  2542. Outputs:
  2543. secret - Will be filled in with the shared secret value. Must be the same
  2544. size as the curve size; for example, if the curve is secp256r1, secret must be
  2545. 32 bytes long.
  2546. Returns 1 if the shared secret was generated successfully, 0 if an error
  2547. occurred.
  2548. */
  2549. int mg_uecc_shared_secret(const uint8_t *public_key, const uint8_t *private_key,
  2550. uint8_t *secret, MG_UECC_Curve curve);
  2551. #if MG_UECC_SUPPORT_COMPRESSED_POINT
  2552. /* mg_uecc_compress() function.
  2553. Compress a public key.
  2554. Inputs:
  2555. public_key - The public key to compress.
  2556. Outputs:
  2557. compressed - Will be filled in with the compressed public key. Must be at
  2558. least (curve size + 1) bytes long; for example, if the curve is secp256r1,
  2559. compressed must be 33 bytes long.
  2560. */
  2561. void mg_uecc_compress(const uint8_t *public_key, uint8_t *compressed,
  2562. MG_UECC_Curve curve);
  2563. /* mg_uecc_decompress() function.
  2564. Decompress a compressed public key.
  2565. Inputs:
  2566. compressed - The compressed public key.
  2567. Outputs:
  2568. public_key - Will be filled in with the decompressed public key.
  2569. */
  2570. void mg_uecc_decompress(const uint8_t *compressed, uint8_t *public_key,
  2571. MG_UECC_Curve curve);
  2572. #endif /* MG_UECC_SUPPORT_COMPRESSED_POINT */
  2573. /* mg_uecc_valid_public_key() function.
  2574. Check to see if a public key is valid.
  2575. Note that you are not required to check for a valid public key before using any
  2576. other uECC functions. However, you may wish to avoid spending CPU time computing
  2577. a shared secret or verifying a signature using an invalid public key.
  2578. Inputs:
  2579. public_key - The public key to check.
  2580. Returns 1 if the public key is valid, 0 if it is invalid.
  2581. */
  2582. int mg_uecc_valid_public_key(const uint8_t *public_key, MG_UECC_Curve curve);
  2583. /* mg_uecc_compute_public_key() function.
  2584. Compute the corresponding public key for a private key.
  2585. Inputs:
  2586. private_key - The private key to compute the public key for
  2587. Outputs:
  2588. public_key - Will be filled in with the corresponding public key
  2589. Returns 1 if the key was computed successfully, 0 if an error occurred.
  2590. */
  2591. int mg_uecc_compute_public_key(const uint8_t *private_key, uint8_t *public_key,
  2592. MG_UECC_Curve curve);
  2593. /* mg_uecc_sign() function.
  2594. Generate an ECDSA signature for a given hash value.
  2595. Usage: Compute a hash of the data you wish to sign (SHA-2 is recommended) and
  2596. pass it in to this function along with your private key.
  2597. Inputs:
  2598. private_key - Your private key.
  2599. message_hash - The hash of the message to sign.
  2600. hash_size - The size of message_hash in bytes.
  2601. Outputs:
  2602. signature - Will be filled in with the signature value. Must be at least 2 *
  2603. curve size long. For example, if the curve is secp256r1, signature must be 64
  2604. bytes long.
  2605. Returns 1 if the signature generated successfully, 0 if an error occurred.
  2606. */
  2607. int mg_uecc_sign(const uint8_t *private_key, const uint8_t *message_hash,
  2608. unsigned hash_size, uint8_t *signature, MG_UECC_Curve curve);
  2609. /* MG_UECC_HashContext structure.
  2610. This is used to pass in an arbitrary hash function to
  2611. mg_uecc_sign_deterministic(). The structure will be used for multiple hash
  2612. computations; each time a new hash is computed, init_hash() will be called,
  2613. followed by one or more calls to update_hash(), and finally a call to
  2614. finish_hash() to produce the resulting hash.
  2615. The intention is that you will create a structure that includes
  2616. MG_UECC_HashContext followed by any hash-specific data. For example:
  2617. typedef struct SHA256_HashContext {
  2618. MG_UECC_HashContext uECC;
  2619. SHA256_CTX ctx;
  2620. } SHA256_HashContext;
  2621. void init_SHA256(MG_UECC_HashContext *base) {
  2622. SHA256_HashContext *context = (SHA256_HashContext *)base;
  2623. SHA256_Init(&context->ctx);
  2624. }
  2625. void update_SHA256(MG_UECC_HashContext *base,
  2626. const uint8_t *message,
  2627. unsigned message_size) {
  2628. SHA256_HashContext *context = (SHA256_HashContext *)base;
  2629. SHA256_Update(&context->ctx, message, message_size);
  2630. }
  2631. void finish_SHA256(MG_UECC_HashContext *base, uint8_t *hash_result) {
  2632. SHA256_HashContext *context = (SHA256_HashContext *)base;
  2633. SHA256_Final(hash_result, &context->ctx);
  2634. }
  2635. ... when signing ...
  2636. {
  2637. uint8_t tmp[32 + 32 + 64];
  2638. SHA256_HashContext ctx = {{&init_SHA256, &update_SHA256, &finish_SHA256, 64,
  2639. 32, tmp}}; mg_uecc_sign_deterministic(key, message_hash, &ctx.uECC, signature);
  2640. }
  2641. */
  2642. typedef struct MG_UECC_HashContext {
  2643. void (*init_hash)(const struct MG_UECC_HashContext *context);
  2644. void (*update_hash)(const struct MG_UECC_HashContext *context,
  2645. const uint8_t *message, unsigned message_size);
  2646. void (*finish_hash)(const struct MG_UECC_HashContext *context,
  2647. uint8_t *hash_result);
  2648. unsigned
  2649. block_size; /* Hash function block size in bytes, eg 64 for SHA-256. */
  2650. unsigned
  2651. result_size; /* Hash function result size in bytes, eg 32 for SHA-256. */
  2652. uint8_t *tmp; /* Must point to a buffer of at least (2 * result_size +
  2653. block_size) bytes. */
  2654. } MG_UECC_HashContext;
  2655. /* mg_uecc_sign_deterministic() function.
  2656. Generate an ECDSA signature for a given hash value, using a deterministic
  2657. algorithm (see RFC 6979). You do not need to set the RNG using mg_uecc_set_rng()
  2658. before calling this function; however, if the RNG is defined it will improve
  2659. resistance to side-channel attacks.
  2660. Usage: Compute a hash of the data you wish to sign (SHA-2 is recommended) and
  2661. pass it to this function along with your private key and a hash context. Note
  2662. that the message_hash does not need to be computed with the same hash function
  2663. used by hash_context.
  2664. Inputs:
  2665. private_key - Your private key.
  2666. message_hash - The hash of the message to sign.
  2667. hash_size - The size of message_hash in bytes.
  2668. hash_context - A hash context to use.
  2669. Outputs:
  2670. signature - Will be filled in with the signature value.
  2671. Returns 1 if the signature generated successfully, 0 if an error occurred.
  2672. */
  2673. int mg_uecc_sign_deterministic(const uint8_t *private_key,
  2674. const uint8_t *message_hash, unsigned hash_size,
  2675. const MG_UECC_HashContext *hash_context,
  2676. uint8_t *signature, MG_UECC_Curve curve);
  2677. /* mg_uecc_verify() function.
  2678. Verify an ECDSA signature.
  2679. Usage: Compute the hash of the signed data using the same hash as the signer and
  2680. pass it to this function along with the signer's public key and the signature
  2681. values (r and s).
  2682. Inputs:
  2683. public_key - The signer's public key.
  2684. message_hash - The hash of the signed data.
  2685. hash_size - The size of message_hash in bytes.
  2686. signature - The signature value.
  2687. Returns 1 if the signature is valid, 0 if it is invalid.
  2688. */
  2689. int mg_uecc_verify(const uint8_t *public_key, const uint8_t *message_hash,
  2690. unsigned hash_size, const uint8_t *signature,
  2691. MG_UECC_Curve curve);
  2692. #ifdef __cplusplus
  2693. } /* end of extern "C" */
  2694. #endif
  2695. #endif /* _UECC_H_ */
  2696. /* Copyright 2015, Kenneth MacKay. Licensed under the BSD 2-clause license. */
  2697. #ifndef _UECC_TYPES_H_
  2698. #define _UECC_TYPES_H_
  2699. #ifndef MG_UECC_PLATFORM
  2700. #if defined(__AVR__) && __AVR__
  2701. #define MG_UECC_PLATFORM mg_uecc_avr
  2702. #elif defined(__thumb2__) || \
  2703. defined(_M_ARMT) /* I think MSVC only supports Thumb-2 targets */
  2704. #define MG_UECC_PLATFORM mg_uecc_arm_thumb2
  2705. #elif defined(__thumb__)
  2706. #define MG_UECC_PLATFORM mg_uecc_arm_thumb
  2707. #elif defined(__arm__) || defined(_M_ARM)
  2708. #define MG_UECC_PLATFORM mg_uecc_arm
  2709. #elif defined(__aarch64__)
  2710. #define MG_UECC_PLATFORM mg_uecc_arm64
  2711. #elif defined(__i386__) || defined(_M_IX86) || defined(_X86_) || \
  2712. defined(__I86__)
  2713. #define MG_UECC_PLATFORM mg_uecc_x86
  2714. #elif defined(__amd64__) || defined(_M_X64)
  2715. #define MG_UECC_PLATFORM mg_uecc_x86_64
  2716. #else
  2717. #define MG_UECC_PLATFORM mg_uecc_arch_other
  2718. #endif
  2719. #endif
  2720. #ifndef MG_UECC_ARM_USE_UMAAL
  2721. #if (MG_UECC_PLATFORM == mg_uecc_arm) && (__ARM_ARCH >= 6)
  2722. #define MG_UECC_ARM_USE_UMAAL 1
  2723. #elif (MG_UECC_PLATFORM == mg_uecc_arm_thumb2) && (__ARM_ARCH >= 6) && \
  2724. (!defined(__ARM_ARCH_7M__) || !__ARM_ARCH_7M__)
  2725. #define MG_UECC_ARM_USE_UMAAL 1
  2726. #else
  2727. #define MG_UECC_ARM_USE_UMAAL 0
  2728. #endif
  2729. #endif
  2730. #ifndef MG_UECC_WORD_SIZE
  2731. #if MG_UECC_PLATFORM == mg_uecc_avr
  2732. #define MG_UECC_WORD_SIZE 1
  2733. #elif (MG_UECC_PLATFORM == mg_uecc_x86_64 || MG_UECC_PLATFORM == mg_uecc_arm64)
  2734. #define MG_UECC_WORD_SIZE 8
  2735. #else
  2736. #define MG_UECC_WORD_SIZE 4
  2737. #endif
  2738. #endif
  2739. #if (MG_UECC_WORD_SIZE != 1) && (MG_UECC_WORD_SIZE != 4) && \
  2740. (MG_UECC_WORD_SIZE != 8)
  2741. #error "Unsupported value for MG_UECC_WORD_SIZE"
  2742. #endif
  2743. #if ((MG_UECC_PLATFORM == mg_uecc_avr) && (MG_UECC_WORD_SIZE != 1))
  2744. #pragma message("MG_UECC_WORD_SIZE must be 1 for AVR")
  2745. #undef MG_UECC_WORD_SIZE
  2746. #define MG_UECC_WORD_SIZE 1
  2747. #endif
  2748. #if ((MG_UECC_PLATFORM == mg_uecc_arm || \
  2749. MG_UECC_PLATFORM == mg_uecc_arm_thumb || \
  2750. MG_UECC_PLATFORM == mg_uecc_arm_thumb2) && \
  2751. (MG_UECC_WORD_SIZE != 4))
  2752. #pragma message("MG_UECC_WORD_SIZE must be 4 for ARM")
  2753. #undef MG_UECC_WORD_SIZE
  2754. #define MG_UECC_WORD_SIZE 4
  2755. #endif
  2756. typedef int8_t wordcount_t;
  2757. typedef int16_t bitcount_t;
  2758. typedef int8_t cmpresult_t;
  2759. #if (MG_UECC_WORD_SIZE == 1)
  2760. typedef uint8_t mg_uecc_word_t;
  2761. typedef uint16_t mg_uecc_dword_t;
  2762. #define HIGH_BIT_SET 0x80
  2763. #define MG_UECC_WORD_BITS 8
  2764. #define MG_UECC_WORD_BITS_SHIFT 3
  2765. #define MG_UECC_WORD_BITS_MASK 0x07
  2766. #elif (MG_UECC_WORD_SIZE == 4)
  2767. typedef uint32_t mg_uecc_word_t;
  2768. typedef uint64_t mg_uecc_dword_t;
  2769. #define HIGH_BIT_SET 0x80000000
  2770. #define MG_UECC_WORD_BITS 32
  2771. #define MG_UECC_WORD_BITS_SHIFT 5
  2772. #define MG_UECC_WORD_BITS_MASK 0x01F
  2773. #elif (MG_UECC_WORD_SIZE == 8)
  2774. typedef uint64_t mg_uecc_word_t;
  2775. #define HIGH_BIT_SET 0x8000000000000000U
  2776. #define MG_UECC_WORD_BITS 64
  2777. #define MG_UECC_WORD_BITS_SHIFT 6
  2778. #define MG_UECC_WORD_BITS_MASK 0x03F
  2779. #endif /* MG_UECC_WORD_SIZE */
  2780. #endif /* _UECC_TYPES_H_ */
  2781. /* Copyright 2015, Kenneth MacKay. Licensed under the BSD 2-clause license. */
  2782. #ifndef _UECC_VLI_H_
  2783. #define _UECC_VLI_H_
  2784. //
  2785. //
  2786. /* Functions for raw large-integer manipulation. These are only available
  2787. if uECC.c is compiled with MG_UECC_ENABLE_VLI_API defined to 1. */
  2788. #ifndef MG_UECC_ENABLE_VLI_API
  2789. #define MG_UECC_ENABLE_VLI_API 0
  2790. #endif
  2791. #ifdef __cplusplus
  2792. extern "C" {
  2793. #endif
  2794. #if MG_UECC_ENABLE_VLI_API
  2795. void mg_uecc_vli_clear(mg_uecc_word_t *vli, wordcount_t num_words);
  2796. /* Constant-time comparison to zero - secure way to compare long integers */
  2797. /* Returns 1 if vli == 0, 0 otherwise. */
  2798. mg_uecc_word_t mg_uecc_vli_isZero(const mg_uecc_word_t *vli,
  2799. wordcount_t num_words);
  2800. /* Returns nonzero if bit 'bit' of vli is set. */
  2801. mg_uecc_word_t mg_uecc_vli_testBit(const mg_uecc_word_t *vli, bitcount_t bit);
  2802. /* Counts the number of bits required to represent vli. */
  2803. bitcount_t mg_uecc_vli_numBits(const mg_uecc_word_t *vli,
  2804. const wordcount_t max_words);
  2805. /* Sets dest = src. */
  2806. void mg_uecc_vli_set(mg_uecc_word_t *dest, const mg_uecc_word_t *src,
  2807. wordcount_t num_words);
  2808. /* Constant-time comparison function - secure way to compare long integers */
  2809. /* Returns one if left == right, zero otherwise */
  2810. mg_uecc_word_t mg_uecc_vli_equal(const mg_uecc_word_t *left,
  2811. const mg_uecc_word_t *right,
  2812. wordcount_t num_words);
  2813. /* Constant-time comparison function - secure way to compare long integers */
  2814. /* Returns sign of left - right, in constant time. */
  2815. cmpresult_t mg_uecc_vli_cmp(const mg_uecc_word_t *left,
  2816. const mg_uecc_word_t *right, wordcount_t num_words);
  2817. /* Computes vli = vli >> 1. */
  2818. void mg_uecc_vli_rshift1(mg_uecc_word_t *vli, wordcount_t num_words);
  2819. /* Computes result = left + right, returning carry. Can modify in place. */
  2820. mg_uecc_word_t mg_uecc_vli_add(mg_uecc_word_t *result,
  2821. const mg_uecc_word_t *left,
  2822. const mg_uecc_word_t *right,
  2823. wordcount_t num_words);
  2824. /* Computes result = left - right, returning borrow. Can modify in place. */
  2825. mg_uecc_word_t mg_uecc_vli_sub(mg_uecc_word_t *result,
  2826. const mg_uecc_word_t *left,
  2827. const mg_uecc_word_t *right,
  2828. wordcount_t num_words);
  2829. /* Computes result = left * right. Result must be 2 * num_words long. */
  2830. void mg_uecc_vli_mult(mg_uecc_word_t *result, const mg_uecc_word_t *left,
  2831. const mg_uecc_word_t *right, wordcount_t num_words);
  2832. /* Computes result = left^2. Result must be 2 * num_words long. */
  2833. void mg_uecc_vli_square(mg_uecc_word_t *result, const mg_uecc_word_t *left,
  2834. wordcount_t num_words);
  2835. /* Computes result = (left + right) % mod.
  2836. Assumes that left < mod and right < mod, and that result does not overlap
  2837. mod. */
  2838. void mg_uecc_vli_modAdd(mg_uecc_word_t *result, const mg_uecc_word_t *left,
  2839. const mg_uecc_word_t *right, const mg_uecc_word_t *mod,
  2840. wordcount_t num_words);
  2841. /* Computes result = (left - right) % mod.
  2842. Assumes that left < mod and right < mod, and that result does not overlap
  2843. mod. */
  2844. void mg_uecc_vli_modSub(mg_uecc_word_t *result, const mg_uecc_word_t *left,
  2845. const mg_uecc_word_t *right, const mg_uecc_word_t *mod,
  2846. wordcount_t num_words);
  2847. /* Computes result = product % mod, where product is 2N words long.
  2848. Currently only designed to work for mod == curve->p or curve_n. */
  2849. void mg_uecc_vli_mmod(mg_uecc_word_t *result, mg_uecc_word_t *product,
  2850. const mg_uecc_word_t *mod, wordcount_t num_words);
  2851. /* Calculates result = product (mod curve->p), where product is up to
  2852. 2 * curve->num_words long. */
  2853. void mg_uecc_vli_mmod_fast(mg_uecc_word_t *result, mg_uecc_word_t *product,
  2854. MG_UECC_Curve curve);
  2855. /* Computes result = (left * right) % mod.
  2856. Currently only designed to work for mod == curve->p or curve_n. */
  2857. void mg_uecc_vli_modMult(mg_uecc_word_t *result, const mg_uecc_word_t *left,
  2858. const mg_uecc_word_t *right, const mg_uecc_word_t *mod,
  2859. wordcount_t num_words);
  2860. /* Computes result = (left * right) % curve->p. */
  2861. void mg_uecc_vli_modMult_fast(mg_uecc_word_t *result,
  2862. const mg_uecc_word_t *left,
  2863. const mg_uecc_word_t *right, MG_UECC_Curve curve);
  2864. /* Computes result = left^2 % mod.
  2865. Currently only designed to work for mod == curve->p or curve_n. */
  2866. void mg_uecc_vli_modSquare(mg_uecc_word_t *result, const mg_uecc_word_t *left,
  2867. const mg_uecc_word_t *mod, wordcount_t num_words);
  2868. /* Computes result = left^2 % curve->p. */
  2869. void mg_uecc_vli_modSquare_fast(mg_uecc_word_t *result,
  2870. const mg_uecc_word_t *left,
  2871. MG_UECC_Curve curve);
  2872. /* Computes result = (1 / input) % mod.*/
  2873. void mg_uecc_vli_modInv(mg_uecc_word_t *result, const mg_uecc_word_t *input,
  2874. const mg_uecc_word_t *mod, wordcount_t num_words);
  2875. #if MG_UECC_SUPPORT_COMPRESSED_POINT
  2876. /* Calculates a = sqrt(a) (mod curve->p) */
  2877. void mg_uecc_vli_mod_sqrt(mg_uecc_word_t *a, MG_UECC_Curve curve);
  2878. #endif
  2879. /* Converts an integer in uECC native format to big-endian bytes. */
  2880. void mg_uecc_vli_nativeToBytes(uint8_t *bytes, int num_bytes,
  2881. const mg_uecc_word_t *native);
  2882. /* Converts big-endian bytes to an integer in uECC native format. */
  2883. void mg_uecc_vli_bytesToNative(mg_uecc_word_t *native, const uint8_t *bytes,
  2884. int num_bytes);
  2885. unsigned mg_uecc_curve_num_words(MG_UECC_Curve curve);
  2886. unsigned mg_uecc_curve_num_bytes(MG_UECC_Curve curve);
  2887. unsigned mg_uecc_curve_num_bits(MG_UECC_Curve curve);
  2888. unsigned mg_uecc_curve_num_n_words(MG_UECC_Curve curve);
  2889. unsigned mg_uecc_curve_num_n_bytes(MG_UECC_Curve curve);
  2890. unsigned mg_uecc_curve_num_n_bits(MG_UECC_Curve curve);
  2891. const mg_uecc_word_t *mg_uecc_curve_p(MG_UECC_Curve curve);
  2892. const mg_uecc_word_t *mg_uecc_curve_n(MG_UECC_Curve curve);
  2893. const mg_uecc_word_t *mg_uecc_curve_G(MG_UECC_Curve curve);
  2894. const mg_uecc_word_t *mg_uecc_curve_b(MG_UECC_Curve curve);
  2895. int mg_uecc_valid_point(const mg_uecc_word_t *point, MG_UECC_Curve curve);
  2896. /* Multiplies a point by a scalar. Points are represented by the X coordinate
  2897. followed by the Y coordinate in the same array, both coordinates are
  2898. curve->num_words long. Note that scalar must be curve->num_n_words long (NOT
  2899. curve->num_words). */
  2900. void mg_uecc_point_mult(mg_uecc_word_t *result, const mg_uecc_word_t *point,
  2901. const mg_uecc_word_t *scalar, MG_UECC_Curve curve);
  2902. /* Generates a random integer in the range 0 < random < top.
  2903. Both random and top have num_words words. */
  2904. int mg_uecc_generate_random_int(mg_uecc_word_t *random,
  2905. const mg_uecc_word_t *top,
  2906. wordcount_t num_words);
  2907. #endif /* MG_UECC_ENABLE_VLI_API */
  2908. #ifdef __cplusplus
  2909. } /* end of extern "C" */
  2910. #endif
  2911. #endif /* _UECC_VLI_H_ */
  2912. // End of uecc BSD-2
  2913. // portable8439 v1.0.1
  2914. // Source: https://github.com/DavyLandman/portable8439
  2915. // Licensed under CC0-1.0
  2916. // Contains poly1305-donna e6ad6e091d30d7f4ec2d4f978be1fcfcbce72781 (Public
  2917. // Domain)
  2918. #if MG_TLS == MG_TLS_BUILTIN && MG_ENABLE_CHACHA20
  2919. #ifndef __PORTABLE_8439_H
  2920. #define __PORTABLE_8439_H
  2921. #if defined(__cplusplus)
  2922. extern "C" {
  2923. #endif
  2924. // provide your own decl specificier like -DPORTABLE_8439_DECL=ICACHE_RAM_ATTR
  2925. #ifndef PORTABLE_8439_DECL
  2926. #define PORTABLE_8439_DECL
  2927. #endif
  2928. /*
  2929. This library implements RFC 8439 a.k.a. ChaCha20-Poly1305 AEAD
  2930. You can use this library to avoid attackers mutating or reusing your
  2931. encrypted messages. This does assume you never reuse a nonce+key pair and,
  2932. if possible, carefully pick your associated data.
  2933. */
  2934. /* Make sure we are either nested in C++ or running in a C99+ compiler
  2935. #if !defined(__cplusplus) && !defined(_MSC_VER) && \
  2936. (!defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L)
  2937. #error "C99 or newer required"
  2938. #endif */
  2939. // #if CHAR_BIT > 8
  2940. // # error "Systems without native octals not suppoted"
  2941. // #endif
  2942. #if defined(_MSC_VER) || defined(__cplusplus)
  2943. // add restrict support is possible
  2944. #if (defined(_MSC_VER) && _MSC_VER >= 1900) || defined(__clang__) || \
  2945. defined(__GNUC__)
  2946. #define restrict __restrict
  2947. #else
  2948. #define restrict
  2949. #endif
  2950. #endif
  2951. #define RFC_8439_TAG_SIZE (16)
  2952. #define RFC_8439_KEY_SIZE (32)
  2953. #define RFC_8439_NONCE_SIZE (12)
  2954. /*
  2955. Encrypt/Seal plain text bytes into a cipher text that can only be
  2956. decrypted by knowing the key, nonce and associated data.
  2957. input:
  2958. - key: RFC_8439_KEY_SIZE bytes that all parties have agreed
  2959. upon beforehand
  2960. - nonce: RFC_8439_NONCE_SIZE bytes that should never be repeated
  2961. for the same key. A counter or a pseudo-random value are fine.
  2962. - ad: associated data to include with calculating the tag of the
  2963. cipher text. Can be null for empty.
  2964. - plain_text: data to be encrypted, pointer + size should not overlap
  2965. with cipher_text pointer
  2966. output:
  2967. - cipher_text: encrypted plain_text with a tag appended. Make sure to
  2968. allocate at least plain_text_size + RFC_8439_TAG_SIZE
  2969. returns:
  2970. - size of bytes written to cipher_text, can be -1 if overlapping
  2971. pointers are passed for plain_text and cipher_text
  2972. */
  2973. PORTABLE_8439_DECL size_t mg_chacha20_poly1305_encrypt(
  2974. uint8_t *restrict cipher_text, const uint8_t key[RFC_8439_KEY_SIZE],
  2975. const uint8_t nonce[RFC_8439_NONCE_SIZE], const uint8_t *restrict ad,
  2976. size_t ad_size, const uint8_t *restrict plain_text, size_t plain_text_size);
  2977. /*
  2978. Decrypt/unseal cipher text given the right key, nonce, and additional data.
  2979. input:
  2980. - key: RFC_8439_KEY_SIZE bytes that all parties have agreed
  2981. upon beforehand
  2982. - nonce: RFC_8439_NONCE_SIZE bytes that should never be repeated for
  2983. the same key. A counter or a pseudo-random value are fine.
  2984. - ad: associated data to include with calculating the tag of the
  2985. cipher text. Can be null for empty.
  2986. - cipher_text: encrypted message.
  2987. output:
  2988. - plain_text: data to be encrypted, pointer + size should not overlap
  2989. with cipher_text pointer, leave at least enough room for
  2990. cipher_text_size - RFC_8439_TAG_SIZE
  2991. returns:
  2992. - size of bytes written to plain_text, -1 signals either:
  2993. - incorrect key/nonce/ad
  2994. - corrupted cipher_text
  2995. - overlapping pointers are passed for plain_text and cipher_text
  2996. */
  2997. PORTABLE_8439_DECL size_t mg_chacha20_poly1305_decrypt(
  2998. uint8_t *restrict plain_text, const uint8_t key[RFC_8439_KEY_SIZE],
  2999. const uint8_t nonce[RFC_8439_NONCE_SIZE],
  3000. const uint8_t *restrict ad, size_t ad_size,
  3001. const uint8_t *restrict cipher_text, size_t cipher_text_size);
  3002. #if defined(__cplusplus)
  3003. }
  3004. #endif
  3005. #endif
  3006. #endif
  3007. #ifndef TLS_RSA_H
  3008. #define TLS_RSA_H
  3009. int mg_rsa_mod_pow(const uint8_t *mod, size_t modsz, const uint8_t *exp, size_t expsz, const uint8_t *msg, size_t msgsz, uint8_t *out, size_t outsz);
  3010. int mg_rsa_crt_sign(const uint8_t *em, size_t em_len,
  3011. const uint8_t *dP, size_t dP_len,
  3012. const uint8_t *dQ, size_t dQ_len,
  3013. const uint8_t *p, size_t p_len,
  3014. const uint8_t *q, size_t q_len,
  3015. const uint8_t *qInv, size_t qInv_len,
  3016. uint8_t *signature, size_t sig_len);
  3017. bool mg_rsa_pkcs_verify(const uint8_t *em, size_t nlen, const uint8_t *hash,
  3018. size_t hashlen);
  3019. bool mg_rsa_verify(const uint8_t *em, size_t nlen, const uint8_t *mhash);
  3020. #endif // TLS_RSA_H
  3021. #if MG_TLS == MG_TLS_MBED
  3022. #include <mbedtls/debug.h>
  3023. #include <mbedtls/error.h>
  3024. #include <mbedtls/net_sockets.h>
  3025. #include <mbedtls/ssl.h>
  3026. #include <mbedtls/ssl_ticket.h>
  3027. struct mg_tls_ctx {
  3028. int dummy;
  3029. #ifdef MBEDTLS_SSL_SESSION_TICKETS
  3030. mbedtls_ssl_ticket_context tickets;
  3031. #endif
  3032. };
  3033. struct mg_tls {
  3034. mbedtls_x509_crt ca; // Parsed CA certificate
  3035. mbedtls_x509_crt cert; // Parsed certificate
  3036. mbedtls_pk_context pk; // Private key context
  3037. mbedtls_ssl_context ssl; // SSL/TLS context
  3038. mbedtls_ssl_config conf; // SSL/TLS config
  3039. #ifdef MBEDTLS_SSL_SESSION_TICKETS
  3040. mbedtls_ssl_ticket_context ticket; // Session tickets context
  3041. #endif
  3042. // https://github.com/Mbed-TLS/mbedtls/blob/3b3c652d/include/mbedtls/ssl.h#L5071C18-L5076C29
  3043. unsigned char *throttled_buf; // see #3074
  3044. size_t throttled_len;
  3045. bool check_name; // set when hostname was set, but no CA certificate given
  3046. };
  3047. #endif
  3048. #if MG_TLS == MG_TLS_OPENSSL || MG_TLS == MG_TLS_WOLFSSL
  3049. #include <openssl/err.h>
  3050. #include <openssl/ssl.h>
  3051. #include <openssl/x509v3.h>
  3052. struct mg_tls {
  3053. BIO_METHOD *bm;
  3054. SSL_CTX *ctx;
  3055. SSL *ssl;
  3056. char *name; // matching hostname
  3057. bool check_name; // set when hostname was set, but no CA certificate given
  3058. };
  3059. #endif
  3060. // WebSocket frame opcodes, used in mg_ws_send() op parameter and
  3061. // in the low 4 bits of mg_ws_message.flags.
  3062. #define WEBSOCKET_OP_CONTINUE 0 // Continuation frame (fragmented message)
  3063. #define WEBSOCKET_OP_TEXT 1 // Text (UTF-8) data frame
  3064. #define WEBSOCKET_OP_BINARY 2 // Binary data frame
  3065. #define WEBSOCKET_OP_CLOSE 8 // Connection close control frame
  3066. #define WEBSOCKET_OP_PING 9 // Ping control frame (auto-replied with PONG)
  3067. #define WEBSOCKET_OP_PONG 10 // Pong control frame
  3068. // WebSocket message delivered as ev_data in MG_EV_WS_MSG and MG_EV_WS_CTL.
  3069. // data is a zero-copy slice into the receive buffer; valid until the next
  3070. // mg_mgr_poll() call.
  3071. struct mg_ws_message {
  3072. struct mg_str data; // Message payload
  3073. uint8_t flags; // First byte of the WS frame header: FIN (bit7) | opcode (bits3:0)
  3074. };
  3075. // Opens an outbound WebSocket connection.
  3076. //
  3077. // Returns:
  3078. // Client connection, or NULL on error.
  3079. // Example:
  3080. // mg_ws_connect(&mgr, "ws://localhost:8000/websocket", fn, NULL, NULL);
  3081. // Full examples:
  3082. // tutorials/websocket/websocket-client, tutorials/mqtt/mqtt-over-ws-client
  3083. // Related APIs:
  3084. // mg_ws_send(), mg_ws_printf(), mg_tls_init(), mg_ws_upgrade()
  3085. // Notes:
  3086. // url may use ws:// or wss://. Sends the HTTP Upgrade request immediately.
  3087. // fmt is a printf-style string for extra HTTP request headers; each header
  3088. // must end with "\r\n". The user-supplied fn event handler receives
  3089. // MG_EV_WS_OPEN on handshake success, MG_EV_WS_MSG for messages, and
  3090. // MG_EV_WS_CTL for control frames.
  3091. struct mg_connection *mg_ws_connect(struct mg_mgr *, const char *url,
  3092. mg_event_handler_t fn, void *fn_data,
  3093. const char *fmt, ...);
  3094. // Upgrades a server-side HTTP connection to WebSocket.
  3095. //
  3096. // Example:
  3097. // if (mg_match(hm->uri, mg_str("/websocket"), NULL)) {
  3098. // mg_ws_upgrade(c, hm, NULL);
  3099. // }
  3100. // Full examples:
  3101. // tutorials/websocket/websocket-server,
  3102. // tutorials/websocket/json-rpc-over-websocket, tutorials/core/timers
  3103. // Related APIs:
  3104. // mg_http_listen(), mg_match(), mg_ws_send(), mg_ws_printf()
  3105. // Notes:
  3106. // Call from an MG_EV_HTTP_MSG handler and pass that event's hm. fmt is a
  3107. // printf-style string for extra response headers; each header must end with
  3108. // "\r\n". Fires MG_EV_WS_OPEN immediately on success. Sends HTTP 426 and
  3109. // drains the connection if the request lacks Sec-WebSocket-Key.
  3110. void mg_ws_upgrade(struct mg_connection *, struct mg_http_message *,
  3111. const char *fmt, ...);
  3112. // Sends one WebSocket frame.
  3113. //
  3114. // Returns:
  3115. // Number of bytes appended to c->send; 0 if the frame header cannot be
  3116. // appended.
  3117. // Example:
  3118. // mg_ws_send(c, "hello", 5, WEBSOCKET_OP_TEXT);
  3119. // Full examples:
  3120. // tutorials/websocket/websocket-server, tutorials/websocket/websocket-client,
  3121. // tutorials/core/timers
  3122. // Related APIs:
  3123. // mg_ws_connect(), mg_ws_upgrade(), mg_ws_printf(), mg_ws_wrap()
  3124. // Notes:
  3125. // op is one of WEBSOCKET_OP_*. Client connections are automatically masked
  3126. // per RFC 6455. On OOM, the return value can be smaller than header + len.
  3127. // Data is appended to c->send and sent by a later mg_mgr_poll() call.
  3128. size_t mg_ws_send(struct mg_connection *, const void *buf, size_t len, int op);
  3129. // Wraps the last len bytes already in c->send with a WebSocket frame header
  3130. // and opcode op. Used internally by mg_ws_printf(); call it directly when you
  3131. // have written data into c->send manually and need to frame it.
  3132. // Returns c->send.len (total buffer size after the operation).
  3133. size_t mg_ws_wrap(struct mg_connection *, size_t len, int op);
  3134. // Formats a WebSocket message using printf-style fmt and sends it with
  3135. // opcode op (WEBSOCKET_OP_TEXT or WEBSOCKET_OP_BINARY).
  3136. // Returns the number of payload bytes written, or 0 on OOM.
  3137. size_t mg_ws_printf(struct mg_connection *c, int op, const char *fmt, ...);
  3138. size_t mg_ws_vprintf(struct mg_connection *c, int op, const char *fmt,
  3139. va_list *);
  3140. // Time / SNTP functions
  3141. // Return milliseconds since boot (uptime). Never goes backwards.
  3142. // On RTOS targets (FreeRTOS, ThreadX, Zephyr, etc.) uses the RTOS tick count.
  3143. // On STM32/Cube uses HAL_GetTick(). On Arduino uses millis().
  3144. // On Linux/macOS uses CLOCK_MONOTONIC_RAW or CLOCK_MONOTONIC; falls back to
  3145. // CLOCK_REALTIME if neither is available.
  3146. uint64_t mg_millis(void);
  3147. // Boot timestamp in ms since Epoch. 0 until the first successful SNTP sync;
  3148. // updated automatically by mg_sntp_connect() on each successful response.
  3149. extern uint64_t mg_boot_timestamp_ms;
  3150. // Return milliseconds since Epoch: mg_millis() + mg_boot_timestamp_ms.
  3151. // Until a successful SNTP request completes, this is identical to mg_millis().
  3152. uint64_t mg_now(void);
  3153. // Checks whether a periodic deadline has expired.
  3154. //
  3155. // Returns:
  3156. // True when the timer has fired; false otherwise.
  3157. // Example:
  3158. // uint64_t timer = 0;
  3159. // if (mg_timer_expired(&timer, 1000, mg_millis())) {
  3160. // MG_INFO(("every second"));
  3161. // }
  3162. // Full examples:
  3163. // tutorials/http/http-server/arduino/teensy41-http,
  3164. // tutorials/mqtt/mqtt-client
  3165. // Related APIs:
  3166. // mg_millis(), mg_now()
  3167. // Notes:
  3168. // Initialise *expiration to 0 before first use. On expiry, this function
  3169. // advances *expiration by period and handles time wrap-around.
  3170. bool mg_timer_expired(uint64_t *expiration, uint64_t period, uint64_t now);
  3171. // Connect to an SNTP server and send a time request.
  3172. // `url` defaults to "udp://time.google.com:123" when NULL.
  3173. // On success the internal boot timestamp is updated so that mg_now() returns
  3174. // the correct wall-clock time, and MG_EV_SNTP_TIME is fired on `fn` (if not
  3175. // NULL) with ev_data pointing to a uint64_t containing the epoch in milliseconds.
  3176. // Pass fn == NULL and fn_data == NULL for a fire-and-forget sync that only
  3177. // updates mg_boot_timestamp_ms. Typical polling usage:
  3178. //
  3179. // ```c
  3180. // uint64_t timer = 0;
  3181. // for (;;) {
  3182. // uint64_t period = mg_boot_timestamp_ms == 0 ? 1000 : 3600 * 1000;
  3183. // if (mg_timer_expired(&timer, period, mg_millis())) {
  3184. // mg_sntp_connect(&mgr, NULL, NULL, NULL);
  3185. // }
  3186. // mg_mgr_poll(&mgr, 1000);
  3187. // }
  3188. // ```
  3189. struct mg_connection *mg_sntp_connect(struct mg_mgr *mgr, const char *url,
  3190. mg_event_handler_t fn, void *fn_data);
  3191. // Private API, do not expose
  3192. void mg_sntp_request(struct mg_connection *c);
  3193. int64_t mg_sntp_parse(const unsigned char *buf, size_t len);
  3194. // MQTT packet type codes. The received command is in mg_mqtt_message.cmd.
  3195. #define MQTT_CMD_CONNECT 1
  3196. #define MQTT_CMD_CONNACK 2
  3197. #define MQTT_CMD_PUBLISH 3
  3198. #define MQTT_CMD_PUBACK 4
  3199. #define MQTT_CMD_PUBREC 5
  3200. #define MQTT_CMD_PUBREL 6
  3201. #define MQTT_CMD_PUBCOMP 7
  3202. #define MQTT_CMD_SUBSCRIBE 8
  3203. #define MQTT_CMD_SUBACK 9
  3204. #define MQTT_CMD_UNSUBSCRIBE 10
  3205. #define MQTT_CMD_UNSUBACK 11
  3206. #define MQTT_CMD_PINGREQ 12
  3207. #define MQTT_CMD_PINGRESP 13
  3208. #define MQTT_CMD_DISCONNECT 14
  3209. #define MQTT_CMD_AUTH 15
  3210. // MQTT5 property IDs. Used in mg_mqtt_prop.id.
  3211. #define MQTT_PROP_PAYLOAD_FORMAT_INDICATOR 0x01
  3212. #define MQTT_PROP_MESSAGE_EXPIRY_INTERVAL 0x02
  3213. #define MQTT_PROP_CONTENT_TYPE 0x03
  3214. #define MQTT_PROP_RESPONSE_TOPIC 0x08
  3215. #define MQTT_PROP_CORRELATION_DATA 0x09
  3216. #define MQTT_PROP_SUBSCRIPTION_IDENTIFIER 0x0B
  3217. #define MQTT_PROP_SESSION_EXPIRY_INTERVAL 0x11
  3218. #define MQTT_PROP_ASSIGNED_CLIENT_IDENTIFIER 0x12
  3219. #define MQTT_PROP_SERVER_KEEP_ALIVE 0x13
  3220. #define MQTT_PROP_AUTHENTICATION_METHOD 0x15
  3221. #define MQTT_PROP_AUTHENTICATION_DATA 0x16
  3222. #define MQTT_PROP_REQUEST_PROBLEM_INFORMATION 0x17
  3223. #define MQTT_PROP_WILL_DELAY_INTERVAL 0x18
  3224. #define MQTT_PROP_REQUEST_RESPONSE_INFORMATION 0x19
  3225. #define MQTT_PROP_RESPONSE_INFORMATION 0x1A
  3226. #define MQTT_PROP_SERVER_REFERENCE 0x1C
  3227. #define MQTT_PROP_REASON_STRING 0x1F
  3228. #define MQTT_PROP_RECEIVE_MAXIMUM 0x21
  3229. #define MQTT_PROP_TOPIC_ALIAS_MAXIMUM 0x22
  3230. #define MQTT_PROP_TOPIC_ALIAS 0x23
  3231. #define MQTT_PROP_MAXIMUM_QOS 0x24
  3232. #define MQTT_PROP_RETAIN_AVAILABLE 0x25
  3233. #define MQTT_PROP_USER_PROPERTY 0x26
  3234. #define MQTT_PROP_MAXIMUM_PACKET_SIZE 0x27
  3235. #define MQTT_PROP_WILDCARD_SUBSCRIPTION_AVAILABLE 0x28
  3236. #define MQTT_PROP_SUBSCRIPTION_IDENTIFIER_AVAILABLE 0x29
  3237. #define MQTT_PROP_SHARED_SUBSCRIPTION_AVAILABLE 0x2A
  3238. // Property value types used internally to encode/decode MQTT5 properties.
  3239. enum {
  3240. MQTT_PROP_TYPE_BYTE,
  3241. MQTT_PROP_TYPE_STRING,
  3242. MQTT_PROP_TYPE_STRING_PAIR,
  3243. MQTT_PROP_TYPE_BINARY_DATA,
  3244. MQTT_PROP_TYPE_VARIABLE_INT,
  3245. MQTT_PROP_TYPE_INT,
  3246. MQTT_PROP_TYPE_SHORT
  3247. };
  3248. // Return codes from mg_mqtt_parse().
  3249. enum { MQTT_OK, MQTT_INCOMPLETE, MQTT_MALFORMED };
  3250. // A single MQTT5 property. Use in mg_mqtt_opts.props / mg_mqtt_opts.will_props
  3251. // arrays, and iterate received properties with mg_mqtt_next_prop().
  3252. struct mg_mqtt_prop {
  3253. uint8_t id; // Property ID, one of MQTT_PROP_*
  3254. uint32_t iv; // Integer value for BYTE, SHORT, INT, VARIABLE_INT types
  3255. struct mg_str key; // Property key string; only set for USER_PROPERTY pairs
  3256. struct mg_str val; // String/binary value; set for STRING, BINARY_DATA, and USER_PROPERTY
  3257. };
  3258. // Options passed to mg_mqtt_connect(), mg_mqtt_pub(), mg_mqtt_sub(),
  3259. // mg_mqtt_unsub(), and mg_mqtt_disconnect(). Zero-initialise and set only
  3260. // the fields relevant to the operation being called.
  3261. struct mg_mqtt_opts {
  3262. struct mg_str user; // CONNECT: username; empty = omit
  3263. struct mg_str pass; // CONNECT: password; empty = omit
  3264. struct mg_str client_id; // CONNECT: client ID; empty = auto-generate
  3265. struct mg_str topic; // CONNECT: will topic; PUBLISH/SUBSCRIBE/UNSUBSCRIBE: topic
  3266. struct mg_str message; // CONNECT: will payload; PUBLISH: message payload
  3267. uint8_t qos; // QoS level: 0, 1, or 2
  3268. uint8_t version; // MQTT version: 4 (3.1.1) or 5; 0 defaults to 4
  3269. uint16_t keepalive; // CONNECT: keepalive interval in seconds; 0 = no timeout
  3270. uint16_t retransmit_id; // PUBLISH: packet ID for retransmit; init to 0 for new message
  3271. bool retain; // PUBLISH/CONNECT will: set the retain flag
  3272. bool clean; // CONNECT: start a clean session
  3273. struct mg_mqtt_prop *props; // MQTT5: properties array; NULL if none
  3274. size_t num_props; // MQTT5: number of entries in props
  3275. struct mg_mqtt_prop *will_props; // MQTT5 CONNECT: will properties; NULL if none
  3276. size_t num_will_props; // MQTT5: number of entries in will_props
  3277. };
  3278. // Received MQTT message. Passed as ev_data for MG_EV_MQTT_MSG (PUBLISH),
  3279. // MG_EV_MQTT_CMD (all packets), and MG_EV_MQTT_OPEN (CONNACK).
  3280. // topic, data, and dgram are zero-copy slices into the receive buffer; they
  3281. // are only valid until the next mg_mgr_poll() call.
  3282. struct mg_mqtt_message {
  3283. struct mg_str topic; // PUBLISH: message topic; slice into dgram
  3284. struct mg_str data; // PUBLISH: message payload; slice into dgram
  3285. struct mg_str dgram; // Complete raw MQTT packet, including fixed header
  3286. uint16_t id; // Packet ID; set for QoS>0 PUBLISH, PUBACK, PUBREC, PUBREL, PUBCOMP, SUBACK, UNSUBACK
  3287. uint8_t cmd; // Packet type, one of MQTT_CMD_*
  3288. uint8_t qos; // QoS level extracted from the PUBLISH fixed header
  3289. uint8_t ack; // CONNACK return code; 0 = success
  3290. size_t props_start; // MQTT5: byte offset from dgram.buf to start of properties
  3291. size_t props_size; // MQTT5: byte length of the properties section
  3292. };
  3293. // Opens an MQTT client connection and sends a CONNECT packet.
  3294. //
  3295. // Returns:
  3296. // Client connection, or NULL on error.
  3297. // Example:
  3298. // struct mg_mqtt_opts opts = {.client_id = mg_str("device1")};
  3299. // mg_mqtt_connect(&mgr, "mqtt://broker:1883", &opts, fn, NULL);
  3300. // Full examples:
  3301. // tutorials/mqtt/mqtt-client, tutorials/mqtt/mqtt-client-aws-iot,
  3302. // tutorials/mqtt/ota-over-mqtt
  3303. // Related APIs:
  3304. // mg_mqtt_pub(), mg_mqtt_sub(), mg_tls_init(), mg_mgr_poll()
  3305. // Notes:
  3306. // opts may be NULL to use MQTT 3.1.1 defaults with no auth and an auto client
  3307. // ID. The user-supplied fn event handler receives normal connection events,
  3308. // MG_EV_MQTT_OPEN when CONNACK is received, MG_EV_MQTT_MSG for incoming
  3309. // PUBLISH packets, and MG_EV_MQTT_CMD for every received MQTT packet.
  3310. struct mg_connection *mg_mqtt_connect(struct mg_mgr *, const char *url,
  3311. const struct mg_mqtt_opts *opts,
  3312. mg_event_handler_t fn, void *fn_data);
  3313. // Creates an MQTT server listener on url.
  3314. // Fires MG_EV_MQTT_CMD for each complete packet received (ev_data: struct mg_mqtt_message *).
  3315. // Returns NULL on error.
  3316. struct mg_connection *mg_mqtt_listen(struct mg_mgr *mgr, const char *url,
  3317. mg_event_handler_t fn, void *fn_data);
  3318. // Sends a CONNECT packet on an already-open connection.
  3319. // Called automatically by mg_mqtt_connect(); exposed for advanced use such
  3320. // as re-authenticating on an existing connection.
  3321. void mg_mqtt_login(struct mg_connection *c, const struct mg_mqtt_opts *opts);
  3322. // Sends an MQTT PUBLISH packet.
  3323. //
  3324. // Returns:
  3325. // 0 for QoS 0; assigned packet ID for QoS 1 or 2.
  3326. // Example:
  3327. // struct mg_mqtt_opts opts = {
  3328. // .topic = mg_str("device/status"),
  3329. // .message = mg_str("{\"ok\":true}"),
  3330. // .qos = 1,
  3331. // };
  3332. // uint16_t id = mg_mqtt_pub(c, &opts);
  3333. // Full examples:
  3334. // tutorials/mqtt/mqtt-client, tutorials/mqtt/mqtt-client-aws-iot,
  3335. // tutorials/mqtt/ota-over-mqtt
  3336. // Related APIs:
  3337. // mg_mqtt_connect(), mg_mqtt_sub(), mg_mqtt_send_header()
  3338. // Notes:
  3339. // On success, opts.topic and opts.message are copied into c->send before the
  3340. // function returns. To retransmit a QoS message, set opts.retransmit_id to the
  3341. // packet ID returned by the previous call; use 0 for a new message.
  3342. uint16_t mg_mqtt_pub(struct mg_connection *c, const struct mg_mqtt_opts *opts);
  3343. // Sends an MQTT SUBSCRIBE packet.
  3344. //
  3345. // Example:
  3346. // struct mg_mqtt_opts opts = {.topic = mg_str("device/rx"), .qos = 1};
  3347. // mg_mqtt_sub(c, &opts);
  3348. // Full examples:
  3349. // tutorials/mqtt/mqtt-client, tutorials/mqtt/mqtt-client-aws-iot,
  3350. // tutorials/mqtt/ota-over-mqtt
  3351. // Related APIs:
  3352. // mg_mqtt_connect(), mg_mqtt_pub(), mg_mqtt_unsub()
  3353. // Notes:
  3354. // Send after MG_EV_MQTT_OPEN reports a successful CONNACK. Incoming PUBLISH
  3355. // messages are delivered to the user-supplied fn event handler as
  3356. // MG_EV_MQTT_MSG with ev_data pointing to struct mg_mqtt_message.
  3357. void mg_mqtt_sub(struct mg_connection *, const struct mg_mqtt_opts *opts);
  3358. // Sends an UNSUBSCRIBE packet for opts.topic.
  3359. void mg_mqtt_unsub(struct mg_connection *c, const struct mg_mqtt_opts *opts);
  3360. // Parses a raw MQTT packet in buf/len. version must be 4 (MQTT 3.1.1) or 5.
  3361. // On success, fills *m; topic, data, and dgram slice into buf (zero-copy).
  3362. // Returns MQTT_OK, MQTT_INCOMPLETE (need more data), or MQTT_MALFORMED.
  3363. int mg_mqtt_parse(const uint8_t *, size_t, uint8_t, struct mg_mqtt_message *);
  3364. // Low-level helper: sends the MQTT fixed header (command byte and
  3365. // variable-length remaining-length field). Call before writing the PDU body.
  3366. // cmd: MQTT_CMD_*; flags: low 4 bits of the first byte; len: remaining length.
  3367. void mg_mqtt_send_header(struct mg_connection *, uint8_t cmd, uint8_t flags,
  3368. uint32_t len);
  3369. // Sends a PINGREQ packet.
  3370. void mg_mqtt_ping(struct mg_connection *);
  3371. // Sends a PINGRESP packet.
  3372. void mg_mqtt_pong(struct mg_connection *);
  3373. // Sends a DISCONNECT packet. For MQTT5, opts.props can carry reason
  3374. // properties. opts may be NULL for a plain disconnect with no properties.
  3375. void mg_mqtt_disconnect(struct mg_connection *, const struct mg_mqtt_opts *);
  3376. // Iterates MQTT5 properties in a received message. Start with ofs=0; pass
  3377. // the returned value back on each successive call. Returns 0 when done.
  3378. // Fills *prop with each property; key and val are zero-copy slices into msg->dgram.
  3379. size_t mg_mqtt_next_prop(struct mg_mqtt_message *, struct mg_mqtt_prop *,
  3380. size_t ofs);
  3381. // DNS record types, used in mg_dns_rr.atype and mg_mdns_query().
  3382. #define MG_DNS_RTYPE_A 1 // IPv4 address (4 bytes)
  3383. #define MG_DNS_RTYPE_PTR 12 // Domain name pointer, used for reverse lookups and service discovery
  3384. #define MG_DNS_RTYPE_TXT 16 // Arbitrary text, used by DNS-SD for service metadata
  3385. #define MG_DNS_RTYPE_AAAA 28 // IPv6 address (16 bytes)
  3386. #define MG_DNS_RTYPE_SRV 33 // Service location: priority, weight, port, target hostname
  3387. // Mongoose sends DNS queries that contain only one question:
  3388. // either A (IPv4) or AAAA (IPv6) address lookup.
  3389. // Therefore, we expect zero or one answer.
  3390. // If `resolved` is true, then `addr` contains resolved IPv4 or IPV6 address.
  3391. struct mg_dns_message {
  3392. uint16_t txnid; // Transaction ID
  3393. bool resolved; // Resolve successful, addr is set
  3394. struct mg_addr addr; // Resolved address
  3395. char name[256]; // Host name
  3396. };
  3397. // DNS wire-format header (RFC 1035). All fields are in network byte order;
  3398. // use mg_ntohs() to read them.
  3399. struct mg_dns_header {
  3400. uint16_t txnid; // Transaction ID, matched between query and response
  3401. uint16_t flags; // Flags: bit15=QR (0=query,1=response), bit10=AA, bit8=RD
  3402. uint16_t num_questions; // Number of question records following the header
  3403. uint16_t num_answers; // Number of answer records in the response
  3404. uint16_t num_authority_prs; // Number of authority records
  3405. uint16_t num_other_prs; // Number of additional records
  3406. };
  3407. // Parsed DNS resource record fields, extracted from the wire format.
  3408. struct mg_dns_rr {
  3409. uint16_t nlen; // Byte length of the encoded name in the wire format
  3410. uint16_t atype; // Record type: MG_DNS_RTYPE_A=1, AAAA=28, PTR=12, SRV=33, TXT=16
  3411. uint16_t aclass; // Record class: 1=INET; mDNS queries: bit15=QU (unicast request)
  3412. uint16_t alen; // Byte length of the RDATA section (e.g. 4 for A, 16 for AAAA)
  3413. };
  3414. // DNS-SD service description. Used by the user to describe a service to advertise.
  3415. struct mg_dnssd_record {
  3416. struct mg_str srvcproto; // Service and protocol label, e.g. "_http._tcp"
  3417. struct mg_str txt; // TXT record contents, verbatim
  3418. uint16_t port; // Port number for the SRV record
  3419. };
  3420. // ev_data for MG_EV_MDNS_REQ. The handler must set is_resp=true and fill r
  3421. // (and optionally respname/addr) to send a response; leave is_resp=false to ignore.
  3422. struct mg_mdns_req {
  3423. struct mg_dns_rr *rr; // Parsed resource record from the incoming query
  3424. struct mg_dnssd_record *r; // User-supplied service record to include in the response
  3425. struct mg_str reqname; // Queried hostname, without the .local suffix
  3426. struct mg_str respname; // Hostname to use in response; defaults to fn_data if empty
  3427. struct mg_addr *addr; // IP address for A record; uses local interface if NULL
  3428. bool is_listing; // True if this is a service-discovery listing (_services._dns-sd._udp)
  3429. bool is_resp; // Set to true in the handler to trigger a response
  3430. bool is_unicast; // True if the client requested a unicast (QU) response
  3431. };
  3432. // ev_data for MG_EV_MDNS_RESP, carrying address/data from a mDNS response
  3433. struct mg_mdns_resp {
  3434. struct mg_dns_rr *rr; // Resource record from the response (1st in chain)
  3435. struct mg_str name; // Resolved hostname, without the .local suffix
  3436. struct mg_addr addr; // Resolved IP address
  3437. struct mg_dnssd_record sd; // Service Discovery data
  3438. };
  3439. // Parses a DNS query or response from buf/len into dm. Returns true on success.
  3440. // On a response, sets dm->resolved=true and fills dm->addr if an A/AAAA record
  3441. // is found. Always fills dm->txnid and dm->name. Rejects packets larger than 512 bytes.
  3442. bool mg_dns_parse(const uint8_t *buf, size_t len, struct mg_dns_message *dm);
  3443. // Parses one DNS record at offset ofs in buf/len into rr. Set is_question=true
  3444. // for question records (no RDATA), false for answer records. Returns the number
  3445. // of bytes consumed (use to advance ofs), or 0 on error.
  3446. size_t mg_dns_parse_rr(const uint8_t *buf, size_t len, size_t ofs,
  3447. bool is_question, struct mg_dns_rr *rr);
  3448. // Creates an mDNS listener on UDP multicast 224.0.0.251:5353. Registers it as
  3449. // the manager's mDNS resolver (mgr->mdns). Fires MG_EV_MDNS_REQ for incoming
  3450. // queries and MG_EV_MDNS_RESP for incoming responses. Returns NULL on error.
  3451. // fn_data is a NUL-terminated server name, or NULL to pass all requests to fn.
  3452. struct mg_connection *mg_mdns_listen(struct mg_mgr *mgr, mg_event_handler_t fn,
  3453. void *fn_data);
  3454. // Sends an mDNS query on connection c (from mg_mdns_listen()) for name, with
  3455. // record type rtype (e.g. MG_DNS_RTYPE_A). Returns false on send error.
  3456. bool mg_mdns_query(struct mg_connection *c, const char *name, unsigned int rtype);
  3457. // Private API, do not expose or call in the user app
  3458. void mg_resolve(struct mg_connection *, const char *url);
  3459. void mg_resolve_cancel(struct mg_connection *);
  3460. // Modbus TCP function codes passed in mg_modbus_req.func.
  3461. #define MG_MODBUS_FUNC_READ_COILS 1 // Read 1-2000 discrete output coils
  3462. #define MG_MODBUS_FUNC_READ_DISCRETE_INPUTS 2 // Read 1-2000 discrete input coils
  3463. #define MG_MODBUS_FUNC_READ_HOLDING_REGISTERS 3 // Read 1-125 holding registers
  3464. #define MG_MODBUS_FUNC_READ_INPUT_REGISTERS 4 // Read 1-125 input registers
  3465. #define MG_MODBUS_FUNC_WRITE_SINGLE_COIL 5 // Write one output coil
  3466. #define MG_MODBUS_FUNC_WRITE_SINGLE_REGISTER 6 // Write one holding register
  3467. #define MG_MODBUS_FUNC_WRITE_MULTIPLE_COILS 15 // Write 1-1968 output coils
  3468. #define MG_MODBUS_FUNC_WRITE_MULTIPLE_REGISTERS 16 // Write 1-123 holding registers
  3469. // Standard Modbus exception codes. Set mg_modbus_req.error to one of these
  3470. // in the MG_EV_MODBUS_REQ handler to return an exception response to the client.
  3471. #define MG_MODBUS_ERR_NONE 0 // No error; send a normal response
  3472. #define MG_MODBUS_ERR_ILLEGAL_FUNCTION 1 // Function code not supported
  3473. #define MG_MODBUS_ERR_ILLEGAL_ADDRESS 2 // Starting address or range out of bounds
  3474. #define MG_MODBUS_ERR_ILLEGAL_VALUE 3 // Data value not accepted
  3475. #define MG_MODBUS_ERR_DEVICE_FAILURE 4 // Unrecoverable device error
  3476. // Modbus request passed as ev_data to the MG_EV_MODBUS_REQ event handler.
  3477. //
  3478. // For READ functions (READ_COILS, READ_DISCRETE_INPUTS, READ_HOLDING_REGISTERS,
  3479. // READ_INPUT_REGISTERS): u.bits / u.regs points to a zeroed, heap-allocated
  3480. // array of len entries. The handler fills in the values to return.
  3481. //
  3482. // For WRITE functions: u.bits / u.regs is pre-populated from the client
  3483. // request. len=1 for single-write functions.
  3484. //
  3485. // Do NOT free u.bits or u.regs - the library frees them after the handler
  3486. // returns and the response has been sent.
  3487. //
  3488. // Set error to a non-zero MG_MODBUS_ERR_* code to send an exception response
  3489. // instead of a data response. The response is sent automatically on return.
  3490. struct mg_modbus_req {
  3491. uint8_t func; // Function code, one of MG_MODBUS_FUNC_*
  3492. uint8_t error; // Exception code; set to MG_MODBUS_ERR_* to return an error
  3493. uint16_t addr; // Starting coil/register address from the request
  3494. union {
  3495. bool *bits; // Coil values; used by coil function codes
  3496. uint16_t *regs; // Register values; used by register function codes
  3497. } u;
  3498. uint16_t len; // Number of entries in u.bits or u.regs
  3499. };
  3500. // Creates a Modbus TCP listener on url. Fires MG_EV_MODBUS_REQ for each
  3501. // complete request; ev_data is struct mg_modbus_req *. Returns the listening
  3502. // connection, or NULL on error.
  3503. struct mg_connection *mg_modbus_listen(struct mg_mgr *mgr, const char *url,
  3504. mg_event_handler_t fn, void *fn_data);
  3505. // Maximum JSON nesting depth. mg_json_get() returns MG_JSON_TOO_DEEP if
  3506. // the path traverses more than this many nested objects/arrays.
  3507. #ifndef MG_JSON_MAX_DEPTH
  3508. #define MG_JSON_MAX_DEPTH 30
  3509. #endif
  3510. // Error codes returned by mg_json_get(). Successful returns are >= 0.
  3511. enum { MG_JSON_TOO_DEEP = -1, MG_JSON_INVALID = -2, MG_JSON_NOT_FOUND = -3 };
  3512. // Low-level token locator. Finds the JSON token at path inside json and
  3513. // returns its byte offset in json.buf. Sets *toklen to the token length.
  3514. // toklen may be NULL if only a presence check is needed.
  3515. // path must start with "$" (root). Use ".key" for object fields and "[N]"
  3516. // for array indices. Example: "$.items[0].name"
  3517. // Returns MG_JSON_NOT_FOUND, MG_JSON_INVALID, or MG_JSON_TOO_DEEP on error.
  3518. int mg_json_get(struct mg_str json, const char *path, int *toklen);
  3519. // Returns the raw JSON token at path.
  3520. //
  3521. // Returns:
  3522. // Zero-copy mg_str slice into json.buf, or {NULL, 0} if not found or invalid.
  3523. // Example:
  3524. // struct mg_str tok = mg_json_get_tok(body, "$.device.name");
  3525. // Full examples:
  3526. // src/dash.c
  3527. // Related APIs:
  3528. // mg_json_get(), mg_json_get_str(), mg_json_unescape()
  3529. // Notes:
  3530. // The returned token is not NUL-terminated. String tokens include the
  3531. // surrounding double quotes and escape sequences; use mg_json_unescape() or
  3532. // mg_json_get_str() when you need decoded string content.
  3533. struct mg_str mg_json_get_tok(struct mg_str json, const char *path);
  3534. // Parses a numeric JSON value at path into *v.
  3535. // Returns true and sets *v on success. Returns false if not found or not a
  3536. // number. v may be NULL to check existence only.
  3537. bool mg_json_get_num(struct mg_str json, const char *path, double *v);
  3538. // Parses a boolean JSON value at path into *v.
  3539. // Returns true and sets *v on success. Returns false if not found or not a
  3540. // boolean literal. v may be NULL to check existence only.
  3541. bool mg_json_get_bool(struct mg_str json, const char *path, bool *v);
  3542. // Returns a JSON number at path as a long, or dflt if not found or not a
  3543. // number. Use mg_json_get_num() when you need to distinguish missing from 0.
  3544. long mg_json_get_long(struct mg_str json, const char *path, long dflt);
  3545. // Returns a heap-allocated, NUL-terminated, JSON-unescaped copy of the string
  3546. // at path. Caller must mg_free() the result. Returns NULL if not found or the
  3547. // token is not a JSON string.
  3548. char *mg_json_get_str(struct mg_str json, const char *path);
  3549. // Decodes a hex-encoded JSON string at path into a heap-allocated byte array.
  3550. // Sets *len to the decoded byte count. Caller must mg_free() the result.
  3551. // Returns NULL if not found, not a string, or not valid hexadecimal.
  3552. char *mg_json_get_hex(struct mg_str json, const char *path, int *len);
  3553. // Decodes a base64-encoded JSON string at path into a heap-allocated byte
  3554. // array. Sets *len to the decoded byte count. Caller must mg_free() the result.
  3555. // Returns NULL if not found or not a string.
  3556. char *mg_json_get_b64(struct mg_str json, const char *path, int *len);
  3557. // Writes a JSON-unescaped string value at path into a caller-supplied buffer.
  3558. //
  3559. // Returns:
  3560. // Number of bytes written excluding the NUL, or 0 on error, not found,
  3561. // non-string token, too-small buffer, or an empty string.
  3562. // Example:
  3563. // char name[32];
  3564. // mg_json_unescape(body, "$.device.name", name, sizeof(name));
  3565. // Full examples:
  3566. // src/dash.c, src/ota.c
  3567. // Related APIs:
  3568. // mg_json_get_tok(), mg_json_get_str(), mg_json_get_num()
  3569. // Notes:
  3570. // On success, NUL-terminates when n > 0. The destination buffer is owned by
  3571. // the caller. Only string tokens are unescaped; other token types return 0.
  3572. size_t mg_json_unescape(struct mg_str json, const char *path, char *, size_t);
  3573. // Sequential iterator over a JSON object or array. Start with ofs=0.
  3574. // Each call fills *key and *val with the next entry and returns the new ofs
  3575. // to pass on the next call. Returns 0 when there are no more entries.
  3576. // For arrays, *key is set to {NULL, 0}. For objects, *key is the raw
  3577. // quoted key (e.g. "\"name\""). *val is the raw unparsed token.
  3578. size_t mg_json_next(struct mg_str obj, size_t ofs, struct mg_str *key,
  3579. struct mg_str *val);
  3580. struct mg_jwt_opts {
  3581. struct mg_str claims; // JSON payload
  3582. struct mg_str header; // Extra header members, no braces; alg/typ are set
  3583. struct mg_str kid; // Key ID protected header
  3584. struct mg_str secret; // HS256 secret
  3585. const uint8_t *private_key; // ES256 private key (MG_TLS_BUILTIN only)
  3586. const uint8_t *public_key; // ES256 public key (MG_TLS_BUILTIN only)
  3587. };
  3588. // Signs JSON claims as a compact JWT. Returns JWT length, or 0 on error.
  3589. size_t mg_jwt_sign_hs256(const struct mg_jwt_opts *opts, char *buf,
  3590. size_t len);
  3591. // Verifies JWT and decodes JSON claims into buf. Returns claims length, or 0.
  3592. size_t mg_jwt_verify_hs256(struct mg_str jwt, const struct mg_jwt_opts *opts,
  3593. char *buf, size_t len);
  3594. size_t mg_jwt_sign_es256(const struct mg_jwt_opts *opts, char *buf,
  3595. size_t len);
  3596. size_t mg_jwt_verify_es256(struct mg_str jwt, const struct mg_jwt_opts *opts,
  3597. char *buf, size_t len);
  3598. // In-flight JSON-RPC request. Populate and pass to mg_rpc_process() to
  3599. // dispatch, or receive one pre-filled in a handler registered with mg_rpc_add().
  3600. struct mg_rpc_req {
  3601. struct mg_rpc **head; // Head of the handler list; allows handlers to call other RPCs
  3602. struct mg_rpc *rpc; // Handler that matched this request; set by mg_rpc_process()
  3603. mg_pfn_t pfn; // Output function for the response (e.g. mg_pfn_iobuf)
  3604. void *pfn_data; // Argument passed to pfn (e.g. pointer to an mg_iobuf)
  3605. void *req_data; // Arbitrary caller data, not touched by the RPC layer
  3606. struct mg_str frame; // Raw JSON-RPC frame, e.g. {"id":1,"method":"add","params":[1,2]}
  3607. };
  3608. // A registered JSON-RPC method handler. Managed by mg_rpc_add/del; do not
  3609. // allocate directly. method is a glob pattern matched via mg_match().
  3610. struct mg_rpc {
  3611. struct mg_rpc *next; // Next handler in the linked list
  3612. struct mg_str method; // Method name glob pattern (heap-allocated copy)
  3613. void (*fn)(struct mg_rpc_req *); // Handler function called on a match
  3614. void *fn_data; // Passed to fn as r->rpc->fn_data
  3615. };
  3616. // Allocates a handler entry and prepends it to *head. method_pattern is
  3617. // copied (mg_strdup). Glob patterns are supported, e.g. "get/*".
  3618. // To receive JSON-RPC responses ($.result / $.error), register with method=""
  3619. void mg_rpc_add(struct mg_rpc **head, struct mg_str method_pattern,
  3620. void (*handler)(struct mg_rpc_req *), void *handler_data);
  3621. // Removes and frees all handlers in *head whose fn matches handler.
  3622. // Pass handler=NULL to remove every handler in the list.
  3623. void mg_rpc_del(struct mg_rpc **head, void (*handler)(struct mg_rpc_req *));
  3624. // Dispatches r->frame to the matching handler. Looks up "$.method" and calls
  3625. // the first handler whose pattern matches. If "$.result" or "$.error" is found
  3626. // instead (i.e. r->frame is a JSON-RPC response), dispatches to the "" handler.
  3627. // Sends a -32601 "not found" error if no handler matches, or -32700 on parse failure.
  3628. void mg_rpc_process(struct mg_rpc_req *);
  3629. // Sends a JSON-RPC success response: {"id":<id>,"result":<fmt>}.
  3630. // fmt is a printf-style format string written to r->pfn; NULL sends "null".
  3631. // Does nothing if the request frame has no "id" field (notification).
  3632. void mg_rpc_ok(struct mg_rpc_req *, const char *fmt, ...);
  3633. void mg_rpc_vok(struct mg_rpc_req *, const char *fmt, va_list *ap);
  3634. // Sends a JSON-RPC error response: {"id":<id>,"error":{"code":<code>,"message":<fmt>}}.
  3635. // fmt is a printf-style format string; NULL sends "null" as the message.
  3636. // The "id" field is omitted if the request had none; the error is always sent.
  3637. void mg_rpc_err(struct mg_rpc_req *, int code, const char *fmt, ...);
  3638. void mg_rpc_verr(struct mg_rpc_req *, int code, const char *fmt, va_list *);
  3639. // Built-in handler: responds with a JSON array of all registered method names.
  3640. // Register it as a method handler, e.g. mg_rpc_add(&head, mg_str("rpc.list"), mg_rpc_list, NULL);
  3641. void mg_rpc_list(struct mg_rpc_req *r);
  3642. #ifndef MG_DASH_MAX_USER_NAME
  3643. #define MG_DASH_MAX_USER_NAME 32
  3644. #endif
  3645. #ifndef MG_HTTP_ADDR
  3646. #if MG_ARCH == MG_ARCH_UNIX || MG_ARCH == MG_ARCH_WIN32
  3647. #define MG_HTTP_ADDR "http://0.0.0.0:8000"
  3648. #define MG_HTTPS_ADDR "https://0.0.0.0:8443"
  3649. #define MG_MODBUS_ADDR "tcp://0.0.0.0:8502"
  3650. #else
  3651. #define MG_HTTP_ADDR "http://0.0.0.0:80"
  3652. #define MG_HTTPS_ADDR "http://0.0.0.0:443"
  3653. #define MG_MODBUS_ADDR "tcp://0.0.0.0:502"
  3654. #endif
  3655. #endif
  3656. #ifndef MG_DASH_MAX_SEND_BUF_SIZE
  3657. #define MG_DASH_MAX_SEND_BUF_SIZE (MG_IO_SIZE * 5)
  3658. #endif
  3659. // C type of a value bound to a dashboard field, see struct mg_field
  3660. enum mg_val_type {
  3661. MG_VAL_INT, // int
  3662. MG_VAL_UINT64, // uint64_t
  3663. MG_VAL_BOOL, // bool
  3664. MG_VAL_DBL, // double
  3665. MG_VAL_STR, // Zero-terminated string
  3666. MG_VAL_RAW, // Pre-formatted JSON value, copied verbatim
  3667. };
  3668. // Dashboard field: binds a JSON key to a C variable for read and/or write
  3669. struct mg_field {
  3670. const char *name; // JSON key
  3671. enum mg_val_type type; // C type of the value, see enum mg_val_type
  3672. void *value; // Pointer to the bound variable
  3673. size_t value_size; // sizeof(*value) for type checking; 0 makes it read-only
  3674. };
  3675. // Operation passed to a struct mg_field_set read/write/delete/add callback.
  3676. // MG_DASH_ADD: fields hold the values of a new element to append; *index is
  3677. // not set. Return true to accept and persist it, false to reject (e.g. a cap
  3678. // was reached)
  3679. enum mg_dash_op { MG_DASH_READ, MG_DASH_WRITE, MG_DASH_DELETE, MG_DASH_ADD };
  3680. struct mg_dash;
  3681. // Authenticated (or guest) dashboard user
  3682. struct mg_dash_user {
  3683. struct mg_dash_user *next; // Next user in the list
  3684. char name[MG_DASH_MAX_USER_NAME]; // Username
  3685. char token[21]; // Session token, sent to the client as a cookie
  3686. int level; // Access level, see struct mg_dash::authenticate
  3687. uint64_t expire; // Session expiration time, see mg_millis()
  3688. struct mg_dash *dash; // Dashboard this user belongs to
  3689. };
  3690. // Named group of related dashboard fields, e.g. "settings" or "metrics"
  3691. struct mg_field_set {
  3692. const char *name; // Set name, used as a JSON key
  3693. struct mg_field *fields; // Zero-terminated array of fields
  3694. bool (*fn)(enum mg_dash_op op,
  3695. struct mg_dash_user *u); // Read/write/delete/add callback
  3696. int *index; // Non-NULL: array set. *index is set before fn(READ) call;
  3697. // fn sets *index = -1 to signal end of iteration.
  3698. // Size query: framework sets *index = -1 before fn(READ); fn
  3699. // sets *index = total size
  3700. bool (*get_dir)(const struct mg_dash_user *u, char *buf,
  3701. size_t len); // Non-NULL: file array
  3702. struct mg_field_set *next; // Next set in the list
  3703. };
  3704. // Custom URI handler, registered with MG_DASH_REGISTER_CUSTOM_HANDLER()
  3705. struct mg_dash_custom_handler {
  3706. struct mg_dash_custom_handler *next; // Next handler in the list
  3707. struct mg_str uri_pattern; // URI to match, see mg_match()
  3708. mg_event_handler_t handler; // Event handler function
  3709. void *handler_data; // Opaque data for the handler
  3710. };
  3711. // Dashboard instance: fields, users and handlers served over HTTP and WS
  3712. struct mg_dash {
  3713. struct mg_field_set *sets; // Field sets, see MG_DASH_ADD_FIELD_SET()
  3714. struct mg_dash_custom_handler *custom_handlers; // Custom URI handlers
  3715. // Validates pass, fills in user, returns access level (<= 0: failure).
  3716. // NULL: no login required, all clients get guest access
  3717. int (*authenticate)(char *user, size_t userlen, const char *pass);
  3718. int session_auto_expiration_seconds; // Session lifetime, 0: 1 hour default
  3719. struct mg_dash_user *guest; // Used when authenticate == NULL
  3720. struct mg_fs *upload_fs; // FS for uploads/listing, default &mg_fs_posix
  3721. };
  3722. #define MG_DASH_ADD_FIELD_SET(dash_, set_) \
  3723. do { \
  3724. (set_)->next = (dash_)->sets; \
  3725. (dash_)->sets = (set_); \
  3726. } while (0)
  3727. #define MG_DASH_REGISTER_CUSTOM_HANDLER(dash_, uri_, fn_, data_) \
  3728. do { \
  3729. static struct mg_dash_custom_handler ch_; \
  3730. ch_.next = (dash_)->custom_handlers; \
  3731. ch_.uri_pattern = mg_str(uri_); \
  3732. ch_.handler = (fn_); \
  3733. ch_.handler_data = (data_); \
  3734. (dash_)->custom_handlers = &ch_; \
  3735. } while (0)
  3736. // Dashboard event handler. Pass to mg_http_listen() as the fn argument
  3737. void mg_dash_ev_handler(struct mg_connection *c, int ev, void *ev_data);
  3738. // Notify WebSocket clients that a field set changed: broadcasts the new
  3739. // array size if *set->index < 0, or a single element update otherwise
  3740. void mg_dash_send_change(struct mg_mgr *mgr, struct mg_field_set *);
  3741. // Default reader for file-backed array sets (set->get_dir != NULL)
  3742. // Usage example - this is a complete implemenation of the file manager:
  3743. // ```c
  3744. // static struct file {
  3745. // int index;
  3746. // char name[64];
  3747. // size_t size;
  3748. // uint64_t checksum;
  3749. // } s_file;
  3750. // static struct mg_field_set set_files;
  3751. //
  3752. // static bool get_dir(const struct mg_dash_user *u, char *buf, size_t len) {
  3753. // (void) u;
  3754. // mkdir("/tmp/dashboard", 0755);
  3755. // mg_snprintf(buf, len, "%s", "/tmp/dashboard");
  3756. // return true;
  3757. // }
  3758. //
  3759. // static struct mg_field fields_files[] = {
  3760. // {"name", MG_VAL_STR, s_file.name, sizeof(s_file.name)},
  3761. // {"size", MG_VAL_UINT64, &s_file.size, 0},
  3762. // {"checksum", MG_VAL_UINT64, &s_file.checksum, sizeof(s_file.checksum)},
  3763. // {NULL, MG_VAL_INT, NULL, 0},
  3764. // };
  3765. //
  3766. // static bool files_fn(enum mg_dash_op op, struct mg_dash_user *u) {
  3767. // if (op == MG_DASH_WRITE) return s_uploads_enabled && u->level >= 7;
  3768. // if (op != MG_DASH_READ) return false;
  3769. // if (!mg_dash_dir_read(&set_files, u)) return false;
  3770. // s_file.checksum = 0; // Mock to show how to set custom fields
  3771. // return true;
  3772. // }
  3773. //
  3774. // static struct mg_field_set set_files = {"files", fields_files, files_fn, &s_file.index, get_dir, NULL};
  3775. // ```
  3776. bool mg_dash_dir_read(struct mg_field_set *set, struct mg_dash_user *u);
  3777. // Helper forward declarations for Mongoose CMSIS pack modules
  3778. extern struct mg_mgr g_mgr;
  3779. extern void mg_dash_init(struct mg_mgr *);
  3780. extern void mg_dash_poll(struct mg_mgr *);
  3781. extern void mg_mqtt_init(struct mg_mgr *);
  3782. extern void mg_mqtt_poll(struct mg_mgr *);
  3783. // Firmware OTA updates
  3784. //
  3785. // This is a low-level OTA API, not intended to be called directly by users.
  3786. // Users are provided with a higher-level API:
  3787. // - defining MG_OTA_URL enables HTTP or HTTPS pull-based updates
  3788. // - mg_http_start_ota() enables push-based updates
  3789. //
  3790. // However, it is possible to use the mg_ota_* API directly. Below is the
  3791. // example code of a function that is called repeatedly. It expects the
  3792. // last chink of size 0, which marks the end of the OTA process
  3793. //
  3794. // ```c
  3795. // static void ota(size_t total, size_t offset, void *buf, size_t len) {
  3796. // bool ok = false;
  3797. // if (ofs == 0 && (ok = mg_ota_begin(total)) == false) {
  3798. // mg_ota_end();
  3799. // } else if (len > 0 && (ok = mg_ota_write(buf, len)) == false) {
  3800. // mg_ota_end();
  3801. // } else if (len == 0) {}
  3802. // ok = mg_ota_end();
  3803. // }
  3804. // return ok;
  3805. // }
  3806. // ```
  3807. // Supported OTA targets
  3808. #define MG_OTA_NONE 0 // No OTA support
  3809. #define MG_OTA_STM32H5 1 // STM32 H5
  3810. #define MG_OTA_STM32H7 2 // STM32 H7
  3811. #define MG_OTA_STM32H7_DUAL_CORE 3 // STM32 H7 dual core
  3812. #define MG_OTA_STM32F 4 // STM32 F7/F4/F2
  3813. #define MG_OTA_CH32V307 100 // WCH CH32V307
  3814. #define MG_OTA_U2A 200 // Renesas U2A16, U2A8, U2A6
  3815. #define MG_OTA_RT1020 300 // IMXRT1020
  3816. #define MG_OTA_RT1050 301 // IMXRT1050
  3817. #define MG_OTA_RT1060 302 // IMXRT1060
  3818. #define MG_OTA_RT1064 303 // IMXRT1064
  3819. #define MG_OTA_RT1170 304 // IMXRT1170
  3820. #define MG_OTA_MCXN 310 // MCXN947
  3821. #define MG_OTA_RW612 320 // FRDM-RW612
  3822. #define MG_OTA_FLASH 900 // OTA via internal flash
  3823. #define MG_OTA_ESP32 910 // ESP32 OTA implementation
  3824. #define MG_OTA_PICOSDK 920 // RP2040/2350 using Pico-SDK hardware_flash
  3825. #define MG_OTA_CUSTOM 1000 // Custom implementation
  3826. // OTA target. Settable in mongoose_config.h
  3827. #ifndef MG_OTA
  3828. #define MG_OTA MG_OTA_NONE
  3829. #else
  3830. #ifndef MG_IRAM
  3831. #if defined(__GNUC__)
  3832. // Places code block in .iram ELF section. A linker script can place it in RAM
  3833. #define MG_IRAM __attribute__((noinline, section(".iram")))
  3834. #else
  3835. #define MG_IRAM
  3836. #endif // compiler
  3837. #endif // IRAM
  3838. #endif // OTA
  3839. // Starts the OTA process. Called once at the beginning of a firmware update.
  3840. bool mg_ota_begin(size_t new_firmware_size);
  3841. // Writes the next firmware chunk. Called repeatedly until all data is written.
  3842. bool mg_ota_write(const void *buf, size_t len);
  3843. // Ends the OTA process and commits the written firmware.
  3844. bool mg_ota_end(void);
  3845. // MG_OTA_ROLLBACK: swap firmware banks and reset. On flash-based OTA, the
  3846. // default calls swap_fn() (no-op on single-bank) then resets. Override in
  3847. // mongoose_config.h for platforms without mg_flash (ESP32, PicoSDK, etc.).
  3848. #ifndef MG_OTA_ROLLBACK
  3849. #define MG_OTA_ROLLBACK() \
  3850. do { \
  3851. mg_flash->swap_fn(); \
  3852. NVIC_SystemReset(); \
  3853. } while (0)
  3854. #endif
  3855. // Arm a hardware watchdog. mg_ota_poll() feeds it while in MG_OTA_TESTING state;
  3856. // if the event loop hangs, it fires, resets the device, and MG_OTA_FAILED
  3857. // triggers MG_OTA_ROLLBACK() on next boot. Timeout is arch-defined.
  3858. #ifndef MG_OTA_ROLLBACK_TIMER_START
  3859. #define MG_OTA_ROLLBACK_TIMER_START()
  3860. #endif
  3861. #ifndef MG_OTA_ROLLBACK_TIMER_FEED
  3862. #define MG_OTA_ROLLBACK_TIMER_FEED()
  3863. #endif
  3864. // OTA state values for MG_OTA_STATE_GET / MG_OTA_STATE_SET.
  3865. // MG_OTA_CONFIRMED: firmware is committed, normal operation.
  3866. // MG_OTA_TESTING: new firmware booted for the first time; IWDG is armed.
  3867. // If the device reboots while in this state, it transitions
  3868. // to MG_OTA_FAILED and rolls back on the next boot.
  3869. // MG_OTA_FAILED: previous boot did not commit in time; rollback on next boot.
  3870. // MG_OTA_ROLLEDBACK: device rolled back to previous firmware. Sent to the OTA
  3871. // server as boot=3 on every poll until a new OTA succeeds,
  3872. // which overwrites this state with MG_OTA_TESTING.
  3873. enum {
  3874. MG_OTA_CONFIRMED = 0,
  3875. MG_OTA_TESTING = 1,
  3876. MG_OTA_FAILED = 2,
  3877. MG_OTA_ROLLEDBACK = 3
  3878. };
  3879. // Persistent OTA state storage. Override in mongoose_config.h to persist state across resets.
  3880. #ifndef MG_OTA_STATE_GET
  3881. #define MG_OTA_STATE_GET() 0
  3882. #endif
  3883. #ifndef MG_OTA_STATE_SET
  3884. #define MG_OTA_STATE_SET(val) (void) (val)
  3885. #endif
  3886. // Evaluation window for new firmware in seconds. mg_ota_poll() feeds the
  3887. // rollback watchdog while in MG_OTA_TESTING state and within this window;
  3888. // when it expires, auto-commits if the OTA server confirmed the same version,
  3889. // otherwise stops feeding and the watchdog triggers a rollback.
  3890. #ifndef MG_OTA_ROLLBACK_TIMEOUT_SECONDS
  3891. #define MG_OTA_ROLLBACK_TIMEOUT_SECONDS 120
  3892. #endif
  3893. // Call once at boot, after clock and backup-domain init (e.g. after HAL_Init()
  3894. // + SystemClock_Config() on CubeMX projects, or after hal_clock_init() on
  3895. // Mongoose tutorials). The backup domain must be write-accessible so the state
  3896. // transition TESTING → FAILED persists across resets.
  3897. // Arms the rollback watchdog if new firmware is in TESTING state, rolls back
  3898. // immediately if FAILED. mg_ota_poll() feeds the watchdog and auto-commits
  3899. // when the server confirms the same version within the window.
  3900. // boot (TESTING) → set FAILED → arm IWDG → run firmware
  3901. // ├── server ok + window expires → set CONFIRMED → IWDG resets cleanly
  3902. // └── no server ok + window expires → stop feeding → IWDG fires → FAILED → rollback
  3903. #define MG_OTA_BOOT_CHECK() \
  3904. do { \
  3905. if (MG_OTA_STATE_GET() == MG_OTA_FAILED) { \
  3906. MG_OTA_STATE_SET(MG_OTA_ROLLEDBACK); \
  3907. MG_INFO(("Commit deadline expired, rolling back")); \
  3908. MG_OTA_ROLLBACK(); \
  3909. } else if (MG_OTA_STATE_GET() == MG_OTA_TESTING) { \
  3910. MG_OTA_STATE_SET(MG_OTA_FAILED); \
  3911. MG_INFO(("New firmware: commit within %u sec or rolls back", \
  3912. (unsigned) MG_OTA_ROLLBACK_TIMEOUT_SECONDS)); \
  3913. MG_OTA_ROLLBACK_TIMER_START(); \
  3914. } \
  3915. } while (0)
  3916. // Pull-based OTA over HTTP or HTTPS. If it's HTTPS, MG_OTA_TLS_CA
  3917. // needs to be defined. Fetches metadata_url, which must
  3918. // return a JSON object like:
  3919. // { "version": "1.2.3", "url": "FIRMWARE_URL", "size": 324645 }
  3920. // If the server version differs from MG_OTA_FIRMWARE_VERSION, downloads
  3921. // FIRMWARE_URL and performs the OTA update. fn is called on every outcome:
  3922. // NULL on successful flash, "Same version" when already up to date, or an
  3923. // error string on failure. Pass NULL to use the default handler which logs
  3924. // failures via MG_ERROR.
  3925. void mg_ota_url_check(struct mg_mgr *mgr, const char *metadata_url,
  3926. void (*fn)(const char *error_message));
  3927. // Firmware info URL for mg_ota_poll() which calls mg_ota_url_check().
  3928. // Example: "http://mongoose.ws/ota/u/0/ota.json". See http://mongoose.ws/ota/
  3929. // Settable in mongoose_config.h
  3930. #ifndef MG_OTA_URL
  3931. #define MG_OTA_URL NULL
  3932. #endif
  3933. // PEM or DER CA certificate used to authenticate an HTTPS OTA server. Set to
  3934. // NULL to use HTTP. Set in mongoose_config.h.
  3935. #ifndef MG_OTA_TLS_CA
  3936. #define MG_OTA_TLS_CA NULL
  3937. #endif
  3938. // OTA status callback function for mg_ota_poll()
  3939. #ifndef MG_OTA_STATUS_FN
  3940. #define MG_OTA_STATUS_FN NULL
  3941. #endif
  3942. // Firmware version for mg_ota_poll(). Settable in mongoose_config.h
  3943. #ifndef MG_OTA_FIRMWARE_VERSION
  3944. #define MG_OTA_FIRMWARE_VERSION "1.0.0"
  3945. #endif
  3946. // Maximum version string length
  3947. #ifndef MG_OTA_MAX_VERSION_LEN
  3948. #define MG_OTA_MAX_VERSION_LEN 64
  3949. #endif
  3950. // How often mg_ota_poll() checks for a firmware update, in seconds
  3951. #ifndef MG_OTA_PULL_INTERVAL_SECONDS
  3952. #define MG_OTA_PULL_INTERVAL_SECONDS 60
  3953. #endif
  3954. // Set to 1 to define a custom mg_ota_device_id(). Settable in mongoose_config.h
  3955. #ifndef MG_ENABLE_CUSTOM_DEVICE_ID
  3956. #define MG_ENABLE_CUSTOM_DEVICE_ID 0
  3957. #endif
  3958. // Populates buf with a unique device ID string.
  3959. // E.g. on STM32, uses the 96-bit MCU UID converted to a hex string.
  3960. void mg_ota_device_id(char *buf, size_t len);
  3961. // Checks for a firmware update over HTTP or HTTPS. Called automatically by
  3962. // mg_mgr_poll() when MG_OTA_URL is set in mongoose_config.h. Do not call
  3963. // directly.
  3964. void mg_ota_poll(struct mg_mgr *);
  3965. #if (MG_OTA != MG_OTA_NONE && MG_OTA != MG_OTA_CUSTOM) || MG_ENABLE_LFS
  3966. struct mg_flash {
  3967. void *start; // Address at which flash starts
  3968. size_t size; // Flash size
  3969. size_t secsz; // Sector size
  3970. size_t align; // Write alignment
  3971. bool (*write_fn)(void *, const void *, size_t); // Write function
  3972. bool (*swap_fn)(void); // Swap partitions
  3973. };
  3974. extern struct mg_flash *mg_flash;
  3975. bool mg_lfs_init(size_t size);
  3976. bool mg_ota_flash_begin(size_t new_firmware_size, struct mg_flash *flash);
  3977. bool mg_ota_flash_write(const void *buf, size_t len, struct mg_flash *flash);
  3978. bool mg_ota_flash_end(struct mg_flash *flash);
  3979. #endif
  3980. struct mg_wifi_data {
  3981. char *ssid, *pass; // STA mode, SSID to connect to
  3982. char *apssid, *appass; // AP mode, our SSID
  3983. uint32_t apip, apmask; // AP mode, our IP address and mask
  3984. uint8_t security; // STA mode, TBD
  3985. uint8_t apsecurity; // AP mode, TBD
  3986. uint8_t apchannel; // AP mode, channel to use
  3987. bool apmode; // start in AP mode; 'false' -> connect to 'ssid' != NULL
  3988. };
  3989. struct mg_wifi_scan_bss_data {
  3990. struct mg_str SSID;
  3991. char *BSSID;
  3992. int16_t RSSI;
  3993. uint8_t security;
  3994. #define MG_WIFI_SECURITY_OPEN 0
  3995. #define MG_WIFI_SECURITY_WEP MG_BIT(0)
  3996. #define MG_WIFI_SECURITY_WPA MG_BIT(1)
  3997. #define MG_WIFI_SECURITY_WPA2 MG_BIT(2)
  3998. #define MG_WIFI_SECURITY_WPA3 MG_BIT(3)
  3999. #define MG_WIFI_SECURITY_WPA_ENTERPRISE MG_BIT(4)
  4000. #define MG_WIFI_SECURITY_WPA2_ENTERPRISE MG_BIT(5)
  4001. #define MG_WIFI_SECURITY_WPA3_ENTERPRISE MG_BIT(6)
  4002. uint8_t channel;
  4003. unsigned band : 2;
  4004. #define MG_WIFI_BAND_2G 0
  4005. #define MG_WIFI_BAND_5G 1
  4006. unsigned has_n : 1;
  4007. unsigned has_ac : 1;
  4008. unsigned has_ax : 1;
  4009. };
  4010. bool mg_wifi_scan(void);
  4011. bool mg_wifi_connect(struct mg_wifi_data *);
  4012. bool mg_wifi_disconnect(void);
  4013. bool mg_wifi_ap_start(struct mg_wifi_data *);
  4014. bool mg_wifi_ap_stop(void);
  4015. #if MG_ENABLE_TCPIP
  4016. // no config defaults to 0 => Ethernet
  4017. enum mg_l2type { MG_TCPIP_L2_ETH = 0, MG_TCPIP_L2_PPP, MG_TCPIP_L2_PPPoE, MG_TCPIP_L2_USER };
  4018. #if defined(__DCC__)
  4019. #pragma pack(1)
  4020. #else
  4021. #pragma pack(push, 1)
  4022. #endif
  4023. struct mg_l2addr {
  4024. union {
  4025. uint8_t mac[6]; // ieee48
  4026. uint64_t ieee64; // PPP ifcid
  4027. uint16_t ieee16;
  4028. } addr;
  4029. };
  4030. // L2 using L2 (PPPoE) must inherit the lower layer first, so they overlap
  4031. struct eth_data {
  4032. uint16_t vlan_id;
  4033. };
  4034. struct pppoe_data { // (struct eth_data *) &pppoe_data = pppoedata.eth
  4035. struct eth_data eth;
  4036. };
  4037. union mg_l2data {
  4038. struct eth_data eth;
  4039. struct pppoe_data pppoe;
  4040. };
  4041. #if defined(__DCC__)
  4042. #pragma pack(0)
  4043. #else
  4044. #pragma pack(pop)
  4045. #endif
  4046. enum mg_l2proto {
  4047. MG_TCPIP_L2PROTO_IPV4 = 0,
  4048. MG_TCPIP_L2PROTO_IPV6,
  4049. MG_TCPIP_L2PROTO_ARP,
  4050. MG_TCPIP_L2PROTO_PPPoE_DISC,
  4051. MG_TCPIP_L2PROTO_PPPoE_SESS
  4052. };
  4053. enum mg_l2addrtype {
  4054. MG_TCPIP_L2ADDR_BCAST,
  4055. MG_TCPIP_L2ADDR_MCAST,
  4056. MG_TCPIP_L2ADDR_MCAST6
  4057. };
  4058. #endif
  4059. #if MG_ENABLE_TCPIP
  4060. // Mongoose TCP/IP network interface
  4061. struct mg_tcpip_if;
  4062. // Hardware driver interface. Implement all function pointers to plug in a
  4063. // new network device. Polling drivers set rx; interrupt/DMA drivers set
  4064. // rx=NULL and push frames via mg_tcpip_qwrite() from their ISR instead.
  4065. struct mg_tcpip_driver {
  4066. bool (*init)(struct mg_tcpip_if *); // One-time hardware init; return false on failure
  4067. size_t (*tx)(const void *, size_t, struct mg_tcpip_if *); // Transmit one raw frame; return bytes sent
  4068. size_t (*rx)(void *buf, size_t len, struct mg_tcpip_if *); // Read one raw frame; return frame size, 0 if none. NULL for interrupt-driven drivers
  4069. bool (*poll)(struct mg_tcpip_if *, bool); // Check link status; second arg is true once per second. Return true=up, false=down
  4070. };
  4071. // Event handler called by the TCP/IP stack for network-level events.
  4072. // ev is one of MG_TCPIP_EV_*; ev_data type is documented per event below.
  4073. typedef void (*mg_tcpip_event_handler_t)(struct mg_tcpip_if *ifp, int ev,
  4074. void *ev_data);
  4075. // clang-format off
  4076. // Events delivered to mg_tcpip_if.fn (user) and mg_tcpip_if.pfn (driver).
  4077. // Each entry shows the ev_data type to cast inside the handler.
  4078. enum {
  4079. MG_TCPIP_EV_STATE_CHANGE, // IPv4 link state changed uint8_t *(&ifp->state)
  4080. MG_TCPIP_EV_DHCP_DNS, // DHCP assigned a DNS server uint32_t *ipaddr
  4081. MG_TCPIP_EV_DHCP_SNTP, // DHCP assigned an SNTP server uint32_t *ipaddr
  4082. MG_TCPIP_EV_ARP, // Raw ARP frame received struct mg_str *
  4083. MG_TCPIP_EV_TIMER_1S, // 1-second periodic tick NULL
  4084. MG_TCPIP_EV_WIFI_SCAN_RESULT, // Wi-Fi BSS scan entry struct mg_wifi_scan_bss_data *
  4085. MG_TCPIP_EV_WIFI_SCAN_END, // Wi-Fi scan finished NULL
  4086. MG_TCPIP_EV_WIFI_CONNECT_ERR, // Wi-Fi connection failed driver and chip specific
  4087. MG_TCPIP_EV_DRIVER, // Driver-defined event driver specific
  4088. MG_TCPIP_EV_STATE6_CHANGE, // IPv6 link state changed uint8_t *(&ifp->state6)
  4089. MG_TCPIP_EV_USER // Starting ID for user-defined events
  4090. };
  4091. // clang-format on
  4092. // Network interface. Zero-initialise, then set the fields marked "user-set"
  4093. // before calling mg_tcpip_init(). Fields in the "internal state" section
  4094. // below are managed by the stack; read them freely but do not modify them.
  4095. struct mg_tcpip_if {
  4096. // User-set configuration
  4097. uint8_t mac[sizeof(struct mg_l2addr)]; // MAC address; must be set to a valid address
  4098. uint32_t ip, mask, gw; // Static IPv4 address, netmask, gateway; 0 = use DHCP
  4099. struct mg_str tx; // TX frame buffer (managed by the stack)
  4100. bool enable_dhcp_client; // Enable DHCP client; auto-set if ip==0
  4101. bool enable_dhcp_server; // Enable DHCP server
  4102. bool enable_get_gateway; // DHCP server offers itself as the default gateway
  4103. bool enable_req_dns; // DHCP client requests a DNS server address
  4104. bool enable_req_sntp; // DHCP client requests an SNTP server address
  4105. bool enable_fcs_check; // Verify and strip FCS from received frames
  4106. bool enable_mac_check; // Drop frames not addressed to this MAC
  4107. bool update_mac_hash_table; // Signal driver to refresh MAC multicast hash table
  4108. bool is_ip_changed; // Set by stack when IP changes; triggers connection restart
  4109. struct mg_tcpip_driver *driver; // Hardware driver; must be set before mg_tcpip_init()
  4110. void *driver_data; // Passed to all driver functions as ifp->driver_data
  4111. mg_tcpip_event_handler_t pfn; // Driver-level event handler; called before fn
  4112. mg_tcpip_event_handler_t fn; // User event handler for MG_TCPIP_EV_* events
  4113. struct mg_mgr *mgr; // Mongoose event manager; set by mg_tcpip_init()
  4114. struct mg_queue recv_queue; // Incoming frame queue; pre-size by setting recv_queue.size
  4115. char dhcp_name[MG_TCPIP_DHCPNAME_SIZE]; // Hostname sent in DHCP requests; defaults to "mip"
  4116. uint16_t mtu; // IP MTU (max payload size at the IP layer)
  4117. uint16_t framesize; // Maximum L2 frame size in bytes
  4118. uint16_t l2mtu; // L2 frame payload, default net MTU
  4119. #if MG_ENABLE_IPV6
  4120. uint64_t ip6ll[2], ip6[2]; // IPv6 link-local and global addresses
  4121. uint8_t prefix[8]; // Global prefix bytes
  4122. uint8_t prefix_len; // Global prefix length in bits
  4123. uint64_t gw6[2]; // IPv6 default gateway
  4124. bool enable_slaac; // Enable SLAAC (stateless address autoconfiguration)
  4125. bool enable_dhcp6_client; // Enable DHCPv6 client (not yet fully implemented)
  4126. bool is_ip6_changed; // Set by stack when IPv6 address changes
  4127. #endif
  4128. // Internal state - read-only for users, managed by the stack
  4129. uint8_t gwmac[sizeof(struct mg_l2addr)]; // Gateway hardware address (resolved via ARP)
  4130. enum mg_l2type l2type; // Layer-2 type: Ethernet, PPP, etc. (see l2.h)
  4131. union mg_l2data l2data; // Layer-2 config and state (see l2.h)
  4132. char *dns4_url; // Active DNS server URL (set from DHCP or config)
  4133. uint64_t now; // Current time in ms (updated each mg_mgr_poll)
  4134. uint64_t timer_1000ms; // Timestamp of last 1-second tick
  4135. uint64_t lease_expire; // DHCP lease expiry time in ms
  4136. uint16_t eport; // Next ephemeral port to assign
  4137. volatile uint32_t ndrop; // Frames received but dropped (queue full)
  4138. volatile uint32_t nrecv; // Total frames received
  4139. volatile uint32_t nsent; // Total frames transmitted
  4140. volatile uint32_t nerr; // Driver-reported transmit errors
  4141. uint8_t state; // Current IPv4 link/IP state (MG_TCPIP_STATE_*)
  4142. #define MG_TCPIP_STATE_DOWN 0 // Physical link is down
  4143. #define MG_TCPIP_STATE_LINK_UP 1 // Driver reports physical link is up
  4144. #define MG_TCPIP_STATE_UP 2 // L2 is ready (e.g. PPP negotiated)
  4145. #define MG_TCPIP_STATE_REQ 3 // DHCP REQUESTING: waiting for DHCP offer
  4146. #define MG_TCPIP_STATE_IP 4 // IP address assigned; resolving gateway MAC
  4147. #define MG_TCPIP_STATE_READY 5 // Fully operational; gateway MAC resolved
  4148. bool gw_ready; // Gateway MAC address has been resolved via ARP
  4149. #if MG_ENABLE_IPV6
  4150. uint8_t gw6mac[sizeof(struct mg_l2addr)]; // IPv6 gateway hardware address
  4151. uint8_t state6; // Current IPv6 link/IP state (MG_TCPIP_STATE_*)
  4152. bool gw6_ready; // IPv6 gateway MAC address has been resolved
  4153. #endif
  4154. };
  4155. // Initialises the TCP/IP stack. Calls driver->init(), allocates the TX frame
  4156. // buffer (ifp->framesize bytes) and the RX queue. If ifp->ip == 0 and the
  4157. // L2 type is not PPP, DHCP client is enabled automatically.
  4158. // Must be called once after populating ifp->driver, ifp->mac, and any
  4159. // static IP/mask/gw values.
  4160. void mg_tcpip_init(struct mg_mgr *, struct mg_tcpip_if *);
  4161. // Frees the TX buffer and RX queue allocated by mg_tcpip_init().
  4162. void mg_tcpip_free(struct mg_tcpip_if *);
  4163. // Pushes a received raw frame into ifp->recv_queue. Used by interrupt-driven
  4164. // or DMA-based drivers (those with rx=NULL) to hand frames to the stack from
  4165. // an ISR or DMA completion callback. Drops the frame and increments ndrop if
  4166. // the queue is full.
  4167. void mg_tcpip_qwrite(void *buf, size_t len, struct mg_tcpip_if *ifp);
  4168. // Sends a broadcast ARP who-has request for ip. mac may be NULL for a plain
  4169. // broadcast, or a non-NULL hint to set the target MAC field in the request.
  4170. void mg_tcpip_arp_request(struct mg_tcpip_if *ifp, uint32_t ip, uint8_t *mac);
  4171. // Built-in hardware drivers. Assign one to mg_tcpip_if.driver before calling
  4172. // mg_tcpip_init(). Each driver also requires a corresponding driver_data
  4173. // struct; see the matching driver header for details.
  4174. extern struct mg_tcpip_driver mg_tcpip_driver_stm32f;
  4175. extern struct mg_tcpip_driver mg_tcpip_driver_w5500;
  4176. extern struct mg_tcpip_driver mg_tcpip_driver_w5100;
  4177. extern struct mg_tcpip_driver mg_tcpip_driver_tm4c;
  4178. extern struct mg_tcpip_driver mg_tcpip_driver_tms570;
  4179. extern struct mg_tcpip_driver mg_tcpip_driver_stm32h;
  4180. extern struct mg_tcpip_driver mg_tcpip_driver_imxrt;
  4181. extern struct mg_tcpip_driver mg_tcpip_driver_same54;
  4182. extern struct mg_tcpip_driver mg_tcpip_driver_cmsis;
  4183. extern struct mg_tcpip_driver mg_tcpip_driver_ra;
  4184. extern struct mg_tcpip_driver mg_tcpip_driver_xmc;
  4185. extern struct mg_tcpip_driver mg_tcpip_driver_xmc7;
  4186. extern struct mg_tcpip_driver mg_tcpip_driver_pico_w;
  4187. extern struct mg_tcpip_driver mg_tcpip_driver_rw612;
  4188. extern struct mg_tcpip_driver mg_tcpip_driver_cyw;
  4189. extern struct mg_tcpip_driver mg_tcpip_driver_nxp_wifi;
  4190. extern struct mg_tcpip_driver mg_tcpip_driver_st67w6;
  4191. extern struct mg_tcpip_driver mg_tcpip_driver_atcmd;
  4192. // SPI bus abstraction for SPI-attached network chips (e.g. W5500).
  4193. // Populate and assign to the driver's driver_data field.
  4194. struct mg_tcpip_spi {
  4195. void *spi; // Opaque SPI bus handle passed to all callbacks
  4196. void (*begin)(void *); // Assert chip-select (start of transaction)
  4197. void (*end)(void *); // Deassert chip-select (end of transaction)
  4198. void (*txn)(void *, uint8_t *write, uint8_t *read, size_t); // Full-duplex transfer: write and read len bytes simultaneously
  4199. };
  4200. // Alignment attributes for DMA-capable Ethernet descriptor buffers.
  4201. // Use these on driver RX/TX descriptor arrays where the hardware requires
  4202. // specific alignment.
  4203. #ifndef MG_8BYTE_ALIGNED
  4204. #if defined(__GNUC__)
  4205. #define MG_8BYTE_ALIGNED __attribute__((aligned((8U))))
  4206. #else
  4207. #define MG_8BYTE_ALIGNED
  4208. #endif // compiler
  4209. #endif // 8BYTE_ALIGNED
  4210. #ifndef MG_16BYTE_ALIGNED
  4211. #if defined(__GNUC__)
  4212. #define MG_16BYTE_ALIGNED __attribute__((aligned((16U))))
  4213. #else
  4214. #define MG_16BYTE_ALIGNED
  4215. #endif // compiler
  4216. #endif // 16BYTE_ALIGNED
  4217. #ifndef MG_32BYTE_ALIGNED
  4218. #if defined(__GNUC__)
  4219. #define MG_32BYTE_ALIGNED __attribute__((aligned((32U))))
  4220. #else
  4221. #define MG_32BYTE_ALIGNED
  4222. #endif // compiler
  4223. #endif // 32BYTE_ALIGNED
  4224. #ifndef MG_64BYTE_ALIGNED
  4225. #if defined(__GNUC__)
  4226. #define MG_64BYTE_ALIGNED __attribute__((aligned((64U))))
  4227. #else
  4228. #define MG_64BYTE_ALIGNED
  4229. #endif // compiler
  4230. #endif // 64BYTE_ALIGNED
  4231. // Memory section attribute for Ethernet frame buffers. Define to
  4232. // __attribute__((section(".eth_ram"))) or similar if the Ethernet DMA
  4233. // requires buffers in a specific RAM region.
  4234. #ifndef MG_ETH_RAM
  4235. #define MG_ETH_RAM
  4236. #endif
  4237. #endif
  4238. #if MG_ENABLE_BSD_SOCKETS
  4239. #ifndef MG_ENABLE_BSD_PROTOTYPES
  4240. #include <arpa/inet.h>
  4241. #include <errno.h>
  4242. #include <fcntl.h>
  4243. #include <netdb.h>
  4244. #include <netinet/in.h>
  4245. #include <netinet/tcp.h>
  4246. #include <poll.h>
  4247. #include <sys/select.h>
  4248. #include <sys/socket.h>
  4249. #include <sys/time.h>
  4250. #include <sys/un.h>
  4251. #else
  4252. #include <errno.h>
  4253. typedef unsigned int socklen_t;
  4254. typedef uint32_t in_addr_t;
  4255. struct in_addr { in_addr_t s_addr; };
  4256. struct in6_addr { uint8_t s6_addr[16]; };
  4257. struct sockaddr { uint16_t sa_family; char sa_data[14]; };
  4258. struct sockaddr_in {
  4259. uint16_t sin_family;
  4260. uint16_t sin_port;
  4261. struct in_addr sin_addr;
  4262. char sin_zero[8];
  4263. };
  4264. struct sockaddr_in6 {
  4265. uint16_t sin6_family;
  4266. uint16_t sin6_port;
  4267. uint32_t sin6_flowinfo;
  4268. struct in6_addr sin6_addr;
  4269. uint32_t sin6_scope_id;
  4270. };
  4271. struct sockaddr_storage { uint16_t ss_family; char __ss_pad[126]; };
  4272. struct hostent {
  4273. char *h_name;
  4274. char **h_aliases;
  4275. int h_addrtype;
  4276. int h_length;
  4277. char **h_addr_list;
  4278. };
  4279. #define h_addr h_addr_list[0]
  4280. struct addrinfo {
  4281. int ai_flags;
  4282. int ai_family;
  4283. int ai_socktype;
  4284. int ai_protocol;
  4285. socklen_t ai_addrlen;
  4286. struct sockaddr *ai_addr;
  4287. char *ai_canonname;
  4288. struct addrinfo *ai_next;
  4289. };
  4290. struct pollfd { int fd; short events; short revents; };
  4291. #define AF_INET 2
  4292. #define AF_INET6 10
  4293. #define AF_UNSPEC 0
  4294. #define PF_INET AF_INET
  4295. #define PF_INET6 AF_INET6
  4296. #define PF_UNSPEC AF_UNSPEC
  4297. #define SOCK_STREAM 1
  4298. #define SOCK_DGRAM 2
  4299. #define IPPROTO_TCP 6
  4300. #define IPPROTO_UDP 17
  4301. #define INADDR_ANY 0
  4302. #define INADDR_LOOPBACK 0x7f000001
  4303. #define SOL_SOCKET 0xffff
  4304. #define SO_REUSEADDR 2
  4305. #define SO_REUSEPORT 15
  4306. #define SO_KEEPALIVE 9
  4307. #define SO_ERROR 4
  4308. #define SO_BROADCAST 6
  4309. #define SO_RCVBUF 8
  4310. #define SO_SNDBUF 7
  4311. #define TCP_NODELAY 1
  4312. #define MSG_DONTWAIT 0x40
  4313. #define MSG_NOSIGNAL 0x4000
  4314. #define MSG_PEEK 0x02
  4315. #define F_GETFL 3
  4316. #define F_SETFL 4
  4317. #define O_NONBLOCK 0x0004
  4318. #define SHUT_RD 0
  4319. #define SHUT_WR 1
  4320. #define SHUT_RDWR 2
  4321. #define AI_PASSIVE 0x0001
  4322. #define NI_MAXHOST 1025
  4323. #define NI_MAXSERV 32
  4324. #ifndef EAGAIN
  4325. #define EAGAIN 11
  4326. #endif
  4327. #ifndef EWOULDBLOCK
  4328. #define EWOULDBLOCK EAGAIN
  4329. #endif
  4330. #ifndef EINPROGRESS
  4331. #define EINPROGRESS 36
  4332. #endif
  4333. #ifndef ENOTCONN
  4334. #define ENOTCONN 107
  4335. #endif
  4336. #ifndef ECONNREFUSED
  4337. #define ECONNREFUSED 111
  4338. #endif
  4339. #ifndef ECONNRESET
  4340. #define ECONNRESET 104
  4341. #endif
  4342. #ifndef EADDRINUSE
  4343. #define EADDRINUSE 98
  4344. #endif
  4345. #ifndef ETIMEDOUT
  4346. #define ETIMEDOUT 110
  4347. #endif
  4348. #define POLLIN 0x001
  4349. #define POLLOUT 0x004
  4350. #define POLLERR 0x008
  4351. #define POLLHUP 0x010
  4352. #define POLLNVAL 0x020
  4353. uint16_t htons(uint16_t);
  4354. uint16_t ntohs(uint16_t);
  4355. uint32_t htonl(uint32_t);
  4356. uint32_t ntohl(uint32_t);
  4357. #endif // MG_ENABLE_BSD_PROTOTYPES
  4358. #define closesocket(a) close(a)
  4359. #ifndef MG_BSD_BACKLOG
  4360. #define MG_BSD_BACKLOG 5
  4361. #endif
  4362. #ifndef MG_BSD_CONNECT_TIMEOUT_MS
  4363. #define MG_BSD_CONNECT_TIMEOUT_MS 10000
  4364. #endif
  4365. // Mongoose-specific API
  4366. void mg_bsd_init(void); // must be called before socket()
  4367. void mg_bsd_poll(struct mg_mgr *); // process pending BSD commands
  4368. // Transport backend: implement these OR define MG_ENABLE_FREERTOS for the built-in backend
  4369. void *mg_bsd_transport_new(int domain, int type, int proto);
  4370. void mg_bsd_transport_free(void *t);
  4371. int mg_bsd_transport_listen(void *t, const struct sockaddr_in *addr);
  4372. void *mg_bsd_transport_accept(void *t, struct sockaddr_in *peer, bool nonblock);
  4373. ssize_t mg_bsd_transport_recv(void *t, void *buf, size_t len, bool nonblock);
  4374. ssize_t mg_bsd_transport_send(void *t, const void *buf, size_t len, bool nonblock);
  4375. int mg_bsd_transport_connect(void *t, const struct sockaddr_in *addr, bool nonblock);
  4376. void mg_bsd_transport_close(void *t);
  4377. // Standard BSD socket API
  4378. int socket(int, int, int);
  4379. int bind(int, const struct sockaddr *, socklen_t);
  4380. int listen(int, int);
  4381. int accept(int, struct sockaddr *, socklen_t *);
  4382. int connect(int, const struct sockaddr *, socklen_t);
  4383. ssize_t send(int, const void *, size_t, int);
  4384. ssize_t recv(int, void *, size_t, int);
  4385. ssize_t sendto(int, const void *, size_t, int, const struct sockaddr *, socklen_t);
  4386. ssize_t recvfrom(int, void *, size_t, int, struct sockaddr *, socklen_t *);
  4387. int close(int);
  4388. int shutdown(int, int);
  4389. int fcntl(int, int, int);
  4390. int setsockopt(int, int, int, const void *, socklen_t);
  4391. int getsockopt(int, int, int, void *, socklen_t *);
  4392. int getsockname(int, struct sockaddr *, socklen_t *);
  4393. int getpeername(int, struct sockaddr *, socklen_t *);
  4394. int select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
  4395. int poll(struct pollfd *, unsigned int, int);
  4396. struct hostent *gethostbyname(const char *);
  4397. int getaddrinfo(const char *, const char *, const struct addrinfo *, struct addrinfo **);
  4398. void freeaddrinfo(struct addrinfo *);
  4399. int inet_pton(int, const char *, void *);
  4400. const char *inet_ntop(int, const void *, char *, socklen_t);
  4401. in_addr_t inet_addr(const char *);
  4402. char *inet_ntoa(struct in_addr);
  4403. #endif // MG_ENABLE_BSD_SOCKETS
  4404. struct mg_tcpip_driver_atcmd_data {
  4405. void *usart; // Opaque UART/SPI descriptor
  4406. void (*reset)(void *); // Modem hardware reset
  4407. void (*tx)(void *, uint8_t); // USART transmit single byte
  4408. int (*rx)(void *); // USART receive single byte
  4409. const char **script; // List of AT commands and expected replies
  4410. int script_index; // Index of the current AT command in the list
  4411. uint64_t deadline; // AT command deadline in ms
  4412. bool no_byte_stuff; // Do not perform byte stuffing/unstuffing
  4413. bool link; // internal use: done with AT processing
  4414. bool unstuffing; // internal use: unstuffing state
  4415. };
  4416. #if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_CMSIS) && MG_ENABLE_DRIVER_CMSIS
  4417. #include "Driver_ETH_MAC.h" // keep this include
  4418. #include "Driver_ETH_PHY.h" // keep this include
  4419. #endif
  4420. #if MG_ENABLE_TCPIP && \
  4421. ((defined(MG_ENABLE_DRIVER_CYW) && MG_ENABLE_DRIVER_CYW) || \
  4422. (defined(MG_ENABLE_DRIVER_CYW_SDIO) && MG_ENABLE_DRIVER_CYW_SDIO))
  4423. struct mg_tcpip_driver_cyw_firmware {
  4424. const uint8_t *code_addr;
  4425. size_t code_len;
  4426. const uint8_t *nvram_addr;
  4427. size_t nvram_len;
  4428. const uint8_t *clm_addr;
  4429. size_t clm_len;
  4430. };
  4431. struct mg_tcpip_driver_cyw_data {
  4432. struct mg_wifi_data wifi;
  4433. void *bus;
  4434. struct mg_tcpip_driver_cyw_firmware *fw;
  4435. bool hs; // use chip "high-speed" mode; otherwise SPI CPOL0 CPHA0 (DS 4.2.3 Table 6)
  4436. };
  4437. #define MG_TCPIP_DRIVER_INIT(mgr) \
  4438. do { \
  4439. static struct mg_tcpip_driver_cyw_data driver_data_; \
  4440. static struct mg_tcpip_if mif_; \
  4441. MG_SET_WIFI_CONFIG(&mif_, &driver_data_); \
  4442. mif_.ip = MG_TCPIP_IP; \
  4443. mif_.mask = MG_TCPIP_MASK; \
  4444. mif_.gw = MG_TCPIP_GW; \
  4445. mif_.driver = &mg_tcpip_driver_cyw; \
  4446. mif_.driver_data = &driver_data_; \
  4447. mif_.recv_queue.size = 8192; \
  4448. mif_.mac[0] = 2; /* MAC read from OTP at driver init */ \
  4449. mg_tcpip_init(mgr, &mif_); \
  4450. MG_INFO(("Driver: cyw, MAC: %M", mg_print_mac, mif_.mac)); \
  4451. } while (0)
  4452. #endif
  4453. #if MG_ENABLE_TCPIP && \
  4454. (defined(MG_ENABLE_DRIVER_IMXRT10) && MG_ENABLE_DRIVER_IMXRT10) || \
  4455. (defined(MG_ENABLE_DRIVER_IMXRT11) && MG_ENABLE_DRIVER_IMXRT11) || \
  4456. (defined(MG_ENABLE_DRIVER_MCXE) && MG_ENABLE_DRIVER_MCXE)
  4457. struct mg_tcpip_driver_imxrt_data {
  4458. // MDC clock divider. MDC clock is derived from IPS Bus clock (ipg_clk),
  4459. // must not exceed 2.5MHz. Configuration for clock range 2.36~2.50 MHz
  4460. // 37.5.1.8.2, Table 37-46 : f = ipg_clk / (2(mdc_cr + 1))
  4461. // ipg_clk mdc_cr VALUE
  4462. // --------------------------
  4463. // -1 <-- TODO() tell driver to guess the value
  4464. // 25 MHz 4
  4465. // 33 MHz 6
  4466. // 40 MHz 7
  4467. // 50 MHz 9
  4468. // 66 MHz 13
  4469. int mdc_cr; // Valid values: -1 to 63
  4470. uint8_t phy_addr; // PHY address
  4471. };
  4472. #ifndef MG_TCPIP_PHY_ADDR
  4473. #define MG_TCPIP_PHY_ADDR 2
  4474. #endif
  4475. #ifndef MG_DRIVER_MDC_CR
  4476. #define MG_DRIVER_MDC_CR 24
  4477. #endif
  4478. #define MG_TCPIP_DRIVER_INIT(mgr) \
  4479. do { \
  4480. static struct mg_tcpip_driver_imxrt_data driver_data_; \
  4481. static struct mg_tcpip_if mif_; \
  4482. driver_data_.mdc_cr = MG_DRIVER_MDC_CR; \
  4483. driver_data_.phy_addr = MG_TCPIP_PHY_ADDR; \
  4484. mif_.ip = MG_TCPIP_IP; \
  4485. mif_.mask = MG_TCPIP_MASK; \
  4486. mif_.gw = MG_TCPIP_GW; \
  4487. mif_.driver = &mg_tcpip_driver_imxrt; \
  4488. mif_.driver_data = &driver_data_; \
  4489. MG_SET_MAC_ADDRESS(mif_.mac); \
  4490. mg_tcpip_init(mgr, &mif_); \
  4491. MG_INFO(("Driver: imxrt, MAC: %M", mg_print_mac, mif_.mac)); \
  4492. } while (0)
  4493. #endif
  4494. #if MG_ENABLE_TCPIP && \
  4495. defined(MG_ENABLE_DRIVER_NXP_WIFI) && MG_ENABLE_DRIVER_NXP_WIFI
  4496. struct mg_tcpip_driver_nxp_wifi_data {
  4497. struct mg_wifi_data wifi;
  4498. };
  4499. #define MG_TCPIP_DRIVER_INIT(mgr) \
  4500. do { \
  4501. static struct mg_tcpip_driver_nxp_wifi_data driver_data_; \
  4502. static struct mg_tcpip_if mif_; \
  4503. MG_SET_WIFI_CONFIG(&mif_, &driver_data_); \
  4504. mif_.ip = MG_TCPIP_IP; \
  4505. mif_.mask = MG_TCPIP_MASK; \
  4506. mif_.gw = MG_TCPIP_GW; \
  4507. mif_.driver = &mg_tcpip_driver_nxp_wifi; \
  4508. mif_.driver_data = &driver_data_; \
  4509. mif_.recv_queue.size = 8192; \
  4510. mif_.mac[0] = 2; /* MAC read from OTP at driver init */ \
  4511. mg_tcpip_init(mgr, &mif_); \
  4512. MG_INFO(("Driver: nxp wifi, MAC: %M", mg_print_mac, mif_.mac)); \
  4513. } while (0)
  4514. #endif
  4515. struct mg_phy {
  4516. uint16_t (*read_reg)(uint8_t addr, uint8_t reg);
  4517. void (*write_reg)(uint8_t addr, uint8_t reg, uint16_t value);
  4518. };
  4519. // PHY configuration settings, bitmask
  4520. enum {
  4521. // Set if PHY LEDs are connected to ground
  4522. MG_PHY_LEDS_ACTIVE_HIGH = (1 << 0),
  4523. // Set when PHY clocks MAC. Otherwise, MAC clocks PHY
  4524. MG_PHY_CLOCKS_MAC = (1 << 1)
  4525. };
  4526. enum { MG_PHY_SPEED_10M, MG_PHY_SPEED_100M, MG_PHY_SPEED_1000M };
  4527. void mg_phy_init(struct mg_phy *, uint8_t addr, uint8_t config);
  4528. bool mg_phy_up(struct mg_phy *, uint8_t addr, bool *full_duplex,
  4529. uint8_t *speed);
  4530. #if MG_ENABLE_TCPIP && MG_ARCH == MG_ARCH_PICOSDK && \
  4531. defined(MG_ENABLE_DRIVER_PICO_W) && MG_ENABLE_DRIVER_PICO_W
  4532. #include "cyw43.h" // keep this include
  4533. #include "pico/cyw43_arch.h" // keep this include
  4534. #include "pico/unique_id.h" // keep this include
  4535. struct mg_tcpip_driver_pico_w_data {
  4536. struct mg_wifi_data wifi;
  4537. };
  4538. #define MG_TCPIP_DRIVER_INIT(mgr) \
  4539. do { \
  4540. static struct mg_tcpip_driver_pico_w_data driver_data_; \
  4541. static struct mg_tcpip_if mif_; \
  4542. MG_SET_WIFI_CONFIG(&mif_, &driver_data_); \
  4543. mif_.ip = MG_TCPIP_IP; \
  4544. mif_.mask = MG_TCPIP_MASK; \
  4545. mif_.gw = MG_TCPIP_GW; \
  4546. mif_.driver = &mg_tcpip_driver_pico_w; \
  4547. mif_.driver_data = &driver_data_; \
  4548. mif_.recv_queue.size = 8192; \
  4549. mif_.mac[0] = 2; /* MAC read from OTP at driver init */ \
  4550. mg_tcpip_init(mgr, &mif_); \
  4551. MG_INFO(("Driver: pico-w, MAC: %M", mg_print_mac, mif_.mac)); \
  4552. } while (0)
  4553. #endif
  4554. #if MG_ENABLE_TCPIP && \
  4555. (defined(MG_ENABLE_DRIVER_RA6) && MG_ENABLE_DRIVER_RA6) || \
  4556. (defined(MG_ENABLE_DRIVER_RA8) && MG_ENABLE_DRIVER_RA8)
  4557. struct mg_tcpip_driver_ra_data {
  4558. // MDC clock "divider". MDC clock is software generated,
  4559. uint32_t clock; // core clock frequency in Hz
  4560. uint16_t irqno; // IRQn, R_ICU->IELSR[irqno]
  4561. uint8_t phy_addr; // PHY address
  4562. };
  4563. #ifndef MG_DRIVER_CLK_FREQ
  4564. #define MG_DRIVER_CLK_FREQ 100000000UL
  4565. #endif
  4566. #ifndef MG_DRIVER_IRQ_NO
  4567. #define MG_DRIVER_IRQ_NO 0
  4568. #endif
  4569. #ifndef MG_TCPIP_PHY_ADDR
  4570. #define MG_TCPIP_PHY_ADDR 0
  4571. #endif
  4572. #define MG_TCPIP_DRIVER_INIT(mgr) \
  4573. do { \
  4574. static struct mg_tcpip_driver_ra_data driver_data_; \
  4575. static struct mg_tcpip_if mif_; \
  4576. driver_data_.clock = MG_DRIVER_CLK_FREQ; \
  4577. driver_data_.irqno = MG_DRIVER_IRQ_NO; \
  4578. driver_data_.phy_addr = MG_TCPIP_PHY_ADDR; \
  4579. mif_.ip = MG_TCPIP_IP; \
  4580. mif_.mask = MG_TCPIP_MASK; \
  4581. mif_.gw = MG_TCPIP_GW; \
  4582. mif_.driver = &mg_tcpip_driver_ra; \
  4583. mif_.driver_data = &driver_data_; \
  4584. MG_SET_MAC_ADDRESS(mif_.mac); \
  4585. mg_tcpip_init(mgr, &mif_); \
  4586. MG_INFO(("Driver: ra, MAC: %M", mg_print_mac, mif_.mac)); \
  4587. } while (0)
  4588. #endif
  4589. #if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_RW612) && MG_ENABLE_DRIVER_RW612
  4590. struct mg_tcpip_driver_rw612_data {
  4591. // 38.1.8 MII Speed Control Register (MSCR)
  4592. // MDC clock frequency must not exceed 2.5 MHz and is calculated as follows:
  4593. // MDC_freq = P_clock / ((mdc_cr + 1) * 2), where P_clock is the
  4594. // peripheral bus clock.
  4595. // IEEE802.3 clause 22 defines a minimum of 10 ns for the hold time on the
  4596. // MDIO output. Depending on the host bus frequency, the setting may need
  4597. // to be increased.
  4598. int mdc_cr;
  4599. int mdc_holdtime; // Valid values: [0-7]
  4600. uint8_t phy_addr;
  4601. };
  4602. #ifndef MG_TCPIP_PHY_ADDR
  4603. #define MG_TCPIP_PHY_ADDR 2
  4604. #endif
  4605. #ifndef MG_DRIVER_MDC_CR
  4606. #define MG_DRIVER_MDC_CR 51
  4607. #endif
  4608. #ifndef MG_DRIVER_MDC_HOLDTIME
  4609. #define MG_DRIVER_MDC_HOLDTIME 3
  4610. #endif
  4611. #define MG_TCPIP_DRIVER_INIT(mgr) \
  4612. do { \
  4613. static struct mg_tcpip_driver_rw612_data driver_data_; \
  4614. static struct mg_tcpip_if mif_; \
  4615. driver_data_.mdc_cr = MG_DRIVER_MDC_CR; \
  4616. driver_data_.phy_addr = MG_TCPIP_PHY_ADDR; \
  4617. mif_.ip = MG_TCPIP_IP; \
  4618. mif_.mask = MG_TCPIP_MASK; \
  4619. mif_.gw = MG_TCPIP_GW; \
  4620. mif_.driver = &mg_tcpip_driver_rw612; \
  4621. mif_.driver_data = &driver_data_; \
  4622. MG_SET_MAC_ADDRESS(mif_.mac); \
  4623. mg_tcpip_init(mgr, &mif_); \
  4624. MG_INFO(("Driver: rw612, MAC: %M", mg_print_mac, mif_.mac)); \
  4625. } while (0)
  4626. #endif
  4627. #if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_SAME54) && \
  4628. MG_ENABLE_DRIVER_SAME54
  4629. #ifndef MG_DRIVER_MDC_CR
  4630. #define MG_DRIVER_MDC_CR 5
  4631. #endif
  4632. #ifndef MG_DRIVER_PHY_ADDR
  4633. #define MG_DRIVER_PHY_ADDR 0
  4634. #endif
  4635. struct mg_tcpip_driver_same54_data {
  4636. int mdc_cr;
  4637. uint8_t phy_addr;
  4638. };
  4639. #define MG_TCPIP_DRIVER_INIT(mgr) \
  4640. do { \
  4641. static struct mg_tcpip_driver_same54_data driver_data_; \
  4642. static struct mg_tcpip_if mif_; \
  4643. driver_data_.mdc_cr = MG_DRIVER_MDC_CR; \
  4644. driver_data_.phy_addr = MG_DRIVER_PHY_ADDR; \
  4645. mif_.ip = MG_TCPIP_IP; \
  4646. mif_.mask = MG_TCPIP_MASK; \
  4647. mif_.gw = MG_TCPIP_GW; \
  4648. mif_.driver = &mg_tcpip_driver_same54; \
  4649. mif_.driver_data = &driver_data_; \
  4650. MG_SET_MAC_ADDRESS(mif_.mac); \
  4651. mg_tcpip_init(mgr, &mif_); \
  4652. MG_INFO(("Driver: same54, MAC: %M", mg_print_mac, mif_.mac)); \
  4653. } while (0)
  4654. #endif
  4655. #if MG_ENABLE_TCPIP && \
  4656. (defined(MG_ENABLE_DRIVER_CYW_SDIO) && MG_ENABLE_DRIVER_CYW_SDIO)
  4657. // Specific chip/card driver --> SDIO driver --> HAL --> SDIO hw controller
  4658. // API with HAL for hardware controller
  4659. // - Provide a function to init the controller (external)
  4660. // - Provide these functions:
  4661. struct mg_tcpip_sdio {
  4662. void *sdio; // Opaque SDIO bus descriptor
  4663. void (*cfg)(void *, uint8_t); // select operating parameters
  4664. // SDIO transaction: send cmd with a possible 1-byte read or write
  4665. bool (*txn)(void *, uint8_t cmd, uint32_t arg, uint32_t *r);
  4666. // SDIO extended transaction: write or read len bytes, using blksz blocks
  4667. bool (*xfr)(void *, bool write, uint32_t arg, uint16_t blksz, uint32_t *,
  4668. uint32_t len, uint32_t *r);
  4669. };
  4670. // API with driver (e.g.: cyw.c)
  4671. // Once the hardware controller has been initialized:
  4672. // - Init card: selects the card, sets F0 block size, sets bus width and speed
  4673. bool mg_sdio_init(struct mg_tcpip_sdio *sdio);
  4674. // - Enable other possible functions (F1 to F7)
  4675. bool mg_sdio_enable_f(struct mg_tcpip_sdio *sdio, unsigned int f);
  4676. // - Wait for them to be ready
  4677. bool mg_sdio_waitready_f(struct mg_tcpip_sdio *sdio, unsigned int f);
  4678. // - Set their transfer block length
  4679. bool mg_sdio_set_blksz(struct mg_tcpip_sdio *sdio, unsigned int f,
  4680. uint16_t blksz);
  4681. // - Transfer data to/from a function (abstracts from transaction type)
  4682. // - Requesting a read transfer > blocksize means block transfer will be used.
  4683. // - Drivers must have room to accomodate a whole block transfer, see sdio.c
  4684. // - Transfers of > 1 byte --> (uint32_t *) data. 1-byte --> (uint8_t *) data
  4685. bool mg_sdio_transfer(struct mg_tcpip_sdio *sdio, bool write, unsigned int f,
  4686. uint32_t addr, void *data, uint32_t len);
  4687. #endif
  4688. #if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_ST67W6) && \
  4689. MG_ENABLE_DRIVER_ST67W6
  4690. struct mg_tcpip_driver_st67w6_data {
  4691. struct mg_wifi_data wifi;
  4692. void *spi;
  4693. bool (*is_ready)(void); // return state of module RDY pin
  4694. struct mg_queue send_queue; // decouple tx calls from module polls
  4695. };
  4696. #define MG_TCPIP_DRIVER_INIT(mgr) \
  4697. do { \
  4698. static struct mg_tcpip_driver_st67w6_data driver_data_; \
  4699. static struct mg_tcpip_if mif_; \
  4700. MG_SET_WIFI_CONFIG(&mif_, &driver_data_); \
  4701. mif_.ip = MG_TCPIP_IP; \
  4702. mif_.mask = MG_TCPIP_MASK; \
  4703. mif_.gw = MG_TCPIP_GW; \
  4704. mif_.driver = &mg_tcpip_driver_st67w6; \
  4705. mif_.driver_data = &driver_data_; \
  4706. mif_.recv_queue.size = 8192; \
  4707. mif_.mac[0] = 2; /* MAC read from OTP at driver init */ \
  4708. mg_tcpip_init(mgr, &mif_); \
  4709. MG_INFO(("Driver: st67w6, MAC: %M", mg_print_mac, mif_.mac)); \
  4710. } while (0)
  4711. #endif
  4712. #if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_STM32F) && \
  4713. MG_ENABLE_DRIVER_STM32F
  4714. struct mg_tcpip_driver_stm32f_data {
  4715. // MDC clock divider. MDC clock is derived from HCLK, must not exceed 2.5MHz
  4716. // HCLK range DIVIDER mdc_cr VALUE
  4717. // -------------------------------------
  4718. // -1 <-- tell driver to guess the value
  4719. // 60-100 MHz HCLK/42 0
  4720. // 100-150 MHz HCLK/62 1
  4721. // 20-35 MHz HCLK/16 2
  4722. // 35-60 MHz HCLK/26 3
  4723. // 150-216 MHz HCLK/102 4 <-- value for Nucleo-F* on max speed
  4724. // 216-310 MHz HCLK/124 5
  4725. // 110, 111 Reserved
  4726. int mdc_cr; // Valid values: -1, 0, 1, 2, 3, 4, 5
  4727. uint8_t phy_addr; // PHY address
  4728. };
  4729. #ifndef MG_TCPIP_PHY_ADDR
  4730. #define MG_TCPIP_PHY_ADDR 0
  4731. #endif
  4732. #ifndef MG_DRIVER_MDC_CR
  4733. #define MG_DRIVER_MDC_CR 4
  4734. #endif
  4735. #if MG_ARCH == MG_ARCH_CUBE && !defined(MG_ENABLE_ETH_IRQ)
  4736. #define MG_ENABLE_ETH_IRQ() NVIC_EnableIRQ(ETH_IRQn)
  4737. #elif !defined(MG_ENABLE_ETH_IRQ)
  4738. #define MG_ENABLE_ETH_IRQ()
  4739. #endif
  4740. #define MG_TCPIP_DRIVER_INIT(mgr) \
  4741. do { \
  4742. static struct mg_tcpip_driver_stm32f_data driver_data_; \
  4743. static struct mg_tcpip_if mif_; \
  4744. driver_data_.mdc_cr = MG_DRIVER_MDC_CR; \
  4745. driver_data_.phy_addr = MG_TCPIP_PHY_ADDR; \
  4746. mif_.ip = MG_TCPIP_IP; \
  4747. mif_.mask = MG_TCPIP_MASK; \
  4748. mif_.gw = MG_TCPIP_GW; \
  4749. mif_.driver = &mg_tcpip_driver_stm32f; \
  4750. mif_.driver_data = &driver_data_; \
  4751. MG_SET_MAC_ADDRESS(mif_.mac); \
  4752. MG_ENABLE_ETH_IRQ(); \
  4753. mg_tcpip_init(mgr, &mif_); \
  4754. MG_INFO(("Driver: stm32f, MAC: %M", mg_print_mac, mif_.mac)); \
  4755. } while (0)
  4756. #endif
  4757. #if MG_ENABLE_TCPIP
  4758. #if !defined(MG_ENABLE_DRIVER_STM32H)
  4759. #define MG_ENABLE_DRIVER_STM32H 0
  4760. #endif
  4761. #if !defined(MG_ENABLE_DRIVER_MCXN)
  4762. #define MG_ENABLE_DRIVER_MCXN 0
  4763. #endif
  4764. #if !defined(MG_ENABLE_DRIVER_STM32N)
  4765. #define MG_ENABLE_DRIVER_STM32N 0
  4766. #endif
  4767. #if MG_ENABLE_DRIVER_STM32H || MG_ENABLE_DRIVER_MCXN || MG_ENABLE_DRIVER_STM32N
  4768. struct mg_tcpip_driver_stm32h_data {
  4769. // MDC clock divider. MDC clock is derived from HCLK, must not exceed 2.5MHz
  4770. // HCLK range DIVIDER mdc_cr VALUE
  4771. // -------------------------------------
  4772. // -1 <-- tell driver to guess the value
  4773. // 60-100 MHz HCLK/42 0
  4774. // 100-150 MHz HCLK/62 1
  4775. // 20-35 MHz HCLK/16 2
  4776. // 35-60 MHz HCLK/26 3
  4777. // 150-250 MHz HCLK/102 4 <-- value for max speed HSI
  4778. // 250-300 MHz HCLK/124 5 <-- value for Nucleo-H* on CSI
  4779. // 300-500 MHz HCLK/204 6
  4780. // 500-800 MHz HCLK/324 7
  4781. int mdc_cr; // Valid values: -1, 0, 1, 2, 3, 4, 5
  4782. uint8_t phy_addr; // PHY address
  4783. uint8_t phy_conf; // PHY config
  4784. };
  4785. #ifndef MG_TCPIP_PHY_CONF
  4786. #define MG_TCPIP_PHY_CONF MG_PHY_CLOCKS_MAC
  4787. #endif
  4788. #ifndef MG_TCPIP_PHY_ADDR
  4789. #define MG_TCPIP_PHY_ADDR 0
  4790. #endif
  4791. #ifndef MG_DRIVER_MDC_CR
  4792. #define MG_DRIVER_MDC_CR 4
  4793. #endif
  4794. #if MG_ENABLE_DRIVER_STM32H && MG_ARCH == MG_ARCH_CUBE && !defined(MG_ENABLE_ETH_IRQ)
  4795. #define MG_ENABLE_ETH_IRQ() NVIC_EnableIRQ(ETH_IRQn)
  4796. #elif MG_ENABLE_DRIVER_STM32N && MG_ARCH == MG_ARCH_CUBE && !defined(MG_ENABLE_ETH_IRQ)
  4797. #define MG_ENABLE_ETH_IRQ() NVIC_EnableIRQ(ETH1_IRQn)
  4798. #elif !defined(MG_ENABLE_ETH_IRQ)
  4799. #define MG_ENABLE_ETH_IRQ()
  4800. #endif
  4801. #if MG_ENABLE_IPV6
  4802. #define MG_IPV6_INIT(mif) \
  4803. do { \
  4804. memcpy(mif.ip6ll, (uint8_t[16]) MG_TCPIP_IPV6_LINKLOCAL, 16); \
  4805. memcpy(mif.ip6, (uint8_t[16]) MG_TCPIP_GLOBAL, 16); \
  4806. memcpy(mif.gw6, (uint8_t[16]) MG_TCPIP_GW6, 16); \
  4807. mif.prefix_len = MG_TCPIP_PREFIX_LEN; \
  4808. } while(0)
  4809. #else
  4810. #define MG_IPV6_INIT(mif)
  4811. #endif
  4812. #define MG_TCPIP_DRIVER_INIT(mgr) \
  4813. do { \
  4814. static struct mg_tcpip_driver_stm32h_data driver_data_; \
  4815. static struct mg_tcpip_if mif_; \
  4816. driver_data_.mdc_cr = MG_DRIVER_MDC_CR; \
  4817. driver_data_.phy_addr = MG_TCPIP_PHY_ADDR; \
  4818. driver_data_.phy_conf = MG_TCPIP_PHY_CONF; \
  4819. mif_.ip = MG_TCPIP_IP; \
  4820. mif_.mask = MG_TCPIP_MASK; \
  4821. mif_.gw = MG_TCPIP_GW; \
  4822. mif_.driver = &mg_tcpip_driver_stm32h; \
  4823. mif_.driver_data = &driver_data_; \
  4824. MG_SET_MAC_ADDRESS(mif_.mac); \
  4825. MG_IPV6_INIT(mif_); \
  4826. mg_tcpip_init(mgr, &mif_); \
  4827. MG_ENABLE_ETH_IRQ(); \
  4828. MG_INFO(("Driver: stm32h, MAC: %M", mg_print_mac, mif_.mac)); \
  4829. } while (0)
  4830. #endif
  4831. #endif
  4832. #if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_TM4C) && MG_ENABLE_DRIVER_TM4C
  4833. struct mg_tcpip_driver_tm4c_data {
  4834. // MDC clock divider. MDC clock is derived from SYSCLK, must not exceed 2.5MHz
  4835. // SYSCLK range DIVIDER mdc_cr VALUE
  4836. // -------------------------------------
  4837. // -1 <-- tell driver to guess the value
  4838. // 60-100 MHz SYSCLK/42 0
  4839. // 100-150 MHz SYSCLK/62 1 <-- value for EK-TM4C129* on max speed
  4840. // 20-35 MHz SYSCLK/16 2
  4841. // 35-60 MHz SYSCLK/26 3
  4842. // 0x4-0xF Reserved
  4843. int mdc_cr; // Valid values: -1, 0, 1, 2, 3
  4844. };
  4845. #ifndef MG_DRIVER_MDC_CR
  4846. #define MG_DRIVER_MDC_CR 1
  4847. #endif
  4848. #define MG_TCPIP_DRIVER_INIT(mgr) \
  4849. do { \
  4850. static struct mg_tcpip_driver_tm4c_data driver_data_; \
  4851. static struct mg_tcpip_if mif_; \
  4852. driver_data_.mdc_cr = MG_DRIVER_MDC_CR; \
  4853. mif_.ip = MG_TCPIP_IP; \
  4854. mif_.mask = MG_TCPIP_MASK; \
  4855. mif_.gw = MG_TCPIP_GW; \
  4856. mif_.driver = &mg_tcpip_driver_tm4c; \
  4857. mif_.driver_data = &driver_data_; \
  4858. MG_SET_MAC_ADDRESS(mif_.mac); \
  4859. mg_tcpip_init(mgr, &mif_); \
  4860. MG_INFO(("Driver: tm4c, MAC: %M", mg_print_mac, mif_.mac)); \
  4861. } while (0)
  4862. #endif
  4863. #if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_TMS570) && MG_ENABLE_DRIVER_TMS570
  4864. struct mg_tcpip_driver_tms570_data {
  4865. int mdc_cr;
  4866. int phy_addr;
  4867. };
  4868. #ifndef MG_TCPIP_PHY_ADDR
  4869. #define MG_TCPIP_PHY_ADDR 0
  4870. #endif
  4871. #ifndef MG_DRIVER_MDC_CR
  4872. #define MG_DRIVER_MDC_CR 1
  4873. #endif
  4874. #define MG_TCPIP_DRIVER_INIT(mgr) \
  4875. do { \
  4876. static struct mg_tcpip_driver_tms570_data driver_data_; \
  4877. static struct mg_tcpip_if mif_; \
  4878. driver_data_.mdc_cr = MG_DRIVER_MDC_CR; \
  4879. driver_data_.phy_addr = MG_TCPIP_PHY_ADDR; \
  4880. mif_.ip = MG_TCPIP_IP; \
  4881. mif_.mask = MG_TCPIP_MASK; \
  4882. mif_.gw = MG_TCPIP_GW; \
  4883. mif_.driver = &mg_tcpip_driver_tms570; \
  4884. mif_.driver_data = &driver_data_; \
  4885. MG_SET_MAC_ADDRESS(mif_.mac); \
  4886. mg_tcpip_init(mgr, &mif_); \
  4887. MG_INFO(("Driver: tms570, MAC: %M", mg_print_mac, mif_.mac));\
  4888. } while (0)
  4889. #endif
  4890. #if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_XMC) && MG_ENABLE_DRIVER_XMC
  4891. struct mg_tcpip_driver_xmc_data {
  4892. // 13.2.8.1 Station Management Functions
  4893. // MDC clock divider (). MDC clock is derived from ETH MAC clock
  4894. // It must not exceed 2.5MHz
  4895. // ETH Clock range DIVIDER mdc_cr VALUE
  4896. // --------------------------------------------
  4897. // -1 <-- tell driver to guess the value
  4898. // 60-100 MHz ETH Clock/42 0
  4899. // 100-150 MHz ETH Clock/62 1
  4900. // 20-35 MHz ETH Clock/16 2
  4901. // 35-60 MHz ETH Clock/26 3
  4902. // 150-250 MHz ETH Clock/102 4
  4903. // 250-300 MHz ETH Clock/124 5
  4904. // 110, 111 Reserved
  4905. int mdc_cr; // Valid values: -1, 0, 1, 2, 3, 4, 5
  4906. uint8_t phy_addr;
  4907. };
  4908. #ifndef MG_TCPIP_PHY_ADDR
  4909. #define MG_TCPIP_PHY_ADDR 0
  4910. #endif
  4911. #ifndef MG_DRIVER_MDC_CR
  4912. #define MG_DRIVER_MDC_CR 4
  4913. #endif
  4914. #define MG_TCPIP_DRIVER_INIT(mgr) \
  4915. do { \
  4916. static struct mg_tcpip_driver_xmc_data driver_data_; \
  4917. static struct mg_tcpip_if mif_; \
  4918. driver_data_.mdc_cr = MG_DRIVER_MDC_CR; \
  4919. driver_data_.phy_addr = MG_TCPIP_PHY_ADDR; \
  4920. mif_.ip = MG_TCPIP_IP; \
  4921. mif_.mask = MG_TCPIP_MASK; \
  4922. mif_.gw = MG_TCPIP_GW; \
  4923. mif_.driver = &mg_tcpip_driver_xmc; \
  4924. mif_.driver_data = &driver_data_; \
  4925. MG_SET_MAC_ADDRESS(mif_.mac); \
  4926. mg_tcpip_init(mgr, &mif_); \
  4927. MG_INFO(("Driver: xmc, MAC: %M", mg_print_mac, mif_.mac)); \
  4928. } while (0)
  4929. #endif
  4930. #if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_XMC7) && MG_ENABLE_DRIVER_XMC7
  4931. struct mg_tcpip_driver_xmc7_data {
  4932. int mdc_cr; // Valid values: -1, 0, 1, 2, 3, 4, 5
  4933. uint8_t phy_addr;
  4934. };
  4935. #ifndef MG_TCPIP_PHY_ADDR
  4936. #define MG_TCPIP_PHY_ADDR 0
  4937. #endif
  4938. #ifndef MG_DRIVER_MDC_CR
  4939. #define MG_DRIVER_MDC_CR 3
  4940. #endif
  4941. #define MG_TCPIP_DRIVER_INIT(mgr) \
  4942. do { \
  4943. static struct mg_tcpip_driver_xmc7_data driver_data_; \
  4944. static struct mg_tcpip_if mif_; \
  4945. driver_data_.mdc_cr = MG_DRIVER_MDC_CR; \
  4946. driver_data_.phy_addr = MG_TCPIP_PHY_ADDR; \
  4947. mif_.ip = MG_TCPIP_IP; \
  4948. mif_.mask = MG_TCPIP_MASK; \
  4949. mif_.gw = MG_TCPIP_GW; \
  4950. mif_.driver = &mg_tcpip_driver_xmc7; \
  4951. mif_.driver_data = &driver_data_; \
  4952. MG_SET_MAC_ADDRESS(mif_.mac); \
  4953. mg_tcpip_init(mgr, &mif_); \
  4954. MG_INFO(("Driver: xmc7, MAC: %M", mg_print_mac, mif_.mac)); \
  4955. } while (0)
  4956. #endif
  4957. #ifdef __cplusplus
  4958. }
  4959. #endif
  4960. #endif // MONGOOSE_H