mongoose.h 108 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288
  1. // Copyright (c) 2004-2013 Sergey Lyubka
  2. // Copyright (c) 2013-2024 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.16"
  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
  31. #define MG_ARCH_AZURERTOS 6 // MS Azure RTOS
  32. #define MG_ARCH_ZEPHYR 7 // Zephyr RTOS
  33. #define MG_ARCH_NEWLIB 8 // Bare metal ARM
  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. #if !defined(MG_ARCH)
  42. #if defined(__unix__) || defined(__APPLE__)
  43. #define MG_ARCH MG_ARCH_UNIX
  44. #elif defined(_WIN32)
  45. #define MG_ARCH MG_ARCH_WIN32
  46. #endif
  47. #endif // !defined(MG_ARCH)
  48. #if !defined(MG_ARCH) || (MG_ARCH == MG_ARCH_CUSTOM)
  49. #include "mongoose_config.h" // keep this include
  50. #endif
  51. #if !defined(MG_ARCH)
  52. #error "MG_ARCH is not specified and we couldn't guess it. Define MG_ARCH=... in your compiler"
  53. #endif
  54. // http://esr.ibiblio.org/?p=5095
  55. #define MG_BIG_ENDIAN (*(uint16_t *) "\0\xff" < 0x100)
  56. #if MG_ARCH == MG_ARCH_ARMCGT
  57. #include <ctype.h>
  58. #include <errno.h>
  59. #include <stdarg.h>
  60. #include <stdbool.h>
  61. #include <stdio.h>
  62. #include <stdlib.h>
  63. #include <string.h>
  64. #include <sys/types.h>
  65. #include <time.h>
  66. #define MG_PATH_MAX 100
  67. #define MG_ENABLE_SOCKET 0
  68. #define MG_ENABLE_DIRLIST 0
  69. #endif
  70. #if MG_ARCH == MG_ARCH_AZURERTOS
  71. #include <stdarg.h>
  72. #include <stdbool.h>
  73. #include <stdint.h>
  74. #include <stdio.h>
  75. #include <time.h>
  76. #include <fx_api.h>
  77. #include <tx_api.h>
  78. #include <nx_api.h>
  79. #include <nx_bsd.h>
  80. #include <nx_port.h>
  81. #include <tx_port.h>
  82. #define PATH_MAX FX_MAXIMUM_PATH
  83. #define MG_DIRSEP '\\'
  84. #define socklen_t int
  85. #define closesocket(x) soc_close(x)
  86. #undef FOPEN_MAX
  87. #endif
  88. #if MG_ARCH == MG_ARCH_ESP32
  89. #include <ctype.h>
  90. #include <dirent.h>
  91. #include <errno.h>
  92. #include <fcntl.h>
  93. #include <limits.h>
  94. #include <netdb.h>
  95. #include <stdarg.h>
  96. #include <stddef.h>
  97. #include <stdio.h>
  98. #include <stdlib.h>
  99. #include <string.h>
  100. #include <sys/stat.h>
  101. #include <sys/types.h>
  102. #include <time.h>
  103. #include <esp_ota_ops.h> // Use angle brackets to avoid
  104. #include <esp_timer.h> // amalgamation ditching them
  105. #define MG_PATH_MAX 128
  106. #endif
  107. #if MG_ARCH == MG_ARCH_ESP8266
  108. #include <ctype.h>
  109. #include <dirent.h>
  110. #include <errno.h>
  111. #include <fcntl.h>
  112. #include <limits.h>
  113. #include <netdb.h>
  114. #include <stdarg.h>
  115. #include <stdbool.h>
  116. #include <stddef.h>
  117. #include <stdio.h>
  118. #include <stdlib.h>
  119. #include <string.h>
  120. #include <sys/stat.h>
  121. #include <sys/time.h>
  122. #include <sys/types.h>
  123. #include <time.h>
  124. #include <esp_system.h>
  125. #define MG_PATH_MAX 128
  126. #endif
  127. #if MG_ARCH == MG_ARCH_FREERTOS
  128. #include <ctype.h>
  129. #if !defined(MG_ENABLE_LWIP) || !MG_ENABLE_LWIP
  130. #include <errno.h>
  131. #endif
  132. #include <stdarg.h>
  133. #include <stdbool.h>
  134. #include <stddef.h>
  135. #include <stdint.h>
  136. #include <stdio.h>
  137. #include <stdlib.h> // rand(), strtol(), atoi()
  138. #include <string.h>
  139. #if defined(__ARMCC_VERSION)
  140. #define mode_t size_t
  141. #include <alloca.h>
  142. #include <time.h>
  143. #elif defined(__CCRH__)
  144. #else
  145. #include <sys/stat.h>
  146. #endif
  147. #include <FreeRTOS.h>
  148. #include <task.h>
  149. #define calloc(a, b) mg_calloc(a, b)
  150. #define free(a) vPortFree(a)
  151. #define malloc(a) pvPortMalloc(a)
  152. #define strdup(s) ((char *) mg_strdup(mg_str(s)).buf)
  153. // Re-route calloc/free to the FreeRTOS's functions, don't use stdlib
  154. static inline void *mg_calloc(size_t cnt, size_t size) {
  155. void *p = pvPortMalloc(cnt * size);
  156. if (p != NULL) memset(p, 0, size * cnt);
  157. return p;
  158. }
  159. #define mkdir(a, b) mg_mkdir(a, b)
  160. static inline int mg_mkdir(const char *path, mode_t mode) {
  161. (void) path, (void) mode;
  162. return -1;
  163. }
  164. #endif // MG_ARCH == MG_ARCH_FREERTOS
  165. #if MG_ARCH == MG_ARCH_NEWLIB
  166. #define _POSIX_TIMERS
  167. #include <ctype.h>
  168. #include <errno.h>
  169. #include <stdarg.h>
  170. #include <stdbool.h>
  171. #include <stdio.h>
  172. #include <stdlib.h>
  173. #include <string.h>
  174. #include <sys/stat.h>
  175. #include <sys/time.h>
  176. #include <sys/types.h>
  177. #include <time.h>
  178. #include <unistd.h>
  179. #define MG_PATH_MAX 100
  180. #define MG_ENABLE_SOCKET 0
  181. #define MG_ENABLE_DIRLIST 0
  182. #endif
  183. #if MG_ARCH == MG_ARCH_PICOSDK
  184. #if !defined(MG_ENABLE_LWIP) || !MG_ENABLE_LWIP
  185. #include <errno.h>
  186. #endif
  187. #include <stdarg.h>
  188. #include <stdbool.h>
  189. #include <stdint.h>
  190. #include <stdio.h>
  191. #include <stdlib.h>
  192. #include <string.h>
  193. #include <time.h>
  194. #include <pico/stdlib.h>
  195. #include <pico/rand.h>
  196. int mkdir(const char *, mode_t);
  197. #if MG_OTA == MG_OTA_PICOSDK
  198. #include <hardware/flash.h>
  199. #if PICO_RP2040
  200. #include <pico/bootrom.h>
  201. #endif
  202. #endif
  203. #endif
  204. #if MG_ARCH == MG_ARCH_RTTHREAD
  205. #include <rtthread.h>
  206. #include <ctype.h>
  207. #include <errno.h>
  208. #include <fcntl.h>
  209. #include <sys/socket.h>
  210. #include <sys/select.h>
  211. #include <stdarg.h>
  212. #include <stdbool.h>
  213. #include <stdint.h>
  214. #include <stdio.h>
  215. #include <stdlib.h>
  216. #include <string.h>
  217. #include <sys/types.h>
  218. #include <time.h>
  219. #ifndef MG_IO_SIZE
  220. #define MG_IO_SIZE 1460
  221. #endif
  222. #endif // MG_ARCH == MG_ARCH_RTTHREAD
  223. #if MG_ARCH == MG_ARCH_ARMCC || MG_ARCH == MG_ARCH_CMSIS_RTOS1 || \
  224. MG_ARCH == MG_ARCH_CMSIS_RTOS2
  225. #include <ctype.h>
  226. #include <errno.h>
  227. #include <stdarg.h>
  228. #include <stdbool.h>
  229. #include <stddef.h>
  230. #include <stdint.h>
  231. #include <stdio.h>
  232. #include <stdlib.h>
  233. #include <alloca.h>
  234. #include <string.h>
  235. #include <time.h>
  236. #if MG_ARCH == MG_ARCH_CMSIS_RTOS1
  237. #include "cmsis_os.h" // keep this include
  238. // https://developer.arm.com/documentation/ka003821/latest
  239. extern uint32_t rt_time_get(void);
  240. #elif MG_ARCH == MG_ARCH_CMSIS_RTOS2
  241. #include "cmsis_os2.h" // keep this include
  242. #endif
  243. #define strdup(s) ((char *) mg_strdup(mg_str(s)).buf)
  244. #if defined(__ARMCC_VERSION)
  245. #define mode_t size_t
  246. #define mkdir(a, b) mg_mkdir(a, b)
  247. static inline int mg_mkdir(const char *path, mode_t mode) {
  248. (void) path, (void) mode;
  249. return -1;
  250. }
  251. #endif
  252. #if (MG_ARCH == MG_ARCH_CMSIS_RTOS1 || MG_ARCH == MG_ARCH_CMSIS_RTOS2) && \
  253. !defined MG_ENABLE_RL && (!defined(MG_ENABLE_LWIP) || !MG_ENABLE_LWIP) && \
  254. (!defined(MG_ENABLE_TCPIP) || !MG_ENABLE_TCPIP)
  255. #define MG_ENABLE_RL 1
  256. #ifndef MG_SOCK_LISTEN_BACKLOG_SIZE
  257. #define MG_SOCK_LISTEN_BACKLOG_SIZE 3
  258. #endif
  259. #endif
  260. #endif
  261. #if MG_ARCH == MG_ARCH_TIRTOS
  262. #include <stdlib.h>
  263. #include <ctype.h>
  264. #include <stdarg.h>
  265. #include <stdbool.h>
  266. #include <stdint.h>
  267. #include <stdio.h>
  268. #include <string.h>
  269. #include <time.h>
  270. #include <serrno.h>
  271. #include <sys/socket.h>
  272. #include <ti/sysbios/knl/Clock.h>
  273. #endif
  274. #if MG_ARCH == MG_ARCH_UNIX
  275. #define _DARWIN_UNLIMITED_SELECT 1 // No limit on file descriptors
  276. #if defined(__APPLE__)
  277. #include <mach/mach_time.h>
  278. #endif
  279. #if !defined(MG_ENABLE_EPOLL) && defined(__linux__)
  280. #define MG_ENABLE_EPOLL 1
  281. #elif !defined(MG_ENABLE_POLL)
  282. #define MG_ENABLE_POLL 1
  283. #endif
  284. #include <arpa/inet.h>
  285. #include <ctype.h>
  286. #include <dirent.h>
  287. #include <errno.h>
  288. #include <fcntl.h>
  289. #include <inttypes.h>
  290. #include <limits.h>
  291. #include <netdb.h>
  292. #include <netinet/in.h>
  293. #include <netinet/tcp.h>
  294. #include <signal.h>
  295. #include <stdarg.h>
  296. #include <stdbool.h>
  297. #include <stddef.h>
  298. #include <stdint.h>
  299. #include <stdio.h>
  300. #include <stdlib.h>
  301. #include <string.h>
  302. #if defined(MG_ENABLE_EPOLL) && MG_ENABLE_EPOLL
  303. #include <sys/epoll.h>
  304. #elif defined(MG_ENABLE_POLL) && MG_ENABLE_POLL
  305. #include <poll.h>
  306. #else
  307. #include <sys/select.h>
  308. #endif
  309. #include <sys/socket.h>
  310. #include <sys/stat.h>
  311. #include <sys/time.h>
  312. #include <sys/types.h>
  313. #include <time.h>
  314. #include <unistd.h>
  315. #ifndef MG_ENABLE_DIRLIST
  316. #define MG_ENABLE_DIRLIST 1
  317. #endif
  318. #ifndef MG_PATH_MAX
  319. #define MG_PATH_MAX FILENAME_MAX
  320. #endif
  321. #ifndef MG_ENABLE_POSIX_FS
  322. #define MG_ENABLE_POSIX_FS 1
  323. #endif
  324. #ifndef MG_IO_SIZE
  325. #define MG_IO_SIZE 16384
  326. #endif
  327. #endif
  328. #if MG_ARCH == MG_ARCH_WIN32
  329. #ifndef _CRT_RAND_S
  330. #define _CRT_RAND_S
  331. #endif
  332. #ifndef WIN32_LEAN_AND_MEAN
  333. #define WIN32_LEAN_AND_MEAN
  334. #endif
  335. #ifndef _CRT_SECURE_NO_WARNINGS
  336. #define _CRT_SECURE_NO_WARNINGS
  337. #endif
  338. #ifndef _WINSOCK_DEPRECATED_NO_WARNINGS
  339. #define _WINSOCK_DEPRECATED_NO_WARNINGS
  340. #endif
  341. #include <ctype.h>
  342. #include <direct.h>
  343. #include <errno.h>
  344. #include <fcntl.h>
  345. #include <limits.h>
  346. #include <signal.h>
  347. #include <stdarg.h>
  348. #include <stddef.h>
  349. #include <stdio.h>
  350. #include <stdlib.h>
  351. #include <string.h>
  352. #include <sys/stat.h>
  353. #include <sys/types.h>
  354. #include <time.h>
  355. #if defined(_MSC_VER) && _MSC_VER < 1700
  356. #define __func__ ""
  357. typedef __int64 int64_t;
  358. typedef unsigned __int64 uint64_t;
  359. typedef unsigned char uint8_t;
  360. typedef char int8_t;
  361. typedef unsigned short uint16_t;
  362. typedef short int16_t;
  363. typedef unsigned int uint32_t;
  364. typedef int int32_t;
  365. typedef enum { false = 0, true = 1 } bool;
  366. #else
  367. #include <stdbool.h>
  368. #include <stdint.h>
  369. #include <ws2tcpip.h>
  370. #endif
  371. #include <process.h>
  372. #include <winerror.h>
  373. #include <winsock2.h>
  374. // For mg_random()
  375. #if defined(_MSC_VER) && _MSC_VER < 1700
  376. #ifndef _WIN32_WINNT
  377. #define _WIN32_WINNT 0x400 // Let vc98 pick up wincrypt.h
  378. #endif
  379. #include <wincrypt.h>
  380. #pragma comment(lib, "advapi32.lib")
  381. #endif
  382. // Protect from calls like std::snprintf in app code
  383. // See https://github.com/cesanta/mongoose/issues/1047
  384. #ifndef __cplusplus
  385. #define snprintf _snprintf
  386. #define vsnprintf _vsnprintf
  387. #ifndef strdup // For MSVC with _DEBUG, see #1359
  388. #define strdup(x) _strdup(x)
  389. #endif
  390. #endif
  391. #define MG_INVALID_SOCKET INVALID_SOCKET
  392. #define MG_SOCKET_TYPE SOCKET
  393. typedef unsigned long nfds_t;
  394. #if defined(_MSC_VER)
  395. #pragma comment(lib, "ws2_32.lib")
  396. #ifndef alloca
  397. #define alloca(a) _alloca(a)
  398. #endif
  399. #endif
  400. #define poll(a, b, c) WSAPoll((a), (b), (c))
  401. #define closesocket(x) closesocket(x)
  402. typedef int socklen_t;
  403. #define MG_DIRSEP '\\'
  404. #ifndef MG_PATH_MAX
  405. #define MG_PATH_MAX FILENAME_MAX
  406. #endif
  407. #ifndef SO_EXCLUSIVEADDRUSE
  408. #define SO_EXCLUSIVEADDRUSE ((int) (~SO_REUSEADDR))
  409. #endif
  410. #define MG_SOCK_ERR(errcode) ((errcode) < 0 ? WSAGetLastError() : 0)
  411. #define MG_SOCK_PENDING(errcode) \
  412. (((errcode) < 0) && \
  413. (WSAGetLastError() == WSAEINTR || WSAGetLastError() == WSAEINPROGRESS || \
  414. WSAGetLastError() == WSAEWOULDBLOCK))
  415. #define MG_SOCK_RESET(errcode) \
  416. (((errcode) < 0) && (WSAGetLastError() == WSAECONNRESET))
  417. #define realpath(a, b) _fullpath((b), (a), MG_PATH_MAX)
  418. #define sleep(x) Sleep((x) * 1000)
  419. #define mkdir(a, b) _mkdir(a)
  420. #define timegm(x) _mkgmtime(x)
  421. #ifndef S_ISDIR
  422. #define S_ISDIR(x) (((x) & _S_IFMT) == _S_IFDIR)
  423. #endif
  424. #ifndef MG_ENABLE_DIRLIST
  425. #define MG_ENABLE_DIRLIST 1
  426. #endif
  427. #ifndef SIGPIPE
  428. #define SIGPIPE 0
  429. #endif
  430. #ifndef MG_ENABLE_POSIX_FS
  431. #define MG_ENABLE_POSIX_FS 1
  432. #endif
  433. #ifndef MG_IO_SIZE
  434. #define MG_IO_SIZE 16384
  435. #endif
  436. #endif
  437. #if MG_ARCH == MG_ARCH_ZEPHYR
  438. #include <zephyr/kernel.h>
  439. #include <ctype.h>
  440. #include <errno.h>
  441. #include <zephyr/net/socket.h>
  442. #include <zephyr/posix/fcntl.h>
  443. #include <zephyr/posix/sys/select.h>
  444. #include <stdarg.h>
  445. #include <stdbool.h>
  446. #include <stdint.h>
  447. #include <stdio.h>
  448. #include <stdlib.h>
  449. #include <string.h>
  450. #include <sys/types.h>
  451. #include <time.h>
  452. #define MG_PUTCHAR(x) printk("%c", x)
  453. #ifndef strdup
  454. #define strdup(s) ((char *) mg_strdup(mg_str(s)).buf)
  455. #endif
  456. #define strerror(x) zsock_gai_strerror(x)
  457. #ifndef FD_CLOEXEC
  458. #define FD_CLOEXEC 0
  459. #endif
  460. #ifndef F_SETFD
  461. #define F_SETFD 0
  462. #endif
  463. #define MG_ENABLE_SSI 0
  464. int rand(void);
  465. int sscanf(const char *, const char *, ...);
  466. #endif
  467. #if defined(MG_ENABLE_FREERTOS_TCP) && MG_ENABLE_FREERTOS_TCP
  468. #include <limits.h>
  469. #include <list.h>
  470. #include <FreeRTOS_IP.h>
  471. #include <FreeRTOS_Sockets.h>
  472. #define MG_SOCKET_TYPE Socket_t
  473. #define MG_INVALID_SOCKET FREERTOS_INVALID_SOCKET
  474. // Why FreeRTOS-TCP did not implement a clean BSD API, but its own thing
  475. // with FreeRTOS_ prefix, is beyond me
  476. #define IPPROTO_TCP FREERTOS_IPPROTO_TCP
  477. #define IPPROTO_UDP FREERTOS_IPPROTO_UDP
  478. #define AF_INET FREERTOS_AF_INET
  479. #define SOCK_STREAM FREERTOS_SOCK_STREAM
  480. #define SOCK_DGRAM FREERTOS_SOCK_DGRAM
  481. #define SO_BROADCAST 0
  482. #define SO_ERROR 0
  483. #define SOL_SOCKET 0
  484. #define SO_REUSEADDR 0
  485. #define MG_SOCK_ERR(errcode) ((errcode) < 0 ? (errcode) : 0)
  486. #define MG_SOCK_PENDING(errcode) \
  487. ((errcode) == -pdFREERTOS_ERRNO_EWOULDBLOCK || \
  488. (errcode) == -pdFREERTOS_ERRNO_EISCONN || \
  489. (errcode) == -pdFREERTOS_ERRNO_EINPROGRESS || \
  490. (errcode) == -pdFREERTOS_ERRNO_EAGAIN)
  491. #define MG_SOCK_RESET(errcode) ((errcode) == -pdFREERTOS_ERRNO_ENOTCONN)
  492. // actually only if optional timeout is enabled
  493. #define MG_SOCK_INTR(fd) (fd == NULL)
  494. #define sockaddr_in freertos_sockaddr
  495. #define sockaddr freertos_sockaddr
  496. #if ipFR_TCP_VERSION_MAJOR >= 4
  497. #define sin_addr sin_address.ulIP_IPv4
  498. #endif
  499. #define accept(a, b, c) FreeRTOS_accept((a), (b), (c))
  500. #define connect(a, b, c) FreeRTOS_connect((a), (b), (c))
  501. #define bind(a, b, c) FreeRTOS_bind((a), (b), (c))
  502. #define listen(a, b) FreeRTOS_listen((a), (b))
  503. #define socket(a, b, c) FreeRTOS_socket((a), (b), (c))
  504. #define send(a, b, c, d) FreeRTOS_send((a), (b), (c), (d))
  505. #define recv(a, b, c, d) FreeRTOS_recv((a), (b), (c), (d))
  506. #define setsockopt(a, b, c, d, e) FreeRTOS_setsockopt((a), (b), (c), (d), (e))
  507. #define sendto(a, b, c, d, e, f) FreeRTOS_sendto((a), (b), (c), (d), (e), (f))
  508. #define recvfrom(a, b, c, d, e, f) \
  509. FreeRTOS_recvfrom((a), (b), (c), (d), (e), (f))
  510. #define closesocket(x) FreeRTOS_closesocket(x)
  511. #define gethostbyname(x) FreeRTOS_gethostbyname(x)
  512. #define getsockname(a, b, c) mg_getsockname((a), (b), (c))
  513. #define getpeername(a, b, c) mg_getpeername((a), (b), (c))
  514. static inline int mg_getsockname(MG_SOCKET_TYPE fd, void *buf, socklen_t *len) {
  515. (void) fd, (void) buf, (void) len;
  516. return -1;
  517. }
  518. static inline int mg_getpeername(MG_SOCKET_TYPE fd, void *buf, socklen_t *len) {
  519. (void) fd, (void) buf, (void) len;
  520. return 0;
  521. }
  522. #endif
  523. #if defined(MG_ENABLE_LWIP) && MG_ENABLE_LWIP
  524. #if defined(__GNUC__) && !defined(__ARMCC_VERSION)
  525. #include <sys/stat.h>
  526. #endif
  527. struct timeval;
  528. #include <lwip/sockets.h>
  529. #if !LWIP_TIMEVAL_PRIVATE
  530. #if defined(__GNUC__) && !defined(__ARMCC_VERSION) // armclang sets both
  531. #include <sys/time.h>
  532. #else
  533. struct timeval {
  534. time_t tv_sec;
  535. long tv_usec;
  536. };
  537. #endif
  538. #endif
  539. #if LWIP_SOCKET != 1
  540. // Sockets support disabled in LWIP by default
  541. #error Set LWIP_SOCKET variable to 1 (in lwipopts.h)
  542. #endif
  543. #endif
  544. #if defined(MG_ENABLE_RL) && MG_ENABLE_RL
  545. #include <rl_net.h>
  546. #define closesocket(x) closesocket(x)
  547. #define TCP_NODELAY SO_KEEPALIVE
  548. #define MG_SOCK_ERR(errcode) ((errcode) < 0 ? (errcode) : 0)
  549. #define MG_SOCK_PENDING(errcode) \
  550. ((errcode) == BSD_EWOULDBLOCK || (errcode) == BSD_EALREADY || \
  551. (errcode) == BSD_EINPROGRESS)
  552. #define MG_SOCK_RESET(errcode) \
  553. ((errcode) == BSD_ECONNABORTED || (errcode) == BSD_ECONNRESET)
  554. // In blocking mode, which is enabled by default, accept() waits for a
  555. // connection request. In non blocking mode, you must call accept()
  556. // again if the error code BSD_EWOULDBLOCK is returned.
  557. #define MG_SOCK_INTR(fd) (fd == BSD_EWOULDBLOCK)
  558. #define socklen_t int
  559. #endif
  560. #ifndef MG_ENABLE_LOG
  561. #define MG_ENABLE_LOG 1
  562. #endif
  563. #ifndef MG_ENABLE_CUSTOM_LOG
  564. #define MG_ENABLE_CUSTOM_LOG 0 // Let user define their own MG_LOG
  565. #endif
  566. #ifndef MG_ENABLE_TCPIP
  567. #define MG_ENABLE_TCPIP 0 // Mongoose built-in network stack
  568. #endif
  569. #ifndef MG_ENABLE_LWIP
  570. #define MG_ENABLE_LWIP 0 // lWIP network stack
  571. #endif
  572. #ifndef MG_ENABLE_FREERTOS_TCP
  573. #define MG_ENABLE_FREERTOS_TCP 0 // Amazon FreeRTOS-TCP network stack
  574. #endif
  575. #ifndef MG_ENABLE_RL
  576. #define MG_ENABLE_RL 0 // ARM MDK network stack
  577. #endif
  578. #ifndef MG_ENABLE_SOCKET
  579. #define MG_ENABLE_SOCKET !MG_ENABLE_TCPIP
  580. #endif
  581. #ifndef MG_ENABLE_POLL
  582. #define MG_ENABLE_POLL 0
  583. #endif
  584. #ifndef MG_ENABLE_EPOLL
  585. #define MG_ENABLE_EPOLL 0
  586. #endif
  587. #ifndef MG_ENABLE_FATFS
  588. #define MG_ENABLE_FATFS 0
  589. #endif
  590. #ifndef MG_ENABLE_SSI
  591. #define MG_ENABLE_SSI 0
  592. #endif
  593. #ifndef MG_ENABLE_IPV6
  594. #define MG_ENABLE_IPV6 0
  595. #endif
  596. #ifndef MG_IPV6_V6ONLY
  597. #define MG_IPV6_V6ONLY 0 // IPv6 socket binds only to V6, not V4 address
  598. #endif
  599. #ifndef MG_ENABLE_MD5
  600. #define MG_ENABLE_MD5 1
  601. #endif
  602. // Set MG_ENABLE_WINSOCK=0 for Win32 builds with external IP stack (like LWIP)
  603. #ifndef MG_ENABLE_WINSOCK
  604. #define MG_ENABLE_WINSOCK 1
  605. #endif
  606. #ifndef MG_ENABLE_DIRLIST
  607. #define MG_ENABLE_DIRLIST 0
  608. #endif
  609. #ifndef MG_ENABLE_CUSTOM_RANDOM
  610. #define MG_ENABLE_CUSTOM_RANDOM 0
  611. #endif
  612. #ifndef MG_ENABLE_CUSTOM_MILLIS
  613. #define MG_ENABLE_CUSTOM_MILLIS 0
  614. #endif
  615. #ifndef MG_ENABLE_PACKED_FS
  616. #define MG_ENABLE_PACKED_FS 0
  617. #endif
  618. #ifndef MG_ENABLE_ASSERT
  619. #define MG_ENABLE_ASSERT 0
  620. #endif
  621. #ifndef MG_IO_SIZE
  622. #define MG_IO_SIZE 256 // Granularity of the send/recv IO buffer growth
  623. #endif
  624. #ifndef MG_MAX_RECV_SIZE
  625. #define MG_MAX_RECV_SIZE (3UL * 1024UL * 1024UL) // Maximum recv IO buffer size
  626. #endif
  627. #ifndef MG_DATA_SIZE
  628. #define MG_DATA_SIZE 32 // struct mg_connection :: data size
  629. #endif
  630. #ifndef MG_MAX_HTTP_HEADERS
  631. #define MG_MAX_HTTP_HEADERS 30
  632. #endif
  633. #ifndef MG_HTTP_INDEX
  634. #define MG_HTTP_INDEX "index.html"
  635. #endif
  636. #ifndef MG_PATH_MAX
  637. #ifdef PATH_MAX
  638. #define MG_PATH_MAX PATH_MAX
  639. #else
  640. #define MG_PATH_MAX 128
  641. #endif
  642. #endif
  643. #ifndef MG_SOCK_LISTEN_BACKLOG_SIZE
  644. #define MG_SOCK_LISTEN_BACKLOG_SIZE 128
  645. #endif
  646. #ifndef MG_DIRSEP
  647. #define MG_DIRSEP '/'
  648. #endif
  649. #ifndef MG_ENABLE_POSIX_FS
  650. #define MG_ENABLE_POSIX_FS 0
  651. #endif
  652. #ifndef MG_INVALID_SOCKET
  653. #define MG_INVALID_SOCKET (-1)
  654. #endif
  655. #ifndef MG_SOCKET_TYPE
  656. #define MG_SOCKET_TYPE int
  657. #endif
  658. #ifndef MG_SOCKET_ERRNO
  659. #define MG_SOCKET_ERRNO errno
  660. #endif
  661. #if MG_ENABLE_EPOLL
  662. #define MG_EPOLL_ADD(c) \
  663. do { \
  664. struct epoll_event ev = {EPOLLIN | EPOLLERR | EPOLLHUP, {c}}; \
  665. epoll_ctl(c->mgr->epoll_fd, EPOLL_CTL_ADD, (int) (size_t) c->fd, &ev); \
  666. } while (0)
  667. #define MG_EPOLL_MOD(c, wr) \
  668. do { \
  669. struct epoll_event ev = {EPOLLIN | EPOLLERR | EPOLLHUP, {c}}; \
  670. if (wr) ev.events |= EPOLLOUT; \
  671. epoll_ctl(c->mgr->epoll_fd, EPOLL_CTL_MOD, (int) (size_t) c->fd, &ev); \
  672. } while (0)
  673. #else
  674. #define MG_EPOLL_ADD(c)
  675. #define MG_EPOLL_MOD(c, wr)
  676. #endif
  677. #ifndef MG_ENABLE_PROFILE
  678. #define MG_ENABLE_PROFILE 0
  679. #endif
  680. #ifndef MG_ENABLE_TCPIP_DRIVER_INIT // mg_mgr_init() will also initialize
  681. #define MG_ENABLE_TCPIP_DRIVER_INIT 1 // enabled built-in driver for
  682. #endif // Mongoose built-in network stack
  683. #ifndef MG_TCPIP_IP // e.g. MG_IPV4(192, 168, 0, 223)
  684. #define MG_TCPIP_IP MG_IPV4(0, 0, 0, 0) // Default is 0.0.0.0 (DHCP)
  685. #endif
  686. #ifndef MG_TCPIP_MASK
  687. #define MG_TCPIP_MASK MG_IPV4(0, 0, 0, 0) // Default is 0.0.0.0 (DHCP)
  688. #endif
  689. #ifndef MG_TCPIP_GW
  690. #define MG_TCPIP_GW MG_IPV4(0, 0, 0, 0) // Default is 0.0.0.0 (DHCP)
  691. #endif
  692. #ifndef MG_SET_MAC_ADDRESS
  693. #define MG_SET_MAC_ADDRESS(mac)
  694. #endif
  695. #ifndef MG_SET_WIFI_CREDS
  696. #define MG_SET_WIFI_CREDS(ssid, pass)
  697. #endif
  698. #ifndef MG_ENABLE_TCPIP_PRINT_DEBUG_STATS
  699. #define MG_ENABLE_TCPIP_PRINT_DEBUG_STATS 0
  700. #endif
  701. // Describes an arbitrary chunk of memory
  702. struct mg_str {
  703. char *buf; // String data
  704. size_t len; // String length
  705. };
  706. // Using macro to avoid shadowing C++ struct constructor, see #1298
  707. #define mg_str(s) mg_str_s(s)
  708. struct mg_str mg_str(const char *s);
  709. struct mg_str mg_str_n(const char *s, size_t n);
  710. int mg_casecmp(const char *s1, const char *s2);
  711. int mg_strcmp(const struct mg_str str1, const struct mg_str str2);
  712. int mg_strcasecmp(const struct mg_str str1, const struct mg_str str2);
  713. struct mg_str mg_strdup(const struct mg_str s);
  714. bool mg_match(struct mg_str str, struct mg_str pattern, struct mg_str *caps);
  715. bool mg_span(struct mg_str s, struct mg_str *a, struct mg_str *b, char delim);
  716. bool mg_str_to_num(struct mg_str, int base, void *val, size_t val_len);
  717. // Single producer, single consumer non-blocking queue
  718. struct mg_queue {
  719. char *buf;
  720. size_t size;
  721. volatile size_t tail;
  722. volatile size_t head;
  723. };
  724. void mg_queue_init(struct mg_queue *, char *, size_t); // Init queue
  725. size_t mg_queue_book(struct mg_queue *, char **buf, size_t); // Reserve space
  726. void mg_queue_add(struct mg_queue *, size_t); // Add new message
  727. size_t mg_queue_next(struct mg_queue *, char **); // Get oldest message
  728. void mg_queue_del(struct mg_queue *, size_t); // Delete oldest message
  729. typedef void (*mg_pfn_t)(char, void *); // Output function
  730. typedef size_t (*mg_pm_t)(mg_pfn_t, void *, va_list *); // %M printer
  731. size_t mg_vxprintf(void (*)(char, void *), void *, const char *fmt, va_list *);
  732. size_t mg_xprintf(void (*fn)(char, void *), void *, const char *fmt, ...);
  733. // Convenience wrappers around mg_xprintf
  734. size_t mg_vsnprintf(char *buf, size_t len, const char *fmt, va_list *ap);
  735. size_t mg_snprintf(char *, size_t, const char *fmt, ...);
  736. char *mg_vmprintf(const char *fmt, va_list *ap);
  737. char *mg_mprintf(const char *fmt, ...);
  738. size_t mg_queue_vprintf(struct mg_queue *, const char *fmt, va_list *);
  739. size_t mg_queue_printf(struct mg_queue *, const char *fmt, ...);
  740. // %M print helper functions
  741. size_t mg_print_base64(void (*out)(char, void *), void *arg, va_list *ap);
  742. size_t mg_print_esc(void (*out)(char, void *), void *arg, va_list *ap);
  743. size_t mg_print_hex(void (*out)(char, void *), void *arg, va_list *ap);
  744. size_t mg_print_ip(void (*out)(char, void *), void *arg, va_list *ap);
  745. size_t mg_print_ip_port(void (*out)(char, void *), void *arg, va_list *ap);
  746. size_t mg_print_ip4(void (*out)(char, void *), void *arg, va_list *ap);
  747. size_t mg_print_ip6(void (*out)(char, void *), void *arg, va_list *ap);
  748. size_t mg_print_mac(void (*out)(char, void *), void *arg, va_list *ap);
  749. // Various output functions
  750. void mg_pfn_iobuf(char ch, void *param); // param: struct mg_iobuf *
  751. void mg_pfn_stdout(char c, void *param); // param: ignored
  752. // A helper macro for printing JSON: mg_snprintf(buf, len, "%m", MG_ESC("hi"))
  753. #define MG_ESC(str) mg_print_esc, 0, (str)
  754. enum { MG_LL_NONE, MG_LL_ERROR, MG_LL_INFO, MG_LL_DEBUG, MG_LL_VERBOSE };
  755. extern int mg_log_level; // Current log level, one of MG_LL_*
  756. void mg_log(const char *fmt, ...);
  757. void mg_log_prefix(int ll, const char *file, int line, const char *fname);
  758. // bool mg_log2(int ll, const char *file, int line, const char *fmt, ...);
  759. void mg_hexdump(const void *buf, size_t len);
  760. void mg_log_set_fn(mg_pfn_t fn, void *param);
  761. #define mg_log_set(level_) mg_log_level = (level_)
  762. #if MG_ENABLE_LOG
  763. #define MG_LOG(level, args) \
  764. do { \
  765. if ((level) <= mg_log_level) { \
  766. mg_log_prefix((level), __FILE__, __LINE__, __func__); \
  767. mg_log args; \
  768. } \
  769. } while (0)
  770. #else
  771. #define MG_LOG(level, args) \
  772. do { \
  773. if (0) mg_log args; \
  774. } while (0)
  775. #endif
  776. #define MG_ERROR(args) MG_LOG(MG_LL_ERROR, args)
  777. #define MG_INFO(args) MG_LOG(MG_LL_INFO, args)
  778. #define MG_DEBUG(args) MG_LOG(MG_LL_DEBUG, args)
  779. #define MG_VERBOSE(args) MG_LOG(MG_LL_VERBOSE, args)
  780. struct mg_timer {
  781. unsigned long id; // Timer ID
  782. uint64_t period_ms; // Timer period in milliseconds
  783. uint64_t expire; // Expiration timestamp in milliseconds
  784. unsigned flags; // Possible flags values below
  785. #define MG_TIMER_ONCE 0 // Call function once
  786. #define MG_TIMER_REPEAT 1 // Call function periodically
  787. #define MG_TIMER_RUN_NOW 2 // Call immediately when timer is set
  788. void (*fn)(void *); // Function to call
  789. void *arg; // Function argument
  790. struct mg_timer *next; // Linkage
  791. };
  792. void mg_timer_init(struct mg_timer **head, struct mg_timer *timer,
  793. uint64_t milliseconds, unsigned flags, void (*fn)(void *),
  794. void *arg);
  795. void mg_timer_free(struct mg_timer **head, struct mg_timer *);
  796. void mg_timer_poll(struct mg_timer **head, uint64_t new_ms);
  797. bool mg_timer_expired(uint64_t *expiration, uint64_t period, uint64_t now);
  798. enum { MG_FS_READ = 1, MG_FS_WRITE = 2, MG_FS_DIR = 4 };
  799. // Filesystem API functions
  800. // st() returns MG_FS_* flags and populates file size and modification time
  801. // ls() calls fn() for every directory entry, allowing to list a directory
  802. //
  803. // NOTE: UNIX-style shorthand names for the API functions are deliberately
  804. // chosen to avoid conflicts with some libraries that make macros for e.g.
  805. // stat(), write(), read() calls.
  806. struct mg_fs {
  807. int (*st)(const char *path, size_t *size, time_t *mtime); // stat file
  808. void (*ls)(const char *path, void (*fn)(const char *, void *),
  809. void *); // List directory entries: call fn(file_name, fn_data)
  810. // for each directory entry
  811. void *(*op)(const char *path, int flags); // Open file
  812. void (*cl)(void *fd); // Close file
  813. size_t (*rd)(void *fd, void *buf, size_t len); // Read file
  814. size_t (*wr)(void *fd, const void *buf, size_t len); // Write file
  815. size_t (*sk)(void *fd, size_t offset); // Set file position
  816. bool (*mv)(const char *from, const char *to); // Rename file
  817. bool (*rm)(const char *path); // Delete file
  818. bool (*mkd)(const char *path); // Create directory
  819. };
  820. extern struct mg_fs mg_fs_posix; // POSIX open/close/read/write/seek
  821. extern struct mg_fs mg_fs_packed; // Packed FS, see examples/device-dashboard
  822. extern struct mg_fs mg_fs_fat; // FAT FS
  823. // File descriptor
  824. struct mg_fd {
  825. void *fd;
  826. struct mg_fs *fs;
  827. };
  828. struct mg_fd *mg_fs_open(struct mg_fs *fs, const char *path, int flags);
  829. void mg_fs_close(struct mg_fd *fd);
  830. bool mg_fs_ls(struct mg_fs *fs, const char *path, char *buf, size_t len);
  831. struct mg_str mg_file_read(struct mg_fs *fs, const char *path);
  832. bool mg_file_write(struct mg_fs *fs, const char *path, const void *, size_t);
  833. bool mg_file_printf(struct mg_fs *fs, const char *path, const char *fmt, ...);
  834. // Packed API
  835. const char *mg_unpack(const char *path, size_t *size, time_t *mtime);
  836. const char *mg_unlist(size_t no); // Get no'th packed filename
  837. struct mg_str mg_unpacked(const char *path); // Packed file as mg_str
  838. #if MG_ENABLE_ASSERT
  839. #include <assert.h>
  840. #elif !defined(assert)
  841. #define assert(x)
  842. #endif
  843. void mg_bzero(volatile unsigned char *buf, size_t len);
  844. bool mg_random(void *buf, size_t len);
  845. char *mg_random_str(char *buf, size_t len);
  846. uint16_t mg_ntohs(uint16_t net);
  847. uint32_t mg_ntohl(uint32_t net);
  848. uint32_t mg_crc32(uint32_t crc, const char *buf, size_t len);
  849. uint64_t mg_millis(void); // Return milliseconds since boot
  850. bool mg_path_is_sane(const struct mg_str path);
  851. #define mg_htons(x) mg_ntohs(x)
  852. #define mg_htonl(x) mg_ntohl(x)
  853. #define MG_U32(a, b, c, d) \
  854. (((uint32_t) ((a) & 255) << 24) | ((uint32_t) ((b) & 255) << 16) | \
  855. ((uint32_t) ((c) & 255) << 8) | (uint32_t) ((d) & 255))
  856. #define MG_IPV4(a, b, c, d) mg_htonl(MG_U32(a, b, c, d))
  857. // For printing IPv4 addresses: printf("%d.%d.%d.%d\n", MG_IPADDR_PARTS(&ip))
  858. #define MG_U8P(ADDR) ((uint8_t *) (ADDR))
  859. #define MG_IPADDR_PARTS(ADDR) \
  860. MG_U8P(ADDR)[0], MG_U8P(ADDR)[1], MG_U8P(ADDR)[2], MG_U8P(ADDR)[3]
  861. #define MG_LOAD_BE16(p) ((uint16_t) ((MG_U8P(p)[0] << 8U) | MG_U8P(p)[1]))
  862. #define MG_LOAD_BE24(p) \
  863. ((uint32_t) ((MG_U8P(p)[0] << 16U) | (MG_U8P(p)[1] << 8U) | MG_U8P(p)[2]))
  864. #define MG_STORE_BE16(p, n) \
  865. do { \
  866. MG_U8P(p)[0] = ((n) >> 8U) & 255; \
  867. MG_U8P(p)[1] = (n) &255; \
  868. } while (0)
  869. #define MG_REG(x) ((volatile uint32_t *) (x))[0]
  870. #define MG_BIT(x) (((uint32_t) 1U) << (x))
  871. #define MG_SET_BITS(R, CLRMASK, SETMASK) (R) = ((R) & ~(CLRMASK)) | (SETMASK)
  872. #define MG_ROUND_UP(x, a) ((a) == 0 ? (x) : ((((x) + (a) -1) / (a)) * (a)))
  873. #define MG_ROUND_DOWN(x, a) ((a) == 0 ? (x) : (((x) / (a)) * (a)))
  874. #if defined(__GNUC__)
  875. #define MG_ARM_DISABLE_IRQ() asm volatile("cpsid i" : : : "memory")
  876. #define MG_ARM_ENABLE_IRQ() asm volatile("cpsie i" : : : "memory")
  877. #elif defined(__CCRH__)
  878. #define MG_RH850_DISABLE_IRQ() __DI()
  879. #define MG_RH850_ENABLE_IRQ() __EI()
  880. #else
  881. #define MG_ARM_DISABLE_IRQ()
  882. #define MG_ARM_ENABLE_IRQ()
  883. #endif
  884. #if defined(__CC_ARM)
  885. #define MG_DSB() __dsb(0xf)
  886. #elif defined(__ARMCC_VERSION)
  887. #define MG_DSB() __builtin_arm_dsb(0xf)
  888. #elif defined(__GNUC__) && defined(__arm__) && defined(__thumb__)
  889. #define MG_DSB() asm("DSB 0xf")
  890. #elif defined(__ICCARM__)
  891. #define MG_DSB() __iar_builtin_DSB()
  892. #else
  893. #define MG_DSB()
  894. #endif
  895. struct mg_addr;
  896. int mg_check_ip_acl(struct mg_str acl, struct mg_addr *remote_ip);
  897. // Linked list management macros
  898. #define LIST_ADD_HEAD(type_, head_, elem_) \
  899. do { \
  900. (elem_)->next = (*head_); \
  901. *(head_) = (elem_); \
  902. } while (0)
  903. #define LIST_ADD_TAIL(type_, head_, elem_) \
  904. do { \
  905. type_ **h = head_; \
  906. while (*h != NULL) h = &(*h)->next; \
  907. *h = (elem_); \
  908. } while (0)
  909. #define LIST_DELETE(type_, head_, elem_) \
  910. do { \
  911. type_ **h = head_; \
  912. while (*h != (elem_)) h = &(*h)->next; \
  913. *h = (elem_)->next; \
  914. } while (0)
  915. unsigned short mg_url_port(const char *url);
  916. int mg_url_is_ssl(const char *url);
  917. struct mg_str mg_url_host(const char *url);
  918. struct mg_str mg_url_user(const char *url);
  919. struct mg_str mg_url_pass(const char *url);
  920. const char *mg_url_uri(const char *url);
  921. struct mg_iobuf {
  922. unsigned char *buf; // Pointer to stored data
  923. size_t size; // Total size available
  924. size_t len; // Current number of bytes
  925. size_t align; // Alignment during allocation
  926. };
  927. int mg_iobuf_init(struct mg_iobuf *, size_t, size_t);
  928. int mg_iobuf_resize(struct mg_iobuf *, size_t);
  929. void mg_iobuf_free(struct mg_iobuf *);
  930. size_t mg_iobuf_add(struct mg_iobuf *, size_t, const void *, size_t);
  931. size_t mg_iobuf_del(struct mg_iobuf *, size_t ofs, size_t len);
  932. size_t mg_base64_update(unsigned char input_byte, char *buf, size_t len);
  933. size_t mg_base64_final(char *buf, size_t len);
  934. size_t mg_base64_encode(const unsigned char *p, size_t n, char *buf, size_t);
  935. size_t mg_base64_decode(const char *src, size_t n, char *dst, size_t);
  936. typedef struct {
  937. uint32_t buf[4];
  938. uint32_t bits[2];
  939. unsigned char in[64];
  940. } mg_md5_ctx;
  941. void mg_md5_init(mg_md5_ctx *c);
  942. void mg_md5_update(mg_md5_ctx *c, const unsigned char *data, size_t len);
  943. void mg_md5_final(mg_md5_ctx *c, unsigned char[16]);
  944. typedef struct {
  945. uint32_t state[5];
  946. uint32_t count[2];
  947. unsigned char buffer[64];
  948. } mg_sha1_ctx;
  949. void mg_sha1_init(mg_sha1_ctx *);
  950. void mg_sha1_update(mg_sha1_ctx *, const unsigned char *data, size_t len);
  951. void mg_sha1_final(unsigned char digest[20], mg_sha1_ctx *);
  952. // https://github.com/B-Con/crypto-algorithms
  953. // Author: Brad Conte (brad AT bradconte.com)
  954. // Disclaimer: This code is presented "as is" without any guarantees.
  955. // Details: Defines the API for the corresponding SHA1 implementation.
  956. // Copyright: public domain
  957. typedef struct {
  958. uint32_t state[8];
  959. uint64_t bits;
  960. uint32_t len;
  961. unsigned char buffer[64];
  962. } mg_sha256_ctx;
  963. void mg_sha256_init(mg_sha256_ctx *);
  964. void mg_sha256_update(mg_sha256_ctx *, const unsigned char *data, size_t len);
  965. void mg_sha256_final(unsigned char digest[32], mg_sha256_ctx *);
  966. void mg_hmac_sha256(uint8_t dst[32], uint8_t *key, size_t keysz, uint8_t *data,
  967. size_t datasz);
  968. #ifndef TLS_X15519_H
  969. #define TLS_X15519_H
  970. #define X25519_BYTES 32
  971. extern const uint8_t X25519_BASE_POINT[X25519_BYTES];
  972. int mg_tls_x25519(uint8_t out[X25519_BYTES], const uint8_t scalar[X25519_BYTES],
  973. const uint8_t x1[X25519_BYTES], int clamp);
  974. #endif /* TLS_X15519_H */
  975. /******************************************************************************
  976. *
  977. * THIS SOURCE CODE IS HEREBY PLACED INTO THE PUBLIC DOMAIN FOR THE GOOD OF ALL
  978. *
  979. * This is a simple and straightforward implementation of AES-GCM authenticated
  980. * encryption. The focus of this work was correctness & accuracy. It is written
  981. * in straight 'C' without any particular focus upon optimization or speed. It
  982. * should be endian (memory byte order) neutral since the few places that care
  983. * are handled explicitly.
  984. *
  985. * This implementation of AES-GCM was created by Steven M. Gibson of GRC.com.
  986. *
  987. * It is intended for general purpose use, but was written in support of GRC's
  988. * reference implementation of the SQRL (Secure Quick Reliable Login) client.
  989. *
  990. * See: http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf
  991. * http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/ \
  992. * gcm/gcm-revised-spec.pdf
  993. *
  994. * NO COPYRIGHT IS CLAIMED IN THIS WORK, HOWEVER, NEITHER IS ANY WARRANTY MADE
  995. * REGARDING ITS FITNESS FOR ANY PARTICULAR PURPOSE. USE IT AT YOUR OWN RISK.
  996. *
  997. *******************************************************************************/
  998. #ifndef TLS_AES128_H
  999. #define TLS_AES128_H
  1000. /******************************************************************************
  1001. * AES_CONTEXT : cipher context / holds inter-call data
  1002. ******************************************************************************/
  1003. typedef struct {
  1004. int mode; // 1 for Encryption, 0 for Decryption
  1005. int rounds; // keysize-based rounds count
  1006. uint32_t *rk; // pointer to current round key
  1007. uint32_t buf[68]; // key expansion buffer
  1008. } aes_context;
  1009. #define GCM_AUTH_FAILURE 0x55555555 // authentication failure
  1010. /******************************************************************************
  1011. * GCM_CONTEXT : MUST be called once before ANY use of this library
  1012. ******************************************************************************/
  1013. int mg_gcm_initialize(void);
  1014. //
  1015. // aes-gcm.h
  1016. // MKo
  1017. //
  1018. // Created by Markus Kosmal on 20/11/14.
  1019. //
  1020. //
  1021. int mg_aes_gcm_encrypt(unsigned char *output, const unsigned char *input,
  1022. size_t input_length, const unsigned char *key,
  1023. const size_t key_len, const unsigned char *iv,
  1024. const size_t iv_len, unsigned char *aead,
  1025. size_t aead_len, unsigned char *tag,
  1026. const size_t tag_len);
  1027. int mg_aes_gcm_decrypt(unsigned char *output, const unsigned char *input,
  1028. size_t input_length, const unsigned char *key,
  1029. const size_t key_len, const unsigned char *iv,
  1030. const size_t iv_len);
  1031. #endif /* TLS_AES128_H */
  1032. // End of aes128 PD
  1033. #define MG_UECC_SUPPORTS_secp256r1 1
  1034. /* Copyright 2014, Kenneth MacKay. Licensed under the BSD 2-clause license. */
  1035. #ifndef _UECC_H_
  1036. #define _UECC_H_
  1037. /* Platform selection options.
  1038. If MG_UECC_PLATFORM is not defined, the code will try to guess it based on
  1039. compiler macros. Possible values for MG_UECC_PLATFORM are defined below: */
  1040. #define mg_uecc_arch_other 0
  1041. #define mg_uecc_x86 1
  1042. #define mg_uecc_x86_64 2
  1043. #define mg_uecc_arm 3
  1044. #define mg_uecc_arm_thumb 4
  1045. #define mg_uecc_arm_thumb2 5
  1046. #define mg_uecc_arm64 6
  1047. #define mg_uecc_avr 7
  1048. /* If desired, you can define MG_UECC_WORD_SIZE as appropriate for your platform
  1049. (1, 4, or 8 bytes). If MG_UECC_WORD_SIZE is not explicitly defined then it will
  1050. be automatically set based on your platform. */
  1051. /* Optimization level; trade speed for code size.
  1052. Larger values produce code that is faster but larger.
  1053. Currently supported values are 0 - 4; 0 is unusably slow for most
  1054. applications. Optimization level 4 currently only has an effect ARM platforms
  1055. where more than one curve is enabled. */
  1056. #ifndef MG_UECC_OPTIMIZATION_LEVEL
  1057. #define MG_UECC_OPTIMIZATION_LEVEL 2
  1058. #endif
  1059. /* MG_UECC_SQUARE_FUNC - If enabled (defined as nonzero), this will cause a
  1060. specific function to be used for (scalar) squaring instead of the generic
  1061. multiplication function. This can make things faster somewhat faster, but
  1062. increases the code size. */
  1063. #ifndef MG_UECC_SQUARE_FUNC
  1064. #define MG_UECC_SQUARE_FUNC 0
  1065. #endif
  1066. /* MG_UECC_VLI_NATIVE_LITTLE_ENDIAN - If enabled (defined as nonzero), this will
  1067. switch to native little-endian format for *all* arrays passed in and out of the
  1068. public API. This includes public and private keys, shared secrets, signatures
  1069. and message hashes. Using this switch reduces the amount of call stack memory
  1070. used by uECC, since less intermediate translations are required. Note that this
  1071. will *only* work on native little-endian processors and it will treat the
  1072. uint8_t arrays passed into the public API as word arrays, therefore requiring
  1073. the provided byte arrays to be word aligned on architectures that do not support
  1074. unaligned accesses. IMPORTANT: Keys and signatures generated with
  1075. MG_UECC_VLI_NATIVE_LITTLE_ENDIAN=1 are incompatible with keys and signatures
  1076. generated with MG_UECC_VLI_NATIVE_LITTLE_ENDIAN=0; all parties must use the same
  1077. endianness. */
  1078. #ifndef MG_UECC_VLI_NATIVE_LITTLE_ENDIAN
  1079. #define MG_UECC_VLI_NATIVE_LITTLE_ENDIAN 0
  1080. #endif
  1081. /* Curve support selection. Set to 0 to remove that curve. */
  1082. #ifndef MG_UECC_SUPPORTS_secp160r1
  1083. #define MG_UECC_SUPPORTS_secp160r1 0
  1084. #endif
  1085. #ifndef MG_UECC_SUPPORTS_secp192r1
  1086. #define MG_UECC_SUPPORTS_secp192r1 0
  1087. #endif
  1088. #ifndef MG_UECC_SUPPORTS_secp224r1
  1089. #define MG_UECC_SUPPORTS_secp224r1 0
  1090. #endif
  1091. #ifndef MG_UECC_SUPPORTS_secp256r1
  1092. #define MG_UECC_SUPPORTS_secp256r1 1
  1093. #endif
  1094. #ifndef MG_UECC_SUPPORTS_secp256k1
  1095. #define MG_UECC_SUPPORTS_secp256k1 0
  1096. #endif
  1097. /* Specifies whether compressed point format is supported.
  1098. Set to 0 to disable point compression/decompression functions. */
  1099. #ifndef MG_UECC_SUPPORT_COMPRESSED_POINT
  1100. #define MG_UECC_SUPPORT_COMPRESSED_POINT 1
  1101. #endif
  1102. struct MG_UECC_Curve_t;
  1103. typedef const struct MG_UECC_Curve_t *MG_UECC_Curve;
  1104. #ifdef __cplusplus
  1105. extern "C" {
  1106. #endif
  1107. #if MG_UECC_SUPPORTS_secp160r1
  1108. MG_UECC_Curve mg_uecc_secp160r1(void);
  1109. #endif
  1110. #if MG_UECC_SUPPORTS_secp192r1
  1111. MG_UECC_Curve mg_uecc_secp192r1(void);
  1112. #endif
  1113. #if MG_UECC_SUPPORTS_secp224r1
  1114. MG_UECC_Curve mg_uecc_secp224r1(void);
  1115. #endif
  1116. #if MG_UECC_SUPPORTS_secp256r1
  1117. MG_UECC_Curve mg_uecc_secp256r1(void);
  1118. #endif
  1119. #if MG_UECC_SUPPORTS_secp256k1
  1120. MG_UECC_Curve mg_uecc_secp256k1(void);
  1121. #endif
  1122. /* MG_UECC_RNG_Function type
  1123. The RNG function should fill 'size' random bytes into 'dest'. It should return 1
  1124. if 'dest' was filled with random data, or 0 if the random data could not be
  1125. generated. The filled-in values should be either truly random, or from a
  1126. cryptographically-secure PRNG.
  1127. A correctly functioning RNG function must be set (using mg_uecc_set_rng())
  1128. before calling mg_uecc_make_key() or mg_uecc_sign().
  1129. Setting a correctly functioning RNG function improves the resistance to
  1130. side-channel attacks for mg_uecc_shared_secret() and
  1131. mg_uecc_sign_deterministic().
  1132. A correct RNG function is set by default when building for Windows, Linux, or OS
  1133. X. If you are building on another POSIX-compliant system that supports
  1134. /dev/random or /dev/urandom, you can define MG_UECC_POSIX to use the predefined
  1135. RNG. For embedded platforms there is no predefined RNG function; you must
  1136. provide your own.
  1137. */
  1138. typedef int (*MG_UECC_RNG_Function)(uint8_t *dest, unsigned size);
  1139. /* mg_uecc_set_rng() function.
  1140. Set the function that will be used to generate random bytes. The RNG function
  1141. should return 1 if the random data was generated, or 0 if the random data could
  1142. not be generated.
  1143. On platforms where there is no predefined RNG function (eg embedded platforms),
  1144. this must be called before mg_uecc_make_key() or mg_uecc_sign() are used.
  1145. Inputs:
  1146. rng_function - The function that will be used to generate random bytes.
  1147. */
  1148. void mg_uecc_set_rng(MG_UECC_RNG_Function rng_function);
  1149. /* mg_uecc_get_rng() function.
  1150. Returns the function that will be used to generate random bytes.
  1151. */
  1152. MG_UECC_RNG_Function mg_uecc_get_rng(void);
  1153. /* mg_uecc_curve_private_key_size() function.
  1154. Returns the size of a private key for the curve in bytes.
  1155. */
  1156. int mg_uecc_curve_private_key_size(MG_UECC_Curve curve);
  1157. /* mg_uecc_curve_public_key_size() function.
  1158. Returns the size of a public key for the curve in bytes.
  1159. */
  1160. int mg_uecc_curve_public_key_size(MG_UECC_Curve curve);
  1161. /* mg_uecc_make_key() function.
  1162. Create a public/private key pair.
  1163. Outputs:
  1164. public_key - Will be filled in with the public key. Must be at least 2 *
  1165. the curve size (in bytes) long. For example, if the curve is secp256r1,
  1166. public_key must be 64 bytes long. private_key - Will be filled in with the
  1167. private key. Must be as long as the curve order; this is typically the same as
  1168. the curve size, except for secp160r1. For example, if the curve is secp256r1,
  1169. private_key must be 32 bytes long.
  1170. For secp160r1, private_key must be 21 bytes long! Note that
  1171. the first byte will almost always be 0 (there is about a 1 in 2^80 chance of it
  1172. being non-zero).
  1173. Returns 1 if the key pair was generated successfully, 0 if an error occurred.
  1174. */
  1175. int mg_uecc_make_key(uint8_t *public_key, uint8_t *private_key,
  1176. MG_UECC_Curve curve);
  1177. /* mg_uecc_shared_secret() function.
  1178. Compute a shared secret given your secret key and someone else's public key. If
  1179. the public key is not from a trusted source and has not been previously
  1180. verified, you should verify it first using mg_uecc_valid_public_key(). Note: It
  1181. is recommended that you hash the result of mg_uecc_shared_secret() before using
  1182. it for symmetric encryption or HMAC.
  1183. Inputs:
  1184. public_key - The public key of the remote party.
  1185. private_key - Your private key.
  1186. Outputs:
  1187. secret - Will be filled in with the shared secret value. Must be the same
  1188. size as the curve size; for example, if the curve is secp256r1, secret must be
  1189. 32 bytes long.
  1190. Returns 1 if the shared secret was generated successfully, 0 if an error
  1191. occurred.
  1192. */
  1193. int mg_uecc_shared_secret(const uint8_t *public_key, const uint8_t *private_key,
  1194. uint8_t *secret, MG_UECC_Curve curve);
  1195. #if MG_UECC_SUPPORT_COMPRESSED_POINT
  1196. /* mg_uecc_compress() function.
  1197. Compress a public key.
  1198. Inputs:
  1199. public_key - The public key to compress.
  1200. Outputs:
  1201. compressed - Will be filled in with the compressed public key. Must be at
  1202. least (curve size + 1) bytes long; for example, if the curve is secp256r1,
  1203. compressed must be 33 bytes long.
  1204. */
  1205. void mg_uecc_compress(const uint8_t *public_key, uint8_t *compressed,
  1206. MG_UECC_Curve curve);
  1207. /* mg_uecc_decompress() function.
  1208. Decompress a compressed public key.
  1209. Inputs:
  1210. compressed - The compressed public key.
  1211. Outputs:
  1212. public_key - Will be filled in with the decompressed public key.
  1213. */
  1214. void mg_uecc_decompress(const uint8_t *compressed, uint8_t *public_key,
  1215. MG_UECC_Curve curve);
  1216. #endif /* MG_UECC_SUPPORT_COMPRESSED_POINT */
  1217. /* mg_uecc_valid_public_key() function.
  1218. Check to see if a public key is valid.
  1219. Note that you are not required to check for a valid public key before using any
  1220. other uECC functions. However, you may wish to avoid spending CPU time computing
  1221. a shared secret or verifying a signature using an invalid public key.
  1222. Inputs:
  1223. public_key - The public key to check.
  1224. Returns 1 if the public key is valid, 0 if it is invalid.
  1225. */
  1226. int mg_uecc_valid_public_key(const uint8_t *public_key, MG_UECC_Curve curve);
  1227. /* mg_uecc_compute_public_key() function.
  1228. Compute the corresponding public key for a private key.
  1229. Inputs:
  1230. private_key - The private key to compute the public key for
  1231. Outputs:
  1232. public_key - Will be filled in with the corresponding public key
  1233. Returns 1 if the key was computed successfully, 0 if an error occurred.
  1234. */
  1235. int mg_uecc_compute_public_key(const uint8_t *private_key, uint8_t *public_key,
  1236. MG_UECC_Curve curve);
  1237. /* mg_uecc_sign() function.
  1238. Generate an ECDSA signature for a given hash value.
  1239. Usage: Compute a hash of the data you wish to sign (SHA-2 is recommended) and
  1240. pass it in to this function along with your private key.
  1241. Inputs:
  1242. private_key - Your private key.
  1243. message_hash - The hash of the message to sign.
  1244. hash_size - The size of message_hash in bytes.
  1245. Outputs:
  1246. signature - Will be filled in with the signature value. Must be at least 2 *
  1247. curve size long. For example, if the curve is secp256r1, signature must be 64
  1248. bytes long.
  1249. Returns 1 if the signature generated successfully, 0 if an error occurred.
  1250. */
  1251. int mg_uecc_sign(const uint8_t *private_key, const uint8_t *message_hash,
  1252. unsigned hash_size, uint8_t *signature, MG_UECC_Curve curve);
  1253. /* MG_UECC_HashContext structure.
  1254. This is used to pass in an arbitrary hash function to
  1255. mg_uecc_sign_deterministic(). The structure will be used for multiple hash
  1256. computations; each time a new hash is computed, init_hash() will be called,
  1257. followed by one or more calls to update_hash(), and finally a call to
  1258. finish_hash() to produce the resulting hash.
  1259. The intention is that you will create a structure that includes
  1260. MG_UECC_HashContext followed by any hash-specific data. For example:
  1261. typedef struct SHA256_HashContext {
  1262. MG_UECC_HashContext uECC;
  1263. SHA256_CTX ctx;
  1264. } SHA256_HashContext;
  1265. void init_SHA256(MG_UECC_HashContext *base) {
  1266. SHA256_HashContext *context = (SHA256_HashContext *)base;
  1267. SHA256_Init(&context->ctx);
  1268. }
  1269. void update_SHA256(MG_UECC_HashContext *base,
  1270. const uint8_t *message,
  1271. unsigned message_size) {
  1272. SHA256_HashContext *context = (SHA256_HashContext *)base;
  1273. SHA256_Update(&context->ctx, message, message_size);
  1274. }
  1275. void finish_SHA256(MG_UECC_HashContext *base, uint8_t *hash_result) {
  1276. SHA256_HashContext *context = (SHA256_HashContext *)base;
  1277. SHA256_Final(hash_result, &context->ctx);
  1278. }
  1279. ... when signing ...
  1280. {
  1281. uint8_t tmp[32 + 32 + 64];
  1282. SHA256_HashContext ctx = {{&init_SHA256, &update_SHA256, &finish_SHA256, 64,
  1283. 32, tmp}}; mg_uecc_sign_deterministic(key, message_hash, &ctx.uECC, signature);
  1284. }
  1285. */
  1286. typedef struct MG_UECC_HashContext {
  1287. void (*init_hash)(const struct MG_UECC_HashContext *context);
  1288. void (*update_hash)(const struct MG_UECC_HashContext *context,
  1289. const uint8_t *message, unsigned message_size);
  1290. void (*finish_hash)(const struct MG_UECC_HashContext *context,
  1291. uint8_t *hash_result);
  1292. unsigned
  1293. block_size; /* Hash function block size in bytes, eg 64 for SHA-256. */
  1294. unsigned
  1295. result_size; /* Hash function result size in bytes, eg 32 for SHA-256. */
  1296. uint8_t *tmp; /* Must point to a buffer of at least (2 * result_size +
  1297. block_size) bytes. */
  1298. } MG_UECC_HashContext;
  1299. /* mg_uecc_sign_deterministic() function.
  1300. Generate an ECDSA signature for a given hash value, using a deterministic
  1301. algorithm (see RFC 6979). You do not need to set the RNG using mg_uecc_set_rng()
  1302. before calling this function; however, if the RNG is defined it will improve
  1303. resistance to side-channel attacks.
  1304. Usage: Compute a hash of the data you wish to sign (SHA-2 is recommended) and
  1305. pass it to this function along with your private key and a hash context. Note
  1306. that the message_hash does not need to be computed with the same hash function
  1307. used by hash_context.
  1308. Inputs:
  1309. private_key - Your private key.
  1310. message_hash - The hash of the message to sign.
  1311. hash_size - The size of message_hash in bytes.
  1312. hash_context - A hash context to use.
  1313. Outputs:
  1314. signature - Will be filled in with the signature value.
  1315. Returns 1 if the signature generated successfully, 0 if an error occurred.
  1316. */
  1317. int mg_uecc_sign_deterministic(const uint8_t *private_key,
  1318. const uint8_t *message_hash, unsigned hash_size,
  1319. const MG_UECC_HashContext *hash_context,
  1320. uint8_t *signature, MG_UECC_Curve curve);
  1321. /* mg_uecc_verify() function.
  1322. Verify an ECDSA signature.
  1323. Usage: Compute the hash of the signed data using the same hash as the signer and
  1324. pass it to this function along with the signer's public key and the signature
  1325. values (r and s).
  1326. Inputs:
  1327. public_key - The signer's public key.
  1328. message_hash - The hash of the signed data.
  1329. hash_size - The size of message_hash in bytes.
  1330. signature - The signature value.
  1331. Returns 1 if the signature is valid, 0 if it is invalid.
  1332. */
  1333. int mg_uecc_verify(const uint8_t *public_key, const uint8_t *message_hash,
  1334. unsigned hash_size, const uint8_t *signature,
  1335. MG_UECC_Curve curve);
  1336. #ifdef __cplusplus
  1337. } /* end of extern "C" */
  1338. #endif
  1339. #endif /* _UECC_H_ */
  1340. /* Copyright 2015, Kenneth MacKay. Licensed under the BSD 2-clause license. */
  1341. #ifndef _UECC_TYPES_H_
  1342. #define _UECC_TYPES_H_
  1343. #ifndef MG_UECC_PLATFORM
  1344. #if defined(__AVR__) && __AVR__
  1345. #define MG_UECC_PLATFORM mg_uecc_avr
  1346. #elif defined(__thumb2__) || \
  1347. defined(_M_ARMT) /* I think MSVC only supports Thumb-2 targets */
  1348. #define MG_UECC_PLATFORM mg_uecc_arm_thumb2
  1349. #elif defined(__thumb__)
  1350. #define MG_UECC_PLATFORM mg_uecc_arm_thumb
  1351. #elif defined(__arm__) || defined(_M_ARM)
  1352. #define MG_UECC_PLATFORM mg_uecc_arm
  1353. #elif defined(__aarch64__)
  1354. #define MG_UECC_PLATFORM mg_uecc_arm64
  1355. #elif defined(__i386__) || defined(_M_IX86) || defined(_X86_) || \
  1356. defined(__I86__)
  1357. #define MG_UECC_PLATFORM mg_uecc_x86
  1358. #elif defined(__amd64__) || defined(_M_X64)
  1359. #define MG_UECC_PLATFORM mg_uecc_x86_64
  1360. #else
  1361. #define MG_UECC_PLATFORM mg_uecc_arch_other
  1362. #endif
  1363. #endif
  1364. #ifndef MG_UECC_ARM_USE_UMAAL
  1365. #if (MG_UECC_PLATFORM == mg_uecc_arm) && (__ARM_ARCH >= 6)
  1366. #define MG_UECC_ARM_USE_UMAAL 1
  1367. #elif (MG_UECC_PLATFORM == mg_uecc_arm_thumb2) && (__ARM_ARCH >= 6) && \
  1368. (!defined(__ARM_ARCH_7M__) || !__ARM_ARCH_7M__)
  1369. #define MG_UECC_ARM_USE_UMAAL 1
  1370. #else
  1371. #define MG_UECC_ARM_USE_UMAAL 0
  1372. #endif
  1373. #endif
  1374. #ifndef MG_UECC_WORD_SIZE
  1375. #if MG_UECC_PLATFORM == mg_uecc_avr
  1376. #define MG_UECC_WORD_SIZE 1
  1377. #elif (MG_UECC_PLATFORM == mg_uecc_x86_64 || MG_UECC_PLATFORM == mg_uecc_arm64)
  1378. #define MG_UECC_WORD_SIZE 8
  1379. #else
  1380. #define MG_UECC_WORD_SIZE 4
  1381. #endif
  1382. #endif
  1383. #if (MG_UECC_WORD_SIZE != 1) && (MG_UECC_WORD_SIZE != 4) && \
  1384. (MG_UECC_WORD_SIZE != 8)
  1385. #error "Unsupported value for MG_UECC_WORD_SIZE"
  1386. #endif
  1387. #if ((MG_UECC_PLATFORM == mg_uecc_avr) && (MG_UECC_WORD_SIZE != 1))
  1388. #pragma message("MG_UECC_WORD_SIZE must be 1 for AVR")
  1389. #undef MG_UECC_WORD_SIZE
  1390. #define MG_UECC_WORD_SIZE 1
  1391. #endif
  1392. #if ((MG_UECC_PLATFORM == mg_uecc_arm || \
  1393. MG_UECC_PLATFORM == mg_uecc_arm_thumb || \
  1394. MG_UECC_PLATFORM == mg_uecc_arm_thumb2) && \
  1395. (MG_UECC_WORD_SIZE != 4))
  1396. #pragma message("MG_UECC_WORD_SIZE must be 4 for ARM")
  1397. #undef MG_UECC_WORD_SIZE
  1398. #define MG_UECC_WORD_SIZE 4
  1399. #endif
  1400. typedef int8_t wordcount_t;
  1401. typedef int16_t bitcount_t;
  1402. typedef int8_t cmpresult_t;
  1403. #if (MG_UECC_WORD_SIZE == 1)
  1404. typedef uint8_t mg_uecc_word_t;
  1405. typedef uint16_t mg_uecc_dword_t;
  1406. #define HIGH_BIT_SET 0x80
  1407. #define MG_UECC_WORD_BITS 8
  1408. #define MG_UECC_WORD_BITS_SHIFT 3
  1409. #define MG_UECC_WORD_BITS_MASK 0x07
  1410. #elif (MG_UECC_WORD_SIZE == 4)
  1411. typedef uint32_t mg_uecc_word_t;
  1412. typedef uint64_t mg_uecc_dword_t;
  1413. #define HIGH_BIT_SET 0x80000000
  1414. #define MG_UECC_WORD_BITS 32
  1415. #define MG_UECC_WORD_BITS_SHIFT 5
  1416. #define MG_UECC_WORD_BITS_MASK 0x01F
  1417. #elif (MG_UECC_WORD_SIZE == 8)
  1418. typedef uint64_t mg_uecc_word_t;
  1419. #define HIGH_BIT_SET 0x8000000000000000U
  1420. #define MG_UECC_WORD_BITS 64
  1421. #define MG_UECC_WORD_BITS_SHIFT 6
  1422. #define MG_UECC_WORD_BITS_MASK 0x03F
  1423. #endif /* MG_UECC_WORD_SIZE */
  1424. #endif /* _UECC_TYPES_H_ */
  1425. /* Copyright 2015, Kenneth MacKay. Licensed under the BSD 2-clause license. */
  1426. #ifndef _UECC_VLI_H_
  1427. #define _UECC_VLI_H_
  1428. //
  1429. //
  1430. /* Functions for raw large-integer manipulation. These are only available
  1431. if uECC.c is compiled with MG_UECC_ENABLE_VLI_API defined to 1. */
  1432. #ifndef MG_UECC_ENABLE_VLI_API
  1433. #define MG_UECC_ENABLE_VLI_API 0
  1434. #endif
  1435. #ifdef __cplusplus
  1436. extern "C" {
  1437. #endif
  1438. #if MG_UECC_ENABLE_VLI_API
  1439. void mg_uecc_vli_clear(mg_uecc_word_t *vli, wordcount_t num_words);
  1440. /* Constant-time comparison to zero - secure way to compare long integers */
  1441. /* Returns 1 if vli == 0, 0 otherwise. */
  1442. mg_uecc_word_t mg_uecc_vli_isZero(const mg_uecc_word_t *vli,
  1443. wordcount_t num_words);
  1444. /* Returns nonzero if bit 'bit' of vli is set. */
  1445. mg_uecc_word_t mg_uecc_vli_testBit(const mg_uecc_word_t *vli, bitcount_t bit);
  1446. /* Counts the number of bits required to represent vli. */
  1447. bitcount_t mg_uecc_vli_numBits(const mg_uecc_word_t *vli,
  1448. const wordcount_t max_words);
  1449. /* Sets dest = src. */
  1450. void mg_uecc_vli_set(mg_uecc_word_t *dest, const mg_uecc_word_t *src,
  1451. wordcount_t num_words);
  1452. /* Constant-time comparison function - secure way to compare long integers */
  1453. /* Returns one if left == right, zero otherwise */
  1454. mg_uecc_word_t mg_uecc_vli_equal(const mg_uecc_word_t *left,
  1455. const mg_uecc_word_t *right,
  1456. wordcount_t num_words);
  1457. /* Constant-time comparison function - secure way to compare long integers */
  1458. /* Returns sign of left - right, in constant time. */
  1459. cmpresult_t mg_uecc_vli_cmp(const mg_uecc_word_t *left,
  1460. const mg_uecc_word_t *right, wordcount_t num_words);
  1461. /* Computes vli = vli >> 1. */
  1462. void mg_uecc_vli_rshift1(mg_uecc_word_t *vli, wordcount_t num_words);
  1463. /* Computes result = left + right, returning carry. Can modify in place. */
  1464. mg_uecc_word_t mg_uecc_vli_add(mg_uecc_word_t *result,
  1465. const mg_uecc_word_t *left,
  1466. const mg_uecc_word_t *right,
  1467. wordcount_t num_words);
  1468. /* Computes result = left - right, returning borrow. Can modify in place. */
  1469. mg_uecc_word_t mg_uecc_vli_sub(mg_uecc_word_t *result,
  1470. const mg_uecc_word_t *left,
  1471. const mg_uecc_word_t *right,
  1472. wordcount_t num_words);
  1473. /* Computes result = left * right. Result must be 2 * num_words long. */
  1474. void mg_uecc_vli_mult(mg_uecc_word_t *result, const mg_uecc_word_t *left,
  1475. const mg_uecc_word_t *right, wordcount_t num_words);
  1476. /* Computes result = left^2. Result must be 2 * num_words long. */
  1477. void mg_uecc_vli_square(mg_uecc_word_t *result, const mg_uecc_word_t *left,
  1478. wordcount_t num_words);
  1479. /* Computes result = (left + right) % mod.
  1480. Assumes that left < mod and right < mod, and that result does not overlap
  1481. mod. */
  1482. void mg_uecc_vli_modAdd(mg_uecc_word_t *result, const mg_uecc_word_t *left,
  1483. const mg_uecc_word_t *right, const mg_uecc_word_t *mod,
  1484. wordcount_t num_words);
  1485. /* Computes result = (left - right) % mod.
  1486. Assumes that left < mod and right < mod, and that result does not overlap
  1487. mod. */
  1488. void mg_uecc_vli_modSub(mg_uecc_word_t *result, const mg_uecc_word_t *left,
  1489. const mg_uecc_word_t *right, const mg_uecc_word_t *mod,
  1490. wordcount_t num_words);
  1491. /* Computes result = product % mod, where product is 2N words long.
  1492. Currently only designed to work for mod == curve->p or curve_n. */
  1493. void mg_uecc_vli_mmod(mg_uecc_word_t *result, mg_uecc_word_t *product,
  1494. const mg_uecc_word_t *mod, wordcount_t num_words);
  1495. /* Calculates result = product (mod curve->p), where product is up to
  1496. 2 * curve->num_words long. */
  1497. void mg_uecc_vli_mmod_fast(mg_uecc_word_t *result, mg_uecc_word_t *product,
  1498. MG_UECC_Curve curve);
  1499. /* Computes result = (left * right) % mod.
  1500. Currently only designed to work for mod == curve->p or curve_n. */
  1501. void mg_uecc_vli_modMult(mg_uecc_word_t *result, const mg_uecc_word_t *left,
  1502. const mg_uecc_word_t *right, const mg_uecc_word_t *mod,
  1503. wordcount_t num_words);
  1504. /* Computes result = (left * right) % curve->p. */
  1505. void mg_uecc_vli_modMult_fast(mg_uecc_word_t *result,
  1506. const mg_uecc_word_t *left,
  1507. const mg_uecc_word_t *right, MG_UECC_Curve curve);
  1508. /* Computes result = left^2 % mod.
  1509. Currently only designed to work for mod == curve->p or curve_n. */
  1510. void mg_uecc_vli_modSquare(mg_uecc_word_t *result, const mg_uecc_word_t *left,
  1511. const mg_uecc_word_t *mod, wordcount_t num_words);
  1512. /* Computes result = left^2 % curve->p. */
  1513. void mg_uecc_vli_modSquare_fast(mg_uecc_word_t *result,
  1514. const mg_uecc_word_t *left,
  1515. MG_UECC_Curve curve);
  1516. /* Computes result = (1 / input) % mod.*/
  1517. void mg_uecc_vli_modInv(mg_uecc_word_t *result, const mg_uecc_word_t *input,
  1518. const mg_uecc_word_t *mod, wordcount_t num_words);
  1519. #if MG_UECC_SUPPORT_COMPRESSED_POINT
  1520. /* Calculates a = sqrt(a) (mod curve->p) */
  1521. void mg_uecc_vli_mod_sqrt(mg_uecc_word_t *a, MG_UECC_Curve curve);
  1522. #endif
  1523. /* Converts an integer in uECC native format to big-endian bytes. */
  1524. void mg_uecc_vli_nativeToBytes(uint8_t *bytes, int num_bytes,
  1525. const mg_uecc_word_t *native);
  1526. /* Converts big-endian bytes to an integer in uECC native format. */
  1527. void mg_uecc_vli_bytesToNative(mg_uecc_word_t *native, const uint8_t *bytes,
  1528. int num_bytes);
  1529. unsigned mg_uecc_curve_num_words(MG_UECC_Curve curve);
  1530. unsigned mg_uecc_curve_num_bytes(MG_UECC_Curve curve);
  1531. unsigned mg_uecc_curve_num_bits(MG_UECC_Curve curve);
  1532. unsigned mg_uecc_curve_num_n_words(MG_UECC_Curve curve);
  1533. unsigned mg_uecc_curve_num_n_bytes(MG_UECC_Curve curve);
  1534. unsigned mg_uecc_curve_num_n_bits(MG_UECC_Curve curve);
  1535. const mg_uecc_word_t *mg_uecc_curve_p(MG_UECC_Curve curve);
  1536. const mg_uecc_word_t *mg_uecc_curve_n(MG_UECC_Curve curve);
  1537. const mg_uecc_word_t *mg_uecc_curve_G(MG_UECC_Curve curve);
  1538. const mg_uecc_word_t *mg_uecc_curve_b(MG_UECC_Curve curve);
  1539. int mg_uecc_valid_point(const mg_uecc_word_t *point, MG_UECC_Curve curve);
  1540. /* Multiplies a point by a scalar. Points are represented by the X coordinate
  1541. followed by the Y coordinate in the same array, both coordinates are
  1542. curve->num_words long. Note that scalar must be curve->num_n_words long (NOT
  1543. curve->num_words). */
  1544. void mg_uecc_point_mult(mg_uecc_word_t *result, const mg_uecc_word_t *point,
  1545. const mg_uecc_word_t *scalar, MG_UECC_Curve curve);
  1546. /* Generates a random integer in the range 0 < random < top.
  1547. Both random and top have num_words words. */
  1548. int mg_uecc_generate_random_int(mg_uecc_word_t *random,
  1549. const mg_uecc_word_t *top,
  1550. wordcount_t num_words);
  1551. #endif /* MG_UECC_ENABLE_VLI_API */
  1552. #ifdef __cplusplus
  1553. } /* end of extern "C" */
  1554. #endif
  1555. #endif /* _UECC_VLI_H_ */
  1556. // End of uecc BSD-2
  1557. // portable8439 v1.0.1
  1558. // Source: https://github.com/DavyLandman/portable8439
  1559. // Licensed under CC0-1.0
  1560. // Contains poly1305-donna e6ad6e091d30d7f4ec2d4f978be1fcfcbce72781 (Public
  1561. // Domain)
  1562. #ifndef __PORTABLE_8439_H
  1563. #define __PORTABLE_8439_H
  1564. #if defined(__cplusplus)
  1565. extern "C" {
  1566. #endif
  1567. // provide your own decl specificier like -DPORTABLE_8439_DECL=ICACHE_RAM_ATTR
  1568. #ifndef PORTABLE_8439_DECL
  1569. #define PORTABLE_8439_DECL
  1570. #endif
  1571. /*
  1572. This library implements RFC 8439 a.k.a. ChaCha20-Poly1305 AEAD
  1573. You can use this library to avoid attackers mutating or reusing your
  1574. encrypted messages. This does assume you never reuse a nonce+key pair and,
  1575. if possible, carefully pick your associated data.
  1576. */
  1577. /* Make sure we are either nested in C++ or running in a C99+ compiler
  1578. #if !defined(__cplusplus) && !defined(_MSC_VER) && \
  1579. (!defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L)
  1580. #error "C99 or newer required"
  1581. #endif */
  1582. // #if CHAR_BIT > 8
  1583. // # error "Systems without native octals not suppoted"
  1584. // #endif
  1585. #if defined(_MSC_VER) || defined(__cplusplus)
  1586. // add restrict support is possible
  1587. #if (defined(_MSC_VER) && _MSC_VER >= 1900) || defined(__clang__) || \
  1588. defined(__GNUC__)
  1589. #define restrict __restrict
  1590. #else
  1591. #define restrict
  1592. #endif
  1593. #endif
  1594. #define RFC_8439_TAG_SIZE (16)
  1595. #define RFC_8439_KEY_SIZE (32)
  1596. #define RFC_8439_NONCE_SIZE (12)
  1597. /*
  1598. Encrypt/Seal plain text bytes into a cipher text that can only be
  1599. decrypted by knowing the key, nonce and associated data.
  1600. input:
  1601. - key: RFC_8439_KEY_SIZE bytes that all parties have agreed
  1602. upon beforehand
  1603. - nonce: RFC_8439_NONCE_SIZE bytes that should never be repeated
  1604. for the same key. A counter or a pseudo-random value are fine.
  1605. - ad: associated data to include with calculating the tag of the
  1606. cipher text. Can be null for empty.
  1607. - plain_text: data to be encrypted, pointer + size should not overlap
  1608. with cipher_text pointer
  1609. output:
  1610. - cipher_text: encrypted plain_text with a tag appended. Make sure to
  1611. allocate at least plain_text_size + RFC_8439_TAG_SIZE
  1612. returns:
  1613. - size of bytes written to cipher_text, can be -1 if overlapping
  1614. pointers are passed for plain_text and cipher_text
  1615. */
  1616. PORTABLE_8439_DECL size_t mg_chacha20_poly1305_encrypt(
  1617. uint8_t *restrict cipher_text, const uint8_t key[RFC_8439_KEY_SIZE],
  1618. const uint8_t nonce[RFC_8439_NONCE_SIZE], const uint8_t *restrict ad,
  1619. size_t ad_size, const uint8_t *restrict plain_text, size_t plain_text_size);
  1620. /*
  1621. Decrypt/unseal cipher text given the right key, nonce, and additional data.
  1622. input:
  1623. - key: RFC_8439_KEY_SIZE bytes that all parties have agreed
  1624. upon beforehand
  1625. - nonce: RFC_8439_NONCE_SIZE bytes that should never be repeated for
  1626. the same key. A counter or a pseudo-random value are fine.
  1627. - ad: associated data to include with calculating the tag of the
  1628. cipher text. Can be null for empty.
  1629. - cipher_text: encrypted message.
  1630. output:
  1631. - plain_text: data to be encrypted, pointer + size should not overlap
  1632. with cipher_text pointer, leave at least enough room for
  1633. cipher_text_size - RFC_8439_TAG_SIZE
  1634. returns:
  1635. - size of bytes written to plain_text, -1 signals either:
  1636. - incorrect key/nonce/ad
  1637. - corrupted cipher_text
  1638. - overlapping pointers are passed for plain_text and cipher_text
  1639. */
  1640. PORTABLE_8439_DECL size_t mg_chacha20_poly1305_decrypt(
  1641. uint8_t *restrict plain_text, const uint8_t key[RFC_8439_KEY_SIZE],
  1642. const uint8_t nonce[RFC_8439_NONCE_SIZE],
  1643. const uint8_t *restrict cipher_text, size_t cipher_text_size);
  1644. #if defined(__cplusplus)
  1645. }
  1646. #endif
  1647. #endif
  1648. struct mg_connection;
  1649. typedef void (*mg_event_handler_t)(struct mg_connection *, int ev,
  1650. void *ev_data);
  1651. void mg_call(struct mg_connection *c, int ev, void *ev_data);
  1652. void mg_error(struct mg_connection *c, const char *fmt, ...);
  1653. enum {
  1654. MG_EV_ERROR, // Error char *error_message
  1655. MG_EV_OPEN, // Connection created NULL
  1656. MG_EV_POLL, // mg_mgr_poll iteration uint64_t *uptime_millis
  1657. MG_EV_RESOLVE, // Host name is resolved NULL
  1658. MG_EV_CONNECT, // Connection established NULL
  1659. MG_EV_ACCEPT, // Connection accepted NULL
  1660. MG_EV_TLS_HS, // TLS handshake succeeded NULL
  1661. MG_EV_READ, // Data received from socket long *bytes_read
  1662. MG_EV_WRITE, // Data written to socket long *bytes_written
  1663. MG_EV_CLOSE, // Connection closed NULL
  1664. MG_EV_HTTP_HDRS, // HTTP headers struct mg_http_message *
  1665. MG_EV_HTTP_MSG, // Full HTTP request/response struct mg_http_message *
  1666. MG_EV_WS_OPEN, // Websocket handshake done struct mg_http_message *
  1667. MG_EV_WS_MSG, // Websocket msg, text or bin struct mg_ws_message *
  1668. MG_EV_WS_CTL, // Websocket control msg struct mg_ws_message *
  1669. MG_EV_MQTT_CMD, // MQTT low-level command struct mg_mqtt_message *
  1670. MG_EV_MQTT_MSG, // MQTT PUBLISH received struct mg_mqtt_message *
  1671. MG_EV_MQTT_OPEN, // MQTT CONNACK received int *connack_status_code
  1672. MG_EV_SNTP_TIME, // SNTP time received uint64_t *epoch_millis
  1673. MG_EV_WAKEUP, // mg_wakeup() data received struct mg_str *data
  1674. MG_EV_USER // Starting ID for user events
  1675. };
  1676. struct mg_dns {
  1677. const char *url; // DNS server URL
  1678. struct mg_connection *c; // DNS server connection
  1679. };
  1680. struct mg_addr {
  1681. uint8_t ip[16]; // Holds IPv4 or IPv6 address, in network byte order
  1682. uint16_t port; // TCP or UDP port in network byte order
  1683. uint8_t scope_id; // IPv6 scope ID
  1684. bool is_ip6; // True when address is IPv6 address
  1685. };
  1686. struct mg_mgr {
  1687. struct mg_connection *conns; // List of active connections
  1688. struct mg_dns dns4; // DNS for IPv4
  1689. struct mg_dns dns6; // DNS for IPv6
  1690. int dnstimeout; // DNS resolve timeout in milliseconds
  1691. bool use_dns6; // Use DNS6 server by default, see #1532
  1692. unsigned long nextid; // Next connection ID
  1693. unsigned long timerid; // Next timer ID
  1694. void *userdata; // Arbitrary user data pointer
  1695. void *tls_ctx; // TLS context shared by all TLS sessions
  1696. uint16_t mqtt_id; // MQTT IDs for pub/sub
  1697. void *active_dns_requests; // DNS requests in progress
  1698. struct mg_timer *timers; // Active timers
  1699. int epoll_fd; // Used when MG_EPOLL_ENABLE=1
  1700. struct mg_tcpip_if *ifp; // Builtin TCP/IP stack only. Interface pointer
  1701. size_t extraconnsize; // Builtin TCP/IP stack only. Extra space
  1702. MG_SOCKET_TYPE pipe; // Socketpair end for mg_wakeup()
  1703. #if MG_ENABLE_FREERTOS_TCP
  1704. SocketSet_t ss; // NOTE(lsm): referenced from socket struct
  1705. #endif
  1706. };
  1707. struct mg_connection {
  1708. struct mg_connection *next; // Linkage in struct mg_mgr :: connections
  1709. struct mg_mgr *mgr; // Our container
  1710. struct mg_addr loc; // Local address
  1711. struct mg_addr rem; // Remote address
  1712. void *fd; // Connected socket, or LWIP data
  1713. unsigned long id; // Auto-incrementing unique connection ID
  1714. struct mg_iobuf recv; // Incoming data
  1715. struct mg_iobuf send; // Outgoing data
  1716. struct mg_iobuf prof; // Profile data enabled by MG_ENABLE_PROFILE
  1717. struct mg_iobuf rtls; // TLS only. Incoming encrypted data
  1718. mg_event_handler_t fn; // User-specified event handler function
  1719. void *fn_data; // User-specified function parameter
  1720. mg_event_handler_t pfn; // Protocol-specific handler function
  1721. void *pfn_data; // Protocol-specific function parameter
  1722. char data[MG_DATA_SIZE]; // Arbitrary connection data
  1723. void *tls; // TLS specific data
  1724. unsigned is_listening : 1; // Listening connection
  1725. unsigned is_client : 1; // Outbound (client) connection
  1726. unsigned is_accepted : 1; // Accepted (server) connection
  1727. unsigned is_resolving : 1; // Non-blocking DNS resolution is in progress
  1728. unsigned is_arplooking : 1; // Non-blocking ARP resolution is in progress
  1729. unsigned is_connecting : 1; // Non-blocking connect is in progress
  1730. unsigned is_tls : 1; // TLS-enabled connection
  1731. unsigned is_tls_hs : 1; // TLS handshake is in progress
  1732. unsigned is_udp : 1; // UDP connection
  1733. unsigned is_websocket : 1; // WebSocket connection
  1734. unsigned is_mqtt5 : 1; // For MQTT connection, v5 indicator
  1735. unsigned is_hexdumping : 1; // Hexdump in/out traffic
  1736. unsigned is_draining : 1; // Send remaining data, then close and free
  1737. unsigned is_closing : 1; // Close and free the connection immediately
  1738. unsigned is_full : 1; // Stop reads, until cleared
  1739. unsigned is_resp : 1; // Response is still being generated
  1740. unsigned is_readable : 1; // Connection is ready to read
  1741. unsigned is_writable : 1; // Connection is ready to write
  1742. };
  1743. void mg_mgr_poll(struct mg_mgr *, int ms);
  1744. void mg_mgr_init(struct mg_mgr *);
  1745. void mg_mgr_free(struct mg_mgr *);
  1746. struct mg_connection *mg_listen(struct mg_mgr *, const char *url,
  1747. mg_event_handler_t fn, void *fn_data);
  1748. struct mg_connection *mg_connect(struct mg_mgr *, const char *url,
  1749. mg_event_handler_t fn, void *fn_data);
  1750. struct mg_connection *mg_wrapfd(struct mg_mgr *mgr, int fd,
  1751. mg_event_handler_t fn, void *fn_data);
  1752. void mg_connect_resolved(struct mg_connection *);
  1753. bool mg_send(struct mg_connection *, const void *, size_t);
  1754. size_t mg_printf(struct mg_connection *, const char *fmt, ...);
  1755. size_t mg_vprintf(struct mg_connection *, const char *fmt, va_list *ap);
  1756. bool mg_aton(struct mg_str str, struct mg_addr *addr);
  1757. // These functions are used to integrate with custom network stacks
  1758. struct mg_connection *mg_alloc_conn(struct mg_mgr *);
  1759. void mg_close_conn(struct mg_connection *c);
  1760. bool mg_open_listener(struct mg_connection *c, const char *url);
  1761. // Utility functions
  1762. bool mg_wakeup(struct mg_mgr *, unsigned long id, const void *buf, size_t len);
  1763. bool mg_wakeup_init(struct mg_mgr *);
  1764. struct mg_timer *mg_timer_add(struct mg_mgr *mgr, uint64_t milliseconds,
  1765. unsigned flags, void (*fn)(void *), void *arg);
  1766. struct mg_http_header {
  1767. struct mg_str name; // Header name
  1768. struct mg_str value; // Header value
  1769. };
  1770. struct mg_http_message {
  1771. struct mg_str method, uri, query, proto; // Request/response line
  1772. struct mg_http_header headers[MG_MAX_HTTP_HEADERS]; // Headers
  1773. struct mg_str body; // Body
  1774. struct mg_str head; // Request + headers
  1775. struct mg_str message; // Request + headers + body
  1776. };
  1777. // Parameter for mg_http_serve_dir()
  1778. struct mg_http_serve_opts {
  1779. const char *root_dir; // Web root directory, must be non-NULL
  1780. const char *ssi_pattern; // SSI file name pattern, e.g. #.shtml
  1781. const char *extra_headers; // Extra HTTP headers to add in responses
  1782. const char *mime_types; // Extra mime types, ext1=type1,ext2=type2,..
  1783. const char *page404; // Path to the 404 page, or NULL by default
  1784. struct mg_fs *fs; // Filesystem implementation. Use NULL for POSIX
  1785. };
  1786. // Parameter for mg_http_next_multipart
  1787. struct mg_http_part {
  1788. struct mg_str name; // Form field name
  1789. struct mg_str filename; // Filename for file uploads
  1790. struct mg_str body; // Part contents
  1791. };
  1792. int mg_http_parse(const char *s, size_t len, struct mg_http_message *);
  1793. int mg_http_get_request_len(const unsigned char *buf, size_t buf_len);
  1794. void mg_http_printf_chunk(struct mg_connection *cnn, const char *fmt, ...);
  1795. void mg_http_write_chunk(struct mg_connection *c, const char *buf, size_t len);
  1796. void mg_http_delete_chunk(struct mg_connection *c, struct mg_http_message *hm);
  1797. struct mg_connection *mg_http_listen(struct mg_mgr *, const char *url,
  1798. mg_event_handler_t fn, void *fn_data);
  1799. struct mg_connection *mg_http_connect(struct mg_mgr *, const char *url,
  1800. mg_event_handler_t fn, void *fn_data);
  1801. void mg_http_serve_dir(struct mg_connection *, struct mg_http_message *hm,
  1802. const struct mg_http_serve_opts *);
  1803. void mg_http_serve_file(struct mg_connection *, struct mg_http_message *hm,
  1804. const char *path, const struct mg_http_serve_opts *);
  1805. void mg_http_reply(struct mg_connection *, int status_code, const char *headers,
  1806. const char *body_fmt, ...);
  1807. struct mg_str *mg_http_get_header(struct mg_http_message *, const char *name);
  1808. struct mg_str mg_http_var(struct mg_str buf, struct mg_str name);
  1809. int mg_http_get_var(const struct mg_str *, const char *name, char *, size_t);
  1810. int mg_url_decode(const char *s, size_t n, char *to, size_t to_len, int form);
  1811. size_t mg_url_encode(const char *s, size_t n, char *buf, size_t len);
  1812. void mg_http_creds(struct mg_http_message *, char *, size_t, char *, size_t);
  1813. long mg_http_upload(struct mg_connection *c, struct mg_http_message *hm,
  1814. struct mg_fs *fs, const char *dir, size_t max_size);
  1815. void mg_http_bauth(struct mg_connection *, const char *user, const char *pass);
  1816. struct mg_str mg_http_get_header_var(struct mg_str s, struct mg_str v);
  1817. size_t mg_http_next_multipart(struct mg_str, size_t, struct mg_http_part *);
  1818. int mg_http_status(const struct mg_http_message *hm);
  1819. void mg_hello(const char *url);
  1820. void mg_http_serve_ssi(struct mg_connection *c, const char *root,
  1821. const char *fullpath);
  1822. #define MG_TLS_NONE 0 // No TLS support
  1823. #define MG_TLS_MBED 1 // mbedTLS
  1824. #define MG_TLS_OPENSSL 2 // OpenSSL
  1825. #define MG_TLS_WOLFSSL 5 // WolfSSL (based on OpenSSL)
  1826. #define MG_TLS_BUILTIN 3 // Built-in
  1827. #define MG_TLS_CUSTOM 4 // Custom implementation
  1828. #ifndef MG_TLS
  1829. #define MG_TLS MG_TLS_NONE
  1830. #endif
  1831. struct mg_tls_opts {
  1832. struct mg_str ca; // PEM or DER
  1833. struct mg_str cert; // PEM or DER
  1834. struct mg_str key; // PEM or DER
  1835. struct mg_str name; // If not empty, enable host name verification
  1836. int skip_verification; // Skip certificate and host name verification
  1837. };
  1838. void mg_tls_init(struct mg_connection *, const struct mg_tls_opts *opts);
  1839. void mg_tls_free(struct mg_connection *);
  1840. long mg_tls_send(struct mg_connection *, const void *buf, size_t len);
  1841. long mg_tls_recv(struct mg_connection *, void *buf, size_t len);
  1842. size_t mg_tls_pending(struct mg_connection *);
  1843. void mg_tls_handshake(struct mg_connection *);
  1844. // Private
  1845. void mg_tls_ctx_init(struct mg_mgr *);
  1846. void mg_tls_ctx_free(struct mg_mgr *);
  1847. // Low-level IO primives used by TLS layer
  1848. enum { MG_IO_ERR = -1, MG_IO_WAIT = -2, MG_IO_RESET = -3 };
  1849. long mg_io_send(struct mg_connection *c, const void *buf, size_t len);
  1850. long mg_io_recv(struct mg_connection *c, void *buf, size_t len);
  1851. #if MG_TLS == MG_TLS_MBED
  1852. #include <mbedtls/debug.h>
  1853. #include <mbedtls/net_sockets.h>
  1854. #include <mbedtls/ssl.h>
  1855. #include <mbedtls/ssl_ticket.h>
  1856. struct mg_tls_ctx {
  1857. int dummy;
  1858. #ifdef MBEDTLS_SSL_SESSION_TICKETS
  1859. mbedtls_ssl_ticket_context tickets;
  1860. #endif
  1861. };
  1862. struct mg_tls {
  1863. mbedtls_x509_crt ca; // Parsed CA certificate
  1864. mbedtls_x509_crt cert; // Parsed certificate
  1865. mbedtls_pk_context pk; // Private key context
  1866. mbedtls_ssl_context ssl; // SSL/TLS context
  1867. mbedtls_ssl_config conf; // SSL-TLS config
  1868. #ifdef MBEDTLS_SSL_SESSION_TICKETS
  1869. mbedtls_ssl_ticket_context ticket; // Session tickets context
  1870. #endif
  1871. };
  1872. #endif
  1873. #if MG_TLS == MG_TLS_OPENSSL || MG_TLS == MG_TLS_WOLFSSL
  1874. #include <openssl/err.h>
  1875. #include <openssl/ssl.h>
  1876. struct mg_tls {
  1877. BIO_METHOD *bm;
  1878. SSL_CTX *ctx;
  1879. SSL *ssl;
  1880. };
  1881. #endif
  1882. #define WEBSOCKET_OP_CONTINUE 0
  1883. #define WEBSOCKET_OP_TEXT 1
  1884. #define WEBSOCKET_OP_BINARY 2
  1885. #define WEBSOCKET_OP_CLOSE 8
  1886. #define WEBSOCKET_OP_PING 9
  1887. #define WEBSOCKET_OP_PONG 10
  1888. struct mg_ws_message {
  1889. struct mg_str data; // Websocket message data
  1890. uint8_t flags; // Websocket message flags
  1891. };
  1892. struct mg_connection *mg_ws_connect(struct mg_mgr *, const char *url,
  1893. mg_event_handler_t fn, void *fn_data,
  1894. const char *fmt, ...);
  1895. void mg_ws_upgrade(struct mg_connection *, struct mg_http_message *,
  1896. const char *fmt, ...);
  1897. size_t mg_ws_send(struct mg_connection *, const void *buf, size_t len, int op);
  1898. size_t mg_ws_wrap(struct mg_connection *, size_t len, int op);
  1899. size_t mg_ws_printf(struct mg_connection *c, int op, const char *fmt, ...);
  1900. size_t mg_ws_vprintf(struct mg_connection *c, int op, const char *fmt,
  1901. va_list *);
  1902. struct mg_connection *mg_sntp_connect(struct mg_mgr *mgr, const char *url,
  1903. mg_event_handler_t fn, void *fn_data);
  1904. void mg_sntp_request(struct mg_connection *c);
  1905. int64_t mg_sntp_parse(const unsigned char *buf, size_t len);
  1906. uint64_t mg_now(void); // Return milliseconds since Epoch
  1907. #define MQTT_CMD_CONNECT 1
  1908. #define MQTT_CMD_CONNACK 2
  1909. #define MQTT_CMD_PUBLISH 3
  1910. #define MQTT_CMD_PUBACK 4
  1911. #define MQTT_CMD_PUBREC 5
  1912. #define MQTT_CMD_PUBREL 6
  1913. #define MQTT_CMD_PUBCOMP 7
  1914. #define MQTT_CMD_SUBSCRIBE 8
  1915. #define MQTT_CMD_SUBACK 9
  1916. #define MQTT_CMD_UNSUBSCRIBE 10
  1917. #define MQTT_CMD_UNSUBACK 11
  1918. #define MQTT_CMD_PINGREQ 12
  1919. #define MQTT_CMD_PINGRESP 13
  1920. #define MQTT_CMD_DISCONNECT 14
  1921. #define MQTT_CMD_AUTH 15
  1922. #define MQTT_PROP_PAYLOAD_FORMAT_INDICATOR 0x01
  1923. #define MQTT_PROP_MESSAGE_EXPIRY_INTERVAL 0x02
  1924. #define MQTT_PROP_CONTENT_TYPE 0x03
  1925. #define MQTT_PROP_RESPONSE_TOPIC 0x08
  1926. #define MQTT_PROP_CORRELATION_DATA 0x09
  1927. #define MQTT_PROP_SUBSCRIPTION_IDENTIFIER 0x0B
  1928. #define MQTT_PROP_SESSION_EXPIRY_INTERVAL 0x11
  1929. #define MQTT_PROP_ASSIGNED_CLIENT_IDENTIFIER 0x12
  1930. #define MQTT_PROP_SERVER_KEEP_ALIVE 0x13
  1931. #define MQTT_PROP_AUTHENTICATION_METHOD 0x15
  1932. #define MQTT_PROP_AUTHENTICATION_DATA 0x16
  1933. #define MQTT_PROP_REQUEST_PROBLEM_INFORMATION 0x17
  1934. #define MQTT_PROP_WILL_DELAY_INTERVAL 0x18
  1935. #define MQTT_PROP_REQUEST_RESPONSE_INFORMATION 0x19
  1936. #define MQTT_PROP_RESPONSE_INFORMATION 0x1A
  1937. #define MQTT_PROP_SERVER_REFERENCE 0x1C
  1938. #define MQTT_PROP_REASON_STRING 0x1F
  1939. #define MQTT_PROP_RECEIVE_MAXIMUM 0x21
  1940. #define MQTT_PROP_TOPIC_ALIAS_MAXIMUM 0x22
  1941. #define MQTT_PROP_TOPIC_ALIAS 0x23
  1942. #define MQTT_PROP_MAXIMUM_QOS 0x24
  1943. #define MQTT_PROP_RETAIN_AVAILABLE 0x25
  1944. #define MQTT_PROP_USER_PROPERTY 0x26
  1945. #define MQTT_PROP_MAXIMUM_PACKET_SIZE 0x27
  1946. #define MQTT_PROP_WILDCARD_SUBSCRIPTION_AVAILABLE 0x28
  1947. #define MQTT_PROP_SUBSCRIPTION_IDENTIFIER_AVAILABLE 0x29
  1948. #define MQTT_PROP_SHARED_SUBSCRIPTION_AVAILABLE 0x2A
  1949. enum {
  1950. MQTT_PROP_TYPE_BYTE,
  1951. MQTT_PROP_TYPE_STRING,
  1952. MQTT_PROP_TYPE_STRING_PAIR,
  1953. MQTT_PROP_TYPE_BINARY_DATA,
  1954. MQTT_PROP_TYPE_VARIABLE_INT,
  1955. MQTT_PROP_TYPE_INT,
  1956. MQTT_PROP_TYPE_SHORT
  1957. };
  1958. enum { MQTT_OK, MQTT_INCOMPLETE, MQTT_MALFORMED };
  1959. struct mg_mqtt_prop {
  1960. uint8_t id; // Enumerated at MQTT5 Reference
  1961. uint32_t iv; // Integer value for 8-, 16-, 32-bit integers types
  1962. struct mg_str key; // Non-NULL only for user property type
  1963. struct mg_str val; // Non-NULL only for UTF-8 types and user properties
  1964. };
  1965. struct mg_mqtt_opts {
  1966. struct mg_str user; // Username, can be empty
  1967. struct mg_str pass; // Password, can be empty
  1968. struct mg_str client_id; // Client ID
  1969. struct mg_str topic; // message/subscription topic
  1970. struct mg_str message; // message content
  1971. uint8_t qos; // message quality of service
  1972. uint8_t version; // Can be 4 (3.1.1), or 5. If 0, assume 4
  1973. uint16_t keepalive; // Keep-alive timer in seconds
  1974. uint16_t retransmit_id; // For PUBLISH, init to 0
  1975. bool retain; // Retain flag
  1976. bool clean; // Clean session flag
  1977. struct mg_mqtt_prop *props; // MQTT5 props array
  1978. size_t num_props; // number of props
  1979. struct mg_mqtt_prop *will_props; // Valid only for CONNECT packet (MQTT5)
  1980. size_t num_will_props; // Number of will props
  1981. };
  1982. struct mg_mqtt_message {
  1983. struct mg_str topic; // Parsed topic for PUBLISH
  1984. struct mg_str data; // Parsed message for PUBLISH
  1985. struct mg_str dgram; // Whole MQTT packet, including headers
  1986. uint16_t id; // For PUBACK, PUBREC, PUBREL, PUBCOMP, SUBACK, PUBLISH
  1987. uint8_t cmd; // MQTT command, one of MQTT_CMD_*
  1988. uint8_t qos; // Quality of service
  1989. uint8_t ack; // CONNACK return code, 0 = success
  1990. size_t props_start; // Offset to the start of the properties (MQTT5)
  1991. size_t props_size; // Length of the properties
  1992. };
  1993. struct mg_connection *mg_mqtt_connect(struct mg_mgr *, const char *url,
  1994. const struct mg_mqtt_opts *opts,
  1995. mg_event_handler_t fn, void *fn_data);
  1996. struct mg_connection *mg_mqtt_listen(struct mg_mgr *mgr, const char *url,
  1997. mg_event_handler_t fn, void *fn_data);
  1998. void mg_mqtt_login(struct mg_connection *c, const struct mg_mqtt_opts *opts);
  1999. uint16_t mg_mqtt_pub(struct mg_connection *c, const struct mg_mqtt_opts *opts);
  2000. void mg_mqtt_sub(struct mg_connection *, const struct mg_mqtt_opts *opts);
  2001. int mg_mqtt_parse(const uint8_t *, size_t, uint8_t, struct mg_mqtt_message *);
  2002. void mg_mqtt_send_header(struct mg_connection *, uint8_t cmd, uint8_t flags,
  2003. uint32_t len);
  2004. void mg_mqtt_ping(struct mg_connection *);
  2005. void mg_mqtt_pong(struct mg_connection *);
  2006. void mg_mqtt_disconnect(struct mg_connection *, const struct mg_mqtt_opts *);
  2007. size_t mg_mqtt_next_prop(struct mg_mqtt_message *, struct mg_mqtt_prop *,
  2008. size_t ofs);
  2009. // Mongoose sends DNS queries that contain only one question:
  2010. // either A (IPv4) or AAAA (IPv6) address lookup.
  2011. // Therefore, we expect zero or one answer.
  2012. // If `resolved` is true, then `addr` contains resolved IPv4 or IPV6 address.
  2013. struct mg_dns_message {
  2014. uint16_t txnid; // Transaction ID
  2015. bool resolved; // Resolve successful, addr is set
  2016. struct mg_addr addr; // Resolved address
  2017. char name[256]; // Host name
  2018. };
  2019. struct mg_dns_header {
  2020. uint16_t txnid; // Transaction ID
  2021. uint16_t flags;
  2022. uint16_t num_questions;
  2023. uint16_t num_answers;
  2024. uint16_t num_authority_prs;
  2025. uint16_t num_other_prs;
  2026. };
  2027. // DNS resource record
  2028. struct mg_dns_rr {
  2029. uint16_t nlen; // Name or pointer length
  2030. uint16_t atype; // Address type
  2031. uint16_t aclass; // Address class
  2032. uint16_t alen; // Address length
  2033. };
  2034. void mg_resolve(struct mg_connection *, const char *url);
  2035. void mg_resolve_cancel(struct mg_connection *);
  2036. bool mg_dns_parse(const uint8_t *buf, size_t len, struct mg_dns_message *);
  2037. size_t mg_dns_parse_rr(const uint8_t *buf, size_t len, size_t ofs,
  2038. bool is_question, struct mg_dns_rr *);
  2039. #ifndef MG_JSON_MAX_DEPTH
  2040. #define MG_JSON_MAX_DEPTH 30
  2041. #endif
  2042. // Error return values - negative. Successful returns are >= 0
  2043. enum { MG_JSON_TOO_DEEP = -1, MG_JSON_INVALID = -2, MG_JSON_NOT_FOUND = -3 };
  2044. int mg_json_get(struct mg_str json, const char *path, int *toklen);
  2045. struct mg_str mg_json_get_tok(struct mg_str json, const char *path);
  2046. bool mg_json_get_num(struct mg_str json, const char *path, double *v);
  2047. bool mg_json_get_bool(struct mg_str json, const char *path, bool *v);
  2048. long mg_json_get_long(struct mg_str json, const char *path, long dflt);
  2049. char *mg_json_get_str(struct mg_str json, const char *path);
  2050. char *mg_json_get_hex(struct mg_str json, const char *path, int *len);
  2051. char *mg_json_get_b64(struct mg_str json, const char *path, int *len);
  2052. bool mg_json_unescape(struct mg_str str, char *buf, size_t len);
  2053. size_t mg_json_next(struct mg_str obj, size_t ofs, struct mg_str *key,
  2054. struct mg_str *val);
  2055. // JSON-RPC request descriptor
  2056. struct mg_rpc_req {
  2057. struct mg_rpc **head; // RPC handlers list head
  2058. struct mg_rpc *rpc; // RPC handler being called
  2059. mg_pfn_t pfn; // Response printing function
  2060. void *pfn_data; // Response printing function data
  2061. void *req_data; // Arbitrary request data
  2062. struct mg_str frame; // Request, e.g. {"id":1,"method":"add","params":[1,2]}
  2063. };
  2064. // JSON-RPC method handler
  2065. struct mg_rpc {
  2066. struct mg_rpc *next; // Next in list
  2067. struct mg_str method; // Method pattern
  2068. void (*fn)(struct mg_rpc_req *); // Handler function
  2069. void *fn_data; // Handler function argument
  2070. };
  2071. void mg_rpc_add(struct mg_rpc **head, struct mg_str method_pattern,
  2072. void (*handler)(struct mg_rpc_req *), void *handler_data);
  2073. void mg_rpc_del(struct mg_rpc **head, void (*handler)(struct mg_rpc_req *));
  2074. void mg_rpc_process(struct mg_rpc_req *);
  2075. // Helper functions to print result or error frame
  2076. void mg_rpc_ok(struct mg_rpc_req *, const char *fmt, ...);
  2077. void mg_rpc_vok(struct mg_rpc_req *, const char *fmt, va_list *ap);
  2078. void mg_rpc_err(struct mg_rpc_req *, int code, const char *fmt, ...);
  2079. void mg_rpc_verr(struct mg_rpc_req *, int code, const char *fmt, va_list *);
  2080. void mg_rpc_list(struct mg_rpc_req *r);
  2081. // Copyright (c) 2023 Cesanta Software Limited
  2082. // All rights reserved
  2083. #define MG_OTA_NONE 0 // No OTA support
  2084. #define MG_OTA_STM32H5 1 // STM32 H5
  2085. #define MG_OTA_STM32H7 2 // STM32 H7
  2086. #define MG_OTA_STM32H7_DUAL_CORE 3 // STM32 H7 dual core
  2087. #define MG_OTA_STM32F 4 // STM32 F7/F4/F2
  2088. #define MG_OTA_CH32V307 100 // WCH CH32V307
  2089. #define MG_OTA_U2A 200 // Renesas U2A16, U2A8, U2A6
  2090. #define MG_OTA_RT1020 300 // IMXRT1020
  2091. #define MG_OTA_RT1060 301 // IMXRT1060
  2092. #define MG_OTA_RT1064 302 // IMXRT1064
  2093. #define MG_OTA_RT1170 303 // IMXRT1170
  2094. #define MG_OTA_MCXN 310 // MCXN947
  2095. #define MG_OTA_FLASH 900 // OTA via an internal flash
  2096. #define MG_OTA_ESP32 910 // ESP32 OTA implementation
  2097. #define MG_OTA_PICOSDK 920 // RP2040/2350 using Pico-SDK hardware_flash
  2098. #define MG_OTA_CUSTOM 1000 // Custom implementation
  2099. #ifndef MG_OTA
  2100. #define MG_OTA MG_OTA_NONE
  2101. #else
  2102. #ifndef MG_IRAM
  2103. #if defined(__GNUC__)
  2104. #define MG_IRAM __attribute__((noinline, section(".iram")))
  2105. #else
  2106. #define MG_IRAM
  2107. #endif // compiler
  2108. #endif // IRAM
  2109. #endif // OTA
  2110. // Firmware update API
  2111. bool mg_ota_begin(size_t new_firmware_size); // Start writing
  2112. bool mg_ota_write(const void *buf, size_t len); // Write chunk, aligned to 1k
  2113. bool mg_ota_end(void); // Stop writing
  2114. #if MG_OTA != MG_OTA_NONE && MG_OTA != MG_OTA_CUSTOM
  2115. struct mg_flash {
  2116. void *start; // Address at which flash starts
  2117. size_t size; // Flash size
  2118. size_t secsz; // Sector size
  2119. size_t align; // Write alignment
  2120. bool (*write_fn)(void *, const void *, size_t); // Write function
  2121. bool (*swap_fn)(void); // Swap partitions
  2122. };
  2123. bool mg_ota_flash_begin(size_t new_firmware_size, struct mg_flash *flash);
  2124. bool mg_ota_flash_write(const void *buf, size_t len, struct mg_flash *flash);
  2125. bool mg_ota_flash_end(struct mg_flash *flash);
  2126. #endif
  2127. struct mg_tcpip_if; // Mongoose TCP/IP network interface
  2128. struct mg_tcpip_driver {
  2129. bool (*init)(struct mg_tcpip_if *); // Init driver
  2130. size_t (*tx)(const void *, size_t, struct mg_tcpip_if *); // Transmit frame
  2131. size_t (*rx)(void *buf, size_t len, struct mg_tcpip_if *); // Receive frame
  2132. bool (*up)(struct mg_tcpip_if *); // Up/down status
  2133. };
  2134. typedef void (*mg_tcpip_event_handler_t)(struct mg_tcpip_if *ifp, int ev,
  2135. void *ev_data);
  2136. enum {
  2137. MG_TCPIP_EV_ST_CHG, // state change uint8_t * (&ifp->state)
  2138. MG_TCPIP_EV_DHCP_DNS, // DHCP DNS assignment uint32_t *ipaddr
  2139. MG_TCPIP_EV_DHCP_SNTP, // DHCP SNTP assignment uint32_t *ipaddr
  2140. MG_TCPIP_EV_ARP, // Got ARP packet struct mg_str *
  2141. MG_TCPIP_EV_TIMER_1S, // 1 second timer NULL
  2142. MG_TCPIP_EV_USER // Starting ID for user events
  2143. };
  2144. // Network interface
  2145. struct mg_tcpip_if {
  2146. uint8_t mac[6]; // MAC address. Must be set to a valid MAC
  2147. uint32_t ip, mask, gw; // IP address, mask, default gateway
  2148. struct mg_str tx; // Output (TX) buffer
  2149. bool enable_dhcp_client; // Enable DCHP client
  2150. bool enable_dhcp_server; // Enable DCHP server
  2151. bool enable_get_gateway; // DCHP server sets client as gateway
  2152. bool enable_req_dns; // DCHP client requests DNS server
  2153. bool enable_req_sntp; // DCHP client requests SNTP server
  2154. bool enable_crc32_check; // Do a CRC check on RX frames and strip it
  2155. bool enable_mac_check; // Do a MAC check on RX frames
  2156. struct mg_tcpip_driver *driver; // Low level driver
  2157. void *driver_data; // Driver-specific data
  2158. mg_tcpip_event_handler_t fn; // User-specified event handler function
  2159. struct mg_mgr *mgr; // Mongoose event manager
  2160. struct mg_queue recv_queue; // Receive queue
  2161. uint16_t mtu; // Interface MTU
  2162. #define MG_TCPIP_MTU_DEFAULT 1500
  2163. // Internal state, user can use it but should not change it
  2164. uint8_t gwmac[6]; // Router's MAC
  2165. uint64_t now; // Current time
  2166. uint64_t timer_1000ms; // 1000 ms timer: for DHCP and link state
  2167. uint64_t lease_expire; // Lease expiration time, in ms
  2168. uint16_t eport; // Next ephemeral port
  2169. volatile uint32_t ndrop; // Number of received, but dropped frames
  2170. volatile uint32_t nrecv; // Number of received frames
  2171. volatile uint32_t nsent; // Number of transmitted frames
  2172. volatile uint32_t nerr; // Number of driver errors
  2173. uint8_t state; // Current state
  2174. #define MG_TCPIP_STATE_DOWN 0 // Interface is down
  2175. #define MG_TCPIP_STATE_UP 1 // Interface is up
  2176. #define MG_TCPIP_STATE_REQ 2 // Interface is up, DHCP REQUESTING state
  2177. #define MG_TCPIP_STATE_IP 3 // Interface is up and has an IP assigned
  2178. #define MG_TCPIP_STATE_READY 4 // Interface has fully come up, ready to work
  2179. };
  2180. void mg_tcpip_init(struct mg_mgr *, struct mg_tcpip_if *);
  2181. void mg_tcpip_free(struct mg_tcpip_if *);
  2182. void mg_tcpip_qwrite(void *buf, size_t len, struct mg_tcpip_if *ifp);
  2183. void mg_tcpip_arp_request(struct mg_tcpip_if *ifp, uint32_t ip, uint8_t *mac);
  2184. extern struct mg_tcpip_driver mg_tcpip_driver_stm32f;
  2185. extern struct mg_tcpip_driver mg_tcpip_driver_w5500;
  2186. extern struct mg_tcpip_driver mg_tcpip_driver_tm4c;
  2187. extern struct mg_tcpip_driver mg_tcpip_driver_tms570;
  2188. extern struct mg_tcpip_driver mg_tcpip_driver_stm32h;
  2189. extern struct mg_tcpip_driver mg_tcpip_driver_imxrt;
  2190. extern struct mg_tcpip_driver mg_tcpip_driver_same54;
  2191. extern struct mg_tcpip_driver mg_tcpip_driver_cmsis;
  2192. extern struct mg_tcpip_driver mg_tcpip_driver_ra;
  2193. extern struct mg_tcpip_driver mg_tcpip_driver_xmc;
  2194. extern struct mg_tcpip_driver mg_tcpip_driver_xmc7;
  2195. extern struct mg_tcpip_driver mg_tcpip_driver_ppp;
  2196. extern struct mg_tcpip_driver mg_tcpip_driver_pico_w;
  2197. // Drivers that require SPI, can use this SPI abstraction
  2198. struct mg_tcpip_spi {
  2199. void *spi; // Opaque SPI bus descriptor
  2200. void (*begin)(void *); // SPI begin: slave select low
  2201. void (*end)(void *); // SPI end: slave select high
  2202. uint8_t (*txn)(void *, uint8_t); // SPI transaction: write 1 byte, read reply
  2203. };
  2204. // Macros to record timestamped events that happens with a connection.
  2205. // They are saved into a c->prof IO buffer, each event is a name and a 32-bit
  2206. // timestamp in milliseconds since connection init time.
  2207. //
  2208. // Test (run in two separate terminals):
  2209. // make -C examples/http-server/ CFLAGS_EXTRA=-DMG_ENABLE_PROFILE=1
  2210. // curl localhost:8000
  2211. // Output:
  2212. // 1ea1f1e7 2 net.c:150:mg_close_conn 3 profile:
  2213. // 1ea1f1e8 2 net.c:150:mg_close_conn 1ea1f1e6 init
  2214. // 1ea1f1e8 2 net.c:150:mg_close_conn 0 EV_OPEN
  2215. // 1ea1f1e8 2 net.c:150:mg_close_conn 0 EV_ACCEPT
  2216. // 1ea1f1e8 2 net.c:150:mg_close_conn 0 EV_READ
  2217. // 1ea1f1e8 2 net.c:150:mg_close_conn 0 EV_HTTP_MSG
  2218. // 1ea1f1e8 2 net.c:150:mg_close_conn 0 EV_WRITE
  2219. // 1ea1f1e8 2 net.c:150:mg_close_conn 1 EV_CLOSE
  2220. //
  2221. // Usage:
  2222. // Enable profiling by setting MG_ENABLE_PROFILE=1
  2223. // Invoke MG_PROF_ADD(c, "MY_EVENT_1") in the places you'd like to measure
  2224. #if MG_ENABLE_PROFILE
  2225. struct mg_profitem {
  2226. const char *name; // Event name
  2227. uint32_t timestamp; // Milliseconds since connection creation (MG_EV_OPEN)
  2228. };
  2229. #define MG_PROFILE_ALLOC_GRANULARITY 256 // Can save 32 items wih to realloc
  2230. // Adding a profile item to the c->prof. Must be as fast as possible.
  2231. // Reallocation of the c->prof iobuf is not desirable here, that's why we
  2232. // pre-allocate c->prof with MG_PROFILE_ALLOC_GRANULARITY.
  2233. // This macro just inits and copies 8 bytes, and calls mg_millis(),
  2234. // which should be fast enough.
  2235. #define MG_PROF_ADD(c, name_) \
  2236. do { \
  2237. struct mg_iobuf *io = &c->prof; \
  2238. uint32_t inittime = ((struct mg_profitem *) io->buf)->timestamp; \
  2239. struct mg_profitem item = {name_, (uint32_t) mg_millis() - inittime}; \
  2240. mg_iobuf_add(io, io->len, &item, sizeof(item)); \
  2241. } while (0)
  2242. // Initialising profile for a new connection. Not time sensitive
  2243. #define MG_PROF_INIT(c) \
  2244. do { \
  2245. struct mg_profitem first = {"init", (uint32_t) mg_millis()}; \
  2246. mg_iobuf_init(&(c)->prof, 0, MG_PROFILE_ALLOC_GRANULARITY); \
  2247. mg_iobuf_add(&c->prof, c->prof.len, &first, sizeof(first)); \
  2248. } while (0)
  2249. #define MG_PROF_FREE(c) mg_iobuf_free(&(c)->prof)
  2250. // Dumping the profile. Not time sensitive
  2251. #define MG_PROF_DUMP(c) \
  2252. do { \
  2253. struct mg_iobuf *io = &c->prof; \
  2254. struct mg_profitem *p = (struct mg_profitem *) io->buf; \
  2255. struct mg_profitem *e = &p[io->len / sizeof(*p)]; \
  2256. MG_INFO(("%lu profile:", c->id)); \
  2257. while (p < e) { \
  2258. MG_INFO(("%5lx %s", (unsigned long) p->timestamp, p->name)); \
  2259. p++; \
  2260. } \
  2261. } while (0)
  2262. #else
  2263. #define MG_PROF_INIT(c)
  2264. #define MG_PROF_FREE(c)
  2265. #define MG_PROF_ADD(c, name)
  2266. #define MG_PROF_DUMP(c)
  2267. #endif
  2268. #if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_CMSIS) && MG_ENABLE_DRIVER_CMSIS
  2269. #include "Driver_ETH_MAC.h" // keep this include
  2270. #include "Driver_ETH_PHY.h" // keep this include
  2271. #endif
  2272. #if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_IMXRT) && MG_ENABLE_DRIVER_IMXRT
  2273. struct mg_tcpip_driver_imxrt_data {
  2274. // MDC clock divider. MDC clock is derived from IPS Bus clock (ipg_clk),
  2275. // must not exceed 2.5MHz. Configuration for clock range 2.36~2.50 MHz
  2276. // 37.5.1.8.2, Table 37-46 : f = ipg_clk / (2(mdc_cr + 1))
  2277. // ipg_clk mdc_cr VALUE
  2278. // --------------------------
  2279. // -1 <-- TODO() tell driver to guess the value
  2280. // 25 MHz 4
  2281. // 33 MHz 6
  2282. // 40 MHz 7
  2283. // 50 MHz 9
  2284. // 66 MHz 13
  2285. int mdc_cr; // Valid values: -1 to 63
  2286. uint8_t phy_addr; // PHY address
  2287. };
  2288. #ifndef MG_TCPIP_PHY_ADDR
  2289. #define MG_TCPIP_PHY_ADDR 2
  2290. #endif
  2291. #ifndef MG_DRIVER_MDC_CR
  2292. #define MG_DRIVER_MDC_CR 24
  2293. #endif
  2294. #define MG_TCPIP_DRIVER_INIT(mgr) \
  2295. do { \
  2296. static struct mg_tcpip_driver_imxrt_data driver_data_; \
  2297. static struct mg_tcpip_if mif_; \
  2298. driver_data_.mdc_cr = MG_DRIVER_MDC_CR; \
  2299. driver_data_.phy_addr = MG_TCPIP_PHY_ADDR; \
  2300. mif_.ip = MG_TCPIP_IP; \
  2301. mif_.mask = MG_TCPIP_MASK; \
  2302. mif_.gw = MG_TCPIP_GW; \
  2303. mif_.driver = &mg_tcpip_driver_imxrt; \
  2304. mif_.driver_data = &driver_data_; \
  2305. MG_SET_MAC_ADDRESS(mif_.mac); \
  2306. mg_tcpip_init(mgr, &mif_); \
  2307. MG_INFO(("Driver: imxrt, MAC: %M", mg_print_mac, mif_.mac)); \
  2308. } while (0)
  2309. #endif
  2310. struct mg_phy {
  2311. uint16_t (*read_reg)(uint8_t addr, uint8_t reg);
  2312. void (*write_reg)(uint8_t addr, uint8_t reg, uint16_t value);
  2313. };
  2314. // PHY configuration settings, bitmask
  2315. enum {
  2316. // Set if PHY LEDs are connected to ground
  2317. MG_PHY_LEDS_ACTIVE_HIGH = (1 << 0),
  2318. // Set when PHY clocks MAC. Otherwise, MAC clocks PHY
  2319. MG_PHY_CLOCKS_MAC = (1 << 1),
  2320. };
  2321. enum { MG_PHY_SPEED_10M, MG_PHY_SPEED_100M, MG_PHY_SPEED_1000M };
  2322. void mg_phy_init(struct mg_phy *, uint8_t addr, uint8_t config);
  2323. bool mg_phy_up(struct mg_phy *, uint8_t addr, bool *full_duplex,
  2324. uint8_t *speed);
  2325. #if MG_ENABLE_TCPIP && MG_ARCH == MG_ARCH_PICOSDK && \
  2326. defined(MG_ENABLE_DRIVER_PICO_W) && MG_ENABLE_DRIVER_PICO_W
  2327. #include "cyw43.h" // keep this include
  2328. #include "pico/cyw43_arch.h" // keep this include
  2329. #include "pico/unique_id.h" // keep this include
  2330. struct mg_tcpip_driver_pico_w_data {
  2331. char *ssid;
  2332. char *pass;
  2333. };
  2334. #define MG_TCPIP_DRIVER_INIT(mgr) \
  2335. do { \
  2336. static struct mg_tcpip_driver_pico_w_data driver_data_; \
  2337. static struct mg_tcpip_if mif_; \
  2338. MG_SET_WIFI_CREDS(&driver_data_.ssid, &driver_data_.pass); \
  2339. mif_.ip = MG_TCPIP_IP; \
  2340. mif_.mask = MG_TCPIP_MASK; \
  2341. mif_.gw = MG_TCPIP_GW; \
  2342. mif_.driver = &mg_tcpip_driver_pico_w; \
  2343. mif_.driver_data = &driver_data_; \
  2344. mif_.recv_queue.size = 8192; \
  2345. mif_.mac[0] = 2; /* MAC read from OTP at driver init */ \
  2346. mg_tcpip_init(mgr, &mif_); \
  2347. MG_INFO(("Driver: pico-w, MAC: %M", mg_print_mac, mif_.mac)); \
  2348. } while (0)
  2349. #endif
  2350. struct mg_tcpip_driver_ppp_data {
  2351. void *uart; // Opaque UART bus descriptor
  2352. void (*reset)(void *); // Modem hardware reset
  2353. void (*tx)(void *, uint8_t); // UART transmit single byte
  2354. int (*rx)(void *); // UART receive single byte
  2355. const char **script; // List of AT commands and expected replies
  2356. int script_index; // Index of the current AT command in the list
  2357. uint64_t deadline; // AT command deadline in ms
  2358. };
  2359. #if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_RA) && MG_ENABLE_DRIVER_RA
  2360. struct mg_tcpip_driver_ra_data {
  2361. // MDC clock "divider". MDC clock is software generated,
  2362. uint32_t clock; // core clock frequency in Hz
  2363. uint16_t irqno; // IRQn, R_ICU->IELSR[irqno]
  2364. uint8_t phy_addr; // PHY address
  2365. };
  2366. #endif
  2367. #if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_SAME54) && MG_ENABLE_DRIVER_SAME54
  2368. struct mg_tcpip_driver_same54_data {
  2369. int mdc_cr;
  2370. };
  2371. #ifndef MG_DRIVER_MDC_CR
  2372. #define MG_DRIVER_MDC_CR 5
  2373. #endif
  2374. #endif
  2375. #if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_STM32F) && \
  2376. MG_ENABLE_DRIVER_STM32F
  2377. struct mg_tcpip_driver_stm32f_data {
  2378. // MDC clock divider. MDC clock is derived from HCLK, must not exceed 2.5MHz
  2379. // HCLK range DIVIDER mdc_cr VALUE
  2380. // -------------------------------------
  2381. // -1 <-- tell driver to guess the value
  2382. // 60-100 MHz HCLK/42 0
  2383. // 100-150 MHz HCLK/62 1
  2384. // 20-35 MHz HCLK/16 2
  2385. // 35-60 MHz HCLK/26 3
  2386. // 150-216 MHz HCLK/102 4 <-- value for Nucleo-F* on max speed
  2387. // 216-310 MHz HCLK/124 5
  2388. // 110, 111 Reserved
  2389. int mdc_cr; // Valid values: -1, 0, 1, 2, 3, 4, 5
  2390. uint8_t phy_addr; // PHY address
  2391. };
  2392. #ifndef MG_TCPIP_PHY_ADDR
  2393. #define MG_TCPIP_PHY_ADDR 0
  2394. #endif
  2395. #ifndef MG_DRIVER_MDC_CR
  2396. #define MG_DRIVER_MDC_CR 4
  2397. #endif
  2398. #define MG_TCPIP_DRIVER_INIT(mgr) \
  2399. do { \
  2400. static struct mg_tcpip_driver_stm32f_data driver_data_; \
  2401. static struct mg_tcpip_if mif_; \
  2402. driver_data_.mdc_cr = MG_DRIVER_MDC_CR; \
  2403. driver_data_.phy_addr = MG_TCPIP_PHY_ADDR; \
  2404. mif_.ip = MG_TCPIP_IP; \
  2405. mif_.mask = MG_TCPIP_MASK; \
  2406. mif_.gw = MG_TCPIP_GW; \
  2407. mif_.driver = &mg_tcpip_driver_stm32f; \
  2408. mif_.driver_data = &driver_data_; \
  2409. MG_SET_MAC_ADDRESS(mif_.mac); \
  2410. mg_tcpip_init(mgr, &mif_); \
  2411. MG_INFO(("Driver: stm32f, MAC: %M", mg_print_mac, mif_.mac)); \
  2412. } while (0)
  2413. #endif
  2414. #if MG_ENABLE_TCPIP
  2415. #if !defined(MG_ENABLE_DRIVER_STM32H)
  2416. #define MG_ENABLE_DRIVER_STM32H 0
  2417. #endif
  2418. #if !defined(MG_ENABLE_DRIVER_MCXN)
  2419. #define MG_ENABLE_DRIVER_MCXN 0
  2420. #endif
  2421. #if MG_ENABLE_DRIVER_STM32H || MG_ENABLE_DRIVER_MCXN
  2422. struct mg_tcpip_driver_stm32h_data {
  2423. // MDC clock divider. MDC clock is derived from HCLK, must not exceed 2.5MHz
  2424. // HCLK range DIVIDER mdc_cr VALUE
  2425. // -------------------------------------
  2426. // -1 <-- tell driver to guess the value
  2427. // 60-100 MHz HCLK/42 0
  2428. // 100-150 MHz HCLK/62 1
  2429. // 20-35 MHz HCLK/16 2
  2430. // 35-60 MHz HCLK/26 3
  2431. // 150-250 MHz HCLK/102 4 <-- value for max speed HSI
  2432. // 250-300 MHz HCLK/124 5 <-- value for Nucleo-H* on CSI
  2433. // 300-500 MHz HCLK/204 6
  2434. // 500-800 MHz HCLK/324 7
  2435. int mdc_cr; // Valid values: -1, 0, 1, 2, 3, 4, 5
  2436. uint8_t phy_addr; // PHY address
  2437. uint8_t phy_conf; // PHY config
  2438. };
  2439. #ifndef MG_TCPIP_PHY_CONF
  2440. #define MG_TCPIP_PHY_CONF MG_PHY_CLOCKS_MAC
  2441. #endif
  2442. #ifndef MG_TCPIP_PHY_ADDR
  2443. #define MG_TCPIP_PHY_ADDR 0
  2444. #endif
  2445. #ifndef MG_DRIVER_MDC_CR
  2446. #define MG_DRIVER_MDC_CR 4
  2447. #endif
  2448. #define MG_TCPIP_DRIVER_INIT(mgr) \
  2449. do { \
  2450. static struct mg_tcpip_driver_stm32h_data driver_data_; \
  2451. static struct mg_tcpip_if mif_; \
  2452. driver_data_.mdc_cr = MG_DRIVER_MDC_CR; \
  2453. driver_data_.phy_addr = MG_TCPIP_PHY_ADDR; \
  2454. driver_data_.phy_conf = MG_TCPIP_PHY_CONF; \
  2455. mif_.ip = MG_TCPIP_IP; \
  2456. mif_.mask = MG_TCPIP_MASK; \
  2457. mif_.gw = MG_TCPIP_GW; \
  2458. mif_.driver = &mg_tcpip_driver_stm32h; \
  2459. mif_.driver_data = &driver_data_; \
  2460. MG_SET_MAC_ADDRESS(mif_.mac); \
  2461. mg_tcpip_init(mgr, &mif_); \
  2462. MG_INFO(("Driver: stm32h, MAC: %M", mg_print_mac, mif_.mac)); \
  2463. } while (0)
  2464. #endif
  2465. #endif
  2466. #if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_TM4C) && MG_ENABLE_DRIVER_TM4C
  2467. struct mg_tcpip_driver_tm4c_data {
  2468. // MDC clock divider. MDC clock is derived from SYSCLK, must not exceed 2.5MHz
  2469. // SYSCLK range DIVIDER mdc_cr VALUE
  2470. // -------------------------------------
  2471. // -1 <-- tell driver to guess the value
  2472. // 60-100 MHz SYSCLK/42 0
  2473. // 100-150 MHz SYSCLK/62 1 <-- value for EK-TM4C129* on max speed
  2474. // 20-35 MHz SYSCLK/16 2
  2475. // 35-60 MHz SYSCLK/26 3
  2476. // 0x4-0xF Reserved
  2477. int mdc_cr; // Valid values: -1, 0, 1, 2, 3
  2478. };
  2479. #ifndef MG_DRIVER_MDC_CR
  2480. #define MG_DRIVER_MDC_CR 1
  2481. #endif
  2482. #define MG_TCPIP_DRIVER_INIT(mgr) \
  2483. do { \
  2484. static struct mg_tcpip_driver_tm4c_data driver_data_; \
  2485. static struct mg_tcpip_if mif_; \
  2486. driver_data_.mdc_cr = MG_DRIVER_MDC_CR; \
  2487. mif_.ip = MG_TCPIP_IP; \
  2488. mif_.mask = MG_TCPIP_MASK; \
  2489. mif_.gw = MG_TCPIP_GW; \
  2490. mif_.driver = &mg_tcpip_driver_tm4c; \
  2491. mif_.driver_data = &driver_data_; \
  2492. MG_SET_MAC_ADDRESS(mif_.mac); \
  2493. mg_tcpip_init(mgr, &mif_); \
  2494. MG_INFO(("Driver: tm4c, MAC: %M", mg_print_mac, mif_.mac)); \
  2495. } while (0)
  2496. #endif
  2497. #if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_TMS570) && MG_ENABLE_DRIVER_TMS570
  2498. struct mg_tcpip_driver_tms570_data {
  2499. int mdc_cr;
  2500. int phy_addr;
  2501. };
  2502. #ifndef MG_TCPIP_PHY_ADDR
  2503. #define MG_TCPIP_PHY_ADDR 0
  2504. #endif
  2505. #ifndef MG_DRIVER_MDC_CR
  2506. #define MG_DRIVER_MDC_CR 1
  2507. #endif
  2508. #define MG_TCPIP_DRIVER_INIT(mgr) \
  2509. do { \
  2510. static struct mg_tcpip_driver_tms570_data driver_data_; \
  2511. static struct mg_tcpip_if mif_; \
  2512. driver_data_.mdc_cr = MG_DRIVER_MDC_CR; \
  2513. driver_data_.phy_addr = MG_TCPIP_PHY_ADDR; \
  2514. mif_.ip = MG_TCPIP_IP; \
  2515. mif_.mask = MG_TCPIP_MASK; \
  2516. mif_.gw = MG_TCPIP_GW; \
  2517. mif_.driver = &mg_tcpip_driver_tms570; \
  2518. mif_.driver_data = &driver_data_; \
  2519. MG_SET_MAC_ADDRESS(mif_.mac); \
  2520. mg_tcpip_init(mgr, &mif_); \
  2521. MG_INFO(("Driver: tms570, MAC: %M", mg_print_mac, mif_.mac));\
  2522. } while (0)
  2523. #endif
  2524. #if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_W5500) && MG_ENABLE_DRIVER_W5500
  2525. #endif
  2526. #if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_XMC7) && MG_ENABLE_DRIVER_XMC7
  2527. struct mg_tcpip_driver_xmc7_data {
  2528. int mdc_cr; // Valid values: -1, 0, 1, 2, 3, 4, 5
  2529. uint8_t phy_addr;
  2530. };
  2531. #ifndef MG_TCPIP_PHY_ADDR
  2532. #define MG_TCPIP_PHY_ADDR 0
  2533. #endif
  2534. #ifndef MG_DRIVER_MDC_CR
  2535. #define MG_DRIVER_MDC_CR 3
  2536. #endif
  2537. #define MG_TCPIP_DRIVER_INIT(mgr) \
  2538. do { \
  2539. static struct mg_tcpip_driver_xmc7_data driver_data_; \
  2540. static struct mg_tcpip_if mif_; \
  2541. driver_data_.mdc_cr = MG_DRIVER_MDC_CR; \
  2542. driver_data_.phy_addr = MG_TCPIP_PHY_ADDR; \
  2543. mif_.ip = MG_TCPIP_IP; \
  2544. mif_.mask = MG_TCPIP_MASK; \
  2545. mif_.gw = MG_TCPIP_GW; \
  2546. mif_.driver = &mg_tcpip_driver_xmc7; \
  2547. mif_.driver_data = &driver_data_; \
  2548. MG_SET_MAC_ADDRESS(mif_.mac); \
  2549. mg_tcpip_init(mgr, &mif_); \
  2550. MG_INFO(("Driver: xmc7, MAC: %M", mg_print_mac, mif_.mac)); \
  2551. } while (0)
  2552. #endif
  2553. #if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_XMC) && MG_ENABLE_DRIVER_XMC
  2554. struct mg_tcpip_driver_xmc_data {
  2555. // 13.2.8.1 Station Management Functions
  2556. // MDC clock divider (). MDC clock is derived from ETH MAC clock
  2557. // It must not exceed 2.5MHz
  2558. // ETH Clock range DIVIDER mdc_cr VALUE
  2559. // --------------------------------------------
  2560. // -1 <-- tell driver to guess the value
  2561. // 60-100 MHz ETH Clock/42 0
  2562. // 100-150 MHz ETH Clock/62 1
  2563. // 20-35 MHz ETH Clock/16 2
  2564. // 35-60 MHz ETH Clock/26 3
  2565. // 150-250 MHz ETH Clock/102 4
  2566. // 250-300 MHz ETH Clock/124 5
  2567. // 110, 111 Reserved
  2568. int mdc_cr; // Valid values: -1, 0, 1, 2, 3, 4, 5
  2569. uint8_t phy_addr;
  2570. };
  2571. #ifndef MG_TCPIP_PHY_ADDR
  2572. #define MG_TCPIP_PHY_ADDR 0
  2573. #endif
  2574. #ifndef MG_DRIVER_MDC_CR
  2575. #define MG_DRIVER_MDC_CR 4
  2576. #endif
  2577. #define MG_TCPIP_DRIVER_INIT(mgr) \
  2578. do { \
  2579. static struct mg_tcpip_driver_xmc_data driver_data_; \
  2580. static struct mg_tcpip_if mif_; \
  2581. driver_data_.mdc_cr = MG_DRIVER_MDC_CR; \
  2582. driver_data_.phy_addr = MG_TCPIP_PHY_ADDR; \
  2583. mif_.ip = MG_TCPIP_IP; \
  2584. mif_.mask = MG_TCPIP_MASK; \
  2585. mif_.gw = MG_TCPIP_GW; \
  2586. mif_.driver = &mg_tcpip_driver_xmc; \
  2587. mif_.driver_data = &driver_data_; \
  2588. MG_SET_MAC_ADDRESS(mif_.mac); \
  2589. mg_tcpip_init(mgr, &mif_); \
  2590. MG_INFO(("Driver: xmc, MAC: %M", mg_print_mac, mif_.mac)); \
  2591. } while (0)
  2592. #endif
  2593. #ifdef __cplusplus
  2594. }
  2595. #endif
  2596. #endif // MONGOOSE_H