mongoose.h 99 KB

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