| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021 |
- // Copyright (c) 2004-2013 Sergey Lyubka
- // Copyright (c) 2013-2024 Cesanta Software Limited
- // All rights reserved
- //
- // This software is dual-licensed: you can redistribute it and/or modify
- // it under the terms of the GNU General Public License version 2 as
- // published by the Free Software Foundation. For the terms of this
- // license, see http://www.gnu.org/licenses/
- //
- // You are free to use this software under the terms of the GNU General
- // Public License, but WITHOUT ANY WARRANTY; without even the implied
- // warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- // See the GNU General Public License for more details.
- //
- // Alternatively, you can license this software under a commercial
- // license, as set out in https://www.mongoose.ws/licensing/
- //
- // SPDX-License-Identifier: GPL-2.0-only or commercial
- #ifndef MONGOOSE_H
- #define MONGOOSE_H
- #define MG_VERSION "7.14"
- #ifdef __cplusplus
- extern "C" {
- #endif
- #define MG_ARCH_CUSTOM 0 // User creates its own mongoose_config.h
- #define MG_ARCH_UNIX 1 // Linux, BSD, Mac, ...
- #define MG_ARCH_WIN32 2 // Windows
- #define MG_ARCH_ESP32 3 // ESP32
- #define MG_ARCH_ESP8266 4 // ESP8266
- #define MG_ARCH_FREERTOS 5 // FreeRTOS
- #define MG_ARCH_AZURERTOS 6 // MS Azure RTOS
- #define MG_ARCH_ZEPHYR 7 // Zephyr RTOS
- #define MG_ARCH_NEWLIB 8 // Bare metal ARM
- #define MG_ARCH_CMSIS_RTOS1 9 // CMSIS-RTOS API v1 (Keil RTX)
- #define MG_ARCH_TIRTOS 10 // Texas Semi TI-RTOS
- #define MG_ARCH_RP2040 11 // Raspberry Pi RP2040
- #define MG_ARCH_ARMCC 12 // Keil MDK-Core with Configuration Wizard
- #define MG_ARCH_CMSIS_RTOS2 13 // CMSIS-RTOS API v2 (Keil RTX5, FreeRTOS)
- #define MG_ARCH_RTTHREAD 14 // RT-Thread RTOS
- #if !defined(MG_ARCH)
- #if defined(__unix__) || defined(__APPLE__)
- #define MG_ARCH MG_ARCH_UNIX
- #elif defined(_WIN32)
- #define MG_ARCH MG_ARCH_WIN32
- #endif
- #endif // !defined(MG_ARCH)
- #if !defined(MG_ARCH) || (MG_ARCH == MG_ARCH_CUSTOM)
- #include "mongoose_config.h" // keep this include
- #endif
- #if !defined(MG_ARCH)
- #error "MG_ARCH is not specified and we couldn't guess it. Define MG_ARCH=... in your compiler"
- #endif
- // http://esr.ibiblio.org/?p=5095
- #define MG_BIG_ENDIAN (*(uint16_t *) "\0\xff" < 0x100)
- #include "cfg.h"
- #if MG_ARCH == MG_ARCH_AZURERTOS
- #include <stdarg.h>
- #include <stdbool.h>
- #include <stdint.h>
- #include <stdio.h>
- #include <time.h>
- #include <fx_api.h>
- #include <tx_api.h>
- #include <nx_api.h>
- #include <nx_bsd.h>
- #include <nx_port.h>
- #include <tx_port.h>
- #define PATH_MAX FX_MAXIMUM_PATH
- #define MG_DIRSEP '\\'
- #define socklen_t int
- #define closesocket(x) soc_close(x)
- #undef FOPEN_MAX
- #endif
- #if MG_ARCH == MG_ARCH_ESP32
- #include <ctype.h>
- #include <dirent.h>
- #include <errno.h>
- #include <fcntl.h>
- #include <limits.h>
- #include <netdb.h>
- #include <stdarg.h>
- #include <stddef.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <sys/stat.h>
- #include <sys/types.h>
- #include <time.h>
- #include <esp_ota_ops.h> // Use angle brackets to avoid
- #include <esp_timer.h> // amalgamation ditching them
- #define MG_PATH_MAX 128
- #endif
- #if MG_ARCH == MG_ARCH_ESP8266
- #include <ctype.h>
- #include <dirent.h>
- #include <errno.h>
- #include <fcntl.h>
- #include <limits.h>
- #include <netdb.h>
- #include <stdarg.h>
- #include <stdbool.h>
- #include <stddef.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <sys/stat.h>
- #include <sys/time.h>
- #include <sys/types.h>
- #include <time.h>
- #include <esp_system.h>
- #define MG_PATH_MAX 128
- #endif
- #if MG_ARCH == MG_ARCH_FREERTOS
- #include <ctype.h>
- #if !defined(MG_ENABLE_LWIP) || !MG_ENABLE_LWIP
- #include <errno.h>
- #endif
- #include <stdarg.h>
- #include <stdbool.h>
- #include <stddef.h>
- #include <stdint.h>
- #include <stdio.h>
- #include <stdlib.h> // rand(), strtol(), atoi()
- #include <string.h>
- #if defined(__ARMCC_VERSION)
- #define mode_t size_t
- #include <alloca.h>
- #include <time.h>
- #elif defined(__CCRH__)
- #else
- #include <sys/stat.h>
- #endif
- #include <FreeRTOS.h>
- #include <task.h>
- #ifndef MG_IO_SIZE
- #define MG_IO_SIZE 512
- #endif
- #define calloc(a, b) mg_calloc(a, b)
- #define free(a) vPortFree(a)
- #define malloc(a) pvPortMalloc(a)
- #define strdup(s) mg_mprintf("%s", s)
- // Re-route calloc/free to the FreeRTOS's functions, don't use stdlib
- static inline void *mg_calloc(size_t cnt, size_t size) {
- void *p = pvPortMalloc(cnt * size);
- if (p != NULL) memset(p, 0, size * cnt);
- return p;
- }
- #define mkdir(a, b) mg_mkdir(a, b)
- static inline int mg_mkdir(const char *path, mode_t mode) {
- (void) path, (void) mode;
- return -1;
- }
- #endif // MG_ARCH == MG_ARCH_FREERTOS
- #if MG_ARCH == MG_ARCH_NEWLIB
- #define _POSIX_TIMERS
- #include <ctype.h>
- #include <errno.h>
- #include <stdarg.h>
- #include <stdbool.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <sys/stat.h>
- #include <sys/time.h>
- #include <sys/types.h>
- #include <time.h>
- #include <unistd.h>
- #define MG_PATH_MAX 100
- #define MG_ENABLE_SOCKET 0
- #define MG_ENABLE_DIRLIST 0
- #endif
- #if MG_ARCH == MG_ARCH_RP2040
- #include <errno.h>
- #include <stdarg.h>
- #include <stdbool.h>
- #include <stdint.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <time.h>
- #include <pico/stdlib.h>
- int mkdir(const char *, mode_t);
- #endif
- #if MG_ARCH == MG_ARCH_RTTHREAD
- #include <rtthread.h>
- #include <ctype.h>
- #include <errno.h>
- #include <fcntl.h>
- #include <sys/socket.h>
- #include <sys/select.h>
- #include <stdarg.h>
- #include <stdbool.h>
- #include <stdint.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <sys/types.h>
- #include <time.h>
- #ifndef MG_IO_SIZE
- #define MG_IO_SIZE 1460
- #endif
- #endif // MG_ARCH == MG_ARCH_RTTHREAD
- #if MG_ARCH == MG_ARCH_ARMCC || MG_ARCH == MG_ARCH_CMSIS_RTOS1 || \
- MG_ARCH == MG_ARCH_CMSIS_RTOS2
- #include <ctype.h>
- #include <errno.h>
- #include <stdarg.h>
- #include <stdbool.h>
- #include <stddef.h>
- #include <stdint.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <alloca.h>
- #include <string.h>
- #include <time.h>
- #if MG_ARCH == MG_ARCH_CMSIS_RTOS1
- #include "cmsis_os.h" // keep this include
- // https://developer.arm.com/documentation/ka003821/latest
- extern uint32_t rt_time_get(void);
- #elif MG_ARCH == MG_ARCH_CMSIS_RTOS2
- #include "cmsis_os2.h" // keep this include
- #endif
- #define strdup(s) mg_mprintf("%s", s)
- #if defined(__ARMCC_VERSION)
- #define mode_t size_t
- #define mkdir(a, b) mg_mkdir(a, b)
- static inline int mg_mkdir(const char *path, mode_t mode) {
- (void) path, (void) mode;
- return -1;
- }
- #endif
- #if (MG_ARCH == MG_ARCH_CMSIS_RTOS1 || MG_ARCH == MG_ARCH_CMSIS_RTOS2) && \
- !defined MG_ENABLE_RL && (!defined(MG_ENABLE_LWIP) || !MG_ENABLE_LWIP) && \
- (!defined(MG_ENABLE_TCPIP) || !MG_ENABLE_TCPIP)
- #define MG_ENABLE_RL 1
- #ifndef MG_SOCK_LISTEN_BACKLOG_SIZE
- #define MG_SOCK_LISTEN_BACKLOG_SIZE 3
- #endif
- #endif
- #endif
- #if MG_ARCH == MG_ARCH_TIRTOS
- #include <stdlib.h>
- #include <ctype.h>
- #include <stdarg.h>
- #include <stdbool.h>
- #include <stdint.h>
- #include <stdio.h>
- #include <string.h>
- #include <time.h>
- #include <serrno.h>
- #include <sys/socket.h>
- #include <ti/sysbios/knl/Clock.h>
- #endif
- #if MG_ARCH == MG_ARCH_UNIX
- #define _DARWIN_UNLIMITED_SELECT 1 // No limit on file descriptors
- #if defined(__APPLE__)
- #include <mach/mach_time.h>
- #endif
- #if !defined(MG_ENABLE_EPOLL) && defined(__linux__)
- #define MG_ENABLE_EPOLL 1
- #elif !defined(MG_ENABLE_POLL)
- #define MG_ENABLE_POLL 1
- #endif
- #include <arpa/inet.h>
- #include <ctype.h>
- #include <dirent.h>
- #include <errno.h>
- #include <fcntl.h>
- #include <inttypes.h>
- #include <limits.h>
- #include <netdb.h>
- #include <netinet/in.h>
- #include <netinet/tcp.h>
- #include <signal.h>
- #include <stdarg.h>
- #include <stdbool.h>
- #include <stddef.h>
- #include <stdint.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #if defined(MG_ENABLE_EPOLL) && MG_ENABLE_EPOLL
- #include <sys/epoll.h>
- #elif defined(MG_ENABLE_POLL) && MG_ENABLE_POLL
- #include <poll.h>
- #else
- #include <sys/select.h>
- #endif
- #include <sys/socket.h>
- #include <sys/stat.h>
- #include <sys/time.h>
- #include <sys/types.h>
- #include <time.h>
- #include <unistd.h>
- #ifndef MG_ENABLE_DIRLIST
- #define MG_ENABLE_DIRLIST 1
- #endif
- #ifndef MG_PATH_MAX
- #define MG_PATH_MAX FILENAME_MAX
- #endif
- #endif
- #if MG_ARCH == MG_ARCH_WIN32
- #ifndef WIN32_LEAN_AND_MEAN
- #define WIN32_LEAN_AND_MEAN
- #endif
- #ifndef _CRT_SECURE_NO_WARNINGS
- #define _CRT_SECURE_NO_WARNINGS
- #endif
- #ifndef _WINSOCK_DEPRECATED_NO_WARNINGS
- #define _WINSOCK_DEPRECATED_NO_WARNINGS
- #endif
- #include <ctype.h>
- #include <direct.h>
- #include <errno.h>
- #include <fcntl.h>
- #include <limits.h>
- #include <signal.h>
- #include <stdarg.h>
- #include <stddef.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <sys/stat.h>
- #include <sys/types.h>
- #include <time.h>
- #if defined(_MSC_VER) && _MSC_VER < 1700
- #define __func__ ""
- typedef __int64 int64_t;
- typedef unsigned __int64 uint64_t;
- typedef unsigned char uint8_t;
- typedef char int8_t;
- typedef unsigned short uint16_t;
- typedef short int16_t;
- typedef unsigned int uint32_t;
- typedef int int32_t;
- typedef enum { false = 0, true = 1 } bool;
- #else
- #include <stdbool.h>
- #include <stdint.h>
- #include <ws2tcpip.h>
- #endif
- #include <process.h>
- #include <winerror.h>
- #include <winsock2.h>
- // Protect from calls like std::snprintf in app code
- // See https://github.com/cesanta/mongoose/issues/1047
- #ifndef __cplusplus
- #define snprintf _snprintf
- #define vsnprintf _vsnprintf
- #ifndef strdup // For MSVC with _DEBUG, see #1359
- #define strdup(x) _strdup(x)
- #endif
- #endif
- #define MG_INVALID_SOCKET INVALID_SOCKET
- #define MG_SOCKET_TYPE SOCKET
- typedef unsigned long nfds_t;
- #if defined(_MSC_VER)
- #pragma comment(lib, "ws2_32.lib")
- #ifndef alloca
- #define alloca(a) _alloca(a)
- #endif
- #endif
- #define poll(a, b, c) WSAPoll((a), (b), (c))
- #define closesocket(x) closesocket(x)
- typedef int socklen_t;
- #define MG_DIRSEP '\\'
- #ifndef MG_PATH_MAX
- #define MG_PATH_MAX FILENAME_MAX
- #endif
- #ifndef SO_EXCLUSIVEADDRUSE
- #define SO_EXCLUSIVEADDRUSE ((int) (~SO_REUSEADDR))
- #endif
- #define MG_SOCK_ERR(errcode) ((errcode) < 0 ? WSAGetLastError() : 0)
- #define MG_SOCK_PENDING(errcode) \
- (((errcode) < 0) && \
- (WSAGetLastError() == WSAEINTR || WSAGetLastError() == WSAEINPROGRESS || \
- WSAGetLastError() == WSAEWOULDBLOCK))
- #define MG_SOCK_RESET(errcode) \
- (((errcode) < 0) && (WSAGetLastError() == WSAECONNRESET))
- #define realpath(a, b) _fullpath((b), (a), MG_PATH_MAX)
- #define sleep(x) Sleep((x) *1000)
- #define mkdir(a, b) _mkdir(a)
- #define timegm(x) _mkgmtime(x)
- #ifndef S_ISDIR
- #define S_ISDIR(x) (((x) &_S_IFMT) == _S_IFDIR)
- #endif
- #ifndef MG_ENABLE_DIRLIST
- #define MG_ENABLE_DIRLIST 1
- #endif
- #ifndef SIGPIPE
- #define SIGPIPE 0
- #endif
- #endif
- #if MG_ARCH == MG_ARCH_ZEPHYR
- #include <zephyr/kernel.h>
- #include <ctype.h>
- #include <errno.h>
- #include <zephyr/net/socket.h>
- #include <zephyr/posix/fcntl.h>
- #include <zephyr/posix/sys/select.h>
- #include <stdarg.h>
- #include <stdbool.h>
- #include <stdint.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <sys/types.h>
- #include <time.h>
- #define MG_PUTCHAR(x) printk("%c", x)
- #ifndef strdup
- #define strdup(s) ((char *) mg_strdup(mg_str(s)).buf)
- #endif
- #define strerror(x) zsock_gai_strerror(x)
- #ifndef FD_CLOEXEC
- #define FD_CLOEXEC 0
- #endif
- #ifndef F_SETFD
- #define F_SETFD 0
- #endif
- #define MG_ENABLE_SSI 0
- int rand(void);
- int sscanf(const char *, const char *, ...);
- #endif
- #if defined(MG_ENABLE_FREERTOS_TCP) && MG_ENABLE_FREERTOS_TCP
- #include <limits.h>
- #include <list.h>
- #include <FreeRTOS_IP.h>
- #include <FreeRTOS_Sockets.h>
- #include <FreeRTOS_errno_TCP.h> // contents to be moved and file removed, some day
- #define MG_SOCKET_TYPE Socket_t
- #define MG_INVALID_SOCKET FREERTOS_INVALID_SOCKET
- // Why FreeRTOS-TCP did not implement a clean BSD API, but its own thing
- // with FreeRTOS_ prefix, is beyond me
- #define IPPROTO_TCP FREERTOS_IPPROTO_TCP
- #define IPPROTO_UDP FREERTOS_IPPROTO_UDP
- #define AF_INET FREERTOS_AF_INET
- #define SOCK_STREAM FREERTOS_SOCK_STREAM
- #define SOCK_DGRAM FREERTOS_SOCK_DGRAM
- #define SO_BROADCAST 0
- #define SO_ERROR 0
- #define SOL_SOCKET 0
- #define SO_REUSEADDR 0
- #define MG_SOCK_ERR(errcode) ((errcode) < 0 ? (errcode) : 0)
- #define MG_SOCK_PENDING(errcode) \
- ((errcode) == -pdFREERTOS_ERRNO_EWOULDBLOCK || \
- (errcode) == -pdFREERTOS_ERRNO_EISCONN || \
- (errcode) == -pdFREERTOS_ERRNO_EINPROGRESS || \
- (errcode) == -pdFREERTOS_ERRNO_EAGAIN)
- #define MG_SOCK_RESET(errcode) ((errcode) == -pdFREERTOS_ERRNO_ENOTCONN)
- // actually only if optional timeout is enabled
- #define MG_SOCK_INTR(fd) (fd == NULL)
- #define sockaddr_in freertos_sockaddr
- #define sockaddr freertos_sockaddr
- #define accept(a, b, c) FreeRTOS_accept((a), (b), (c))
- #define connect(a, b, c) FreeRTOS_connect((a), (b), (c))
- #define bind(a, b, c) FreeRTOS_bind((a), (b), (c))
- #define listen(a, b) FreeRTOS_listen((a), (b))
- #define socket(a, b, c) FreeRTOS_socket((a), (b), (c))
- #define send(a, b, c, d) FreeRTOS_send((a), (b), (c), (d))
- #define recv(a, b, c, d) FreeRTOS_recv((a), (b), (c), (d))
- #define setsockopt(a, b, c, d, e) FreeRTOS_setsockopt((a), (b), (c), (d), (e))
- #define sendto(a, b, c, d, e, f) FreeRTOS_sendto((a), (b), (c), (d), (e), (f))
- #define recvfrom(a, b, c, d, e, f) \
- FreeRTOS_recvfrom((a), (b), (c), (d), (e), (f))
- #define closesocket(x) FreeRTOS_closesocket(x)
- #define gethostbyname(x) FreeRTOS_gethostbyname(x)
- #define getsockname(a, b, c) mg_getsockname((a), (b), (c))
- #define getpeername(a, b, c) mg_getpeername((a), (b), (c))
- static inline int mg_getsockname(MG_SOCKET_TYPE fd, void *buf, socklen_t *len) {
- (void) fd, (void) buf, (void) len;
- return -1;
- }
- static inline int mg_getpeername(MG_SOCKET_TYPE fd, void *buf, socklen_t *len) {
- (void) fd, (void) buf, (void) len;
- return 0;
- }
- #endif
- #if defined(MG_ENABLE_LWIP) && MG_ENABLE_LWIP
- #if defined(__GNUC__) && !defined(__ARMCC_VERSION)
- #include <sys/stat.h>
- #endif
- struct timeval;
- #include <lwip/sockets.h>
- #if !LWIP_TIMEVAL_PRIVATE
- #if defined(__GNUC__) && !defined(__ARMCC_VERSION) // armclang sets both
- #include <sys/time.h>
- #else
- struct timeval {
- time_t tv_sec;
- long tv_usec;
- };
- #endif
- #endif
- #if LWIP_SOCKET != 1
- // Sockets support disabled in LWIP by default
- #error Set LWIP_SOCKET variable to 1 (in lwipopts.h)
- #endif
- #endif
- #if defined(MG_ENABLE_RL) && MG_ENABLE_RL
- #include <rl_net.h>
- #define closesocket(x) closesocket(x)
- #define TCP_NODELAY SO_KEEPALIVE
- #define MG_SOCK_ERR(errcode) ((errcode) < 0 ? (errcode) : 0)
- #define MG_SOCK_PENDING(errcode) \
- ((errcode) == BSD_EWOULDBLOCK || (errcode) == BSD_EALREADY || \
- (errcode) == BSD_EINPROGRESS)
- #define MG_SOCK_RESET(errcode) \
- ((errcode) == BSD_ECONNABORTED || (errcode) == BSD_ECONNRESET)
- // In blocking mode, which is enabled by default, accept() waits for a
- // connection request. In non blocking mode, you must call accept()
- // again if the error code BSD_EWOULDBLOCK is returned.
- #define MG_SOCK_INTR(fd) (fd == BSD_EWOULDBLOCK)
- #define socklen_t int
- #endif
- #ifndef MG_ENABLE_LOG
- #define MG_ENABLE_LOG 1
- #endif
- #ifndef MG_ENABLE_CUSTOM_LOG
- #define MG_ENABLE_CUSTOM_LOG 0 // Let user define their own MG_LOG
- #endif
- #ifndef MG_ENABLE_TCPIP
- #define MG_ENABLE_TCPIP 0 // Mongoose built-in network stack
- #endif
- #ifndef MG_ENABLE_LWIP
- #define MG_ENABLE_LWIP 0 // lWIP network stack
- #endif
- #ifndef MG_ENABLE_FREERTOS_TCP
- #define MG_ENABLE_FREERTOS_TCP 0 // Amazon FreeRTOS-TCP network stack
- #endif
- #ifndef MG_ENABLE_RL
- #define MG_ENABLE_RL 0 // ARM MDK network stack
- #endif
- #ifndef MG_ENABLE_SOCKET
- #define MG_ENABLE_SOCKET !MG_ENABLE_TCPIP
- #endif
- #ifndef MG_ENABLE_POLL
- #define MG_ENABLE_POLL 0
- #endif
- #ifndef MG_ENABLE_EPOLL
- #define MG_ENABLE_EPOLL 0
- #endif
- #ifndef MG_ENABLE_FATFS
- #define MG_ENABLE_FATFS 0
- #endif
- #ifndef MG_ENABLE_SSI
- #define MG_ENABLE_SSI 0
- #endif
- #ifndef MG_ENABLE_IPV6
- #define MG_ENABLE_IPV6 1
- #endif
- #ifndef MG_IPV6_V6ONLY
- #define MG_IPV6_V6ONLY 0 // IPv6 socket binds only to V6, not V4 address
- #endif
- #ifndef MG_ENABLE_MD5
- #define MG_ENABLE_MD5 1
- #endif
- // Set MG_ENABLE_WINSOCK=0 for Win32 builds with external IP stack (like LWIP)
- #ifndef MG_ENABLE_WINSOCK
- #define MG_ENABLE_WINSOCK 1
- #endif
- #ifndef MG_ENABLE_DIRLIST
- #define MG_ENABLE_DIRLIST 0
- #endif
- #ifndef MG_ENABLE_CUSTOM_RANDOM
- #define MG_ENABLE_CUSTOM_RANDOM 0
- #endif
- #ifndef MG_ENABLE_CUSTOM_MILLIS
- #define MG_ENABLE_CUSTOM_MILLIS 0
- #endif
- #ifndef MG_ENABLE_PACKED_FS
- #define MG_ENABLE_PACKED_FS 1
- #endif
- #ifndef MG_ENABLE_ASSERT
- #define MG_ENABLE_ASSERT 0
- #endif
- #ifndef MG_IO_SIZE
- #define MG_IO_SIZE (1024*1024) // Granularity of the send/recv IO buffer growth
- #endif
- #ifndef MG_MAX_RECV_SIZE
- #define MG_MAX_RECV_SIZE (30UL * 1024UL * 1024UL) // Maximum recv IO buffer size
- #endif
- #ifndef MG_DATA_SIZE
- #define MG_DATA_SIZE 32 // struct mg_connection :: data size
- #endif
- #ifndef MG_MAX_HTTP_HEADERS
- #define MG_MAX_HTTP_HEADERS 30
- #endif
- #ifndef MG_HTTP_INDEX
- #define MG_HTTP_INDEX "index.html"
- #endif
- #ifndef MG_PATH_MAX
- #ifdef PATH_MAX
- #define MG_PATH_MAX PATH_MAX
- #else
- #define MG_PATH_MAX 128
- #endif
- #endif
- #ifndef MG_SOCK_LISTEN_BACKLOG_SIZE
- #define MG_SOCK_LISTEN_BACKLOG_SIZE 128
- #endif
- #ifndef MG_DIRSEP
- #define MG_DIRSEP '/'
- #endif
- #ifndef MG_ENABLE_POSIX_FS
- #if defined(FOPEN_MAX)
- #define MG_ENABLE_POSIX_FS 1
- #else
- #define MG_ENABLE_POSIX_FS 0
- #endif
- #endif
- #ifndef MG_INVALID_SOCKET
- #define MG_INVALID_SOCKET (-1)
- #endif
- #ifndef MG_SOCKET_TYPE
- #define MG_SOCKET_TYPE int
- #endif
- #ifndef MG_SOCKET_ERRNO
- #define MG_SOCKET_ERRNO errno
- #endif
- #if MG_ENABLE_EPOLL
- #define MG_EPOLL_ADD(c) \
- do { \
- struct epoll_event ev = {EPOLLIN | EPOLLERR | EPOLLHUP, {c}}; \
- epoll_ctl(c->mgr->epoll_fd, EPOLL_CTL_ADD, (int) (size_t) c->fd, &ev); \
- } while (0)
- #define MG_EPOLL_MOD(c, wr) \
- do { \
- struct epoll_event ev = {EPOLLIN | EPOLLERR | EPOLLHUP, {c}}; \
- if (wr) ev.events |= EPOLLOUT; \
- epoll_ctl(c->mgr->epoll_fd, EPOLL_CTL_MOD, (int) (size_t) c->fd, &ev); \
- } while (0)
- #else
- #define MG_EPOLL_ADD(c)
- #define MG_EPOLL_MOD(c, wr)
- #endif
- #ifndef MG_ENABLE_PROFILE
- #define MG_ENABLE_PROFILE 0
- #endif
- #ifndef MG_ENABLE_TCPIP_DRIVER_INIT // mg_mgr_init() will also initialize
- #define MG_ENABLE_TCPIP_DRIVER_INIT 1 // enabled built-in driver for
- #endif // Mongoose built-in network stack
- #ifndef MG_TCPIP_IP // e.g. MG_IPV4(192, 168, 0, 223)
- #define MG_TCPIP_IP MG_IPV4(0, 0, 0, 0) // Default is 0.0.0.0 (DHCP)
- #endif
- #ifndef MG_TCPIP_MASK
- #define MG_TCPIP_MASK MG_IPV4(0, 0, 0, 0) // Default is 0.0.0.0 (DHCP)
- #endif
- #ifndef MG_TCPIP_GW
- #define MG_TCPIP_GW MG_IPV4(0, 0, 0, 0) // Default is 0.0.0.0 (DHCP)
- #endif
- #ifndef MG_SET_MAC_ADDRESS
- #define MG_SET_MAC_ADDRESS(mac)
- #endif
- #ifndef MG_ENABLE_TCPIP_PRINT_DEBUG_STATS
- #define MG_ENABLE_TCPIP_PRINT_DEBUG_STATS 0
- #endif
- // Describes an arbitrary chunk of memory
- struct mg_str {
- char *buf; // String data
- size_t len; // String length
- };
- // Using macro to avoid shadowing C++ struct constructor, see #1298
- #define mg_str(s) mg_str_s(s)
- struct mg_str mg_str(const char *s);
- struct mg_str mg_str_n(const char *s, size_t n);
- int mg_casecmp(const char *s1, const char *s2);
- int mg_strcmp(const struct mg_str str1, const struct mg_str str2);
- int mg_strcasecmp(const struct mg_str str1, const struct mg_str str2);
- bool mg_match(struct mg_str str, struct mg_str pattern, struct mg_str *caps);
- bool mg_span(struct mg_str s, struct mg_str *a, struct mg_str *b, char delim);
- bool mg_str_to_num(struct mg_str, int base, void *val, size_t val_len);
- // Single producer, single consumer non-blocking queue
- struct mg_queue {
- char *buf;
- size_t size;
- volatile size_t tail;
- volatile size_t head;
- };
- void mg_queue_init(struct mg_queue *, char *, size_t); // Init queue
- size_t mg_queue_book(struct mg_queue *, char **buf, size_t); // Reserve space
- void mg_queue_add(struct mg_queue *, size_t); // Add new message
- size_t mg_queue_next(struct mg_queue *, char **); // Get oldest message
- void mg_queue_del(struct mg_queue *, size_t); // Delete oldest message
- typedef void (*mg_pfn_t)(char, void *); // Output function
- typedef size_t (*mg_pm_t)(mg_pfn_t, void *, va_list *); // %M printer
- size_t mg_vxprintf(void (*)(char, void *), void *, const char *fmt, va_list *);
- size_t mg_xprintf(void (*fn)(char, void *), void *, const char *fmt, ...);
- // Convenience wrappers around mg_xprintf
- size_t mg_vsnprintf(char *buf, size_t len, const char *fmt, va_list *ap);
- size_t mg_snprintf(char *, size_t, const char *fmt, ...);
- char *mg_vmprintf(const char *fmt, va_list *ap);
- char *mg_mprintf(const char *fmt, ...);
- size_t mg_queue_vprintf(struct mg_queue *, const char *fmt, va_list *);
- size_t mg_queue_printf(struct mg_queue *, const char *fmt, ...);
- // %M print helper functions
- size_t mg_print_base64(void (*out)(char, void *), void *arg, va_list *ap);
- size_t mg_print_esc(void (*out)(char, void *), void *arg, va_list *ap);
- size_t mg_print_hex(void (*out)(char, void *), void *arg, va_list *ap);
- size_t mg_print_ip(void (*out)(char, void *), void *arg, va_list *ap);
- size_t mg_print_ip_port(void (*out)(char, void *), void *arg, va_list *ap);
- size_t mg_print_ip4(void (*out)(char, void *), void *arg, va_list *ap);
- size_t mg_print_ip6(void (*out)(char, void *), void *arg, va_list *ap);
- size_t mg_print_mac(void (*out)(char, void *), void *arg, va_list *ap);
- // Various output functions
- void mg_pfn_iobuf(char ch, void *param); // param: struct mg_iobuf *
- void mg_pfn_stdout(char c, void *param); // param: ignored
- // A helper macro for printing JSON: mg_snprintf(buf, len, "%m", MG_ESC("hi"))
- #define MG_ESC(str) mg_print_esc, 0, (str)
- enum { MG_LL_NONE, MG_LL_ERROR, MG_LL_INFO, MG_LL_DEBUG, MG_LL_VERBOSE };
- extern int mg_log_level; // Current log level, one of MG_LL_*
- void mg_log(const char *fmt, ...);
- void mg_log_prefix(int ll, const char *file, int line, const char *fname);
- // bool mg_log2(int ll, const char *file, int line, const char *fmt, ...);
- void mg_hexdump(const void *buf, size_t len);
- void mg_log_set_fn(mg_pfn_t fn, void *param);
- #define mg_log_set(level_) mg_log_level = (level_)
- #if MG_ENABLE_LOG
- #define MG_LOG(level, args) \
- do { \
- if ((level) <= mg_log_level) { \
- mg_log_prefix((level), __FILE__, __LINE__, __func__); \
- mg_log args; \
- } \
- } while (0)
- #else
- #define MG_LOG(level, args) \
- do { \
- if (0) mg_log args; \
- } while (0)
- #endif
- #define MG_ERROR(args) MG_LOG(MG_LL_ERROR, args)
- #define MG_INFO(args) MG_LOG(MG_LL_INFO, args)
- #define MG_DEBUG(args) MG_LOG(MG_LL_DEBUG, args)
- #define MG_VERBOSE(args) MG_LOG(MG_LL_VERBOSE, args)
- struct mg_timer {
- unsigned long id; // Timer ID
- uint64_t period_ms; // Timer period in milliseconds
- uint64_t expire; // Expiration timestamp in milliseconds
- unsigned flags; // Possible flags values below
- #define MG_TIMER_ONCE 0 // Call function once
- #define MG_TIMER_REPEAT 1 // Call function periodically
- #define MG_TIMER_RUN_NOW 2 // Call immediately when timer is set
- void (*fn)(void *); // Function to call
- void *arg; // Function argument
- struct mg_timer *next; // Linkage
- };
- void mg_timer_init(struct mg_timer **head, struct mg_timer *timer,
- uint64_t milliseconds, unsigned flags, void (*fn)(void *),
- void *arg);
- void mg_timer_free(struct mg_timer **head, struct mg_timer *);
- void mg_timer_poll(struct mg_timer **head, uint64_t new_ms);
- bool mg_timer_expired(uint64_t *expiration, uint64_t period, uint64_t now);
- enum { MG_FS_READ = 1, MG_FS_WRITE = 2, MG_FS_DIR = 4 };
- // Filesystem API functions
- // st() returns MG_FS_* flags and populates file size and modification time
- // ls() calls fn() for every directory entry, allowing to list a directory
- //
- // NOTE: UNIX-style shorthand names for the API functions are deliberately
- // chosen to avoid conflicts with some libraries that make macros for e.g.
- // stat(), write(), read() calls.
- struct mg_fs {
- int (*st)(const char *path, size_t *size, time_t *mtime); // stat file
- void (*ls)(const char *path, void (*fn)(const char *, void *),
- void *); // List directory entries: call fn(file_name, fn_data)
- // for each directory entry
- void *(*op)(const char *path, int flags); // Open file
- void (*cl)(void *fd); // Close file
- size_t (*rd)(void *fd, void *buf, size_t len); // Read file
- size_t (*wr)(void *fd, const void *buf, size_t len); // Write file
- size_t (*sk)(void *fd, size_t offset); // Set file position
- bool (*mv)(const char *from, const char *to); // Rename file
- bool (*rm)(const char *path); // Delete file
- bool (*mkd)(const char *path); // Create directory
- };
- extern struct mg_fs mg_fs_posix; // POSIX open/close/read/write/seek
- extern struct mg_fs mg_fs_packed; // Packed FS, see examples/device-dashboard
- extern struct mg_fs mg_fs_fat; // FAT FS
- // File descriptor
- struct mg_fd {
- void *fd;
- struct mg_fs *fs;
- };
- struct mg_fd *mg_fs_open(struct mg_fs *fs, const char *path, int flags);
- void mg_fs_close(struct mg_fd *fd);
- bool mg_fs_ls(struct mg_fs *fs, const char *path, char *buf, size_t len);
- struct mg_str mg_file_read(struct mg_fs *fs, const char *path);
- bool mg_file_write(struct mg_fs *fs, const char *path, const void *, size_t);
- bool mg_file_printf(struct mg_fs *fs, const char *path, const char *fmt, ...);
- // Packed API
- const char *mg_unpack(const char *path, size_t *size, time_t *mtime);
- const char *mg_unlist(size_t no); // Get no'th packed filename
- struct mg_str mg_unpacked(const char *path); // Packed file as mg_str
- #if MG_ENABLE_ASSERT
- #include <assert.h>
- #elif !defined(assert)
- #define assert(x)
- #endif
- void mg_bzero(volatile unsigned char *buf, size_t len);
- void mg_random(void *buf, size_t len);
- char *mg_random_str(char *buf, size_t len);
- uint16_t mg_ntohs(uint16_t net);
- uint32_t mg_ntohl(uint32_t net);
- uint32_t mg_crc32(uint32_t crc, const char *buf, size_t len);
- uint64_t mg_millis(void); // Return milliseconds since boot
- uint64_t mg_now(void); // Return milliseconds since Epoch
- bool mg_path_is_sane(const struct mg_str path);
- #define mg_htons(x) mg_ntohs(x)
- #define mg_htonl(x) mg_ntohl(x)
- #define MG_U32(a, b, c, d) \
- (((uint32_t) ((a) & 255) << 24) | ((uint32_t) ((b) & 255) << 16) | \
- ((uint32_t) ((c) & 255) << 8) | (uint32_t) ((d) & 255))
- #define MG_IPV4(a, b, c, d) mg_htonl(MG_U32(a, b, c, d))
- // For printing IPv4 addresses: printf("%d.%d.%d.%d\n", MG_IPADDR_PARTS(&ip))
- #define MG_U8P(ADDR) ((uint8_t *) (ADDR))
- #define MG_IPADDR_PARTS(ADDR) \
- MG_U8P(ADDR)[0], MG_U8P(ADDR)[1], MG_U8P(ADDR)[2], MG_U8P(ADDR)[3]
- #define MG_REG(x) ((volatile uint32_t *) (x))[0]
- #define MG_BIT(x) (((uint32_t) 1U) << (x))
- #define MG_SET_BITS(R, CLRMASK, SETMASK) (R) = ((R) & ~(CLRMASK)) | (SETMASK)
- #define MG_ROUND_UP(x, a) ((a) == 0 ? (x) : ((((x) + (a) -1) / (a)) * (a)))
- #define MG_ROUND_DOWN(x, a) ((a) == 0 ? (x) : (((x) / (a)) * (a)))
- #if defined(__GNUC__)
- #define MG_ARM_DISABLE_IRQ() asm volatile("cpsid i" : : : "memory")
- #define MG_ARM_ENABLE_IRQ() asm volatile("cpsie i" : : : "memory")
- #elif defined(__CCRH__)
- #define MG_RH850_DISABLE_IRQ() __DI()
- #define MG_RH850_ENABLE_IRQ() __EI()
- #else
- #define MG_ARM_DISABLE_IRQ()
- #define MG_ARM_ENABLE_IRQ()
- #endif
- #if defined(__CC_ARM)
- #define MG_DSB() __dsb(0xf)
- #elif defined(__ARMCC_VERSION)
- #define MG_DSB() __builtin_arm_dsb(0xf)
- #elif defined(__GNUC__) && defined(__arm__) && defined(__thumb__)
- #define MG_DSB() asm("DSB 0xf")
- #elif defined(__ICCARM__)
- #define MG_DSB() __iar_builtin_DSB()
- #else
- #define MG_DSB()
- #endif
- struct mg_addr;
- int mg_check_ip_acl(struct mg_str acl, struct mg_addr *remote_ip);
- // Linked list management macros
- #define LIST_ADD_HEAD(type_, head_, elem_) \
- do { \
- (elem_)->next = (*head_); \
- *(head_) = (elem_); \
- } while (0)
- #define LIST_ADD_TAIL(type_, head_, elem_) \
- do { \
- type_ **h = head_; \
- while (*h != NULL) h = &(*h)->next; \
- *h = (elem_); \
- } while (0)
- #define LIST_DELETE(type_, head_, elem_) \
- do { \
- type_ **h = head_; \
- while (*h != (elem_)) h = &(*h)->next; \
- *h = (elem_)->next; \
- } while (0)
- unsigned short mg_url_port(const char *url);
- int mg_url_is_ssl(const char *url);
- struct mg_str mg_url_host(const char *url);
- struct mg_str mg_url_user(const char *url);
- struct mg_str mg_url_pass(const char *url);
- const char *mg_url_uri(const char *url);
- struct mg_iobuf {
- unsigned char *buf; // Pointer to stored data
- size_t size; // Total size available
- size_t len; // Current number of bytes
- size_t align; // Alignment during allocation
- };
- int mg_iobuf_init(struct mg_iobuf *, size_t, size_t);
- int mg_iobuf_resize(struct mg_iobuf *, size_t);
- void mg_iobuf_free(struct mg_iobuf *);
- size_t mg_iobuf_add(struct mg_iobuf *, size_t, const void *, size_t);
- size_t mg_iobuf_del(struct mg_iobuf *, size_t ofs, size_t len);
- size_t mg_base64_update(unsigned char input_byte, char *buf, size_t len);
- size_t mg_base64_final(char *buf, size_t len);
- size_t mg_base64_encode(const unsigned char *p, size_t n, char *buf, size_t);
- size_t mg_base64_decode(const char *src, size_t n, char *dst, size_t);
- typedef struct {
- uint32_t buf[4];
- uint32_t bits[2];
- unsigned char in[64];
- } mg_md5_ctx;
- void mg_md5_init(mg_md5_ctx *c);
- void mg_md5_update(mg_md5_ctx *c, const unsigned char *data, size_t len);
- void mg_md5_final(mg_md5_ctx *c, unsigned char[16]);
- typedef struct {
- uint32_t state[5];
- uint32_t count[2];
- unsigned char buffer[64];
- } mg_sha1_ctx;
- void mg_sha1_init(mg_sha1_ctx *);
- void mg_sha1_update(mg_sha1_ctx *, const unsigned char *data, size_t len);
- void mg_sha1_final(unsigned char digest[20], mg_sha1_ctx *);
- // https://github.com/B-Con/crypto-algorithms
- // Author: Brad Conte (brad AT bradconte.com)
- // Disclaimer: This code is presented "as is" without any guarantees.
- // Details: Defines the API for the corresponding SHA1 implementation.
- // Copyright: public domain
- typedef struct {
- uint32_t state[8];
- uint64_t bits;
- uint32_t len;
- unsigned char buffer[64];
- } mg_sha256_ctx;
- void mg_sha256_init(mg_sha256_ctx *);
- void mg_sha256_update(mg_sha256_ctx *, const unsigned char *data, size_t len);
- void mg_sha256_final(unsigned char digest[32], mg_sha256_ctx *);
- void mg_hmac_sha256(uint8_t dst[32], uint8_t *key, size_t keysz, uint8_t *data,
- size_t datasz);
- #ifndef TLS_X15519_H
- #define TLS_X15519_H
- #define X25519_BYTES 32
- extern const uint8_t X25519_BASE_POINT[X25519_BYTES];
- int mg_tls_x25519(uint8_t out[X25519_BYTES], const uint8_t scalar[X25519_BYTES],
- const uint8_t x1[X25519_BYTES], int clamp);
- #endif /* TLS_X15519_H */
- /******************************************************************************
- *
- * THIS SOURCE CODE IS HEREBY PLACED INTO THE PUBLIC DOMAIN FOR THE GOOD OF ALL
- *
- * This is a simple and straightforward implementation of AES-GCM authenticated
- * encryption. The focus of this work was correctness & accuracy. It is written
- * in straight 'C' without any particular focus upon optimization or speed. It
- * should be endian (memory byte order) neutral since the few places that care
- * are handled explicitly.
- *
- * This implementation of AES-GCM was created by Steven M. Gibson of GRC.com.
- *
- * It is intended for general purpose use, but was written in support of GRC's
- * reference implementation of the SQRL (Secure Quick Reliable Login) client.
- *
- * See: http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf
- * http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/ \
- * gcm/gcm-revised-spec.pdf
- *
- * NO COPYRIGHT IS CLAIMED IN THIS WORK, HOWEVER, NEITHER IS ANY WARRANTY MADE
- * REGARDING ITS FITNESS FOR ANY PARTICULAR PURPOSE. USE IT AT YOUR OWN RISK.
- *
- *******************************************************************************/
- #ifndef TLS_AES128_H
- #define TLS_AES128_H
- typedef unsigned char uchar; // add some convienent shorter types
- typedef unsigned int uint;
- /******************************************************************************
- * AES_CONTEXT : cipher context / holds inter-call data
- ******************************************************************************/
- typedef struct {
- int mode; // 1 for Encryption, 0 for Decryption
- int rounds; // keysize-based rounds count
- uint32_t *rk; // pointer to current round key
- uint32_t buf[68]; // key expansion buffer
- } aes_context;
- #define GCM_AUTH_FAILURE 0x55555555 // authentication failure
- /******************************************************************************
- * GCM_CONTEXT : MUST be called once before ANY use of this library
- ******************************************************************************/
- int mg_gcm_initialize(void);
- //
- // aes-gcm.h
- // MKo
- //
- // Created by Markus Kosmal on 20/11/14.
- //
- //
- int mg_aes_gcm_encrypt(unsigned char *output, const unsigned char *input,
- size_t input_length, const unsigned char *key,
- const size_t key_len, const unsigned char *iv,
- const size_t iv_len, unsigned char *aead,
- size_t aead_len, unsigned char *tag,
- const size_t tag_len);
- int mg_aes_gcm_decrypt(unsigned char *output, const unsigned char *input,
- size_t input_length, const unsigned char *key,
- const size_t key_len, const unsigned char *iv,
- const size_t iv_len);
- #endif /* TLS_AES128_H */
- // End of aes128 PD
- #define MG_UECC_SUPPORTS_secp256r1 1
- /* Copyright 2014, Kenneth MacKay. Licensed under the BSD 2-clause license. */
- #ifndef _UECC_H_
- #define _UECC_H_
- /* Platform selection options.
- If MG_UECC_PLATFORM is not defined, the code will try to guess it based on
- compiler macros. Possible values for MG_UECC_PLATFORM are defined below: */
- #define mg_uecc_arch_other 0
- #define mg_uecc_x86 1
- #define mg_uecc_x86_64 2
- #define mg_uecc_arm 3
- #define mg_uecc_arm_thumb 4
- #define mg_uecc_arm_thumb2 5
- #define mg_uecc_arm64 6
- #define mg_uecc_avr 7
- /* If desired, you can define MG_UECC_WORD_SIZE as appropriate for your platform
- (1, 4, or 8 bytes). If MG_UECC_WORD_SIZE is not explicitly defined then it will
- be automatically set based on your platform. */
- /* Optimization level; trade speed for code size.
- Larger values produce code that is faster but larger.
- Currently supported values are 0 - 4; 0 is unusably slow for most
- applications. Optimization level 4 currently only has an effect ARM platforms
- where more than one curve is enabled. */
- #ifndef MG_UECC_OPTIMIZATION_LEVEL
- #define MG_UECC_OPTIMIZATION_LEVEL 2
- #endif
- /* MG_UECC_SQUARE_FUNC - If enabled (defined as nonzero), this will cause a
- specific function to be used for (scalar) squaring instead of the generic
- multiplication function. This can make things faster somewhat faster, but
- increases the code size. */
- #ifndef MG_UECC_SQUARE_FUNC
- #define MG_UECC_SQUARE_FUNC 0
- #endif
- /* MG_UECC_VLI_NATIVE_LITTLE_ENDIAN - If enabled (defined as nonzero), this will
- switch to native little-endian format for *all* arrays passed in and out of the
- public API. This includes public and private keys, shared secrets, signatures
- and message hashes. Using this switch reduces the amount of call stack memory
- used by uECC, since less intermediate translations are required. Note that this
- will *only* work on native little-endian processors and it will treat the
- uint8_t arrays passed into the public API as word arrays, therefore requiring
- the provided byte arrays to be word aligned on architectures that do not support
- unaligned accesses. IMPORTANT: Keys and signatures generated with
- MG_UECC_VLI_NATIVE_LITTLE_ENDIAN=1 are incompatible with keys and signatures
- generated with MG_UECC_VLI_NATIVE_LITTLE_ENDIAN=0; all parties must use the same
- endianness. */
- #ifndef MG_UECC_VLI_NATIVE_LITTLE_ENDIAN
- #define MG_UECC_VLI_NATIVE_LITTLE_ENDIAN 0
- #endif
- /* Curve support selection. Set to 0 to remove that curve. */
- #ifndef MG_UECC_SUPPORTS_secp160r1
- #define MG_UECC_SUPPORTS_secp160r1 0
- #endif
- #ifndef MG_UECC_SUPPORTS_secp192r1
- #define MG_UECC_SUPPORTS_secp192r1 0
- #endif
- #ifndef MG_UECC_SUPPORTS_secp224r1
- #define MG_UECC_SUPPORTS_secp224r1 0
- #endif
- #ifndef MG_UECC_SUPPORTS_secp256r1
- #define MG_UECC_SUPPORTS_secp256r1 1
- #endif
- #ifndef MG_UECC_SUPPORTS_secp256k1
- #define MG_UECC_SUPPORTS_secp256k1 0
- #endif
- /* Specifies whether compressed point format is supported.
- Set to 0 to disable point compression/decompression functions. */
- #ifndef MG_UECC_SUPPORT_COMPRESSED_POINT
- #define MG_UECC_SUPPORT_COMPRESSED_POINT 1
- #endif
- struct MG_UECC_Curve_t;
- typedef const struct MG_UECC_Curve_t *MG_UECC_Curve;
- #ifdef __cplusplus
- extern "C" {
- #endif
- #if MG_UECC_SUPPORTS_secp160r1
- MG_UECC_Curve mg_uecc_secp160r1(void);
- #endif
- #if MG_UECC_SUPPORTS_secp192r1
- MG_UECC_Curve mg_uecc_secp192r1(void);
- #endif
- #if MG_UECC_SUPPORTS_secp224r1
- MG_UECC_Curve mg_uecc_secp224r1(void);
- #endif
- #if MG_UECC_SUPPORTS_secp256r1
- MG_UECC_Curve mg_uecc_secp256r1(void);
- #endif
- #if MG_UECC_SUPPORTS_secp256k1
- MG_UECC_Curve mg_uecc_secp256k1(void);
- #endif
- /* MG_UECC_RNG_Function type
- The RNG function should fill 'size' random bytes into 'dest'. It should return 1
- if 'dest' was filled with random data, or 0 if the random data could not be
- generated. The filled-in values should be either truly random, or from a
- cryptographically-secure PRNG.
- A correctly functioning RNG function must be set (using mg_uecc_set_rng())
- before calling mg_uecc_make_key() or mg_uecc_sign().
- Setting a correctly functioning RNG function improves the resistance to
- side-channel attacks for mg_uecc_shared_secret() and
- mg_uecc_sign_deterministic().
- A correct RNG function is set by default when building for Windows, Linux, or OS
- X. If you are building on another POSIX-compliant system that supports
- /dev/random or /dev/urandom, you can define MG_UECC_POSIX to use the predefined
- RNG. For embedded platforms there is no predefined RNG function; you must
- provide your own.
- */
- typedef int (*MG_UECC_RNG_Function)(uint8_t *dest, unsigned size);
- /* mg_uecc_set_rng() function.
- Set the function that will be used to generate random bytes. The RNG function
- should return 1 if the random data was generated, or 0 if the random data could
- not be generated.
- On platforms where there is no predefined RNG function (eg embedded platforms),
- this must be called before mg_uecc_make_key() or mg_uecc_sign() are used.
- Inputs:
- rng_function - The function that will be used to generate random bytes.
- */
- void mg_uecc_set_rng(MG_UECC_RNG_Function rng_function);
- /* mg_uecc_get_rng() function.
- Returns the function that will be used to generate random bytes.
- */
- MG_UECC_RNG_Function mg_uecc_get_rng(void);
- /* mg_uecc_curve_private_key_size() function.
- Returns the size of a private key for the curve in bytes.
- */
- int mg_uecc_curve_private_key_size(MG_UECC_Curve curve);
- /* mg_uecc_curve_public_key_size() function.
- Returns the size of a public key for the curve in bytes.
- */
- int mg_uecc_curve_public_key_size(MG_UECC_Curve curve);
- /* mg_uecc_make_key() function.
- Create a public/private key pair.
- Outputs:
- public_key - Will be filled in with the public key. Must be at least 2 *
- the curve size (in bytes) long. For example, if the curve is secp256r1,
- public_key must be 64 bytes long. private_key - Will be filled in with the
- private key. Must be as long as the curve order; this is typically the same as
- the curve size, except for secp160r1. For example, if the curve is secp256r1,
- private_key must be 32 bytes long.
- For secp160r1, private_key must be 21 bytes long! Note that
- the first byte will almost always be 0 (there is about a 1 in 2^80 chance of it
- being non-zero).
- Returns 1 if the key pair was generated successfully, 0 if an error occurred.
- */
- int mg_uecc_make_key(uint8_t *public_key, uint8_t *private_key,
- MG_UECC_Curve curve);
- /* mg_uecc_shared_secret() function.
- Compute a shared secret given your secret key and someone else's public key. If
- the public key is not from a trusted source and has not been previously
- verified, you should verify it first using mg_uecc_valid_public_key(). Note: It
- is recommended that you hash the result of mg_uecc_shared_secret() before using
- it for symmetric encryption or HMAC.
- Inputs:
- public_key - The public key of the remote party.
- private_key - Your private key.
- Outputs:
- secret - Will be filled in with the shared secret value. Must be the same
- size as the curve size; for example, if the curve is secp256r1, secret must be
- 32 bytes long.
- Returns 1 if the shared secret was generated successfully, 0 if an error
- occurred.
- */
- int mg_uecc_shared_secret(const uint8_t *public_key, const uint8_t *private_key,
- uint8_t *secret, MG_UECC_Curve curve);
- #if MG_UECC_SUPPORT_COMPRESSED_POINT
- /* mg_uecc_compress() function.
- Compress a public key.
- Inputs:
- public_key - The public key to compress.
- Outputs:
- compressed - Will be filled in with the compressed public key. Must be at
- least (curve size + 1) bytes long; for example, if the curve is secp256r1,
- compressed must be 33 bytes long.
- */
- void mg_uecc_compress(const uint8_t *public_key, uint8_t *compressed,
- MG_UECC_Curve curve);
- /* mg_uecc_decompress() function.
- Decompress a compressed public key.
- Inputs:
- compressed - The compressed public key.
- Outputs:
- public_key - Will be filled in with the decompressed public key.
- */
- void mg_uecc_decompress(const uint8_t *compressed, uint8_t *public_key,
- MG_UECC_Curve curve);
- #endif /* MG_UECC_SUPPORT_COMPRESSED_POINT */
- /* mg_uecc_valid_public_key() function.
- Check to see if a public key is valid.
- Note that you are not required to check for a valid public key before using any
- other uECC functions. However, you may wish to avoid spending CPU time computing
- a shared secret or verifying a signature using an invalid public key.
- Inputs:
- public_key - The public key to check.
- Returns 1 if the public key is valid, 0 if it is invalid.
- */
- int mg_uecc_valid_public_key(const uint8_t *public_key, MG_UECC_Curve curve);
- /* mg_uecc_compute_public_key() function.
- Compute the corresponding public key for a private key.
- Inputs:
- private_key - The private key to compute the public key for
- Outputs:
- public_key - Will be filled in with the corresponding public key
- Returns 1 if the key was computed successfully, 0 if an error occurred.
- */
- int mg_uecc_compute_public_key(const uint8_t *private_key, uint8_t *public_key,
- MG_UECC_Curve curve);
- /* mg_uecc_sign() function.
- Generate an ECDSA signature for a given hash value.
- Usage: Compute a hash of the data you wish to sign (SHA-2 is recommended) and
- pass it in to this function along with your private key.
- Inputs:
- private_key - Your private key.
- message_hash - The hash of the message to sign.
- hash_size - The size of message_hash in bytes.
- Outputs:
- signature - Will be filled in with the signature value. Must be at least 2 *
- curve size long. For example, if the curve is secp256r1, signature must be 64
- bytes long.
- Returns 1 if the signature generated successfully, 0 if an error occurred.
- */
- int mg_uecc_sign(const uint8_t *private_key, const uint8_t *message_hash,
- unsigned hash_size, uint8_t *signature, MG_UECC_Curve curve);
- /* MG_UECC_HashContext structure.
- This is used to pass in an arbitrary hash function to
- mg_uecc_sign_deterministic(). The structure will be used for multiple hash
- computations; each time a new hash is computed, init_hash() will be called,
- followed by one or more calls to update_hash(), and finally a call to
- finish_hash() to produce the resulting hash.
- The intention is that you will create a structure that includes
- MG_UECC_HashContext followed by any hash-specific data. For example:
- typedef struct SHA256_HashContext {
- MG_UECC_HashContext uECC;
- SHA256_CTX ctx;
- } SHA256_HashContext;
- void init_SHA256(MG_UECC_HashContext *base) {
- SHA256_HashContext *context = (SHA256_HashContext *)base;
- SHA256_Init(&context->ctx);
- }
- void update_SHA256(MG_UECC_HashContext *base,
- const uint8_t *message,
- unsigned message_size) {
- SHA256_HashContext *context = (SHA256_HashContext *)base;
- SHA256_Update(&context->ctx, message, message_size);
- }
- void finish_SHA256(MG_UECC_HashContext *base, uint8_t *hash_result) {
- SHA256_HashContext *context = (SHA256_HashContext *)base;
- SHA256_Final(hash_result, &context->ctx);
- }
- ... when signing ...
- {
- uint8_t tmp[32 + 32 + 64];
- SHA256_HashContext ctx = {{&init_SHA256, &update_SHA256, &finish_SHA256, 64,
- 32, tmp}}; mg_uecc_sign_deterministic(key, message_hash, &ctx.uECC, signature);
- }
- */
- typedef struct MG_UECC_HashContext {
- void (*init_hash)(const struct MG_UECC_HashContext *context);
- void (*update_hash)(const struct MG_UECC_HashContext *context,
- const uint8_t *message, unsigned message_size);
- void (*finish_hash)(const struct MG_UECC_HashContext *context,
- uint8_t *hash_result);
- unsigned
- block_size; /* Hash function block size in bytes, eg 64 for SHA-256. */
- unsigned
- result_size; /* Hash function result size in bytes, eg 32 for SHA-256. */
- uint8_t *tmp; /* Must point to a buffer of at least (2 * result_size +
- block_size) bytes. */
- } MG_UECC_HashContext;
- /* mg_uecc_sign_deterministic() function.
- Generate an ECDSA signature for a given hash value, using a deterministic
- algorithm (see RFC 6979). You do not need to set the RNG using mg_uecc_set_rng()
- before calling this function; however, if the RNG is defined it will improve
- resistance to side-channel attacks.
- Usage: Compute a hash of the data you wish to sign (SHA-2 is recommended) and
- pass it to this function along with your private key and a hash context. Note
- that the message_hash does not need to be computed with the same hash function
- used by hash_context.
- Inputs:
- private_key - Your private key.
- message_hash - The hash of the message to sign.
- hash_size - The size of message_hash in bytes.
- hash_context - A hash context to use.
- Outputs:
- signature - Will be filled in with the signature value.
- Returns 1 if the signature generated successfully, 0 if an error occurred.
- */
- int mg_uecc_sign_deterministic(const uint8_t *private_key,
- const uint8_t *message_hash, unsigned hash_size,
- const MG_UECC_HashContext *hash_context,
- uint8_t *signature, MG_UECC_Curve curve);
- /* mg_uecc_verify() function.
- Verify an ECDSA signature.
- Usage: Compute the hash of the signed data using the same hash as the signer and
- pass it to this function along with the signer's public key and the signature
- values (r and s).
- Inputs:
- public_key - The signer's public key.
- message_hash - The hash of the signed data.
- hash_size - The size of message_hash in bytes.
- signature - The signature value.
- Returns 1 if the signature is valid, 0 if it is invalid.
- */
- int mg_uecc_verify(const uint8_t *public_key, const uint8_t *message_hash,
- unsigned hash_size, const uint8_t *signature,
- MG_UECC_Curve curve);
- #ifdef __cplusplus
- } /* end of extern "C" */
- #endif
- #endif /* _UECC_H_ */
- /* Copyright 2015, Kenneth MacKay. Licensed under the BSD 2-clause license. */
- #ifndef _UECC_VLI_H_
- #define _UECC_VLI_H_
- //
- //
- /* Functions for raw large-integer manipulation. These are only available
- if uECC.c is compiled with MG_UECC_ENABLE_VLI_API defined to 1. */
- #ifndef MG_UECC_ENABLE_VLI_API
- #define MG_UECC_ENABLE_VLI_API 0
- #endif
- #ifdef __cplusplus
- extern "C" {
- #endif
- #if MG_UECC_ENABLE_VLI_API
- void mg_uecc_vli_clear(mg_uecc_word_t *vli, wordcount_t num_words);
- /* Constant-time comparison to zero - secure way to compare long integers */
- /* Returns 1 if vli == 0, 0 otherwise. */
- mg_uecc_word_t mg_uecc_vli_isZero(const mg_uecc_word_t *vli,
- wordcount_t num_words);
- /* Returns nonzero if bit 'bit' of vli is set. */
- mg_uecc_word_t mg_uecc_vli_testBit(const mg_uecc_word_t *vli, bitcount_t bit);
- /* Counts the number of bits required to represent vli. */
- bitcount_t mg_uecc_vli_numBits(const mg_uecc_word_t *vli,
- const wordcount_t max_words);
- /* Sets dest = src. */
- void mg_uecc_vli_set(mg_uecc_word_t *dest, const mg_uecc_word_t *src,
- wordcount_t num_words);
- /* Constant-time comparison function - secure way to compare long integers */
- /* Returns one if left == right, zero otherwise */
- mg_uecc_word_t mg_uecc_vli_equal(const mg_uecc_word_t *left,
- const mg_uecc_word_t *right,
- wordcount_t num_words);
- /* Constant-time comparison function - secure way to compare long integers */
- /* Returns sign of left - right, in constant time. */
- cmpresult_t mg_uecc_vli_cmp(const mg_uecc_word_t *left,
- const mg_uecc_word_t *right, wordcount_t num_words);
- /* Computes vli = vli >> 1. */
- void mg_uecc_vli_rshift1(mg_uecc_word_t *vli, wordcount_t num_words);
- /* Computes result = left + right, returning carry. Can modify in place. */
- mg_uecc_word_t mg_uecc_vli_add(mg_uecc_word_t *result,
- const mg_uecc_word_t *left,
- const mg_uecc_word_t *right,
- wordcount_t num_words);
- /* Computes result = left - right, returning borrow. Can modify in place. */
- mg_uecc_word_t mg_uecc_vli_sub(mg_uecc_word_t *result,
- const mg_uecc_word_t *left,
- const mg_uecc_word_t *right,
- wordcount_t num_words);
- /* Computes result = left * right. Result must be 2 * num_words long. */
- void mg_uecc_vli_mult(mg_uecc_word_t *result, const mg_uecc_word_t *left,
- const mg_uecc_word_t *right, wordcount_t num_words);
- /* Computes result = left^2. Result must be 2 * num_words long. */
- void mg_uecc_vli_square(mg_uecc_word_t *result, const mg_uecc_word_t *left,
- wordcount_t num_words);
- /* Computes result = (left + right) % mod.
- Assumes that left < mod and right < mod, and that result does not overlap
- mod. */
- void mg_uecc_vli_modAdd(mg_uecc_word_t *result, const mg_uecc_word_t *left,
- const mg_uecc_word_t *right, const mg_uecc_word_t *mod,
- wordcount_t num_words);
- /* Computes result = (left - right) % mod.
- Assumes that left < mod and right < mod, and that result does not overlap
- mod. */
- void mg_uecc_vli_modSub(mg_uecc_word_t *result, const mg_uecc_word_t *left,
- const mg_uecc_word_t *right, const mg_uecc_word_t *mod,
- wordcount_t num_words);
- /* Computes result = product % mod, where product is 2N words long.
- Currently only designed to work for mod == curve->p or curve_n. */
- void mg_uecc_vli_mmod(mg_uecc_word_t *result, mg_uecc_word_t *product,
- const mg_uecc_word_t *mod, wordcount_t num_words);
- /* Calculates result = product (mod curve->p), where product is up to
- 2 * curve->num_words long. */
- void mg_uecc_vli_mmod_fast(mg_uecc_word_t *result, mg_uecc_word_t *product,
- MG_UECC_Curve curve);
- /* Computes result = (left * right) % mod.
- Currently only designed to work for mod == curve->p or curve_n. */
- void mg_uecc_vli_modMult(mg_uecc_word_t *result, const mg_uecc_word_t *left,
- const mg_uecc_word_t *right, const mg_uecc_word_t *mod,
- wordcount_t num_words);
- /* Computes result = (left * right) % curve->p. */
- void mg_uecc_vli_modMult_fast(mg_uecc_word_t *result,
- const mg_uecc_word_t *left,
- const mg_uecc_word_t *right, MG_UECC_Curve curve);
- /* Computes result = left^2 % mod.
- Currently only designed to work for mod == curve->p or curve_n. */
- void mg_uecc_vli_modSquare(mg_uecc_word_t *result, const mg_uecc_word_t *left,
- const mg_uecc_word_t *mod, wordcount_t num_words);
- /* Computes result = left^2 % curve->p. */
- void mg_uecc_vli_modSquare_fast(mg_uecc_word_t *result,
- const mg_uecc_word_t *left,
- MG_UECC_Curve curve);
- /* Computes result = (1 / input) % mod.*/
- void mg_uecc_vli_modInv(mg_uecc_word_t *result, const mg_uecc_word_t *input,
- const mg_uecc_word_t *mod, wordcount_t num_words);
- #if MG_UECC_SUPPORT_COMPRESSED_POINT
- /* Calculates a = sqrt(a) (mod curve->p) */
- void mg_uecc_vli_mod_sqrt(mg_uecc_word_t *a, MG_UECC_Curve curve);
- #endif
- /* Converts an integer in uECC native format to big-endian bytes. */
- void mg_uecc_vli_nativeToBytes(uint8_t *bytes, int num_bytes,
- const mg_uecc_word_t *native);
- /* Converts big-endian bytes to an integer in uECC native format. */
- void mg_uecc_vli_bytesToNative(mg_uecc_word_t *native, const uint8_t *bytes,
- int num_bytes);
- unsigned mg_uecc_curve_num_words(MG_UECC_Curve curve);
- unsigned mg_uecc_curve_num_bytes(MG_UECC_Curve curve);
- unsigned mg_uecc_curve_num_bits(MG_UECC_Curve curve);
- unsigned mg_uecc_curve_num_n_words(MG_UECC_Curve curve);
- unsigned mg_uecc_curve_num_n_bytes(MG_UECC_Curve curve);
- unsigned mg_uecc_curve_num_n_bits(MG_UECC_Curve curve);
- const mg_uecc_word_t *mg_uecc_curve_p(MG_UECC_Curve curve);
- const mg_uecc_word_t *mg_uecc_curve_n(MG_UECC_Curve curve);
- const mg_uecc_word_t *mg_uecc_curve_G(MG_UECC_Curve curve);
- const mg_uecc_word_t *mg_uecc_curve_b(MG_UECC_Curve curve);
- int mg_uecc_valid_point(const mg_uecc_word_t *point, MG_UECC_Curve curve);
- /* Multiplies a point by a scalar. Points are represented by the X coordinate
- followed by the Y coordinate in the same array, both coordinates are
- curve->num_words long. Note that scalar must be curve->num_n_words long (NOT
- curve->num_words). */
- void mg_uecc_point_mult(mg_uecc_word_t *result, const mg_uecc_word_t *point,
- const mg_uecc_word_t *scalar, MG_UECC_Curve curve);
- /* Generates a random integer in the range 0 < random < top.
- Both random and top have num_words words. */
- int mg_uecc_generate_random_int(mg_uecc_word_t *random,
- const mg_uecc_word_t *top,
- wordcount_t num_words);
- #endif /* MG_UECC_ENABLE_VLI_API */
- #ifdef __cplusplus
- } /* end of extern "C" */
- #endif
- #endif /* _UECC_VLI_H_ */
- /* Copyright 2015, Kenneth MacKay. Licensed under the BSD 2-clause license. */
- #ifndef _UECC_TYPES_H_
- #define _UECC_TYPES_H_
- #ifndef MG_UECC_PLATFORM
- #if defined(__AVR__) && __AVR__
- #define MG_UECC_PLATFORM mg_uecc_avr
- #elif defined(__thumb2__) || \
- defined(_M_ARMT) /* I think MSVC only supports Thumb-2 targets */
- #define MG_UECC_PLATFORM mg_uecc_arm_thumb2
- #elif defined(__thumb__)
- #define MG_UECC_PLATFORM mg_uecc_arm_thumb
- #elif defined(__arm__) || defined(_M_ARM)
- #define MG_UECC_PLATFORM mg_uecc_arm
- #elif defined(__aarch64__)
- #define MG_UECC_PLATFORM mg_uecc_arm64
- #elif defined(__i386__) || defined(_M_IX86) || defined(_X86_) || \
- defined(__I86__)
- #define MG_UECC_PLATFORM mg_uecc_x86
- #elif defined(__amd64__) || defined(_M_X64)
- #define MG_UECC_PLATFORM mg_uecc_x86_64
- #else
- #define MG_UECC_PLATFORM mg_uecc_arch_other
- #endif
- #endif
- #ifndef MG_UECC_ARM_USE_UMAAL
- #if (MG_UECC_PLATFORM == mg_uecc_arm) && (__ARM_ARCH >= 6)
- #define MG_UECC_ARM_USE_UMAAL 1
- #elif (MG_UECC_PLATFORM == mg_uecc_arm_thumb2) && (__ARM_ARCH >= 6) && \
- (!defined(__ARM_ARCH_7M__) || !__ARM_ARCH_7M__)
- #define MG_UECC_ARM_USE_UMAAL 1
- #else
- #define MG_UECC_ARM_USE_UMAAL 0
- #endif
- #endif
- #ifndef MG_UECC_WORD_SIZE
- #if MG_UECC_PLATFORM == mg_uecc_avr
- #define MG_UECC_WORD_SIZE 1
- #elif (MG_UECC_PLATFORM == mg_uecc_x86_64 || MG_UECC_PLATFORM == mg_uecc_arm64)
- #define MG_UECC_WORD_SIZE 8
- #else
- #define MG_UECC_WORD_SIZE 4
- #endif
- #endif
- #if (MG_UECC_WORD_SIZE != 1) && (MG_UECC_WORD_SIZE != 4) && \
- (MG_UECC_WORD_SIZE != 8)
- #error "Unsupported value for MG_UECC_WORD_SIZE"
- #endif
- #if ((MG_UECC_PLATFORM == mg_uecc_avr) && (MG_UECC_WORD_SIZE != 1))
- #pragma message("MG_UECC_WORD_SIZE must be 1 for AVR")
- #undef MG_UECC_WORD_SIZE
- #define MG_UECC_WORD_SIZE 1
- #endif
- #if ((MG_UECC_PLATFORM == mg_uecc_arm || \
- MG_UECC_PLATFORM == mg_uecc_arm_thumb || \
- MG_UECC_PLATFORM == mg_uecc_arm_thumb2) && \
- (MG_UECC_WORD_SIZE != 4))
- #pragma message("MG_UECC_WORD_SIZE must be 4 for ARM")
- #undef MG_UECC_WORD_SIZE
- #define MG_UECC_WORD_SIZE 4
- #endif
- typedef int8_t wordcount_t;
- typedef int16_t bitcount_t;
- typedef int8_t cmpresult_t;
- #if (MG_UECC_WORD_SIZE == 1)
- typedef uint8_t mg_uecc_word_t;
- typedef uint16_t mg_uecc_dword_t;
- #define HIGH_BIT_SET 0x80
- #define MG_UECC_WORD_BITS 8
- #define MG_UECC_WORD_BITS_SHIFT 3
- #define MG_UECC_WORD_BITS_MASK 0x07
- #elif (MG_UECC_WORD_SIZE == 4)
- typedef uint32_t mg_uecc_word_t;
- typedef uint64_t mg_uecc_dword_t;
- #define HIGH_BIT_SET 0x80000000
- #define MG_UECC_WORD_BITS 32
- #define MG_UECC_WORD_BITS_SHIFT 5
- #define MG_UECC_WORD_BITS_MASK 0x01F
- #elif (MG_UECC_WORD_SIZE == 8)
- typedef uint64_t mg_uecc_word_t;
- #define HIGH_BIT_SET 0x8000000000000000U
- #define MG_UECC_WORD_BITS 64
- #define MG_UECC_WORD_BITS_SHIFT 6
- #define MG_UECC_WORD_BITS_MASK 0x03F
- #endif /* MG_UECC_WORD_SIZE */
- #endif /* _UECC_TYPES_H_ */
- // End of uecc BSD-2
- struct mg_connection;
- typedef void (*mg_event_handler_t)(struct mg_connection *, int ev,
- void *ev_data);
- void mg_call(struct mg_connection *c, int ev, void *ev_data);
- void mg_error(struct mg_connection *c, const char *fmt, ...);
- enum {
- MG_EV_ERROR, // Error char *error_message
- MG_EV_OPEN, // Connection created NULL
- MG_EV_POLL, // mg_mgr_poll iteration uint64_t *uptime_millis
- MG_EV_RESOLVE, // Host name is resolved NULL
- MG_EV_CONNECT, // Connection established NULL
- MG_EV_ACCEPT, // Connection accepted NULL
- MG_EV_TLS_HS, // TLS handshake succeeded NULL
- MG_EV_READ, // Data received from socket long *bytes_read
- MG_EV_WRITE, // Data written to socket long *bytes_written
- MG_EV_CLOSE, // Connection closed NULL
- MG_EV_HTTP_HDRS, // HTTP headers struct mg_http_message *
- MG_EV_HTTP_MSG, // Full HTTP request/response struct mg_http_message *
- MG_EV_WS_OPEN, // Websocket handshake done struct mg_http_message *
- MG_EV_WS_MSG, // Websocket msg, text or bin struct mg_ws_message *
- MG_EV_WS_CTL, // Websocket control msg struct mg_ws_message *
- MG_EV_MQTT_CMD, // MQTT low-level command struct mg_mqtt_message *
- MG_EV_MQTT_MSG, // MQTT PUBLISH received struct mg_mqtt_message *
- MG_EV_MQTT_OPEN, // MQTT CONNACK received int *connack_status_code
- MG_EV_SNTP_TIME, // SNTP time received uint64_t *epoch_millis
- MG_EV_WAKEUP, // mg_wakeup() data received struct mg_str *data
- MG_EV_USER // Starting ID for user events
- };
- struct mg_dns {
- const char *url; // DNS server URL
- struct mg_connection *c; // DNS server connection
- };
- struct mg_addr {
- uint8_t ip[16]; // Holds IPv4 or IPv6 address, in network byte order
- uint16_t port; // TCP or UDP port in network byte order
- uint8_t scope_id; // IPv6 scope ID
- bool is_ip6; // True when address is IPv6 address
- };
- struct mg_mgr {
- struct mg_connection *conns; // List of active connections
- struct mg_dns dns4; // DNS for IPv4
- struct mg_dns dns6; // DNS for IPv6
- int dnstimeout; // DNS resolve timeout in milliseconds
- bool use_dns6; // Use DNS6 server by default, see #1532
- unsigned long nextid; // Next connection ID
- unsigned long timerid; // Next timer ID
- void *userdata; // Arbitrary user data pointer
- void *tls_ctx; // TLS context shared by all TLS sessions
- uint16_t mqtt_id; // MQTT IDs for pub/sub
- void *active_dns_requests; // DNS requests in progress
- struct mg_timer *timers; // Active timers
- int epoll_fd; // Used when MG_EPOLL_ENABLE=1
- void *priv; // Used by the MIP stack
- size_t extraconnsize; // Used by the MIP stack
- MG_SOCKET_TYPE pipe; // Socketpair end for mg_wakeup()
- #if MG_ENABLE_FREERTOS_TCP
- SocketSet_t ss; // NOTE(lsm): referenced from socket struct
- #endif
- };
- struct mg_connection {
- struct mg_connection *next; // Linkage in struct mg_mgr :: connections
- struct mg_mgr *mgr; // Our container
- struct mg_addr loc; // Local address
- struct mg_addr rem; // Remote address
- void *fd; // Connected socket, or LWIP data
- unsigned long id; // Auto-incrementing unique connection ID
- struct mg_iobuf recv; // Incoming data
- struct mg_iobuf send; // Outgoing data
- struct mg_iobuf prof; // Profile data enabled by MG_ENABLE_PROFILE
- struct mg_iobuf rtls; // TLS only. Incoming encrypted data
- mg_event_handler_t fn; // User-specified event handler function
- void *fn_data; // User-specified function parameter
- mg_event_handler_t pfn; // Protocol-specific handler function
- void *pfn_data; // Protocol-specific function parameter
- char data[MG_DATA_SIZE]; // Arbitrary connection data
- void *tls; // TLS specific data
- unsigned is_listening : 1; // Listening connection
- unsigned is_client : 1; // Outbound (client) connection
- unsigned is_accepted : 1; // Accepted (server) connection
- unsigned is_resolving : 1; // Non-blocking DNS resolution is in progress
- unsigned is_arplooking : 1; // Non-blocking ARP resolution is in progress
- unsigned is_connecting : 1; // Non-blocking connect is in progress
- unsigned is_tls : 1; // TLS-enabled connection
- unsigned is_tls_hs : 1; // TLS handshake is in progress
- unsigned is_udp : 1; // UDP connection
- unsigned is_websocket : 1; // WebSocket connection
- unsigned is_mqtt5 : 1; // For MQTT connection, v5 indicator
- unsigned is_hexdumping : 1; // Hexdump in/out traffic
- unsigned is_draining : 1; // Send remaining data, then close and free
- unsigned is_closing : 1; // Close and free the connection immediately
- unsigned is_full : 1; // Stop reads, until cleared
- unsigned is_resp : 1; // Response is still being generated
- unsigned is_readable : 1; // Connection is ready to read
- unsigned is_writable : 1; // Connection is ready to write
- };
- void mg_mgr_poll(struct mg_mgr *, int ms);
- void mg_mgr_init(struct mg_mgr *);
- void mg_mgr_free(struct mg_mgr *);
- struct mg_connection *mg_listen(struct mg_mgr *, const char *url,
- mg_event_handler_t fn, void *fn_data);
- struct mg_connection *mg_connect(struct mg_mgr *, const char *url,
- mg_event_handler_t fn, void *fn_data);
- struct mg_connection *mg_wrapfd(struct mg_mgr *mgr, int fd,
- mg_event_handler_t fn, void *fn_data);
- void mg_connect_resolved(struct mg_connection *);
- bool mg_send(struct mg_connection *, const void *, size_t);
- size_t mg_printf(struct mg_connection *, const char *fmt, ...);
- size_t mg_vprintf(struct mg_connection *, const char *fmt, va_list *ap);
- bool mg_aton(struct mg_str str, struct mg_addr *addr);
- // These functions are used to integrate with custom network stacks
- struct mg_connection *mg_alloc_conn(struct mg_mgr *);
- void mg_close_conn(struct mg_connection *c);
- bool mg_open_listener(struct mg_connection *c, const char *url);
- // Utility functions
- bool mg_wakeup(struct mg_mgr *, unsigned long id, const void *buf, size_t len);
- bool mg_wakeup_init(struct mg_mgr *);
- struct mg_timer *mg_timer_add(struct mg_mgr *mgr, uint64_t milliseconds,
- unsigned flags, void (*fn)(void *), void *arg);
- struct mg_http_header {
- struct mg_str name; // Header name
- struct mg_str value; // Header value
- };
- struct mg_http_message {
- struct mg_str method, uri, query, proto; // Request/response line
- struct mg_http_header headers[MG_MAX_HTTP_HEADERS]; // Headers
- struct mg_str body; // Body
- struct mg_str head; // Request + headers
- struct mg_str message; // Request + headers + body
- };
- // Parameter for mg_http_serve_dir()
- struct mg_http_serve_opts {
- const char *root_dir; // Web root directory, must be non-NULL
- const char *ssi_pattern; // SSI file name pattern, e.g. #.shtml
- const char *extra_headers; // Extra HTTP headers to add in responses
- const char *mime_types; // Extra mime types, ext1=type1,ext2=type2,..
- const char *page404; // Path to the 404 page, or NULL by default
- struct mg_fs *fs; // Filesystem implementation. Use NULL for POSIX
- };
- // Parameter for mg_http_next_multipart
- struct mg_http_part {
- struct mg_str name; // Form field name
- struct mg_str filename; // Filename for file uploads
- struct mg_str body; // Part contents
- };
- int mg_http_parse(const char *s, size_t len, struct mg_http_message *);
- int mg_http_get_request_len(const unsigned char *buf, size_t buf_len);
- void mg_http_printf_chunk(struct mg_connection *cnn, const char *fmt, ...);
- void mg_http_write_chunk(struct mg_connection *c, const char *buf, size_t len);
- void mg_http_delete_chunk(struct mg_connection *c, struct mg_http_message *hm);
- struct mg_connection *mg_http_listen(struct mg_mgr *, const char *url,
- mg_event_handler_t fn, void *fn_data);
- struct mg_connection *mg_http_connect(struct mg_mgr *, const char *url,
- mg_event_handler_t fn, void *fn_data);
- void mg_http_serve_dir(struct mg_connection *, struct mg_http_message *hm,
- const struct mg_http_serve_opts *);
- void mg_http_serve_file(struct mg_connection *, struct mg_http_message *hm,
- const char *path, const struct mg_http_serve_opts *);
- void mg_http_serve_file2(struct mg_connection *, struct mg_http_message *hm,
- const char *path, const struct mg_http_serve_opts *);
- void mg_http_reply(struct mg_connection *, int status_code, const char *headers,
- const char *body_fmt, ...);
- int mg_http_reply2(struct mg_connection *c, int code, const char *headers,
- const char *body_fmt, ...);
- struct mg_str *mg_http_get_header(struct mg_http_message *, const char *name);
- struct mg_str mg_http_var(struct mg_str buf, struct mg_str name);
- int mg_http_get_var(const struct mg_str *, const char *name, char *, size_t);
- int mg_url_decode(const char *s, size_t n, char *to, size_t to_len, int form);
- size_t mg_url_encode(const char *s, size_t n, char *buf, size_t len);
- void mg_http_creds(struct mg_http_message *, char *, size_t, char *, size_t);
- long mg_http_upload(struct mg_connection *c, struct mg_http_message *hm,
- struct mg_fs *fs, const char *dir, size_t max_size);
- void mg_http_bauth(struct mg_connection *, const char *user, const char *pass);
- struct mg_str mg_http_get_header_var(struct mg_str s, struct mg_str v);
- size_t mg_http_next_multipart(struct mg_str, size_t, struct mg_http_part *);
- int mg_http_status(const struct mg_http_message *hm);
- void mg_hello(const char *url);
- void mg_http_serve_ssi(struct mg_connection *c, const char *root,
- const char *fullpath);
- #define MG_TLS_NONE 0 // No TLS support
- #define MG_TLS_MBED 1 // mbedTLS
- #define MG_TLS_OPENSSL 2 // OpenSSL
- #define MG_TLS_WOLFSSL 5 // WolfSSL (based on OpenSSL)
- #define MG_TLS_BUILTIN 3 // Built-in
- #define MG_TLS_CUSTOM 4 // Custom implementation
- #ifndef MG_TLS
- #define MG_TLS MG_TLS_OPENSSL
- #endif
- struct mg_tls_opts {
- struct mg_str ca; // PEM or DER
- struct mg_str cert; // PEM or DER
- struct mg_str key; // PEM or DER
- struct mg_str name; // If not empty, enable host name verification
- int skip_verification; // Skip certificate and host name verification
- };
- void mg_tls_init(struct mg_connection *, const struct mg_tls_opts *opts);
- void mg_tls_free(struct mg_connection *);
- long mg_tls_send(struct mg_connection *, const void *buf, size_t len);
- long mg_tls_recv(struct mg_connection *, void *buf, size_t len);
- size_t mg_tls_pending(struct mg_connection *);
- void mg_tls_handshake(struct mg_connection *);
- // Private
- void mg_tls_ctx_init(struct mg_mgr *);
- void mg_tls_ctx_free(struct mg_mgr *);
- // Low-level IO primives used by TLS layer
- enum { MG_IO_ERR = -1, MG_IO_WAIT = -2, MG_IO_RESET = -3 };
- long mg_io_send(struct mg_connection *c, const void *buf, size_t len);
- long mg_io_recv(struct mg_connection *c, void *buf, size_t len);
- #if MG_TLS == MG_TLS_MBED
- #include <mbedtls/debug.h>
- #include <mbedtls/net_sockets.h>
- #include <mbedtls/ssl.h>
- #include <mbedtls/ssl_ticket.h>
- struct mg_tls_ctx {
- int dummy;
- #ifdef MBEDTLS_SSL_SESSION_TICKETS
- mbedtls_ssl_ticket_context tickets;
- #endif
- };
- struct mg_tls {
- mbedtls_x509_crt ca; // Parsed CA certificate
- mbedtls_x509_crt cert; // Parsed certificate
- mbedtls_pk_context pk; // Private key context
- mbedtls_ssl_context ssl; // SSL/TLS context
- mbedtls_ssl_config conf; // SSL-TLS config
- #ifdef MBEDTLS_SSL_SESSION_TICKETS
- mbedtls_ssl_ticket_context ticket; // Session tickets context
- #endif
- };
- #endif
- #if MG_TLS == MG_TLS_OPENSSL || MG_TLS == MG_TLS_WOLFSSL
- #include <openssl/err.h>
- #include <openssl/ssl.h>
- struct mg_tls {
- BIO_METHOD *bm;
- SSL_CTX *ctx;
- SSL *ssl;
- };
- #endif
- #define WEBSOCKET_OP_CONTINUE 0
- #define WEBSOCKET_OP_TEXT 1
- #define WEBSOCKET_OP_BINARY 2
- #define WEBSOCKET_OP_CLOSE 8
- #define WEBSOCKET_OP_PING 9
- #define WEBSOCKET_OP_PONG 10
- struct mg_ws_message {
- struct mg_str data; // Websocket message data
- uint8_t flags; // Websocket message flags
- };
- struct mg_connection *mg_ws_connect(struct mg_mgr *, const char *url,
- mg_event_handler_t fn, void *fn_data,
- const char *fmt, ...);
- void mg_ws_upgrade(struct mg_connection *, struct mg_http_message *,
- const char *fmt, ...);
- size_t mg_ws_send(struct mg_connection *, const void *buf, size_t len, int op);
- size_t mg_ws_send2(struct mg_connection *, const void *buf, size_t len, int op, int max_tlen);
- size_t mg_ws_wrap(struct mg_connection *, size_t len, int op);
- size_t mg_ws_printf(struct mg_connection *c, int op, const char *fmt, ...);
- size_t mg_ws_vprintf(struct mg_connection *c, int op, const char *fmt,
- va_list *);
- struct mg_connection *mg_sntp_connect(struct mg_mgr *mgr, const char *url,
- mg_event_handler_t fn, void *fn_data);
- void mg_sntp_request(struct mg_connection *c);
- int64_t mg_sntp_parse(const unsigned char *buf, size_t len);
- #define MQTT_CMD_CONNECT 1
- #define MQTT_CMD_CONNACK 2
- #define MQTT_CMD_PUBLISH 3
- #define MQTT_CMD_PUBACK 4
- #define MQTT_CMD_PUBREC 5
- #define MQTT_CMD_PUBREL 6
- #define MQTT_CMD_PUBCOMP 7
- #define MQTT_CMD_SUBSCRIBE 8
- #define MQTT_CMD_SUBACK 9
- #define MQTT_CMD_UNSUBSCRIBE 10
- #define MQTT_CMD_UNSUBACK 11
- #define MQTT_CMD_PINGREQ 12
- #define MQTT_CMD_PINGRESP 13
- #define MQTT_CMD_DISCONNECT 14
- #define MQTT_CMD_AUTH 15
- #define MQTT_PROP_PAYLOAD_FORMAT_INDICATOR 0x01
- #define MQTT_PROP_MESSAGE_EXPIRY_INTERVAL 0x02
- #define MQTT_PROP_CONTENT_TYPE 0x03
- #define MQTT_PROP_RESPONSE_TOPIC 0x08
- #define MQTT_PROP_CORRELATION_DATA 0x09
- #define MQTT_PROP_SUBSCRIPTION_IDENTIFIER 0x0B
- #define MQTT_PROP_SESSION_EXPIRY_INTERVAL 0x11
- #define MQTT_PROP_ASSIGNED_CLIENT_IDENTIFIER 0x12
- #define MQTT_PROP_SERVER_KEEP_ALIVE 0x13
- #define MQTT_PROP_AUTHENTICATION_METHOD 0x15
- #define MQTT_PROP_AUTHENTICATION_DATA 0x16
- #define MQTT_PROP_REQUEST_PROBLEM_INFORMATION 0x17
- #define MQTT_PROP_WILL_DELAY_INTERVAL 0x18
- #define MQTT_PROP_REQUEST_RESPONSE_INFORMATION 0x19
- #define MQTT_PROP_RESPONSE_INFORMATION 0x1A
- #define MQTT_PROP_SERVER_REFERENCE 0x1C
- #define MQTT_PROP_REASON_STRING 0x1F
- #define MQTT_PROP_RECEIVE_MAXIMUM 0x21
- #define MQTT_PROP_TOPIC_ALIAS_MAXIMUM 0x22
- #define MQTT_PROP_TOPIC_ALIAS 0x23
- #define MQTT_PROP_MAXIMUM_QOS 0x24
- #define MQTT_PROP_RETAIN_AVAILABLE 0x25
- #define MQTT_PROP_USER_PROPERTY 0x26
- #define MQTT_PROP_MAXIMUM_PACKET_SIZE 0x27
- #define MQTT_PROP_WILDCARD_SUBSCRIPTION_AVAILABLE 0x28
- #define MQTT_PROP_SUBSCRIPTION_IDENTIFIER_AVAILABLE 0x29
- #define MQTT_PROP_SHARED_SUBSCRIPTION_AVAILABLE 0x2A
- enum {
- MQTT_PROP_TYPE_BYTE,
- MQTT_PROP_TYPE_STRING,
- MQTT_PROP_TYPE_STRING_PAIR,
- MQTT_PROP_TYPE_BINARY_DATA,
- MQTT_PROP_TYPE_VARIABLE_INT,
- MQTT_PROP_TYPE_INT,
- MQTT_PROP_TYPE_SHORT
- };
- enum { MQTT_OK, MQTT_INCOMPLETE, MQTT_MALFORMED };
- struct mg_mqtt_prop {
- uint8_t id; // Enumerated at MQTT5 Reference
- uint32_t iv; // Integer value for 8-, 16-, 32-bit integers types
- struct mg_str key; // Non-NULL only for user property type
- struct mg_str val; // Non-NULL only for UTF-8 types and user properties
- };
- struct mg_mqtt_opts {
- struct mg_str user; // Username, can be empty
- struct mg_str pass; // Password, can be empty
- struct mg_str client_id; // Client ID
- struct mg_str topic; // message/subscription topic
- struct mg_str message; // message content
- uint8_t qos; // message quality of service
- uint8_t version; // Can be 4 (3.1.1), or 5. If 0, assume 4
- uint16_t keepalive; // Keep-alive timer in seconds
- uint16_t retransmit_id; // For PUBLISH, init to 0
- bool retain; // Retain flag
- bool clean; // Clean session flag
- struct mg_mqtt_prop *props; // MQTT5 props array
- size_t num_props; // number of props
- struct mg_mqtt_prop *will_props; // Valid only for CONNECT packet (MQTT5)
- size_t num_will_props; // Number of will props
- };
- struct mg_mqtt_message {
- struct mg_str topic; // Parsed topic for PUBLISH
- struct mg_str data; // Parsed message for PUBLISH
- struct mg_str dgram; // Whole MQTT packet, including headers
- uint16_t id; // For PUBACK, PUBREC, PUBREL, PUBCOMP, SUBACK, PUBLISH
- uint8_t cmd; // MQTT command, one of MQTT_CMD_*
- uint8_t qos; // Quality of service
- uint8_t ack; // CONNACK return code, 0 = success
- size_t props_start; // Offset to the start of the properties (MQTT5)
- size_t props_size; // Length of the properties
- };
- struct mg_connection *mg_mqtt_connect(struct mg_mgr *, const char *url,
- const struct mg_mqtt_opts *opts,
- mg_event_handler_t fn, void *fn_data);
- struct mg_connection *mg_mqtt_listen(struct mg_mgr *mgr, const char *url,
- mg_event_handler_t fn, void *fn_data);
- void mg_mqtt_login(struct mg_connection *c, const struct mg_mqtt_opts *opts);
- uint16_t mg_mqtt_pub(struct mg_connection *c, const struct mg_mqtt_opts *opts);
- void mg_mqtt_sub(struct mg_connection *, const struct mg_mqtt_opts *opts);
- int mg_mqtt_parse(const uint8_t *, size_t, uint8_t, struct mg_mqtt_message *);
- void mg_mqtt_send_header(struct mg_connection *, uint8_t cmd, uint8_t flags,
- uint32_t len);
- void mg_mqtt_ping(struct mg_connection *);
- void mg_mqtt_pong(struct mg_connection *);
- void mg_mqtt_disconnect(struct mg_connection *, const struct mg_mqtt_opts *);
- size_t mg_mqtt_next_prop(struct mg_mqtt_message *, struct mg_mqtt_prop *,
- size_t ofs);
- // Mongoose sends DNS queries that contain only one question:
- // either A (IPv4) or AAAA (IPv6) address lookup.
- // Therefore, we expect zero or one answer.
- // If `resolved` is true, then `addr` contains resolved IPv4 or IPV6 address.
- struct mg_dns_message {
- uint16_t txnid; // Transaction ID
- bool resolved; // Resolve successful, addr is set
- struct mg_addr addr; // Resolved address
- char name[256]; // Host name
- };
- struct mg_dns_header {
- uint16_t txnid; // Transaction ID
- uint16_t flags;
- uint16_t num_questions;
- uint16_t num_answers;
- uint16_t num_authority_prs;
- uint16_t num_other_prs;
- };
- // DNS resource record
- struct mg_dns_rr {
- uint16_t nlen; // Name or pointer length
- uint16_t atype; // Address type
- uint16_t aclass; // Address class
- uint16_t alen; // Address length
- };
- void mg_resolve(struct mg_connection *, const char *url);
- void mg_resolve_cancel(struct mg_connection *);
- bool mg_dns_parse(const uint8_t *buf, size_t len, struct mg_dns_message *);
- size_t mg_dns_parse_rr(const uint8_t *buf, size_t len, size_t ofs,
- bool is_question, struct mg_dns_rr *);
- #ifndef MG_JSON_MAX_DEPTH
- #define MG_JSON_MAX_DEPTH 30
- #endif
- // Error return values - negative. Successful returns are >= 0
- enum { MG_JSON_TOO_DEEP = -1, MG_JSON_INVALID = -2, MG_JSON_NOT_FOUND = -3 };
- int mg_json_get(struct mg_str json, const char *path, int *toklen);
- struct mg_str mg_json_get_tok(struct mg_str json, const char *path);
- bool mg_json_get_num(struct mg_str json, const char *path, double *v);
- bool mg_json_get_bool(struct mg_str json, const char *path, bool *v);
- long mg_json_get_long(struct mg_str json, const char *path, long dflt);
- char *mg_json_get_str(struct mg_str json, const char *path);
- char *mg_json_get_hex(struct mg_str json, const char *path, int *len);
- char *mg_json_get_b64(struct mg_str json, const char *path, int *len);
- bool mg_json_unescape(struct mg_str str, char *buf, size_t len);
- size_t mg_json_next(struct mg_str obj, size_t ofs, struct mg_str *key,
- struct mg_str *val);
- // JSON-RPC request descriptor
- struct mg_rpc_req {
- struct mg_rpc **head; // RPC handlers list head
- struct mg_rpc *rpc; // RPC handler being called
- mg_pfn_t pfn; // Response printing function
- void *pfn_data; // Response printing function data
- void *req_data; // Arbitrary request data
- struct mg_str frame; // Request, e.g. {"id":1,"method":"add","params":[1,2]}
- };
- // JSON-RPC method handler
- struct mg_rpc {
- struct mg_rpc *next; // Next in list
- struct mg_str method; // Method pattern
- void (*fn)(struct mg_rpc_req *); // Handler function
- void *fn_data; // Handler function argument
- };
- void mg_rpc_add(struct mg_rpc **head, struct mg_str method_pattern,
- void (*handler)(struct mg_rpc_req *), void *handler_data);
- void mg_rpc_del(struct mg_rpc **head, void (*handler)(struct mg_rpc_req *));
- void mg_rpc_process(struct mg_rpc_req *);
- // Helper functions to print result or error frame
- void mg_rpc_ok(struct mg_rpc_req *, const char *fmt, ...);
- void mg_rpc_vok(struct mg_rpc_req *, const char *fmt, va_list *ap);
- void mg_rpc_err(struct mg_rpc_req *, int code, const char *fmt, ...);
- void mg_rpc_verr(struct mg_rpc_req *, int code, const char *fmt, va_list *);
- void mg_rpc_list(struct mg_rpc_req *r);
- // Copyright (c) 2023 Cesanta Software Limited
- // All rights reserved
- #define MG_OTA_NONE 0 // No OTA support
- #define MG_OTA_FLASH 1 // OTA via an internal flash
- #define MG_OTA_ESP32 2 // ESP32 OTA implementation
- #define MG_OTA_CUSTOM 100 // Custom implementation
- #ifndef MG_OTA
- #define MG_OTA MG_OTA_NONE
- #endif
- #if defined(__GNUC__) && !defined(__APPLE__)
- #define MG_IRAM __attribute__((section(".iram")))
- #else
- #define MG_IRAM
- #endif
- // Firmware update API
- bool mg_ota_begin(size_t new_firmware_size); // Start writing
- bool mg_ota_write(const void *buf, size_t len); // Write chunk, aligned to 1k
- bool mg_ota_end(void); // Stop writing
- enum {
- MG_OTA_UNAVAILABLE = 0, // No OTA information is present
- MG_OTA_FIRST_BOOT = 1, // Device booting the first time after the OTA
- MG_OTA_UNCOMMITTED = 2, // Ditto, but marking us for the rollback
- MG_OTA_COMMITTED = 3 // The firmware is good
- };
- enum { MG_FIRMWARE_CURRENT = 0, MG_FIRMWARE_PREVIOUS = 1 };
- int mg_ota_status(int firmware); // Return firmware status MG_OTA_*
- uint32_t mg_ota_crc32(int firmware); // Return firmware checksum
- uint32_t mg_ota_timestamp(int firmware); // Firmware timestamp, UNIX UTC epoch
- size_t mg_ota_size(int firmware); // Firmware size
- bool mg_ota_commit(void); // Commit current firmware
- bool mg_ota_rollback(void); // Rollback to the previous firmware
- MG_IRAM void mg_ota_boot(void); // Bootloader function
- // Copyright (c) 2023 Cesanta Software Limited
- // All rights reserved
- #define MG_DEVICE_NONE 0 // Dummy system
- #define MG_DEVICE_STM32H5 1 // STM32 H5
- #define MG_DEVICE_STM32H7 2 // STM32 H7
- #define MG_DEVICE_CH32V307 100 // WCH CH32V307
- #define MG_DEVICE_U2A 200 // Renesas U2A16, U2A8, U2A6
- #define MG_DEVICE_RT1020 300 // IMXRT1020
- #define MG_DEVICE_RT1060 301 // IMXRT1060
- #define MG_DEVICE_CUSTOM 1000 // Custom implementation
- #ifndef MG_DEVICE
- #define MG_DEVICE MG_DEVICE_NONE
- #endif
- // Flash information
- void *mg_flash_start(void); // Return flash start address
- size_t mg_flash_size(void); // Return flash size
- size_t mg_flash_sector_size(void); // Return flash sector size
- size_t mg_flash_write_align(void); // Return flash write align, minimum 4
- int mg_flash_bank(void); // 0: not dual bank, 1: bank1, 2: bank2
- // Write, erase, swap bank
- bool mg_flash_write(void *addr, const void *buf, size_t len);
- bool mg_flash_erase(void *sector);
- bool mg_flash_swap_bank(void);
- // Convenience functions to store data on a flash sector with wear levelling
- // If `sector` is NULL, then the last sector of flash is used
- bool mg_flash_load(void *sector, uint32_t key, void *buf, size_t len);
- bool mg_flash_save(void *sector, uint32_t key, const void *buf, size_t len);
- void mg_device_reset(void); // Reboot device immediately
- #if defined(MG_ENABLE_TCPIP) && MG_ENABLE_TCPIP
- struct mg_tcpip_if; // Mongoose TCP/IP network interface
- struct mg_tcpip_driver {
- bool (*init)(struct mg_tcpip_if *); // Init driver
- size_t (*tx)(const void *, size_t, struct mg_tcpip_if *); // Transmit frame
- size_t (*rx)(void *buf, size_t len, struct mg_tcpip_if *); // Receive frame
- bool (*up)(struct mg_tcpip_if *); // Up/down status
- };
- // Network interface
- struct mg_tcpip_if {
- uint8_t mac[6]; // MAC address. Must be set to a valid MAC
- uint32_t ip, mask, gw; // IP address, mask, default gateway
- struct mg_str tx; // Output (TX) buffer
- bool enable_dhcp_client; // Enable DCHP client
- bool enable_dhcp_server; // Enable DCHP server
- bool enable_get_gateway; // DCHP server sets client as gateway
- bool enable_crc32_check; // Do a CRC check on RX frames and strip it
- bool enable_mac_check; // Do a MAC check on RX frames
- struct mg_tcpip_driver *driver; // Low level driver
- void *driver_data; // Driver-specific data
- struct mg_mgr *mgr; // Mongoose event manager
- struct mg_queue recv_queue; // Receive queue
- uint16_t mtu; // Interface MTU
- #define MG_TCPIP_MTU_DEFAULT 1500
- // Internal state, user can use it but should not change it
- uint8_t gwmac[6]; // Router's MAC
- uint64_t now; // Current time
- uint64_t timer_1000ms; // 1000 ms timer: for DHCP and link state
- uint64_t lease_expire; // Lease expiration time, in ms
- uint16_t eport; // Next ephemeral port
- volatile uint32_t ndrop; // Number of received, but dropped frames
- volatile uint32_t nrecv; // Number of received frames
- volatile uint32_t nsent; // Number of transmitted frames
- volatile uint32_t nerr; // Number of driver errors
- uint8_t state; // Current state
- #define MG_TCPIP_STATE_DOWN 0 // Interface is down
- #define MG_TCPIP_STATE_UP 1 // Interface is up
- #define MG_TCPIP_STATE_REQ 2 // Interface is up and has requested an IP
- #define MG_TCPIP_STATE_READY 3 // Interface is up and has an IP assigned
- };
- void mg_tcpip_init(struct mg_mgr *, struct mg_tcpip_if *);
- void mg_tcpip_free(struct mg_tcpip_if *);
- void mg_tcpip_qwrite(void *buf, size_t len, struct mg_tcpip_if *ifp);
- extern struct mg_tcpip_driver mg_tcpip_driver_stm32f;
- extern struct mg_tcpip_driver mg_tcpip_driver_w5500;
- extern struct mg_tcpip_driver mg_tcpip_driver_tm4c;
- extern struct mg_tcpip_driver mg_tcpip_driver_stm32h;
- extern struct mg_tcpip_driver mg_tcpip_driver_imxrt;
- extern struct mg_tcpip_driver mg_tcpip_driver_same54;
- extern struct mg_tcpip_driver mg_tcpip_driver_cmsis;
- extern struct mg_tcpip_driver mg_tcpip_driver_ra;
- extern struct mg_tcpip_driver mg_tcpip_driver_xmc;
- extern struct mg_tcpip_driver mg_tcpip_driver_xmc7;
- // Drivers that require SPI, can use this SPI abstraction
- struct mg_tcpip_spi {
- void *spi; // Opaque SPI bus descriptor
- void (*begin)(void *); // SPI begin: slave select low
- void (*end)(void *); // SPI end: slave select high
- uint8_t (*txn)(void *, uint8_t); // SPI transaction: write 1 byte, read reply
- };
- #endif
- // Macros to record timestamped events that happens with a connection.
- // They are saved into a c->prof IO buffer, each event is a name and a 32-bit
- // timestamp in milliseconds since connection init time.
- //
- // Test (run in two separate terminals):
- // make -C examples/http-server/ CFLAGS_EXTRA=-DMG_ENABLE_PROFILE=1
- // curl localhost:8000
- // Output:
- // 1ea1f1e7 2 net.c:150:mg_close_conn 3 profile:
- // 1ea1f1e8 2 net.c:150:mg_close_conn 1ea1f1e6 init
- // 1ea1f1e8 2 net.c:150:mg_close_conn 0 EV_OPEN
- // 1ea1f1e8 2 net.c:150:mg_close_conn 0 EV_ACCEPT
- // 1ea1f1e8 2 net.c:150:mg_close_conn 0 EV_READ
- // 1ea1f1e8 2 net.c:150:mg_close_conn 0 EV_HTTP_MSG
- // 1ea1f1e8 2 net.c:150:mg_close_conn 0 EV_WRITE
- // 1ea1f1e8 2 net.c:150:mg_close_conn 1 EV_CLOSE
- //
- // Usage:
- // Enable profiling by setting MG_ENABLE_PROFILE=1
- // Invoke MG_PROF_ADD(c, "MY_EVENT_1") in the places you'd like to measure
- #if MG_ENABLE_PROFILE
- struct mg_profitem {
- const char *name; // Event name
- uint32_t timestamp; // Milliseconds since connection creation (MG_EV_OPEN)
- };
- #define MG_PROFILE_ALLOC_GRANULARITY 256 // Can save 32 items wih to realloc
- // Adding a profile item to the c->prof. Must be as fast as possible.
- // Reallocation of the c->prof iobuf is not desirable here, that's why we
- // pre-allocate c->prof with MG_PROFILE_ALLOC_GRANULARITY.
- // This macro just inits and copies 8 bytes, and calls mg_millis(),
- // which should be fast enough.
- #define MG_PROF_ADD(c, name_) \
- do { \
- struct mg_iobuf *io = &c->prof; \
- uint32_t inittime = ((struct mg_profitem *) io->buf)->timestamp; \
- struct mg_profitem item = {name_, (uint32_t) mg_millis() - inittime}; \
- mg_iobuf_add(io, io->len, &item, sizeof(item)); \
- } while (0)
- // Initialising profile for a new connection. Not time sensitive
- #define MG_PROF_INIT(c) \
- do { \
- struct mg_profitem first = {"init", (uint32_t) mg_millis()}; \
- mg_iobuf_init(&(c)->prof, 0, MG_PROFILE_ALLOC_GRANULARITY); \
- mg_iobuf_add(&c->prof, c->prof.len, &first, sizeof(first)); \
- } while (0)
- #define MG_PROF_FREE(c) mg_iobuf_free(&(c)->prof)
- // Dumping the profile. Not time sensitive
- #define MG_PROF_DUMP(c) \
- do { \
- struct mg_iobuf *io = &c->prof; \
- struct mg_profitem *p = (struct mg_profitem *) io->buf; \
- struct mg_profitem *e = &p[io->len / sizeof(*p)]; \
- MG_INFO(("%lu profile:", c->id)); \
- while (p < e) { \
- MG_INFO(("%5lx %s", (unsigned long) p->timestamp, p->name)); \
- p++; \
- } \
- } while (0)
- #else
- #define MG_PROF_INIT(c)
- #define MG_PROF_FREE(c)
- #define MG_PROF_ADD(c, name)
- #define MG_PROF_DUMP(c)
- #endif
- #if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_CMSIS) && MG_ENABLE_DRIVER_CMSIS
- #include "Driver_ETH_MAC.h" // keep this include
- #include "Driver_ETH_PHY.h" // keep this include
- #endif
- #if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_IMXRT) && MG_ENABLE_DRIVER_IMXRT
- struct mg_tcpip_driver_imxrt_data {
- // MDC clock divider. MDC clock is derived from IPS Bus clock (ipg_clk),
- // must not exceed 2.5MHz. Configuration for clock range 2.36~2.50 MHz
- // 37.5.1.8.2, Table 37-46 : f = ipg_clk / (2(mdc_cr + 1))
- // ipg_clk mdc_cr VALUE
- // --------------------------
- // -1 <-- TODO() tell driver to guess the value
- // 25 MHz 4
- // 33 MHz 6
- // 40 MHz 7
- // 50 MHz 9
- // 66 MHz 13
- int mdc_cr; // Valid values: -1 to 63
- uint8_t phy_addr; // PHY address
- };
- #ifndef MG_TCPIP_PHY_ADDR
- #define MG_TCPIP_PHY_ADDR 2
- #endif
- #ifndef MG_DRIVER_MDC_CR
- #define MG_DRIVER_MDC_CR 24
- #endif
- #define MG_TCPIP_DRIVER_INIT(mgr) \
- do { \
- static struct mg_tcpip_driver_imxrt_data driver_data_; \
- static struct mg_tcpip_if mif_; \
- driver_data_.mdc_cr = MG_DRIVER_MDC_CR; \
- driver_data_.phy_addr = MG_TCPIP_PHY_ADDR; \
- mif_.ip = MG_TCPIP_IP; \
- mif_.mask = MG_TCPIP_MASK; \
- mif_.gw = MG_TCPIP_GW; \
- mif_.driver = &mg_tcpip_driver_imxrt; \
- mif_.driver_data = &driver_data_; \
- MG_SET_MAC_ADDRESS(mif_.mac); \
- mg_tcpip_init(mgr, &mif_); \
- MG_INFO(("Driver: imxrt, MAC: %M", mg_print_mac, mif_.mac)); \
- } while (0)
- #endif
- struct mg_phy {
- uint16_t (*read_reg)(uint8_t addr, uint8_t reg);
- void (*write_reg)(uint8_t addr, uint8_t reg, uint16_t value);
- };
- // PHY configuration settings, bitmask
- enum {
- MG_PHY_LEDS_ACTIVE_HIGH =
- (1 << 0), // Set if PHY LEDs are connected to ground
- MG_PHY_CLOCKS_MAC =
- (1 << 1) // Set when PHY clocks MAC. Otherwise, MAC clocks PHY
- };
- enum { MG_PHY_SPEED_10M, MG_PHY_SPEED_100M, MG_PHY_SPEED_1000M };
- void mg_phy_init(struct mg_phy *, uint8_t addr, uint8_t config);
- bool mg_phy_up(struct mg_phy *, uint8_t addr, bool *full_duplex,
- uint8_t *speed);
- #if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_RA) && MG_ENABLE_DRIVER_RA
- struct mg_tcpip_driver_ra_data {
- // MDC clock "divider". MDC clock is software generated,
- uint32_t clock; // core clock frequency in Hz
- uint16_t irqno; // IRQn, R_ICU->IELSR[irqno]
- uint8_t phy_addr; // PHY address
- };
- #endif
- #if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_SAME54) && MG_ENABLE_DRIVER_SAME54
- struct mg_tcpip_driver_same54_data {
- int mdc_cr;
- };
- #ifndef MG_DRIVER_MDC_CR
- #define MG_DRIVER_MDC_CR 5
- #endif
- #endif
- #if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_STM32F) && \
- MG_ENABLE_DRIVER_STM32F
- struct mg_tcpip_driver_stm32f_data {
- // MDC clock divider. MDC clock is derived from HCLK, must not exceed 2.5MHz
- // HCLK range DIVIDER mdc_cr VALUE
- // -------------------------------------
- // -1 <-- tell driver to guess the value
- // 60-100 MHz HCLK/42 0
- // 100-150 MHz HCLK/62 1
- // 20-35 MHz HCLK/16 2
- // 35-60 MHz HCLK/26 3
- // 150-216 MHz HCLK/102 4 <-- value for Nucleo-F* on max speed
- // 216-310 MHz HCLK/124 5
- // 110, 111 Reserved
- int mdc_cr; // Valid values: -1, 0, 1, 2, 3, 4, 5
- uint8_t phy_addr; // PHY address
- };
- #ifndef MG_TCPIP_PHY_ADDR
- #define MG_TCPIP_PHY_ADDR 0
- #endif
- #ifndef MG_DRIVER_MDC_CR
- #define MG_DRIVER_MDC_CR 4
- #endif
- #define MG_TCPIP_DRIVER_INIT(mgr) \
- do { \
- static struct mg_tcpip_driver_stm32f_data driver_data_; \
- static struct mg_tcpip_if mif_; \
- driver_data_.mdc_cr = MG_DRIVER_MDC_CR; \
- driver_data_.phy_addr = MG_TCPIP_PHY_ADDR; \
- mif_.ip = MG_TCPIP_IP; \
- mif_.mask = MG_TCPIP_MASK; \
- mif_.gw = MG_TCPIP_GW; \
- mif_.driver = &mg_tcpip_driver_stm32f; \
- mif_.driver_data = &driver_data_; \
- MG_SET_MAC_ADDRESS(mif_.mac); \
- mg_tcpip_init(mgr, &mif_); \
- MG_INFO(("Driver: stm32f, MAC: %M", mg_print_mac, mif_.mac)); \
- } while (0)
- #endif
- #if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_STM32H) && \
- MG_ENABLE_DRIVER_STM32H
- struct mg_tcpip_driver_stm32h_data {
- // MDC clock divider. MDC clock is derived from HCLK, must not exceed 2.5MHz
- // HCLK range DIVIDER mdc_cr VALUE
- // -------------------------------------
- // -1 <-- tell driver to guess the value
- // 60-100 MHz HCLK/42 0
- // 100-150 MHz HCLK/62 1
- // 20-35 MHz HCLK/16 2
- // 35-60 MHz HCLK/26 3
- // 150-250 MHz HCLK/102 4 <-- value for max speed HSI
- // 250-300 MHz HCLK/124 5 <-- value for Nucleo-H* on CSI
- // 110, 111 Reserved
- int mdc_cr; // Valid values: -1, 0, 1, 2, 3, 4, 5
- uint8_t phy_addr; // PHY address
- uint8_t phy_conf; // PHY config
- };
- #ifndef MG_TCPIP_PHY_ADDR
- #define MG_TCPIP_PHY_ADDR 0
- #endif
- #ifndef MG_DRIVER_MDC_CR
- #define MG_DRIVER_MDC_CR 4
- #endif
- #define MG_TCPIP_DRIVER_INIT(mgr) \
- do { \
- static struct mg_tcpip_driver_stm32h_data driver_data_; \
- static struct mg_tcpip_if mif_; \
- driver_data_.mdc_cr = MG_DRIVER_MDC_CR; \
- driver_data_.phy_addr = MG_TCPIP_PHY_ADDR; \
- mif_.ip = MG_TCPIP_IP; \
- mif_.mask = MG_TCPIP_MASK; \
- mif_.gw = MG_TCPIP_GW; \
- mif_.driver = &mg_tcpip_driver_stm32h; \
- mif_.driver_data = &driver_data_; \
- MG_SET_MAC_ADDRESS(mif_.mac); \
- mg_tcpip_init(mgr, &mif_); \
- MG_INFO(("Driver: stm32h, MAC: %M", mg_print_mac, mif_.mac)); \
- } while (0)
- #endif
- #if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_TM4C) && MG_ENABLE_DRIVER_TM4C
- struct mg_tcpip_driver_tm4c_data {
- // MDC clock divider. MDC clock is derived from SYSCLK, must not exceed 2.5MHz
- // SYSCLK range DIVIDER mdc_cr VALUE
- // -------------------------------------
- // -1 <-- tell driver to guess the value
- // 60-100 MHz SYSCLK/42 0
- // 100-150 MHz SYSCLK/62 1 <-- value for EK-TM4C129* on max speed
- // 20-35 MHz SYSCLK/16 2
- // 35-60 MHz SYSCLK/26 3
- // 0x4-0xF Reserved
- int mdc_cr; // Valid values: -1, 0, 1, 2, 3
- };
- #ifndef MG_DRIVER_MDC_CR
- #define MG_DRIVER_MDC_CR 1
- #endif
- #endif
- #if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_W5500) && MG_ENABLE_DRIVER_W5500
- #undef MG_ENABLE_TCPIP_DRIVER_INIT
- #define MG_ENABLE_TCPIP_DRIVER_INIT 0
- #endif
- #if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_XMC7) && MG_ENABLE_DRIVER_XMC7
- struct mg_tcpip_driver_xmc7_data {
- int mdc_cr; // Valid values: -1, 0, 1, 2, 3, 4, 5
- uint8_t phy_addr;
- };
- #ifndef MG_TCPIP_PHY_ADDR
- #define MG_TCPIP_PHY_ADDR 0
- #endif
- #ifndef MG_DRIVER_MDC_CR
- #define MG_DRIVER_MDC_CR 3
- #endif
- #define MG_TCPIP_DRIVER_INIT(mgr) \
- do { \
- static struct mg_tcpip_driver_xmc7_data driver_data_; \
- static struct mg_tcpip_if mif_; \
- driver_data_.mdc_cr = MG_DRIVER_MDC_CR; \
- driver_data_.phy_addr = MG_TCPIP_PHY_ADDR; \
- mif_.ip = MG_TCPIP_IP; \
- mif_.mask = MG_TCPIP_MASK; \
- mif_.gw = MG_TCPIP_GW; \
- mif_.driver = &mg_tcpip_driver_xmc7; \
- mif_.driver_data = &driver_data_; \
- MG_SET_MAC_ADDRESS(mif_.mac); \
- mg_tcpip_init(mgr, &mif_); \
- MG_INFO(("Driver: xmc7, MAC: %M", mg_print_mac, mif_.mac)); \
- } while (0)
- #endif
- #if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_XMC) && MG_ENABLE_DRIVER_XMC
- struct mg_tcpip_driver_xmc_data {
- // 13.2.8.1 Station Management Functions
- // MDC clock divider (). MDC clock is derived from ETH MAC clock
- // It must not exceed 2.5MHz
- // ETH Clock range DIVIDER mdc_cr VALUE
- // --------------------------------------------
- // -1 <-- tell driver to guess the value
- // 60-100 MHz ETH Clock/42 0
- // 100-150 MHz ETH Clock/62 1
- // 20-35 MHz ETH Clock/16 2
- // 35-60 MHz ETH Clock/26 3
- // 150-250 MHz ETH Clock/102 4
- // 250-300 MHz ETH Clock/124 5
- // 110, 111 Reserved
- int mdc_cr; // Valid values: -1, 0, 1, 2, 3, 4, 5
- uint8_t phy_addr;
- };
- #ifndef MG_TCPIP_PHY_ADDR
- #define MG_TCPIP_PHY_ADDR 0
- #endif
- #ifndef MG_DRIVER_MDC_CR
- #define MG_DRIVER_MDC_CR 4
- #endif
- #define MG_TCPIP_DRIVER_INIT(mgr) \
- do { \
- static struct mg_tcpip_driver_xmc_data driver_data_; \
- static struct mg_tcpip_if mif_; \
- driver_data_.mdc_cr = MG_DRIVER_MDC_CR; \
- driver_data_.phy_addr = MG_TCPIP_PHY_ADDR; \
- mif_.ip = MG_TCPIP_IP; \
- mif_.mask = MG_TCPIP_MASK; \
- mif_.gw = MG_TCPIP_GW; \
- mif_.driver = &mg_tcpip_driver_xmc; \
- mif_.driver_data = &driver_data_; \
- MG_SET_MAC_ADDRESS(mif_.mac); \
- mg_tcpip_init(mgr, &mif_); \
- MG_INFO(("Driver: xmc, MAC: %M", mg_print_mac, mif_.mac)); \
- } while (0)
- #endif
- #ifdef __cplusplus
- }
- #endif
- #endif // MONGOOSE_H
|