mongoose.h 51 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682
  1. // Copyright (c) 2004-2013 Sergey Lyubka
  2. // Copyright (c) 2013-2022 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.9"
  22. #ifdef __cplusplus
  23. extern "C" {
  24. #endif
  25. #define MG_ARCH_CUSTOM 0 // User creates its own mongoose_custom.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. #if !defined(MG_ARCH)
  40. #if defined(__unix__) || defined(__APPLE__)
  41. #define MG_ARCH MG_ARCH_UNIX
  42. #elif defined(_WIN32)
  43. #define MG_ARCH MG_ARCH_WIN32
  44. #elif defined(ICACHE_FLASH) || defined(ICACHE_RAM_ATTR)
  45. #define MG_ARCH MG_ARCH_ESP8266
  46. #elif defined(__ZEPHYR__)
  47. #define MG_ARCH MG_ARCH_ZEPHYR
  48. #elif defined(ESP_PLATFORM)
  49. #define MG_ARCH MG_ARCH_ESP32
  50. #elif defined(FREERTOS_IP_H)
  51. #define MG_ARCH MG_ARCH_FREERTOS
  52. #define MG_ENABLE_FREERTOS_TCP 1
  53. #elif defined(AZURE_RTOS_THREADX)
  54. #define MG_ARCH MG_ARCH_AZURERTOS
  55. #elif defined(PICO_TARGET_NAME)
  56. #define MG_ARCH MG_ARCH_RP2040
  57. #elif defined(__ARMCC_VERSION)
  58. #define MG_ARCH MG_ARCH_ARMCC
  59. #endif
  60. #endif // !defined(MG_ARCH)
  61. // if the user did not specify an MG_ARCH, or specified a custom one, OR
  62. // we guessed a known IDE, pull the customized config (Configuration Wizard)
  63. #if !defined(MG_ARCH) || (MG_ARCH == MG_ARCH_CUSTOM) || MG_ARCH == MG_ARCH_ARMCC
  64. #include "mongoose_custom.h" // keep this include
  65. #endif
  66. #if !defined(MG_ARCH)
  67. #error "MG_ARCH is not specified and we couldn't guess it. Set -D MG_ARCH=..."
  68. #endif
  69. // http://esr.ibiblio.org/?p=5095
  70. #define MG_BIG_ENDIAN (*(uint16_t *) "\0\xff" < 0x100)
  71. #if MG_ARCH == MG_ARCH_AZURERTOS
  72. #include <stdarg.h>
  73. #include <stdbool.h>
  74. #include <stdint.h>
  75. #include <stdio.h>
  76. #include <time.h>
  77. #include <fx_api.h>
  78. #include <tx_api.h>
  79. #include <nx_api.h>
  80. #include <nx_bsd.h>
  81. #include <nx_port.h>
  82. #include <tx_port.h>
  83. #define PATH_MAX FX_MAXIMUM_PATH
  84. #define MG_DIRSEP '\\'
  85. #define socklen_t int
  86. #define closesocket(x) soc_close(x)
  87. #undef FOPEN_MAX
  88. #endif
  89. #if MG_ARCH == MG_ARCH_ESP32
  90. #include <ctype.h>
  91. #include <dirent.h>
  92. #include <errno.h>
  93. #include <fcntl.h>
  94. #include <limits.h>
  95. #include <netdb.h>
  96. #include <stdarg.h>
  97. #include <stddef.h>
  98. #include <stdio.h>
  99. #include <stdlib.h>
  100. #include <string.h>
  101. #include <sys/stat.h>
  102. #include <sys/types.h>
  103. #include <time.h>
  104. #include <esp_timer.h>
  105. #define MG_PATH_MAX 128
  106. #endif
  107. #if MG_ARCH == MG_ARCH_ESP8266
  108. #include <ctype.h>
  109. #include <dirent.h>
  110. #include <errno.h>
  111. #include <fcntl.h>
  112. #include <limits.h>
  113. #include <netdb.h>
  114. #include <stdarg.h>
  115. #include <stdbool.h>
  116. #include <stddef.h>
  117. #include <stdio.h>
  118. #include <stdlib.h>
  119. #include <string.h>
  120. #include <sys/stat.h>
  121. #include <sys/time.h>
  122. #include <sys/types.h>
  123. #include <time.h>
  124. #include <esp_system.h>
  125. #define MG_PATH_MAX 128
  126. #endif
  127. #if MG_ARCH == MG_ARCH_FREERTOS
  128. #include <ctype.h>
  129. #if !defined(MG_ENABLE_LWIP) || !MG_ENABLE_LWIP
  130. #include <errno.h>
  131. #endif
  132. #include <stdarg.h>
  133. #include <stdbool.h>
  134. #include <stddef.h>
  135. #include <stdint.h>
  136. #include <stdio.h>
  137. #include <stdlib.h> // rand(), strtol(), atoi()
  138. #include <string.h>
  139. #if defined(__ARMCC_VERSION)
  140. #define mode_t size_t
  141. #include <time.h>
  142. #else
  143. #include <sys/stat.h>
  144. #endif
  145. #include <FreeRTOS.h>
  146. #include <task.h>
  147. #ifndef MG_IO_SIZE
  148. #define MG_IO_SIZE 512
  149. #endif
  150. #define calloc(a, b) mg_calloc(a, b)
  151. #define free(a) vPortFree(a)
  152. #define malloc(a) pvPortMalloc(a)
  153. #define strdup(s) ((char *) mg_strdup(mg_str(s)).ptr)
  154. // Re-route calloc/free to the FreeRTOS's functions, don't use stdlib
  155. static inline void *mg_calloc(size_t cnt, size_t size) {
  156. void *p = pvPortMalloc(cnt * size);
  157. if (p != NULL) memset(p, 0, size * cnt);
  158. return p;
  159. }
  160. #define mkdir(a, b) mg_mkdir(a, b)
  161. static inline int mg_mkdir(const char *path, mode_t mode) {
  162. (void) path, (void) mode;
  163. return -1;
  164. }
  165. #endif // MG_ARCH == MG_ARCH_FREERTOS
  166. #if MG_ARCH == MG_ARCH_NEWLIB
  167. #define _POSIX_TIMERS
  168. #include <ctype.h>
  169. #include <errno.h>
  170. #include <stdarg.h>
  171. #include <stdbool.h>
  172. #include <stdio.h>
  173. #include <stdlib.h>
  174. #include <string.h>
  175. #include <sys/stat.h>
  176. #include <sys/time.h>
  177. #include <sys/types.h>
  178. #include <time.h>
  179. #include <unistd.h>
  180. #define MG_PATH_MAX 100
  181. #define MG_ENABLE_SOCKET 0
  182. #define MG_ENABLE_DIRLIST 0
  183. #endif
  184. #if MG_ARCH == MG_ARCH_RP2040
  185. #include <errno.h>
  186. #include <stdarg.h>
  187. #include <stdbool.h>
  188. #include <stdint.h>
  189. #include <stdio.h>
  190. #include <stdlib.h>
  191. #include <string.h>
  192. #include <time.h>
  193. #include <pico/stdlib.h>
  194. int mkdir(const char *, mode_t);
  195. #endif
  196. #if MG_ARCH == MG_ARCH_ARMCC || MG_ARCH == MG_ARCH_CMSIS_RTOS1 || \
  197. MG_ARCH == MG_ARCH_CMSIS_RTOS2
  198. #include <ctype.h>
  199. #include <errno.h>
  200. #include <stdarg.h>
  201. #include <stdbool.h>
  202. #include <stddef.h>
  203. #include <stdint.h>
  204. #include <stdio.h>
  205. #include <stdlib.h>
  206. #include <string.h>
  207. #include <time.h>
  208. #if MG_ARCH == MG_ARCH_CMSIS_RTOS1
  209. #include "cmsis_os.h" // keep this include
  210. // https://developer.arm.com/documentation/ka003821/latest
  211. extern uint32_t rt_time_get(void);
  212. #elif MG_ARCH == MG_ARCH_CMSIS_RTOS2
  213. #include "cmsis_os2.h" // keep this include
  214. #endif
  215. #define strdup(s) ((char *) mg_strdup(mg_str(s)).ptr)
  216. #if defined(__ARMCC_VERSION)
  217. #define mode_t size_t
  218. #define mkdir(a, b) mg_mkdir(a, b)
  219. static inline int mg_mkdir(const char *path, mode_t mode) {
  220. (void) path, (void) mode;
  221. return -1;
  222. }
  223. #endif
  224. #if (MG_ARCH == MG_ARCH_CMSIS_RTOS1 || MG_ARCH == MG_ARCH_CMSIS_RTOS2) && \
  225. !defined MG_ENABLE_RL && (!defined(MG_ENABLE_LWIP) || !MG_ENABLE_LWIP) && \
  226. (!defined(MG_ENABLE_TCPIP) || !MG_ENABLE_TCPIP)
  227. #define MG_ENABLE_RL 1
  228. #endif
  229. #endif
  230. #if MG_ARCH == MG_ARCH_TIRTOS
  231. #include <stdlib.h>
  232. #include <ctype.h>
  233. #include <stdarg.h>
  234. #include <stdbool.h>
  235. #include <stdint.h>
  236. #include <stdio.h>
  237. #include <string.h>
  238. #include <time.h>
  239. #include <serrno.h>
  240. #include <sys/socket.h>
  241. #include <ti/sysbios/knl/Clock.h>
  242. #endif
  243. #if MG_ARCH == MG_ARCH_UNIX
  244. #define _DARWIN_UNLIMITED_SELECT 1 // No limit on file descriptors
  245. #if defined(__APPLE__)
  246. #include <mach/mach_time.h>
  247. #endif
  248. #if !defined(MG_ENABLE_EPOLL) && defined(__linux__)
  249. #define MG_ENABLE_EPOLL 1
  250. #elif !defined(MG_ENABLE_POLL)
  251. #define MG_ENABLE_POLL 1
  252. #endif
  253. #include <arpa/inet.h>
  254. #include <ctype.h>
  255. #include <dirent.h>
  256. #include <errno.h>
  257. #include <fcntl.h>
  258. #include <inttypes.h>
  259. #include <limits.h>
  260. #include <netdb.h>
  261. #include <netinet/in.h>
  262. #include <netinet/tcp.h>
  263. #include <signal.h>
  264. #include <stdarg.h>
  265. #include <stdbool.h>
  266. #include <stddef.h>
  267. #include <stdint.h>
  268. #include <stdio.h>
  269. #include <stdlib.h>
  270. #include <string.h>
  271. #if defined(MG_ENABLE_EPOLL) && MG_ENABLE_EPOLL
  272. #include <sys/epoll.h>
  273. #elif defined(MG_ENABLE_POLL) && MG_ENABLE_POLL
  274. #include <poll.h>
  275. #else
  276. #include <sys/select.h>
  277. #endif
  278. #include <sys/socket.h>
  279. #include <sys/stat.h>
  280. #include <sys/time.h>
  281. #include <sys/types.h>
  282. #include <time.h>
  283. #include <unistd.h>
  284. #ifndef MG_ENABLE_DIRLIST
  285. #define MG_ENABLE_DIRLIST 1
  286. #endif
  287. #ifndef MG_PATH_MAX
  288. #define MG_PATH_MAX FILENAME_MAX
  289. #endif
  290. #endif
  291. #if MG_ARCH == MG_ARCH_WIN32
  292. #ifndef WIN32_LEAN_AND_MEAN
  293. #define WIN32_LEAN_AND_MEAN
  294. #endif
  295. #ifndef _CRT_SECURE_NO_WARNINGS
  296. #define _CRT_SECURE_NO_WARNINGS
  297. #endif
  298. #ifndef _WINSOCK_DEPRECATED_NO_WARNINGS
  299. #define _WINSOCK_DEPRECATED_NO_WARNINGS
  300. #endif
  301. #include <ctype.h>
  302. #include <direct.h>
  303. #include <errno.h>
  304. #include <fcntl.h>
  305. #include <limits.h>
  306. #include <signal.h>
  307. #include <stdarg.h>
  308. #include <stddef.h>
  309. #include <stdio.h>
  310. #include <stdlib.h>
  311. #include <string.h>
  312. #include <sys/stat.h>
  313. #include <sys/types.h>
  314. #include <time.h>
  315. #if defined(_MSC_VER) && _MSC_VER < 1700
  316. #define __func__ ""
  317. typedef __int64 int64_t;
  318. typedef unsigned __int64 uint64_t;
  319. typedef unsigned char uint8_t;
  320. typedef char int8_t;
  321. typedef unsigned short uint16_t;
  322. typedef short int16_t;
  323. typedef unsigned int uint32_t;
  324. typedef int int32_t;
  325. typedef enum { false = 0, true = 1 } bool;
  326. #else
  327. #include <stdbool.h>
  328. #include <stdint.h>
  329. #include <ws2tcpip.h>
  330. #endif
  331. #include <process.h>
  332. #include <winerror.h>
  333. #include <winsock2.h>
  334. // Protect from calls like std::snprintf in app code
  335. // See https://github.com/cesanta/mongoose/issues/1047
  336. #ifndef __cplusplus
  337. #define snprintf _snprintf
  338. #define vsnprintf _vsnprintf
  339. #ifndef strdup // For MSVC with _DEBUG, see #1359
  340. #define strdup(x) _strdup(x)
  341. #endif
  342. #endif
  343. #define MG_INVALID_SOCKET INVALID_SOCKET
  344. #define MG_SOCKET_TYPE SOCKET
  345. typedef unsigned long nfds_t;
  346. #if defined(_MSC_VER)
  347. #pragma comment(lib, "ws2_32.lib")
  348. #ifndef alloca
  349. #define alloca(a) _alloca(a)
  350. #endif
  351. #endif
  352. #define poll(a, b, c) WSAPoll((a), (b), (c))
  353. #define closesocket(x) closesocket(x)
  354. typedef int socklen_t;
  355. #define MG_DIRSEP '\\'
  356. #ifndef MG_PATH_MAX
  357. #define MG_PATH_MAX FILENAME_MAX
  358. #endif
  359. #ifndef SO_EXCLUSIVEADDRUSE
  360. #define SO_EXCLUSIVEADDRUSE ((int) (~SO_REUSEADDR))
  361. #endif
  362. #define MG_SOCK_ERR(errcode) ((errcode) < 0 ? WSAGetLastError() : 0)
  363. #define MG_SOCK_PENDING(errcode) \
  364. (((errcode) < 0) && \
  365. (WSAGetLastError() == WSAEINTR || WSAGetLastError() == WSAEINPROGRESS || \
  366. WSAGetLastError() == WSAEWOULDBLOCK))
  367. #define MG_SOCK_RESET(errcode) \
  368. (((errcode) < 0) && (WSAGetLastError() == WSAECONNRESET))
  369. #define realpath(a, b) _fullpath((b), (a), MG_PATH_MAX)
  370. #define sleep(x) Sleep(x)
  371. #define mkdir(a, b) _mkdir(a)
  372. #ifndef S_ISDIR
  373. #define S_ISDIR(x) (((x) &_S_IFMT) == _S_IFDIR)
  374. #endif
  375. #ifndef MG_ENABLE_DIRLIST
  376. #define MG_ENABLE_DIRLIST 1
  377. #endif
  378. #endif
  379. #if MG_ARCH == MG_ARCH_ZEPHYR
  380. #include <zephyr/kernel.h>
  381. #include <ctype.h>
  382. #include <errno.h>
  383. #include <fcntl.h>
  384. #include <zephyr/net/socket.h>
  385. #include <stdarg.h>
  386. #include <stdbool.h>
  387. #include <stdint.h>
  388. #include <stdio.h>
  389. #include <stdlib.h>
  390. #include <string.h>
  391. #include <sys/types.h>
  392. #include <time.h>
  393. #define MG_PUTCHAR(x) printk("%c", x)
  394. #ifndef strdup
  395. #define strdup(s) ((char *) mg_strdup(mg_str(s)).ptr)
  396. #endif
  397. #define strerror(x) zsock_gai_strerror(x)
  398. #define FD_CLOEXEC 0
  399. #define F_SETFD 0
  400. #define MG_ENABLE_SSI 0
  401. int rand(void);
  402. int sscanf(const char *, const char *, ...);
  403. #endif
  404. #if defined(MG_ENABLE_FREERTOS_TCP) && MG_ENABLE_FREERTOS_TCP
  405. #include <limits.h>
  406. #include <list.h>
  407. #include <FreeRTOS_IP.h>
  408. #include <FreeRTOS_Sockets.h>
  409. #include <FreeRTOS_errno_TCP.h> // contents to be moved and file removed, some day
  410. #define MG_SOCKET_TYPE Socket_t
  411. #define MG_INVALID_SOCKET FREERTOS_INVALID_SOCKET
  412. // Why FreeRTOS-TCP did not implement a clean BSD API, but its own thing
  413. // with FreeRTOS_ prefix, is beyond me
  414. #define IPPROTO_TCP FREERTOS_IPPROTO_TCP
  415. #define IPPROTO_UDP FREERTOS_IPPROTO_UDP
  416. #define AF_INET FREERTOS_AF_INET
  417. #define SOCK_STREAM FREERTOS_SOCK_STREAM
  418. #define SOCK_DGRAM FREERTOS_SOCK_DGRAM
  419. #define SO_BROADCAST 0
  420. #define SO_ERROR 0
  421. #define SOL_SOCKET 0
  422. #define SO_REUSEADDR 0
  423. #define MG_SOCK_ERR(errcode) ((errcode) < 0 ? (errcode) : 0)
  424. #define MG_SOCK_PENDING(errcode) \
  425. ((errcode) == -pdFREERTOS_ERRNO_EWOULDBLOCK || \
  426. (errcode) == -pdFREERTOS_ERRNO_EISCONN || \
  427. (errcode) == -pdFREERTOS_ERRNO_EINPROGRESS || \
  428. (errcode) == -pdFREERTOS_ERRNO_EAGAIN)
  429. #define MG_SOCK_RESET(errcode) ((errcode) == -pdFREERTOS_ERRNO_ENOTCONN)
  430. // actually only if optional timeout is enabled
  431. #define MG_SOCK_INTR(fd) (fd == NULL)
  432. #define sockaddr_in freertos_sockaddr
  433. #define sockaddr freertos_sockaddr
  434. #define accept(a, b, c) FreeRTOS_accept((a), (b), (c))
  435. #define connect(a, b, c) FreeRTOS_connect((a), (b), (c))
  436. #define bind(a, b, c) FreeRTOS_bind((a), (b), (c))
  437. #define listen(a, b) FreeRTOS_listen((a), (b))
  438. #define socket(a, b, c) FreeRTOS_socket((a), (b), (c))
  439. #define send(a, b, c, d) FreeRTOS_send((a), (b), (c), (d))
  440. #define recv(a, b, c, d) FreeRTOS_recv((a), (b), (c), (d))
  441. #define setsockopt(a, b, c, d, e) FreeRTOS_setsockopt((a), (b), (c), (d), (e))
  442. #define sendto(a, b, c, d, e, f) FreeRTOS_sendto((a), (b), (c), (d), (e), (f))
  443. #define recvfrom(a, b, c, d, e, f) \
  444. FreeRTOS_recvfrom((a), (b), (c), (d), (e), (f))
  445. #define closesocket(x) FreeRTOS_closesocket(x)
  446. #define gethostbyname(x) FreeRTOS_gethostbyname(x)
  447. #define getsockname(a, b, c) mg_getsockname((a), (b), (c))
  448. #define getpeername(a, b, c) mg_getpeername((a), (b), (c))
  449. static inline int mg_getsockname(MG_SOCKET_TYPE fd, void *buf, socklen_t *len) {
  450. (void) fd, (void) buf, (void) len;
  451. return -1;
  452. }
  453. static inline int mg_getpeername(MG_SOCKET_TYPE fd, void *buf, socklen_t *len) {
  454. (void) fd, (void) buf, (void) len;
  455. return 0;
  456. }
  457. #endif
  458. #if defined(MG_ENABLE_LWIP) && MG_ENABLE_LWIP
  459. #if defined(__GNUC__) && !defined(__ARMCC_VERSION)
  460. #include <sys/stat.h>
  461. #endif
  462. struct timeval;
  463. #include <lwip/sockets.h>
  464. #if !LWIP_TIMEVAL_PRIVATE
  465. #if defined(__GNUC__) && !defined(__ARMCC_VERSION) // armclang sets both
  466. #include <sys/time.h>
  467. #else
  468. struct timeval {
  469. time_t tv_sec;
  470. long tv_usec;
  471. };
  472. #endif
  473. #endif
  474. #if LWIP_SOCKET != 1
  475. // Sockets support disabled in LWIP by default
  476. #error Set LWIP_SOCKET variable to 1 (in lwipopts.h)
  477. #endif
  478. #endif
  479. #if defined(MG_ENABLE_RL) && MG_ENABLE_RL
  480. #include <rl_net.h>
  481. #define closesocket(x) closesocket(x)
  482. #define TCP_NODELAY SO_KEEPALIVE
  483. #define MG_SOCK_ERR(errcode) ((errcode) < 0 ? (errcode) : 0)
  484. #define MG_SOCK_PENDING(errcode) \
  485. ((errcode) == BSD_EWOULDBLOCK || (errcode) == BSD_EALREADY || \
  486. (errcode) == BSD_EINPROGRESS)
  487. #define MG_SOCK_RESET(errcode) \
  488. ((errcode) == BSD_ECONNABORTED || (errcode) == BSD_ECONNRESET)
  489. #define MG_SOCK_INTR(fd) 0
  490. #define socklen_t int
  491. #endif
  492. #ifndef MG_ENABLE_LOG
  493. #define MG_ENABLE_LOG 1
  494. #endif
  495. #ifndef MG_ENABLE_TCPIP
  496. #define MG_ENABLE_TCPIP 0 // Mongoose built-in network stack
  497. #endif
  498. #ifndef MG_ENABLE_LWIP
  499. #define MG_ENABLE_LWIP 0 // lWIP network stack
  500. #endif
  501. #ifndef MG_ENABLE_FREERTOS_TCP
  502. #define MG_ENABLE_FREERTOS_TCP 0 // Amazon FreeRTOS-TCP network stack
  503. #endif
  504. #ifndef MG_ENABLE_RL
  505. #define MG_ENABLE_RL 0 // ARM MDK network stack
  506. #endif
  507. #ifndef MG_ENABLE_SOCKET
  508. #define MG_ENABLE_SOCKET !MG_ENABLE_TCPIP
  509. #endif
  510. #ifndef MG_ENABLE_POLL
  511. #define MG_ENABLE_POLL 0
  512. #endif
  513. #ifndef MG_ENABLE_EPOLL
  514. #define MG_ENABLE_EPOLL 0
  515. #endif
  516. #ifndef MG_ENABLE_FATFS
  517. #define MG_ENABLE_FATFS 0
  518. #endif
  519. #ifndef MG_ENABLE_MBEDTLS
  520. #define MG_ENABLE_MBEDTLS 0
  521. #endif
  522. #ifndef MG_ENABLE_OPENSSL
  523. #define MG_ENABLE_OPENSSL 0
  524. #endif
  525. #ifndef MG_ENABLE_CUSTOM_TLS
  526. #define MG_ENABLE_CUSTOM_TLS 0
  527. #endif
  528. #ifndef MG_ENABLE_SSI
  529. #define MG_ENABLE_SSI 0
  530. #endif
  531. #ifndef MG_ENABLE_IPV6
  532. #define MG_ENABLE_IPV6 0
  533. #endif
  534. #ifndef MG_ENABLE_MD5
  535. #define MG_ENABLE_MD5 1
  536. #endif
  537. // Set MG_ENABLE_WINSOCK=0 for Win32 builds with external IP stack (like LWIP)
  538. #ifndef MG_ENABLE_WINSOCK
  539. #define MG_ENABLE_WINSOCK 1
  540. #endif
  541. #ifndef MG_ENABLE_DIRLIST
  542. #define MG_ENABLE_DIRLIST 0
  543. #endif
  544. #ifndef MG_ENABLE_CUSTOM_RANDOM
  545. #define MG_ENABLE_CUSTOM_RANDOM 0
  546. #endif
  547. #ifndef MG_ENABLE_CUSTOM_MILLIS
  548. #define MG_ENABLE_CUSTOM_MILLIS 0
  549. #endif
  550. #ifndef MG_ENABLE_PACKED_FS
  551. #define MG_ENABLE_PACKED_FS 0
  552. #endif
  553. #ifndef MG_ENABLE_ASSERT
  554. #define MG_ENABLE_ASSERT 0
  555. #endif
  556. #ifndef MG_IO_SIZE
  557. #define MG_IO_SIZE 2048 // Granularity of the send/recv IO buffer growth
  558. #endif
  559. #ifndef MG_MAX_RECV_SIZE
  560. #define MG_MAX_RECV_SIZE (3 * 1024 * 1024) // Maximum recv IO buffer size
  561. #endif
  562. #ifndef MG_DATA_SIZE
  563. #define MG_DATA_SIZE 32 // struct mg_connection :: data size
  564. #endif
  565. #ifndef MG_MAX_HTTP_HEADERS
  566. #define MG_MAX_HTTP_HEADERS 30
  567. #endif
  568. #ifndef MG_HTTP_INDEX
  569. #define MG_HTTP_INDEX "index.html"
  570. #endif
  571. #ifndef MG_PATH_MAX
  572. #ifdef PATH_MAX
  573. #define MG_PATH_MAX PATH_MAX
  574. #else
  575. #define MG_PATH_MAX 128
  576. #endif
  577. #endif
  578. #ifndef MG_SOCK_LISTEN_BACKLOG_SIZE
  579. #define MG_SOCK_LISTEN_BACKLOG_SIZE 3
  580. #endif
  581. #ifndef MG_DIRSEP
  582. #define MG_DIRSEP '/'
  583. #endif
  584. #ifndef MG_ENABLE_FILE
  585. #if defined(FOPEN_MAX)
  586. #define MG_ENABLE_FILE 1
  587. #else
  588. #define MG_ENABLE_FILE 0
  589. #endif
  590. #endif
  591. #ifndef MG_INVALID_SOCKET
  592. #define MG_INVALID_SOCKET (-1)
  593. #endif
  594. #ifndef MG_SOCKET_TYPE
  595. #define MG_SOCKET_TYPE int
  596. #endif
  597. #ifndef MG_SOCKET_ERRNO
  598. #define MG_SOCKET_ERRNO errno
  599. #endif
  600. #if MG_ENABLE_EPOLL
  601. #define MG_EPOLL_ADD(c) \
  602. do { \
  603. struct epoll_event ev = {EPOLLIN | EPOLLERR | EPOLLHUP, {c}}; \
  604. epoll_ctl(c->mgr->epoll_fd, EPOLL_CTL_ADD, (int) (size_t) c->fd, &ev); \
  605. } while (0)
  606. #define MG_EPOLL_MOD(c, wr) \
  607. do { \
  608. struct epoll_event ev = {EPOLLIN | EPOLLERR | EPOLLHUP, {c}}; \
  609. if (wr) ev.events |= EPOLLOUT; \
  610. epoll_ctl(c->mgr->epoll_fd, EPOLL_CTL_MOD, (int) (size_t) c->fd, &ev); \
  611. } while (0)
  612. #else
  613. #define MG_EPOLL_ADD(c)
  614. #define MG_EPOLL_MOD(c, wr)
  615. #endif
  616. struct mg_str {
  617. const char *ptr; // Pointer to string data
  618. size_t len; // String len
  619. };
  620. #define MG_NULL_STR \
  621. { NULL, 0 }
  622. #define MG_C_STR(a) \
  623. { (a), sizeof(a) - 1 }
  624. // Using macro to avoid shadowing C++ struct constructor, see #1298
  625. #define mg_str(s) mg_str_s(s)
  626. struct mg_str mg_str(const char *s);
  627. struct mg_str mg_str_n(const char *s, size_t n);
  628. int mg_lower(const char *s);
  629. int mg_ncasecmp(const char *s1, const char *s2, size_t len);
  630. int mg_casecmp(const char *s1, const char *s2);
  631. int mg_vcmp(const struct mg_str *s1, const char *s2);
  632. int mg_vcasecmp(const struct mg_str *str1, const char *str2);
  633. int mg_strcmp(const struct mg_str str1, const struct mg_str str2);
  634. struct mg_str mg_strstrip(struct mg_str s);
  635. struct mg_str mg_strdup(const struct mg_str s);
  636. const char *mg_strstr(const struct mg_str haystack, const struct mg_str needle);
  637. bool mg_match(struct mg_str str, struct mg_str pattern, struct mg_str *caps);
  638. bool mg_globmatch(const char *pattern, size_t plen, const char *s, size_t n);
  639. bool mg_commalist(struct mg_str *s, struct mg_str *k, struct mg_str *v);
  640. bool mg_split(struct mg_str *s, struct mg_str *k, struct mg_str *v, char delim);
  641. char *mg_hex(const void *buf, size_t len, char *dst);
  642. void mg_unhex(const char *buf, size_t len, unsigned char *to);
  643. unsigned long mg_unhexn(const char *s, size_t len);
  644. int mg_check_ip_acl(struct mg_str acl, uint32_t remote_ip);
  645. int64_t mg_to64(struct mg_str str);
  646. uint64_t mg_tou64(struct mg_str str);
  647. char *mg_remove_double_dots(char *s);
  648. // Single producer, single consumer non-blocking queue
  649. //
  650. // Producer:
  651. // char *buf;
  652. // while (mg_queue_book(q, &buf) < len) WAIT(); // Wait for space
  653. // memcpy(buf, my_data, len); // Copy data to the queue
  654. // mg_queue_add(q, len);
  655. //
  656. // Consumer:
  657. // char *buf;
  658. // while ((len = mg_queue_get(q, &buf)) == 0) WAIT();
  659. // mg_hexdump(buf, len); // Handle message
  660. // mg_queue_del(q, len);
  661. //
  662. struct mg_queue {
  663. char *buf;
  664. size_t size;
  665. volatile size_t tail;
  666. volatile size_t head;
  667. };
  668. void mg_queue_init(struct mg_queue *, char *, size_t); // Init queue
  669. size_t mg_queue_book(struct mg_queue *, char **buf, size_t); // Reserve space
  670. void mg_queue_add(struct mg_queue *, size_t); // Add new message
  671. size_t mg_queue_next(struct mg_queue *, char **); // Get oldest message
  672. void mg_queue_del(struct mg_queue *, size_t); // Delete oldest message
  673. typedef void (*mg_pfn_t)(char, void *); // Output function
  674. typedef size_t (*mg_pm_t)(mg_pfn_t, void *, va_list *); // %M printer
  675. size_t mg_vxprintf(void (*)(char, void *), void *, const char *fmt, va_list *);
  676. size_t mg_xprintf(void (*fn)(char, void *), void *, const char *fmt, ...);
  677. // Convenience wrappers around mg_xprintf
  678. size_t mg_vsnprintf(char *buf, size_t len, const char *fmt, va_list *ap);
  679. size_t mg_snprintf(char *, size_t, const char *fmt, ...);
  680. char *mg_vmprintf(const char *fmt, va_list *ap);
  681. char *mg_mprintf(const char *fmt, ...);
  682. size_t mg_queue_vprintf(struct mg_queue *, const char *fmt, va_list *);
  683. size_t mg_queue_printf(struct mg_queue *, const char *fmt, ...);
  684. // %M print helper functions
  685. size_t mg_print_base64(void (*out)(char, void *), void *arg, va_list *ap);
  686. size_t mg_print_esc(void (*out)(char, void *), void *arg, va_list *ap);
  687. size_t mg_print_hex(void (*out)(char, void *), void *arg, va_list *ap);
  688. size_t mg_print_ip(void (*out)(char, void *), void *arg, va_list *ap);
  689. size_t mg_print_ip_port(void (*out)(char, void *), void *arg, va_list *ap);
  690. size_t mg_print_ip4(void (*out)(char, void *), void *arg, va_list *ap);
  691. size_t mg_print_ip6(void (*out)(char, void *), void *arg, va_list *ap);
  692. size_t mg_print_mac(void (*out)(char, void *), void *arg, va_list *ap);
  693. // Various output functions
  694. void mg_pfn_iobuf(char ch, void *param); // param: struct mg_iobuf *
  695. void mg_pfn_stdout(char c, void *param); // param: ignored
  696. enum { MG_LL_NONE, MG_LL_ERROR, MG_LL_INFO, MG_LL_DEBUG, MG_LL_VERBOSE };
  697. void mg_log(const char *fmt, ...);
  698. bool mg_log_prefix(int ll, const char *file, int line, const char *fname);
  699. void mg_log_set(int log_level);
  700. void mg_hexdump(const void *buf, size_t len);
  701. void mg_log_set_fn(mg_pfn_t fn, void *param);
  702. #if MG_ENABLE_LOG
  703. #define MG_LOG(level, args) \
  704. do { \
  705. if (mg_log_prefix((level), __FILE__, __LINE__, __func__)) mg_log args; \
  706. } while (0)
  707. #else
  708. #define MG_LOG(level, args) \
  709. do { \
  710. if (0) mg_log args; \
  711. } while (0)
  712. #endif
  713. #define MG_ERROR(args) MG_LOG(MG_LL_ERROR, args)
  714. #define MG_INFO(args) MG_LOG(MG_LL_INFO, args)
  715. #define MG_DEBUG(args) MG_LOG(MG_LL_DEBUG, args)
  716. #define MG_VERBOSE(args) MG_LOG(MG_LL_VERBOSE, args)
  717. struct mg_timer {
  718. unsigned long id; // Timer ID
  719. uint64_t period_ms; // Timer period in milliseconds
  720. uint64_t expire; // Expiration timestamp in milliseconds
  721. unsigned flags; // Possible flags values below
  722. #define MG_TIMER_ONCE 0 // Call function once
  723. #define MG_TIMER_REPEAT 1 // Call function periodically
  724. #define MG_TIMER_RUN_NOW 2 // Call immediately when timer is set
  725. void (*fn)(void *); // Function to call
  726. void *arg; // Function argument
  727. struct mg_timer *next; // Linkage
  728. };
  729. void mg_timer_init(struct mg_timer **head, struct mg_timer *timer,
  730. uint64_t milliseconds, unsigned flags, void (*fn)(void *),
  731. void *arg);
  732. void mg_timer_free(struct mg_timer **head, struct mg_timer *);
  733. void mg_timer_poll(struct mg_timer **head, uint64_t new_ms);
  734. bool mg_timer_expired(uint64_t *expiration, uint64_t period, uint64_t now);
  735. enum { MG_FS_READ = 1, MG_FS_WRITE = 2, MG_FS_DIR = 4 };
  736. // Filesystem API functions
  737. // st() returns MG_FS_* flags and populates file size and modification time
  738. // ls() calls fn() for every directory entry, allowing to list a directory
  739. //
  740. // NOTE: UNIX-style shorthand names for the API functions are deliberately
  741. // chosen to avoid conflicts with some libraries that make macros for e.g.
  742. // stat(), write(), read() calls.
  743. struct mg_fs {
  744. int (*st)(const char *path, size_t *size, time_t *mtime); // stat file
  745. void (*ls)(const char *path, void (*fn)(const char *, void *), void *);
  746. void *(*op)(const char *path, int flags); // Open file
  747. void (*cl)(void *fd); // Close file
  748. size_t (*rd)(void *fd, void *buf, size_t len); // Read file
  749. size_t (*wr)(void *fd, const void *buf, size_t len); // Write file
  750. size_t (*sk)(void *fd, size_t offset); // Set file position
  751. bool (*mv)(const char *from, const char *to); // Rename file
  752. bool (*rm)(const char *path); // Delete file
  753. bool (*mkd)(const char *path); // Create directory
  754. };
  755. extern struct mg_fs mg_fs_posix; // POSIX open/close/read/write/seek
  756. extern struct mg_fs mg_fs_packed; // Packed FS, see examples/device-dashboard
  757. extern struct mg_fs mg_fs_fat; // FAT FS
  758. // File descriptor
  759. struct mg_fd {
  760. void *fd;
  761. struct mg_fs *fs;
  762. };
  763. struct mg_fd *mg_fs_open(struct mg_fs *fs, const char *path, int flags);
  764. void mg_fs_close(struct mg_fd *fd);
  765. char *mg_file_read(struct mg_fs *fs, const char *path, size_t *size);
  766. bool mg_file_write(struct mg_fs *fs, const char *path, const void *, size_t);
  767. bool mg_file_printf(struct mg_fs *fs, const char *path, const char *fmt, ...);
  768. #if MG_ENABLE_ASSERT
  769. #include <assert.h>
  770. #elif !defined(assert)
  771. #define assert(x)
  772. #endif
  773. void mg_random(void *buf, size_t len);
  774. char *mg_random_str(char *buf, size_t len);
  775. uint16_t mg_ntohs(uint16_t net);
  776. uint32_t mg_ntohl(uint32_t net);
  777. uint32_t mg_crc32(uint32_t crc, const char *buf, size_t len);
  778. uint64_t mg_millis(void);
  779. #define mg_htons(x) mg_ntohs(x)
  780. #define mg_htonl(x) mg_ntohl(x)
  781. #define MG_U32(a, b, c, d) \
  782. (((uint32_t) ((a) &255) << 24) | ((uint32_t) ((b) &255) << 16) | \
  783. ((uint32_t) ((c) &255) << 8) | (uint32_t) ((d) &255))
  784. // For printing IPv4 addresses: printf("%d.%d.%d.%d\n", MG_IPADDR_PARTS(&ip))
  785. #define MG_U8P(ADDR) ((uint8_t *) (ADDR))
  786. #define MG_IPADDR_PARTS(ADDR) \
  787. MG_U8P(ADDR)[0], MG_U8P(ADDR)[1], MG_U8P(ADDR)[2], MG_U8P(ADDR)[3]
  788. // Linked list management macros
  789. #define LIST_ADD_HEAD(type_, head_, elem_) \
  790. do { \
  791. (elem_)->next = (*head_); \
  792. *(head_) = (elem_); \
  793. } while (0)
  794. #define LIST_ADD_TAIL(type_, head_, elem_) \
  795. do { \
  796. type_ **h = head_; \
  797. while (*h != NULL) h = &(*h)->next; \
  798. *h = (elem_); \
  799. } while (0)
  800. #define LIST_DELETE(type_, head_, elem_) \
  801. do { \
  802. type_ **h = head_; \
  803. while (*h != (elem_)) h = &(*h)->next; \
  804. *h = (elem_)->next; \
  805. } while (0)
  806. unsigned short mg_url_port(const char *url);
  807. int mg_url_is_ssl(const char *url);
  808. struct mg_str mg_url_host(const char *url);
  809. struct mg_str mg_url_user(const char *url);
  810. struct mg_str mg_url_pass(const char *url);
  811. const char *mg_url_uri(const char *url);
  812. struct mg_iobuf {
  813. unsigned char *buf; // Pointer to stored data
  814. size_t size; // Total size available
  815. size_t len; // Current number of bytes
  816. size_t align; // Alignment during allocation
  817. };
  818. int mg_iobuf_init(struct mg_iobuf *, size_t, size_t);
  819. int mg_iobuf_resize(struct mg_iobuf *, size_t);
  820. void mg_iobuf_free(struct mg_iobuf *);
  821. size_t mg_iobuf_add(struct mg_iobuf *, size_t, const void *, size_t);
  822. size_t mg_iobuf_del(struct mg_iobuf *, size_t ofs, size_t len);
  823. int mg_base64_update(unsigned char p, char *to, int len);
  824. int mg_base64_final(char *to, int len);
  825. int mg_base64_encode(const unsigned char *p, int n, char *to);
  826. int mg_base64_decode(const char *src, int n, char *dst);
  827. typedef struct {
  828. uint32_t buf[4];
  829. uint32_t bits[2];
  830. unsigned char in[64];
  831. } mg_md5_ctx;
  832. void mg_md5_init(mg_md5_ctx *c);
  833. void mg_md5_update(mg_md5_ctx *c, const unsigned char *data, size_t len);
  834. void mg_md5_final(mg_md5_ctx *c, unsigned char[16]);
  835. typedef struct {
  836. uint32_t state[5];
  837. uint32_t count[2];
  838. unsigned char buffer[64];
  839. } mg_sha1_ctx;
  840. void mg_sha1_init(mg_sha1_ctx *);
  841. void mg_sha1_update(mg_sha1_ctx *, const unsigned char *data, size_t len);
  842. void mg_sha1_final(unsigned char digest[20], mg_sha1_ctx *);
  843. struct mg_connection;
  844. typedef void (*mg_event_handler_t)(struct mg_connection *, int ev,
  845. void *ev_data, void *fn_data);
  846. void mg_call(struct mg_connection *c, int ev, void *ev_data);
  847. void mg_error(struct mg_connection *c, const char *fmt, ...);
  848. enum {
  849. MG_EV_ERROR, // Error char *error_message
  850. MG_EV_OPEN, // Connection created NULL
  851. MG_EV_POLL, // mg_mgr_poll iteration uint64_t *uptime_millis
  852. MG_EV_RESOLVE, // Host name is resolved NULL
  853. MG_EV_CONNECT, // Connection established NULL
  854. MG_EV_ACCEPT, // Connection accepted NULL
  855. MG_EV_TLS_HS, // TLS handshake succeeded NULL
  856. MG_EV_READ, // Data received from socket long *bytes_read
  857. MG_EV_WRITE, // Data written to socket long *bytes_written
  858. MG_EV_CLOSE, // Connection closed NULL
  859. MG_EV_HTTP_MSG, // HTTP request/response struct mg_http_message *
  860. MG_EV_HTTP_CHUNK, // HTTP chunk (partial msg) struct mg_http_message *
  861. MG_EV_WS_OPEN, // Websocket handshake done struct mg_http_message *
  862. MG_EV_WS_MSG, // Websocket msg, text or bin struct mg_ws_message *
  863. MG_EV_WS_CTL, // Websocket control msg struct mg_ws_message *
  864. MG_EV_MQTT_CMD, // MQTT low-level command struct mg_mqtt_message *
  865. MG_EV_MQTT_MSG, // MQTT PUBLISH received struct mg_mqtt_message *
  866. MG_EV_MQTT_OPEN, // MQTT CONNACK received int *connack_status_code
  867. MG_EV_SNTP_TIME, // SNTP time received uint64_t *epoch_millis
  868. MG_EV_USER // Starting ID for user events
  869. };
  870. struct mg_dns {
  871. const char *url; // DNS server URL
  872. struct mg_connection *c; // DNS server connection
  873. };
  874. struct mg_addr {
  875. uint16_t port; // TCP or UDP port in network byte order
  876. uint32_t ip; // IP address in network byte order
  877. uint8_t ip6[16]; // IPv6 address
  878. bool is_ip6; // True when address is IPv6 address
  879. };
  880. struct mg_mgr {
  881. struct mg_connection *conns; // List of active connections
  882. struct mg_dns dns4; // DNS for IPv4
  883. struct mg_dns dns6; // DNS for IPv6
  884. int dnstimeout; // DNS resolve timeout in milliseconds
  885. bool use_dns6; // Use DNS6 server by default, see #1532
  886. unsigned long nextid; // Next connection ID
  887. unsigned long timerid; // Next timer ID
  888. void *userdata; // Arbitrary user data pointer
  889. uint16_t mqtt_id; // MQTT IDs for pub/sub
  890. void *active_dns_requests; // DNS requests in progress
  891. struct mg_timer *timers; // Active timers
  892. int epoll_fd; // Used when MG_EPOLL_ENABLE=1
  893. void *priv; // Used by the MIP stack
  894. size_t extraconnsize; // Used by the MIP stack
  895. #if MG_ENABLE_FREERTOS_TCP
  896. SocketSet_t ss; // NOTE(lsm): referenced from socket struct
  897. #endif
  898. };
  899. struct mg_connection {
  900. struct mg_connection *next; // Linkage in struct mg_mgr :: connections
  901. struct mg_mgr *mgr; // Our container
  902. struct mg_addr loc; // Local address
  903. struct mg_addr rem; // Remote address
  904. void *fd; // Connected socket, or LWIP data
  905. unsigned long id; // Auto-incrementing unique connection ID
  906. struct mg_iobuf recv; // Incoming data
  907. struct mg_iobuf send; // Outgoing data
  908. mg_event_handler_t fn; // User-specified event handler function
  909. void *fn_data; // User-specified function parameter
  910. mg_event_handler_t pfn; // Protocol-specific handler function
  911. void *pfn_data; // Protocol-specific function parameter
  912. char data[MG_DATA_SIZE]; // Arbitrary connection data
  913. void *tls; // TLS specific data
  914. unsigned is_listening : 1; // Listening connection
  915. unsigned is_client : 1; // Outbound (client) connection
  916. unsigned is_accepted : 1; // Accepted (server) connection
  917. unsigned is_resolving : 1; // Non-blocking DNS resolution is in progress
  918. unsigned is_arplooking : 1; // Non-blocking ARP resolution is in progress
  919. unsigned is_connecting : 1; // Non-blocking connect is in progress
  920. unsigned is_tls : 1; // TLS-enabled connection
  921. unsigned is_tls_hs : 1; // TLS handshake is in progress
  922. unsigned is_udp : 1; // UDP connection
  923. unsigned is_websocket : 1; // WebSocket connection
  924. unsigned is_mqtt5 : 1; // For MQTT connection, v5 indicator
  925. unsigned is_hexdumping : 1; // Hexdump in/out traffic
  926. unsigned is_draining : 1; // Send remaining data, then close and free
  927. unsigned is_closing : 1; // Close and free the connection immediately
  928. unsigned is_full : 1; // Stop reads, until cleared
  929. unsigned is_resp : 1; // Response is still being generated
  930. unsigned is_readable : 1; // Connection is ready to read
  931. unsigned is_writable : 1; // Connection is ready to write
  932. };
  933. void mg_mgr_poll(struct mg_mgr *, int ms);
  934. void mg_mgr_init(struct mg_mgr *);
  935. void mg_mgr_free(struct mg_mgr *);
  936. struct mg_connection *mg_listen(struct mg_mgr *, const char *url,
  937. mg_event_handler_t fn, void *fn_data);
  938. struct mg_connection *mg_connect(struct mg_mgr *, const char *url,
  939. mg_event_handler_t fn, void *fn_data);
  940. struct mg_connection *mg_wrapfd(struct mg_mgr *mgr, int fd,
  941. mg_event_handler_t fn, void *fn_data);
  942. void mg_connect_resolved(struct mg_connection *);
  943. bool mg_send(struct mg_connection *, const void *, size_t);
  944. size_t mg_printf(struct mg_connection *, const char *fmt, ...);
  945. size_t mg_vprintf(struct mg_connection *, const char *fmt, va_list *ap);
  946. bool mg_aton(struct mg_str str, struct mg_addr *addr);
  947. int mg_mkpipe(struct mg_mgr *, mg_event_handler_t, void *, bool udp);
  948. // These functions are used to integrate with custom network stacks
  949. struct mg_connection *mg_alloc_conn(struct mg_mgr *);
  950. void mg_close_conn(struct mg_connection *c);
  951. bool mg_open_listener(struct mg_connection *c, const char *url);
  952. // Utility functions
  953. struct mg_timer *mg_timer_add(struct mg_mgr *mgr, uint64_t milliseconds,
  954. unsigned flags, void (*fn)(void *), void *arg);
  955. // Low-level IO primives used by TLS layer
  956. enum { MG_IO_ERR = -1, MG_IO_WAIT = -2, MG_IO_RESET = -3 };
  957. long mg_io_send(struct mg_connection *c, const void *buf, size_t len);
  958. long mg_io_recv(struct mg_connection *c, void *buf, size_t len);
  959. struct mg_http_header {
  960. struct mg_str name; // Header name
  961. struct mg_str value; // Header value
  962. };
  963. struct mg_http_message {
  964. struct mg_str method, uri, query, proto; // Request/response line
  965. struct mg_http_header headers[MG_MAX_HTTP_HEADERS]; // Headers
  966. struct mg_str body; // Body
  967. struct mg_str head; // Request + headers
  968. struct mg_str chunk; // Chunk for chunked encoding, or partial body
  969. struct mg_str message; // Request + headers + body
  970. };
  971. // Parameter for mg_http_serve_dir()
  972. struct mg_http_serve_opts {
  973. const char *root_dir; // Web root directory, must be non-NULL
  974. const char *ssi_pattern; // SSI file name pattern, e.g. #.shtml
  975. const char *extra_headers; // Extra HTTP headers to add in responses
  976. const char *mime_types; // Extra mime types, ext1=type1,ext2=type2,..
  977. const char *page404; // Path to the 404 page, or NULL by default
  978. struct mg_fs *fs; // Filesystem implementation. Use NULL for POSIX
  979. };
  980. // Parameter for mg_http_next_multipart
  981. struct mg_http_part {
  982. struct mg_str name; // Form field name
  983. struct mg_str filename; // Filename for file uploads
  984. struct mg_str body; // Part contents
  985. };
  986. int mg_http_parse(const char *s, size_t len, struct mg_http_message *);
  987. int mg_http_get_request_len(const unsigned char *buf, size_t buf_len);
  988. void mg_http_printf_chunk(struct mg_connection *cnn, const char *fmt, ...);
  989. void mg_http_write_chunk(struct mg_connection *c, const char *buf, size_t len);
  990. void mg_http_delete_chunk(struct mg_connection *c, struct mg_http_message *hm);
  991. struct mg_connection *mg_http_listen(struct mg_mgr *, const char *url,
  992. mg_event_handler_t fn, void *fn_data);
  993. struct mg_connection *mg_http_connect(struct mg_mgr *, const char *url,
  994. mg_event_handler_t fn, void *fn_data);
  995. void mg_http_serve_dir(struct mg_connection *, struct mg_http_message *hm,
  996. const struct mg_http_serve_opts *);
  997. void mg_http_serve_file(struct mg_connection *, struct mg_http_message *hm,
  998. const char *path, const struct mg_http_serve_opts *);
  999. void mg_http_reply(struct mg_connection *, int status_code, const char *headers,
  1000. const char *body_fmt, ...);
  1001. struct mg_str *mg_http_get_header(struct mg_http_message *, const char *name);
  1002. struct mg_str mg_http_var(struct mg_str buf, struct mg_str name);
  1003. int mg_http_get_var(const struct mg_str *, const char *name, char *, size_t);
  1004. int mg_url_decode(const char *s, size_t n, char *to, size_t to_len, int form);
  1005. size_t mg_url_encode(const char *s, size_t n, char *buf, size_t len);
  1006. void mg_http_creds(struct mg_http_message *, char *, size_t, char *, size_t);
  1007. bool mg_http_match_uri(const struct mg_http_message *, const char *glob);
  1008. long mg_http_upload(struct mg_connection *c, struct mg_http_message *hm,
  1009. struct mg_fs *fs, const char *path, size_t max_size);
  1010. void mg_http_bauth(struct mg_connection *, const char *user, const char *pass);
  1011. struct mg_str mg_http_get_header_var(struct mg_str s, struct mg_str v);
  1012. size_t mg_http_next_multipart(struct mg_str, size_t, struct mg_http_part *);
  1013. int mg_http_status(const struct mg_http_message *hm);
  1014. void mg_hello(const char *url);
  1015. void mg_http_serve_ssi(struct mg_connection *c, const char *root,
  1016. const char *fullpath);
  1017. struct mg_tls_opts {
  1018. const char *ca; // CA certificate file. For both listeners and clients
  1019. const char *crl; // Certificate Revocation List. For clients
  1020. const char *cert; // Certificate
  1021. const char *certkey; // Certificate key
  1022. const char *ciphers; // Cipher list
  1023. struct mg_str srvname; // If not empty, enables server name verification
  1024. struct mg_fs *fs; // FS API for reading certificate files
  1025. };
  1026. void mg_tls_init(struct mg_connection *, const struct mg_tls_opts *);
  1027. void mg_tls_free(struct mg_connection *);
  1028. long mg_tls_send(struct mg_connection *, const void *buf, size_t len);
  1029. long mg_tls_recv(struct mg_connection *, void *buf, size_t len);
  1030. size_t mg_tls_pending(struct mg_connection *);
  1031. void mg_tls_handshake(struct mg_connection *);
  1032. #if MG_ENABLE_MBEDTLS
  1033. #include <mbedtls/debug.h>
  1034. #include <mbedtls/net_sockets.h>
  1035. #include <mbedtls/ssl.h>
  1036. struct mg_tls {
  1037. char *cafile; // CA certificate path
  1038. mbedtls_x509_crt ca; // Parsed CA certificate
  1039. mbedtls_x509_crt cert; // Parsed certificate
  1040. mbedtls_ssl_context ssl; // SSL/TLS context
  1041. mbedtls_ssl_config conf; // SSL-TLS config
  1042. mbedtls_pk_context pk; // Private key context
  1043. };
  1044. #endif
  1045. #if MG_ENABLE_OPENSSL
  1046. #include <openssl/err.h>
  1047. #include <openssl/ssl.h>
  1048. struct mg_tls {
  1049. SSL_CTX *ctx;
  1050. SSL *ssl;
  1051. };
  1052. #endif
  1053. #define WEBSOCKET_OP_CONTINUE 0
  1054. #define WEBSOCKET_OP_TEXT 1
  1055. #define WEBSOCKET_OP_BINARY 2
  1056. #define WEBSOCKET_OP_CLOSE 8
  1057. #define WEBSOCKET_OP_PING 9
  1058. #define WEBSOCKET_OP_PONG 10
  1059. struct mg_ws_message {
  1060. struct mg_str data; // Websocket message data
  1061. uint8_t flags; // Websocket message flags
  1062. };
  1063. struct mg_connection *mg_ws_connect(struct mg_mgr *, const char *url,
  1064. mg_event_handler_t fn, void *fn_data,
  1065. const char *fmt, ...);
  1066. void mg_ws_upgrade(struct mg_connection *, struct mg_http_message *,
  1067. const char *fmt, ...);
  1068. size_t mg_ws_send(struct mg_connection *, const void *buf, size_t len, int op);
  1069. size_t mg_ws_wrap(struct mg_connection *, size_t len, int op);
  1070. size_t mg_ws_printf(struct mg_connection *c, int op, const char *fmt, ...);
  1071. size_t mg_ws_vprintf(struct mg_connection *c, int op, const char *fmt,
  1072. va_list *);
  1073. struct mg_connection *mg_sntp_connect(struct mg_mgr *mgr, const char *url,
  1074. mg_event_handler_t fn, void *fn_data);
  1075. void mg_sntp_request(struct mg_connection *c);
  1076. int64_t mg_sntp_parse(const unsigned char *buf, size_t len);
  1077. #define MQTT_CMD_CONNECT 1
  1078. #define MQTT_CMD_CONNACK 2
  1079. #define MQTT_CMD_PUBLISH 3
  1080. #define MQTT_CMD_PUBACK 4
  1081. #define MQTT_CMD_PUBREC 5
  1082. #define MQTT_CMD_PUBREL 6
  1083. #define MQTT_CMD_PUBCOMP 7
  1084. #define MQTT_CMD_SUBSCRIBE 8
  1085. #define MQTT_CMD_SUBACK 9
  1086. #define MQTT_CMD_UNSUBSCRIBE 10
  1087. #define MQTT_CMD_UNSUBACK 11
  1088. #define MQTT_CMD_PINGREQ 12
  1089. #define MQTT_CMD_PINGRESP 13
  1090. #define MQTT_CMD_DISCONNECT 14
  1091. #define MQTT_CMD_AUTH 15
  1092. enum { MQTT_OK, MQTT_INCOMPLETE, MQTT_MALFORMED };
  1093. struct mg_mqtt_opts {
  1094. struct mg_str user; // Username, can be empty
  1095. struct mg_str pass; // Password, can be empty
  1096. struct mg_str client_id; // Client ID
  1097. struct mg_str will_topic; // Will topic
  1098. struct mg_str will_message; // Will message
  1099. uint8_t will_qos; // Will message quality of service
  1100. uint8_t version; // Can be 4 (3.1.1), or 5. If 0, assume 4.
  1101. uint16_t keepalive; // Keep-alive timer in seconds
  1102. bool will_retain; // Retain last will
  1103. bool clean; // Use clean session, 0 or 1
  1104. };
  1105. struct mg_mqtt_message {
  1106. struct mg_str topic; // Parsed topic
  1107. struct mg_str data; // Parsed message
  1108. struct mg_str dgram; // Whole MQTT datagram, including headers
  1109. uint16_t id; // Set for PUBACK, PUBREC, PUBREL, PUBCOMP, SUBACK, PUBLISH
  1110. uint8_t cmd; // MQTT command, one of MQTT_CMD_*
  1111. uint8_t qos; // Quality of service
  1112. uint8_t ack; // Connack return code. 0 - success
  1113. };
  1114. struct mg_connection *mg_mqtt_connect(struct mg_mgr *, const char *url,
  1115. const struct mg_mqtt_opts *opts,
  1116. mg_event_handler_t fn, void *fn_data);
  1117. struct mg_connection *mg_mqtt_listen(struct mg_mgr *mgr, const char *url,
  1118. mg_event_handler_t fn, void *fn_data);
  1119. void mg_mqtt_login(struct mg_connection *c, const struct mg_mqtt_opts *opts);
  1120. void mg_mqtt_pub(struct mg_connection *c, struct mg_str topic,
  1121. struct mg_str data, int qos, bool retain);
  1122. void mg_mqtt_sub(struct mg_connection *, struct mg_str topic, int qos);
  1123. int mg_mqtt_parse(const uint8_t *, size_t, uint8_t, struct mg_mqtt_message *);
  1124. void mg_mqtt_send_header(struct mg_connection *, uint8_t cmd, uint8_t flags,
  1125. uint32_t len);
  1126. void mg_mqtt_ping(struct mg_connection *);
  1127. void mg_mqtt_pong(struct mg_connection *);
  1128. void mg_mqtt_disconnect(struct mg_connection *);
  1129. // Mongoose sends DNS queries that contain only one question:
  1130. // either A (IPv4) or AAAA (IPv6) address lookup.
  1131. // Therefore, we expect zero or one answer.
  1132. // If `resolved` is true, then `addr` contains resolved IPv4 or IPV6 address.
  1133. struct mg_dns_message {
  1134. uint16_t txnid; // Transaction ID
  1135. bool resolved; // Resolve successful, addr is set
  1136. struct mg_addr addr; // Resolved address
  1137. char name[256]; // Host name
  1138. };
  1139. struct mg_dns_header {
  1140. uint16_t txnid; // Transaction ID
  1141. uint16_t flags;
  1142. uint16_t num_questions;
  1143. uint16_t num_answers;
  1144. uint16_t num_authority_prs;
  1145. uint16_t num_other_prs;
  1146. };
  1147. // DNS resource record
  1148. struct mg_dns_rr {
  1149. uint16_t nlen; // Name or pointer length
  1150. uint16_t atype; // Address type
  1151. uint16_t aclass; // Address class
  1152. uint16_t alen; // Address length
  1153. };
  1154. void mg_resolve(struct mg_connection *, const char *url);
  1155. void mg_resolve_cancel(struct mg_connection *);
  1156. bool mg_dns_parse(const uint8_t *buf, size_t len, struct mg_dns_message *);
  1157. size_t mg_dns_parse_rr(const uint8_t *buf, size_t len, size_t ofs,
  1158. bool is_question, struct mg_dns_rr *);
  1159. #ifndef MG_JSON_MAX_DEPTH
  1160. #define MG_JSON_MAX_DEPTH 30
  1161. #endif
  1162. // Error return values - negative. Successful returns are >= 0
  1163. enum { MG_JSON_TOO_DEEP = -1, MG_JSON_INVALID = -2, MG_JSON_NOT_FOUND = -3 };
  1164. int mg_json_get(struct mg_str json, const char *path, int *toklen);
  1165. bool mg_json_get_num(struct mg_str json, const char *path, double *v);
  1166. bool mg_json_get_bool(struct mg_str json, const char *path, bool *v);
  1167. long mg_json_get_long(struct mg_str json, const char *path, long dflt);
  1168. char *mg_json_get_str(struct mg_str json, const char *path);
  1169. char *mg_json_get_hex(struct mg_str json, const char *path, int *len);
  1170. char *mg_json_get_b64(struct mg_str json, const char *path, int *len);
  1171. // JSON-RPC request descriptor
  1172. struct mg_rpc_req {
  1173. struct mg_rpc **head; // RPC handlers list head
  1174. struct mg_rpc *rpc; // RPC handler being called
  1175. mg_pfn_t pfn; // Response printing function
  1176. void *pfn_data; // Response printing function data
  1177. void *req_data; // Arbitrary request data
  1178. struct mg_str frame; // Request, e.g. {"id":1,"method":"add","params":[1,2]}
  1179. };
  1180. // JSON-RPC method handler
  1181. struct mg_rpc {
  1182. struct mg_rpc *next; // Next in list
  1183. struct mg_str method; // Method pattern
  1184. void (*fn)(struct mg_rpc_req *); // Handler function
  1185. void *fn_data; // Handler function argument
  1186. };
  1187. void mg_rpc_add(struct mg_rpc **head, struct mg_str method_pattern,
  1188. void (*handler)(struct mg_rpc_req *), void *handler_data);
  1189. void mg_rpc_del(struct mg_rpc **head, void (*handler)(struct mg_rpc_req *));
  1190. void mg_rpc_process(struct mg_rpc_req *);
  1191. // Helper functions to print result or error frame
  1192. void mg_rpc_ok(struct mg_rpc_req *, const char *fmt, ...);
  1193. void mg_rpc_vok(struct mg_rpc_req *, const char *fmt, va_list *ap);
  1194. void mg_rpc_err(struct mg_rpc_req *, int code, const char *fmt, ...);
  1195. void mg_rpc_verr(struct mg_rpc_req *, int code, const char *fmt, va_list *);
  1196. void mg_rpc_list(struct mg_rpc_req *r);
  1197. struct mg_tcpip_if; // MIP network interface
  1198. struct mg_tcpip_driver {
  1199. bool (*init)(struct mg_tcpip_if *); // Init driver
  1200. size_t (*tx)(const void *, size_t, struct mg_tcpip_if *); // Transmit frame
  1201. size_t (*rx)(void *buf, size_t len, struct mg_tcpip_if *); // Receive frame
  1202. bool (*up)(struct mg_tcpip_if *); // Up/down status
  1203. };
  1204. // Network interface
  1205. struct mg_tcpip_if {
  1206. uint8_t mac[6]; // MAC address. Must be set to a valid MAC
  1207. uint32_t ip, mask, gw; // IP address, mask, default gateway
  1208. struct mg_str tx; // Output (TX) buffer
  1209. bool enable_dhcp_client; // Enable DCHP client
  1210. bool enable_dhcp_server; // Enable DCHP server
  1211. bool enable_crc32_check; // Do a CRC check on rx frames and strip it
  1212. bool enable_mac_check; // Do a MAC check on rx frames
  1213. struct mg_tcpip_driver *driver; // Low level driver
  1214. void *driver_data; // Driver-specific data
  1215. struct mg_mgr *mgr; // Mongoose event manager
  1216. struct mg_queue recv_queue; // Receive queue
  1217. // Internal state, user can use it but should not change it
  1218. uint8_t gwmac[6]; // Router's MAC
  1219. uint64_t now; // Current time
  1220. uint64_t timer_1000ms; // 1000 ms timer: for DHCP and link state
  1221. uint64_t lease_expire; // Lease expiration time
  1222. uint16_t eport; // Next ephemeral port
  1223. volatile uint32_t ndrop; // Number of received, but dropped frames
  1224. volatile uint32_t nrecv; // Number of received frames
  1225. volatile uint32_t nsent; // Number of transmitted frames
  1226. volatile uint32_t nerr; // Number of driver errors
  1227. uint8_t state; // Current state
  1228. #define MG_TCPIP_STATE_DOWN 0 // Interface is down
  1229. #define MG_TCPIP_STATE_UP 1 // Interface is up
  1230. #define MG_TCPIP_STATE_READY 2 // Interface is up and has IP
  1231. };
  1232. void mg_tcpip_init(struct mg_mgr *, struct mg_tcpip_if *);
  1233. void mg_tcpip_free(struct mg_tcpip_if *);
  1234. void mg_tcpip_qwrite(void *buf, size_t len, struct mg_tcpip_if *ifp);
  1235. extern struct mg_tcpip_driver mg_tcpip_driver_stm32;
  1236. extern struct mg_tcpip_driver mg_tcpip_driver_w5500;
  1237. extern struct mg_tcpip_driver mg_tcpip_driver_tm4c;
  1238. extern struct mg_tcpip_driver mg_tcpip_driver_stm32h;
  1239. extern struct mg_tcpip_driver mg_tcpip_driver_imxrt;
  1240. // Drivers that require SPI, can use this SPI abstraction
  1241. struct mg_tcpip_spi {
  1242. void *spi; // Opaque SPI bus descriptor
  1243. void (*begin)(void *); // SPI begin: slave select low
  1244. void (*end)(void *); // SPI end: slave select high
  1245. uint8_t (*txn)(void *, uint8_t); // SPI transaction: write 1 byte, read reply
  1246. };
  1247. #if MG_ENABLE_TCPIP
  1248. #if !defined(MG_ENABLE_DRIVER_STM32H) && !defined(MG_ENABLE_DRIVER_TM4C)
  1249. #define MG_ENABLE_DRIVER_STM32 1
  1250. #else
  1251. #define MG_ENABLE_DRIVER_STM32 0
  1252. #endif
  1253. #endif
  1254. struct mg_tcpip_driver_imxrt1020_data {
  1255. // MDC clock divider. MDC clock is derived from IPS Bus clock (ipg_clk),
  1256. // must not exceed 2.5MHz. Configuration for clock range 2.36~2.50 MHz
  1257. // ipg_clk MSCR mdc_cr VALUE
  1258. // -------------------------------------
  1259. // -1 <-- tell driver to guess the value
  1260. // 25 MHz 0x04 0
  1261. // 33 MHz 0x06 1
  1262. // 40 MHz 0x07 2
  1263. // 50 MHz 0x09 3
  1264. // 66 MHz 0x0D 4 <-- value for iMXRT1020-EVK at max freq.
  1265. int mdc_cr; // Valid values: -1, 0, 1, 2, 3, 4
  1266. };
  1267. struct mg_tcpip_driver_stm32_data {
  1268. // MDC clock divider. MDC clock is derived from HCLK, must not exceed 2.5MHz
  1269. // HCLK range DIVIDER mdc_cr VALUE
  1270. // -------------------------------------
  1271. // -1 <-- tell driver to guess the value
  1272. // 60-100 MHz HCLK/42 0
  1273. // 100-150 MHz HCLK/62 1
  1274. // 20-35 MHz HCLK/16 2
  1275. // 35-60 MHz HCLK/26 3
  1276. // 150-216 MHz HCLK/102 4 <-- value for Nucleo-F* on max speed
  1277. // 216-310 MHz HCLK/124 5
  1278. // 110, 111 Reserved
  1279. int mdc_cr; // Valid values: -1, 0, 1, 2, 3, 4, 5
  1280. };
  1281. struct mg_tcpip_driver_stm32h_data {
  1282. // MDC clock divider. MDC clock is derived from HCLK, must not exceed 2.5MHz
  1283. // HCLK range DIVIDER mdc_cr VALUE
  1284. // -------------------------------------
  1285. // -1 <-- tell driver to guess the value
  1286. // 60-100 MHz HCLK/42 0
  1287. // 100-150 MHz HCLK/62 1
  1288. // 20-35 MHz HCLK/16 2
  1289. // 35-60 MHz HCLK/26 3
  1290. // 150-250 MHz HCLK/102 4 <-- value for Nucleo-H* on max speed driven by HSI
  1291. // 250-300 MHz HCLK/124 5 <-- value for Nucleo-H* on max speed driven by CSI
  1292. // 110, 111 Reserved
  1293. int mdc_cr; // Valid values: -1, 0, 1, 2, 3, 4, 5
  1294. };
  1295. struct mg_tcpip_driver_tm4c_data {
  1296. // MDC clock divider. MDC clock is derived from SYSCLK, must not exceed 2.5MHz
  1297. // SYSCLK range DIVIDER mdc_cr VALUE
  1298. // -------------------------------------
  1299. // -1 <-- tell driver to guess the value
  1300. // 60-100 MHz SYSCLK/42 0
  1301. // 100-150 MHz SYSCLK/62 1 <-- value for EK-TM4C129* on max speed
  1302. // 20-35 MHz SYSCLK/16 2
  1303. // 35-60 MHz SYSCLK/26 3
  1304. // 0x4-0xF Reserved
  1305. int mdc_cr; // Valid values: -1, 0, 1, 2, 3
  1306. };
  1307. #ifdef __cplusplus
  1308. }
  1309. #endif
  1310. #endif // MONGOOSE_H