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