mongoose.h 99 KB

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