From 616dc4584f462d19555298178a1d6201be2f8be9 Mon Sep 17 00:00:00 2001 From: TXuian <1163589503@qq.com> Date: Wed, 6 Dec 2023 15:59:27 +0800 Subject: [PATCH] Support double lwip eport, use mongoose.a --- .../Applications/app_test/test_socket.c | 15 +- APP_Framework/Applications/mongoose/Makefile | 2 +- .../Applications/mongoose/lib/Makefile | 3 + .../Applications/mongoose/mongoose.a | Bin 0 -> 1346900 bytes .../Applications/mongoose/mongoose.c | 10610 ---------------- .../Applications/mongoose/netsetting.c | 102 - APP_Framework/Applications/mongoose/project.c | 24 +- Ubiquitous/XiZi_IIoT/Makefile | 14 + .../third_party_driver/ethernet/eth_driver.c | 3 - .../third_party_driver/ethernet/eth_netdev.c | 11 +- .../third_party_driver/ethernet/Makefile | 2 +- .../ethernet/connect_w5500.c | 6 +- .../ethernet/{ => test}/connect_w5500_test.c | 0 .../ethernet/{ => test}/wiz_iperf.c | 0 .../ethernet/{ => test}/wiz_ping.c | 0 .../ethernet/{ => test}/wiz_ping.h | 0 .../third_party_driver/spi/connect_spi.c | 42 +- .../third_party_driver/ethernet/eth_netdev.c | 11 +- .../third_party_driver/ethernet/eth_netdev.c | 11 +- .../third_party_driver/ethernet/eth_netdev.c | 11 +- .../XiZi_IIoT/board/xishutong-arm32/config.mk | 4 + .../third_party_driver/ethernet/eth_driver.c | 3 - .../third_party_driver/ethernet/eth_netdev.c | 11 +- .../third_party_driver/ethernet/ethernetif.c | 1 - .../ethernet_wiz/w5x00_lwip.c | 1 - .../third_party_driver/ethernet/eth_netdev.c | 11 +- Ubiquitous/XiZi_IIoT/compiler.mk | 3 + Ubiquitous/XiZi_IIoT/kernel/include/xs_kdbg.h | 13 +- Ubiquitous/XiZi_IIoT/link.mk | 2 +- Ubiquitous/XiZi_IIoT/link_mongoose.mk | 9 + .../resources/ethernet/LwIP/api/sockets.c | 8 +- .../resources/ethernet/LwIP/arch/lwipopts.h | 17 +- .../resources/ethernet/LwIP/arch/sys_arch.c | 15 +- .../resources/ethernet/LwIP/core/ipv4/ip4.c | 89 + .../ethernet/LwIP/include/lwip/ip4.h | 40 +- .../ethernet/LwIP/include/lwip/opt.h | 14 +- .../ethernet/cmd_lwip/lwip_config_demo.c | 205 +- .../ethernet/netdev/netdev_lowlevel.c | 12 +- .../ethernet/netdev/netdev_manipulate.c | 14 +- .../ethernet/netdev/netdev_register.c | 13 +- .../resources/include/netdev/netdev.h | 6 +- 41 files changed, 417 insertions(+), 10941 deletions(-) create mode 100644 APP_Framework/Applications/mongoose/lib/Makefile create mode 100644 APP_Framework/Applications/mongoose/mongoose.a delete mode 100644 APP_Framework/Applications/mongoose/mongoose.c delete mode 100644 APP_Framework/Applications/mongoose/netsetting.c rename Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/{ => test}/connect_w5500_test.c (100%) rename Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/{ => test}/wiz_iperf.c (100%) rename Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/{ => test}/wiz_ping.c (100%) rename Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/{ => test}/wiz_ping.h (100%) create mode 100644 Ubiquitous/XiZi_IIoT/link_mongoose.mk diff --git a/APP_Framework/Applications/app_test/test_socket.c b/APP_Framework/Applications/app_test/test_socket.c index 2d4d10be9..d717ba251 100644 --- a/APP_Framework/Applications/app_test/test_socket.c +++ b/APP_Framework/Applications/app_test/test_socket.c @@ -76,10 +76,12 @@ struct IperfParam { static void* TestIperfServer(void* param) { struct IperfParam* iperf_param = (struct IperfParam*)param; - int sock = socket(AF_INET, SOCK_STREAM, 0); + int sock = socket(AF_INET, SOCK_STREAM, 6); if (sock < 0) { printf("[%s] Err: Can't create socker.\n", __func__); return NULL; + } else { + printf("[%s] Info Create server socket %d\n", __func__, sock); } uint8_t* recv_data = (uint8_t*)malloc(IPERF_BUFSZ); @@ -121,8 +123,9 @@ static void* TestIperfServer(void* param) socklen_t sin_size = sizeof(struct sockaddr_in); struct sockaddr_in client_addr; int connection = accept(sock, (struct sockaddr*)&client_addr, &sin_size); - printf("[%s] Info: New client connected from (%s, %d)\n", __func__, - inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port)); + printf("[%s] Info: New client connected from (%s, %d), connect: %d\n", __func__, + inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port), + connection); int flag = 1; setsockopt(connection, @@ -141,8 +144,8 @@ static void* TestIperfServer(void* param) inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port)); break; } else if (bytes_received < 0) { - KPrintf("recv error, client: (%s, %d)\n", - inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port)); + KPrintf("recv error: %d, client: (%s, %d)\n", + bytes_received, inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port)); break; } @@ -258,8 +261,6 @@ enum IperfParamEnum { void TestSocket(int argc, char* argv[]) { - lwip_config_tcp(0, lwip_ipaddr, lwip_netmask, lwip_gwaddr); - static char usage_info[] = "Run either a iperf server or iperf client."; static char program_info[] = "Lwip socket test task, a simple iperf."; static const char* const usages[] = { diff --git a/APP_Framework/Applications/mongoose/Makefile b/APP_Framework/Applications/mongoose/Makefile index 12fd727dd..40f525b5e 100644 --- a/APP_Framework/Applications/mongoose/Makefile +++ b/APP_Framework/Applications/mongoose/Makefile @@ -1,3 +1,3 @@ -SRC_FILES += mongoose.c netsetting.c project.c +SRC_FILES += project.c include $(KERNEL_ROOT)/compiler.mk \ No newline at end of file diff --git a/APP_Framework/Applications/mongoose/lib/Makefile b/APP_Framework/Applications/mongoose/lib/Makefile new file mode 100644 index 000000000..0824ed779 --- /dev/null +++ b/APP_Framework/Applications/mongoose/lib/Makefile @@ -0,0 +1,3 @@ +SRC_FILES += mongoose.c + +include $(KERNEL_ROOT)/compiler.mk \ No newline at end of file diff --git a/APP_Framework/Applications/mongoose/mongoose.a b/APP_Framework/Applications/mongoose/mongoose.a new file mode 100644 index 0000000000000000000000000000000000000000..fd5000247183dac1106d0b15ab5ca20fe664c8a6 GIT binary patch literal 1346900 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ΝW)YX#uI63M1i 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%0DDU~{%+XLe_Q4&-o- z;$%+ed@kZjuH`{~$CEtG$9%@v9rR`rreFqUVQ%JQ5f*1zR$z73Vgoi|SN7y59K^X? zz-3&;joivTJiw#;foFN1S9yca7<4ojzQQcb&U`G$%B;>hY`~A$lI_`2#z=R)6!dA*F+`4{i=5nnJ?r^wqSU}C0bdS+uTzRfbM$f|6{R_wqo{EQ+TK4Z`&()Sf6VFqSlJ{DwgmSiI~WgE6 zHtym#{FWzqniqJ9fAAI`@G*m~kvYU>YNls4=3)t!V)f8HQ9&&>U=y}tJ9cGHe#*fd z$+4Wunf#JpaToXTTOQ+&Jj=`colp3jFLjIbiO=-R%$%VyuSXV@ORxstXM@m~*BRT& z9oRo~Zx9UR2#)4tPUk!>&%$vN+_}wG>NyrpT!_3UaJj~DHEXlfT z$YyNC4(!6-?8jmJoYO-q#|mb1A(wD9*K<2}^AL~l6wmNCUg2N7!$*9|SUn>9iOa-H z&RopP!YsxQSf5SVf*-RJ`>;QUa5yJ$3TJa3H*-7p@gR@!1b^qByvK)p#-L|p4yl=* zS(%fsvk;53BtKw%Hf0Nb%uejdz8ufVoW;5PieGaLH}D9*=V|`JOT5OLyvwA$B6CQ| zjC_^3nU8PqO_pJKR%K1rWkWV+Yj$K;4&?}r<0LNR60Qo3xu5Nn_wpzH%!{Eh_p>|l zeZJH?(my`agf@r{GB7)HvmlGG6yISL)?ht0Vhgt62#)3?PUCzo;&QI$R_^2h9_C4& z<^^72&?nM2HWM&0(=sEoGdByf7)$XTR^xlD$42~wgE)etIh8XxpNqJP>$sIWd5A}N zlBfBY&lsz3WFB#ulqs2kS(u0US(GJMo|RaWwK^{*oKgRa%qbpUVREKsCT8Vpe4Uk9ogc71o3aHzW+(P!Uk>C@&f;7y z;c~9yChq2b{>ZcZhyOCVUt|t(n25=kmKm9Yudx*0Vdc=6`&kY7eKxTEvD}G$*q;+Q zm2*O4?t5R#UvY)?o$_9O%VYeFSNLaW%>JIp&zZD;WDY5rAvET^dF28u&q}Nr8gsl4 zs#b2b-*#+-MFyqxQ-@0Snpd!FKT{>8sTWA^t*e#-EBV#4+0p)r47 zq~@#4!M9n46+@du1=ZyDSkHP}xdVH!4@Yx6r*RfnaxJ%T2T$<~f8}NV!CQR5$4u~P zq;F!TVmiLgLM+ab{DAe@lr8u%JFzGGazyCPAQ;WboX&Y%$mLwk&D_pYJi}jknKyZt zkNA`+2SoOhmRXpcud@(~vn1=XA)B!kJF`3g$4@z(v$=qaxrQ6KoxAxHf954#W7NP% zzn7SlDfudM@D0An(k#a+tid*H&))3EksQmJ{DPafjo*cq34-H1&0lz#zw_cD_)6*Dm_^DsXvvMS$aT{dAewq*wn;c$-SM9$zGF60vK;y!-MWBie4`5UkB zAO6dz!I62q#5Byn?99!otjT(8#O7?xPVC0M{Dea}g5x-eGx-G5tiaRtjy}H%Z6;hHtfW1?8gC|&e>eR#azP; z+|J$nmdALRzw;LF@hM+0&1aE$WMDStVj&h~NtR_*)?{D5_Uz1F{2vE#7$=9Wjro2& z&f`LE=WZV4cRazLc%B#elrI=(MC5!gGbvLt1G6v}^Rh6D@jZUPMr_JfPUc)L;MZKqlRV7}yu?3wn-BSfvBpH^5tkYHDswX*i}5YK!*|(% zUD%ubIFutej+3~F+qjqC@HkKMI{)I|{D&_XYiy)vPUc}D7G-IcV*@r}OSWY<_TncT z#A%$xFZmT$b3M=TH~!8)d7qD%a9pHUQl?=B)(#yL1oikKo3lMTvlsuzp&Y?+oWwbt z&m~;W4cx-r+|Q%@foFJ*5BQib7;Ai_*DFlI)J)HOq2q&~Ad9mkE3h(au@0NC8QZZV zhjSDsaw_L>A(wF#w{Qo4;?KOutGvZ~e9UKjX+orLd}d`%=4WBP#nP_0Y>Gc}8{ z1k17lYq1X7vIBdvFGq4L=W+ozhAs$#t=z){{FxVcl{a{g4;g=I%<$g7304T+D6U#c%j6FYpp?@Fru;jP#AmL`=rC%*gD_ z%`z;{s;tSnY{+J8#gQD#shr9AT*Q@J%Pri&{XE3)d5Y)w8*lI?AM+Vw&x*_^9{I8NnE&gUX7=W1@^Hty#k9_LA3@JM*#t-wn+Y6;xp@)?u5_JW)Y=c4u!6;1G`DI4{7jQ9GaxJ%W zH_!4sukbo=^KU-kbH<$)>63t2nUk-x5R0=UE3zt^vo$-iEBmlNKjTO);9{=iT5jPE z?&l#M=Slv>JN$?LGS&P@|8&gFe0+#IoLynKUivMejGI%}~3o3J%MW;gcY01n|Oj^lLB<{~cTYOd!t?&2XH z;Ypt6Z@j`kd7BUUgq0UZ=2M+@*nl6gB|ESSd$S*has(%E3TJa3mvRNyb2E?dd!FGr zUg34#;eGzg|M=39NZ8cEX-mo#dlbRHCTrY*qp7|kzF}}LpYLSIfXMg zpNqJhtGSumd6hSKmk;=qFBorWWL~c@Ia4zWvokLXusBPy0xPo?>+nN1=f~{C-t5O! zT*qD9$KyQ7UwN6g`8WS#^w*KziI|L;n3efin59{cHCdZ2*oNKNn?pF9(>RNZxs02* zjoo!Om(L)%9MpK&ZFawfmvVlLx4ZsKn4=MjF-tGvNGywCV6Bl}6n6imas zEWl!Xi|?~8o3I%_W+(P$KThU!&gB9w=W1@@4xZu}{u&zdeFj(L>%49KzWj*)Sx>tv zGKY-J#k?%cVl2xFtj71)kRP%Y+i@bNat`Nn372yZ5AZi$;h((CV0ENVY?fhpR%K1r zWkYslPxj|P4(BLNsB+kD6;jI}<}CoU5)88a{o zb1^TAvINVr0$Z>RJFy%4b0CLv6sK?o=W!tq@d!`yG%xZh|Kc6~!+#ljLu4NDn3&0# zj+vN)udzHUu_kM?AwOhWcHk!*#95rnrCh;H+{Obu%!|Crzj%jF_?*c%M*64btIWYt ze20};o%Ps=UD$*DIDnsVBWxl*Avj0SUl{uJ?1zA3HN>osZHCdaj zLSv5Ij$PT4qd1OJIg|6bh&#B4hj@f1d78KRH=po1V{eY^FCH^63k!rEi3;A}+bqLM zti}&mpPkr^efbH8as=mbA(wF#H*zaagx-n@e&Tsv^Bip zGA*+(JM*#tE3-O3V0|`cYj$K;_F;cc=5)^G0)EYv+{c4F#uGft^SsYT{EyMwB6En( zgiOIS%*z5S78>*Uz}s>eR}$CEtG z3%tY|yvh4~#FuyI&y1m^qk~uZ8eeBomS8znWKGs)TXtY~_U1^A-u(JjcuYox#4yJYq8e6EiI{GCOm#94oR0 z-)Ccf#5QctK^(?0oWR9g#)Wa#BS^x8gspmkVo?ie#xbwF~{31Z|C{BF1MzzRDcT z$AWy9Ral1&*phAeX=uynU@&KfwvGiwq5qlw@R7$(}Po&BE2?|x*@y=Ff5=bCF~?zyjP?wMf<@5TG^ zVSEICkAK9BAEcJ|7(4|}#q;qscrm^n-;8g?Mr_8tcs1ULH{qx8Gx$Zk9S`6nei!e? zS)9Y4;VcTn&rtpkyp8F1Q2r`@gX!O){C&KS>5owU9j@Ri{sW)F<7QIp=L9?%Pr)&F5n_QijU!w_&@kh%)Bqv?x*94 z_#Av5o`x^NGx02Z1-=R|#EWq!?#4Fkz<1-nVm}VxP53FC#DjP@-ivd12!DmY!9U=i z@PF_hnEAuhdN~$Pz>}~9OYxQXYPZ^7H~%lKWq8-IvD z!iVt@T*pA?$n3cNG&~*?Scosfm*YA33VaK`9e3hxY{L$`4&Q@)*pD~jP5AG4D;~rt zoWWWA3H}Tp#z*k?_(xpDH4J7`>m?gsh-cuLcovpp1y*4-z6IZoJ8?I*V<%pZH{g(| zU1Qua2UVsHkCdADH=HsrcucIv%_b zUxqKobMO^diB)(RUXJg;M!X8!@p`-gKZ&2l&*JCt4*V+KhY#Q(oX20|f8$^A@0c-{ zYVR?4DxQun#jUs<&%+w5#Vc_ac40Su2tR_in7x_7XK@V2@%#7#d;oupkK$wa1pXCs zf1JvnhbQAHc&7Q$%-}3M56{O7@nU=8}Q?JGv0!q$J_8; zydNLJU*PZX5BOL7J0AOBs=ZIg=iu}3Mfg&z#u|J(?!b3q8@>zQi`U}~cr)IDV>pg; zcnBA85g*0J@Nf9Pc>GUN?Ry3mU;Tfz7xFlh}nH!%yJNcngl3!D$qSc`RdCGNt# zcr|_)KZ-Zur|@?CGJXTUjX%Yo<03BMpYRFHc_`K1TznRuj73PJH{wnBY5WX+9&f`5Jb?F_f6EN+ z#|QBtTsHra863t{T*KfOsrlKMj|EtS#aM||ScA3Lg00wv-8g`QIE?#o+e zaT;fE4iDi1F5)sC#$$h(%Kvmc37?Ip;_3KO+=^vbj+f$_a0l+h_u&We2K+eQjJM$D z@izPl-ih~^CuRlr;g9jB_$&Mk{tx~GGZ#|tKNe5Glkg0D3BCefg>S;Q;1zf!?!mqI ze*6&LfFH+U+>dve&&vwFiQmI}@W1dU_zQd(SIrk>1#9>eX8kHP{n_S=vV!O03-Jtm zCB7Oj!hgXx;+yd*Y{zTxT{vLAEGrnqVcd_SIEE8=01x66&fqLA;W9psPvYP4pLoo} zspUBiUx;VmHarI_u?pW|o}U#o;vU?K@52w`01o08@IUb@cqiVE|Ai0XFK`7{@gMjU zKI_-1V8oRLvKZGB_Tk&&vJAN7O z!f)b_@Im~!sq-oiQ+@=0&-A}j{wL=ACbd3t@icr9o@v%+1luT|gXc5-4U{j#x8W7o zf!E-B@O?Oh!+0xx4kz&--i`O-kMKeKE&d)?a21b#B-P$$;B)YK_(D7bi?IY>gBN18 zsrCJK$~&+Vuf_M8T8}qS{y2UPzle93%J*%`-@~8c&vDUIzQ-v)iO2o7rZ;8zQvJ9|Q^W#2_d#Ptx-&%`HJtW}X}b73TATpvpWo2x`pJgP_iQaS$|^ zX9huwxh)8i=Jp`yHqQ%!Ub9@!y)yOp9R|${^xS6i!XOwiFV)`}H7^T-3G>ZCFlnli zDf8_?Fk@a31aoF%5X_rRL9l4<4uWN~H3(MB_8?d@JM@1Ua$gYSnB75;XTC@6H{YlB zn|*4(`C+x+yk6}$^?cI`Q_uOVGW9&l8dJ}0tTXjI!v<5&1#B_(e7~fr=hAhXx2yf8 zo>Sd#>iOM+rk*o5Z0dPwBc`51KW6HA{u8GDPRgXI=Y>s~-&6a|yVZVE&-Ix%?^XNF z`_z8(ezo8Hk=k#DD@#78_GikUsr}|J)P8dz2omPQYQOo2+Hd|&?KibjE6hKr{pKIl ze)Dm)-_-Md8q6ove)Df?zqzjVn@_3zW=2NPZ)Rl#gXYsRf?@Nxj9|n(UiUefCu9T@ z=1CdBq`5`+IhoJN2xiRuj9|`uK}IldCNhFWvoIrAHeZwxte7v&2-eJ(Yb9jKvonGm zvn(UXGhdYvN-O+nGqz-YchgvvnM0yHQ%rHo7xEm&5x@6=AhbdenRaxhtz)alWM>DX|>B~%|EOC=3mr)b4~3x z*VTUWDYf6s()iNU_4v#{brxqZ+=+qH?LRwP5oZ6Xx^aqn>VWc<|ovCb4cyif#1$M=a`>S`^{0c z-_-fGgn66VZ{DuwGe zV*an%Z|ZzS@HCl`737%5WCeMq#_9Ryv$BGOnV%IDnHt}gm>Q>+nHrB)m@ml+s!WX+ zYs`|Ypw8T$6*QQy$O>9ajlYs+MOM&lzBVi9HLJ3MepBO}L9-?+7&hOO6^xj5S;3h3 z_N-vSydo=@G}XVFGSv^7F`Ki3IkP1zm^alQSTtL+f@SmStYF1dKVZ$gP6vS;`Chf( z{Gi%zenjmzZ&3Tq8`XaE6N=Z%`UU#!|7)!7e%di})%+rIQ z8f&l?>#!ahunCjch5CvQ^Yvga_TiwZ{>l&z<9-}7)sGp+2|R$4co3&>8s|*)e-7b1 zF5n_A;W8e^HC)HQzQ>g>8*?xh^H5)vVVu4aL-myyT7<<|f~Bah#4xTLE3gu4%vbBV z%~*#T5`@zmunAkR6_eP7-Kej|@csQbfP*-MBc}R?qd11+IEe>w3a4=fXK@Y>;UX^K zG9JbiT*bip73!yEV-DtGJ{F+9lEU~xw67$4zrKn>%S`n*%drA0u?nlP&KwAWdThWZ zOq%MKc40U6V83~55DefT+E;~5AIAMShT}Ma2XGP(;*6<&?<~&YA)LnrT*kw=f~&ZO z>lj$SM)|Wb&s6_<3+hlFmJ2X}g;<2es6%-eUy3?(hviDtp*t*BqYl+!xgHy^33X@= z=j)IhnnWFv!*Vb7VLuMwFz&|@9K|sl#|b=uQ#g$?IE(YRfQz_<%Xk>qa2@T7!Pa*+ z=9wD5Y{7gizyuaziK%f;DVAY5R$(>PU@bP7-wlE$Y{6FS#vbg&J{-g$9LD`PhT}Ma z2XG3faRz5`4iDixF5t4MaoS;A!Bt$tbquT@r}%8l!CcHY^`%pQ2`t1CQ{%riF zz)GyaTCBr*Y{6DcVi)$B8fW%lKMvq9?#B@v#R)uslXwuPa2n@KeYqaOd0fD-U;K#H zx0U4zuHqW5V_^M8#bsj-=3*Xh!F(*h1Qucu7GnvPVi}fW1y*7eR$~p;Vjb3F12$m` zwqg>yup4`@7yGau2XGLFa2WUF2#(?yj^hL#z)3uaQ#g$?IE!<52cP#W_5L^SFSExP&XF&NHpz8m?nFj?sCh+#JQpa6BWo zP!7j4Di=}?$2BS!Q!c}DtiVdF!fLF;dThWZOkx*yV-NP@01o01j^HSc;W$p>L7c*A zoHL)&@ek*50T*!zm+>&J;3@{kDWA^MWn&KJVjgb61Qucu7GnvPVg*)W6;@*n)?$OH z^My^=g00w%J=lwV*pCA^Z0bDYejLG39K&&(zymmC>b&AK&fqN0;US#I1zg6%xPq$~ zJYD%UD9gqi%*A{xzyuaz5f)Jk_V)KXWk;w_rXNV3Dbl#l={HrC4F=chgF& z!fLF;dThWZOkx*yV-NOX9}eOW4�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 c$ewLo;|iOj-AGTyCZ8Kv$haq{i<= 'A' && c <= 'Z') { - return c - 'A'; - } else if (c >= 'a' && c <= 'z') { - return c + 26 - 'a'; - } else if (c >= '0' && c <= '9') { - return c + 52 - '0'; - } else if (c == '+') { - return 62; - } else if (c == '/') { - return 63; - } else if (c == '=') { - return 64; - } else { - return -1; - } -} - -size_t mg_base64_update(unsigned char ch, char* to, size_t n) -{ - unsigned long rem = (n & 3) % 3; - if (rem == 0) { - to[n] = (char)mg_base64_encode_single(ch >> 2); - to[++n] = (char)((ch & 3) << 4); - } else if (rem == 1) { - to[n] = (char)mg_base64_encode_single(to[n] | (ch >> 4)); - to[++n] = (char)((ch & 15) << 2); - } else { - to[n] = (char)mg_base64_encode_single(to[n] | (ch >> 6)); - to[++n] = (char)mg_base64_encode_single(ch & 63); - n++; - } - return n; -} - -size_t mg_base64_final(char* to, size_t n) -{ - size_t saved = n; - // printf("---[%.*s]\n", n, to); - if (n & 3) - n = mg_base64_update(0, to, n); - if ((saved & 3) == 2) - n--; - // printf(" %d[%.*s]\n", n, n, to); - while (n & 3) - to[n++] = '='; - to[n] = '\0'; - return n; -} - -size_t mg_base64_encode(const unsigned char* p, size_t n, char* to, size_t dl) -{ - size_t i, len = 0; - if (dl > 0) - to[0] = '\0'; - if (dl < ((n / 3) + (n % 3 ? 1 : 0)) * 4 + 1) - return 0; - for (i = 0; i < n; i++) - len = mg_base64_update(p[i], to, len); - len = mg_base64_final(to, len); - return len; -} - -size_t mg_base64_decode(const char* src, size_t n, char* dst, size_t dl) -{ - const char* end = src == NULL ? NULL : src + n; // Cannot add to NULL - size_t len = 0; - if (dl > 0) - dst[0] = '\0'; - if (dl < n / 4 * 3 + 1) - return 0; - while (src != NULL && src + 3 < end) { - int a = mg_base64_decode_single(src[0]), - b = mg_base64_decode_single(src[1]), - c = mg_base64_decode_single(src[2]), - d = mg_base64_decode_single(src[3]); - if (a == 64 || a < 0 || b == 64 || b < 0 || c < 0 || d < 0) - return 0; - dst[len++] = (char)((a << 2) | (b >> 4)); - if (src[2] != '=') { - dst[len++] = (char)((b << 4) | (c >> 2)); - if (src[3] != '=') - dst[len++] = (char)((c << 6) | d); - } - src += 4; - } - dst[len] = '\0'; - return len; -} - -#ifdef MG_ENABLE_LINES -#line 1 "src/dns.c" -#endif - -struct dns_data { - struct dns_data* next; - struct mg_connection* c; - uint64_t expire; - uint16_t txnid; -}; - -static void mg_sendnsreq(struct mg_connection*, struct mg_str*, int, - struct mg_dns*, bool); - -static void mg_dns_free(struct dns_data** head, struct dns_data* d) -{ - LIST_DELETE(struct dns_data, head, d); - free(d); -} - -void mg_resolve_cancel(struct mg_connection* c) -{ - struct dns_data *tmp, *d; - struct dns_data** head = (struct dns_data**)&c->mgr->active_dns_requests; - for (d = *head; d != NULL; d = tmp) { - tmp = d->next; - if (d->c == c) - mg_dns_free(head, d); - } -} - -static size_t mg_dns_parse_name_depth(const uint8_t* s, size_t len, size_t ofs, - char* to, size_t tolen, size_t j, - int depth) -{ - size_t i = 0; - if (tolen > 0 && depth == 0) - to[0] = '\0'; - if (depth > 5) - return 0; - // MG_INFO(("ofs %lx %x %x", (unsigned long) ofs, s[ofs], s[ofs + 1])); - while (ofs + i + 1 < len) { - size_t n = s[ofs + i]; - if (n == 0) { - i++; - break; - } - if (n & 0xc0) { - size_t ptr = (((n & 0x3f) << 8) | s[ofs + i + 1]); // 12 is hdr len - // MG_INFO(("PTR %lx", (unsigned long) ptr)); - if (ptr + 1 < len && (s[ptr] & 0xc0) == 0 && mg_dns_parse_name_depth(s, len, ptr, to, tolen, j, depth + 1) == 0) - return 0; - i += 2; - break; - } - if (ofs + i + n + 1 >= len) - return 0; - if (j > 0) { - if (j < tolen) - to[j] = '.'; - j++; - } - if (j + n < tolen) - memcpy(&to[j], &s[ofs + i + 1], n); - j += n; - i += n + 1; - if (j < tolen) - to[j] = '\0'; // Zero-terminate this chunk - // MG_INFO(("--> [%s]", to)); - } - if (tolen > 0) - to[tolen - 1] = '\0'; // Make sure make sure it is nul-term - return i; -} - -static size_t mg_dns_parse_name(const uint8_t* s, size_t n, size_t ofs, - char* dst, size_t dstlen) -{ - return mg_dns_parse_name_depth(s, n, ofs, dst, dstlen, 0, 0); -} - -size_t mg_dns_parse_rr(const uint8_t* buf, size_t len, size_t ofs, - bool is_question, struct mg_dns_rr* rr) -{ - const uint8_t *s = buf + ofs, *e = &buf[len]; - - memset(rr, 0, sizeof(*rr)); - if (len < sizeof(struct mg_dns_header)) - return 0; // Too small - if (len > 512) - return 0; // Too large, we don't expect that - if (s >= e) - return 0; // Overflow - - if ((rr->nlen = (uint16_t)mg_dns_parse_name(buf, len, ofs, NULL, 0)) == 0) - return 0; - s += rr->nlen + 4; - if (s > e) - return 0; - rr->atype = (uint16_t)(((uint16_t)s[-4] << 8) | s[-3]); - rr->aclass = (uint16_t)(((uint16_t)s[-2] << 8) | s[-1]); - if (is_question) - return (size_t)(rr->nlen + 4); - - s += 6; - if (s > e) - return 0; - rr->alen = (uint16_t)(((uint16_t)s[-2] << 8) | s[-1]); - if (s + rr->alen > e) - return 0; - return (size_t)(rr->nlen + rr->alen + 10); -} - -bool mg_dns_parse(const uint8_t* buf, size_t len, struct mg_dns_message* dm) -{ - const struct mg_dns_header* h = (struct mg_dns_header*)buf; - struct mg_dns_rr rr; - size_t i, n, ofs = sizeof(*h); - memset(dm, 0, sizeof(*dm)); - - if (len < sizeof(*h)) - return 0; // Too small, headers dont fit - if (mg_ntohs(h->num_questions) > 1) - return 0; // Sanity - if (mg_ntohs(h->num_answers) > 10) - return 0; // Sanity - dm->txnid = mg_ntohs(h->txnid); - - for (i = 0; i < mg_ntohs(h->num_questions); i++) { - if ((n = mg_dns_parse_rr(buf, len, ofs, true, &rr)) == 0) - return false; - // MG_INFO(("Q %lu %lu %hu/%hu", ofs, n, rr.atype, rr.aclass)); - ofs += n; - } - for (i = 0; i < mg_ntohs(h->num_answers); i++) { - if ((n = mg_dns_parse_rr(buf, len, ofs, false, &rr)) == 0) - return false; - // MG_INFO(("A -- %lu %lu %hu/%hu %s", ofs, n, rr.atype, rr.aclass, - // dm->name)); - mg_dns_parse_name(buf, len, ofs, dm->name, sizeof(dm->name)); - ofs += n; - - if (rr.alen == 4 && rr.atype == 1 && rr.aclass == 1) { - dm->addr.is_ip6 = false; - memcpy(&dm->addr.ip, &buf[ofs - 4], 4); - dm->resolved = true; - break; // Return success - } else if (rr.alen == 16 && rr.atype == 28 && rr.aclass == 1) { - dm->addr.is_ip6 = true; - memcpy(&dm->addr.ip, &buf[ofs - 16], 16); - dm->resolved = true; - break; // Return success - } - } - return true; -} - -static void dns_cb(struct mg_connection* c, int ev, void* ev_data, - void* fn_data) -{ - struct dns_data *d, *tmp; - struct dns_data** head = (struct dns_data**)&c->mgr->active_dns_requests; - if (ev == MG_EV_POLL) { - uint64_t now = *(uint64_t*)ev_data; - for (d = *head; d != NULL; d = tmp) { - tmp = d->next; - // MG_DEBUG ("%lu %lu dns poll", d->expire, now)); - if (now > d->expire) - mg_error(d->c, "DNS timeout"); - } - } else if (ev == MG_EV_READ) { - struct mg_dns_message dm; - int resolved = 0; - if (mg_dns_parse(c->recv.buf, c->recv.len, &dm) == false) { - MG_ERROR(("Unexpected DNS response:")); - mg_hexdump(c->recv.buf, c->recv.len); - } else { - // MG_VERBOSE(("%s %d", dm.name, dm.resolved)); - for (d = *head; d != NULL; d = tmp) { - tmp = d->next; - // MG_INFO(("d %p %hu %hu", d, d->txnid, dm.txnid)); - if (dm.txnid != d->txnid) - continue; - if (d->c->is_resolving) { - if (dm.resolved) { - dm.addr.port = d->c->rem.port; // Save port - d->c->rem = dm.addr; // Copy resolved address - MG_DEBUG( - ("%lu %s is %M", d->c->id, dm.name, mg_print_ip, &d->c->rem)); - mg_connect_resolved(d->c); -#if MG_ENABLE_IPV6 - } else if (dm.addr.is_ip6 == false && dm.name[0] != '\0' && c->mgr->use_dns6 == false) { - struct mg_str x = mg_str(dm.name); - mg_sendnsreq(d->c, &x, c->mgr->dnstimeout, &c->mgr->dns6, true); -#endif - } else { - mg_error(d->c, "%s DNS lookup failed", dm.name); - } - } else { - MG_ERROR(("%lu already resolved", d->c->id)); - } - mg_dns_free(head, d); - resolved = 1; - } - } - if (!resolved) - MG_ERROR(("stray DNS reply")); - c->recv.len = 0; - } else if (ev == MG_EV_CLOSE) { - for (d = *head; d != NULL; d = tmp) { - tmp = d->next; - mg_error(d->c, "DNS error"); - mg_dns_free(head, d); - } - } - (void)fn_data; -} - -static bool mg_dns_send(struct mg_connection* c, const struct mg_str* name, - uint16_t txnid, bool ipv6) -{ - struct { - struct mg_dns_header header; - uint8_t data[256]; - } pkt; - size_t i, n; - memset(&pkt, 0, sizeof(pkt)); - pkt.header.txnid = mg_htons(txnid); - pkt.header.flags = mg_htons(0x100); - pkt.header.num_questions = mg_htons(1); - for (i = n = 0; i < sizeof(pkt.data) - 5; i++) { - if (name->ptr[i] == '.' || i >= name->len) { - pkt.data[n] = (uint8_t)(i - n); - memcpy(&pkt.data[n + 1], name->ptr + n, i - n); - n = i + 1; - } - if (i >= name->len) - break; - } - memcpy(&pkt.data[n], "\x00\x00\x01\x00\x01", 5); // A query - n += 5; - if (ipv6) - pkt.data[n - 3] = 0x1c; // AAAA query - // memcpy(&pkt.data[n], "\xc0\x0c\x00\x1c\x00\x01", 6); // AAAA query - // n += 6; - return mg_send(c, &pkt, sizeof(pkt.header) + n); -} - -static void mg_sendnsreq(struct mg_connection* c, struct mg_str* name, int ms, - struct mg_dns* dnsc, bool ipv6) -{ - struct dns_data* d = NULL; - if (dnsc->url == NULL) { - mg_error(c, "DNS server URL is NULL. Call mg_mgr_init()"); - } else if (dnsc->c == NULL) { - dnsc->c = mg_connect(c->mgr, dnsc->url, NULL, NULL); - if (dnsc->c != NULL) { - dnsc->c->pfn = dns_cb; - // dnsc->c->is_hexdumping = 1; - } - } - if (dnsc->c == NULL) { - mg_error(c, "resolver"); - } else if ((d = (struct dns_data*)calloc(1, sizeof(*d))) == NULL) { - mg_error(c, "resolve OOM"); - } else { - struct dns_data* reqs = (struct dns_data*)c->mgr->active_dns_requests; - d->txnid = reqs ? (uint16_t)(reqs->txnid + 1) : 1; - d->next = (struct dns_data*)c->mgr->active_dns_requests; - c->mgr->active_dns_requests = d; - d->expire = mg_millis() + (uint64_t)ms; - d->c = c; - c->is_resolving = 1; - MG_VERBOSE(("%lu resolving %.*s @ %s, txnid %hu", c->id, (int)name->len, - name->ptr, dnsc->url, d->txnid)); - if (!mg_dns_send(dnsc->c, name, d->txnid, ipv6)) { - mg_error(dnsc->c, "DNS send"); - } - } -} - -void mg_resolve(struct mg_connection* c, const char* url) -{ - struct mg_str host = mg_url_host(url); - c->rem.port = mg_htons(mg_url_port(url)); - if (mg_aton(host, &c->rem)) { - // host is an IP address, do not fire name resolution - mg_connect_resolved(c); - } else { - // host is not an IP, send DNS resolution request - struct mg_dns* dns = c->mgr->use_dns6 ? &c->mgr->dns6 : &c->mgr->dns4; - mg_sendnsreq(c, &host, c->mgr->dnstimeout, dns, c->mgr->use_dns6); - } -} - -#ifdef MG_ENABLE_LINES -#line 1 "src/event.c" -#endif - -void mg_call(struct mg_connection* c, int ev, void* ev_data) -{ - // Run user-defined handler first, in order to give it an ability - // to intercept processing (e.g. clean input buffer) before the - // protocol handler kicks in - if (c->fn != NULL) - c->fn(c, ev, ev_data, c->fn_data); - if (c->pfn != NULL) - c->pfn(c, ev, ev_data, c->pfn_data); -} - -void mg_error(struct mg_connection* c, const char* fmt, ...) -{ - char buf[64]; - va_list ap; - va_start(ap, fmt); - mg_vsnprintf(buf, sizeof(buf), fmt, &ap); - va_end(ap); - MG_ERROR(("%lu %ld %s", c->id, c->fd, buf)); - c->is_closing = 1; // Set is_closing before sending MG_EV_CALL - mg_call(c, MG_EV_ERROR, buf); // Let user handler to override it -} - -#ifdef MG_ENABLE_LINES -#line 1 "src/fmt.c" -#endif - -static bool is_digit(int c) -{ - return c >= '0' && c <= '9'; -} - -static int addexp(char* buf, int e, int sign) -{ - int n = 0; - buf[n++] = 'e'; - buf[n++] = (char)sign; - if (e > 400) - return 0; - if (e < 10) - buf[n++] = '0'; - if (e >= 100) - buf[n++] = (char)(e / 100 + '0'), e -= 100 * (e / 100); - if (e >= 10) - buf[n++] = (char)(e / 10 + '0'), e -= 10 * (e / 10); - buf[n++] = (char)(e + '0'); - return n; -} - -static int xisinf(double x) -{ - union { - double f; - uint64_t u; - } ieee754 = { x }; - return ((unsigned)(ieee754.u >> 32) & 0x7fffffff) == 0x7ff00000 && ((unsigned)ieee754.u == 0); -} - -static int xisnan(double x) -{ - union { - double f; - uint64_t u; - } ieee754 = { x }; - return ((unsigned)(ieee754.u >> 32) & 0x7fffffff) + ((unsigned)ieee754.u != 0) > 0x7ff00000; -} - -static size_t mg_dtoa(char* dst, size_t dstlen, double d, int width, bool tz) -{ - char buf[40]; - int i, s = 0, n = 0, e = 0; - double t, mul, saved; - if (d == 0.0) - return mg_snprintf(dst, dstlen, "%s", "0"); - if (xisinf(d)) - return mg_snprintf(dst, dstlen, "%s", d > 0 ? "inf" : "-inf"); - if (xisnan(d)) - return mg_snprintf(dst, dstlen, "%s", "nan"); - if (d < 0.0) - d = -d, buf[s++] = '-'; - - // Round - saved = d; - mul = 1.0; - while (d >= 10.0 && d / mul >= 10.0) - mul *= 10.0; - while (d <= 1.0 && d / mul <= 1.0) - mul /= 10.0; - for (i = 0, t = mul * 5; i < width; i++) - t /= 10.0; - d += t; - // Calculate exponent, and 'mul' for scientific representation - mul = 1.0; - while (d >= 10.0 && d / mul >= 10.0) - mul *= 10.0, e++; - while (d < 1.0 && d / mul < 1.0) - mul /= 10.0, e--; - // printf(" --> %g %d %g %g\n", saved, e, t, mul); - - if (e >= width && width > 1) { - n = (int)mg_dtoa(buf, sizeof(buf), saved / mul, width, tz); - // printf(" --> %.*g %d [%.*s]\n", 10, d / t, e, n, buf); - n += addexp(buf + s + n, e, '+'); - return mg_snprintf(dst, dstlen, "%.*s", n, buf); - } else if (e <= -width && width > 1) { - n = (int)mg_dtoa(buf, sizeof(buf), saved / mul, width, tz); - // printf(" --> %.*g %d [%.*s]\n", 10, d / mul, e, n, buf); - n += addexp(buf + s + n, -e, '-'); - return mg_snprintf(dst, dstlen, "%.*s", n, buf); - } else { - for (i = 0, t = mul; t >= 1.0 && s + n < (int)sizeof(buf); i++) { - int ch = (int)(d / t); - if (n > 0 || ch > 0) - buf[s + n++] = (char)(ch + '0'); - d -= ch * t; - t /= 10.0; - } - // printf(" --> [%g] -> %g %g (%d) [%.*s]\n", saved, d, t, n, s + n, buf); - if (n == 0) - buf[s++] = '0'; - while (t >= 1.0 && n + s < (int)sizeof(buf)) - buf[n++] = '0', t /= 10.0; - if (s + n < (int)sizeof(buf)) - buf[n + s++] = '.'; - // printf(" 1--> [%g] -> [%.*s]\n", saved, s + n, buf); - for (i = 0, t = 0.1; s + n < (int)sizeof(buf) && n < width; i++) { - int ch = (int)(d / t); - buf[s + n++] = (char)(ch + '0'); - d -= ch * t; - t /= 10.0; - } - } - while (tz && n > 0 && buf[s + n - 1] == '0') - n--; // Trim trailing zeroes - if (n > 0 && buf[s + n - 1] == '.') - n--; // Trim trailing dot - n += s; - if (n >= (int)sizeof(buf)) - n = (int)sizeof(buf) - 1; - buf[n] = '\0'; - return mg_snprintf(dst, dstlen, "%s", buf); -} - -static size_t mg_lld(char* buf, int64_t val, bool is_signed, bool is_hex) -{ - const char* letters = "0123456789abcdef"; - uint64_t v = (uint64_t)val; - size_t s = 0, n, i; - if (is_signed && val < 0) - buf[s++] = '-', v = (uint64_t)(-val); - // This loop prints a number in reverse order. I guess this is because we - // write numbers from right to left: least significant digit comes last. - // Maybe because we use Arabic numbers, and Arabs write RTL? - if (is_hex) { - for (n = 0; v; v >>= 4) - buf[s + n++] = letters[v & 15]; - } else { - for (n = 0; v; v /= 10) - buf[s + n++] = letters[v % 10]; - } - // Reverse a string - for (i = 0; i < n / 2; i++) { - char t = buf[s + i]; - buf[s + i] = buf[s + n - i - 1], buf[s + n - i - 1] = t; - } - if (val == 0) - buf[n++] = '0'; // Handle special case - return n + s; -} - -static size_t scpy(void (*out)(char, void*), void* ptr, char* buf, - size_t len) -{ - size_t i = 0; - while (i < len && buf[i] != '\0') - out(buf[i++], ptr); - return i; -} - -size_t mg_xprintf(void (*out)(char, void*), void* ptr, const char* fmt, ...) -{ - size_t len = 0; - va_list ap; - va_start(ap, fmt); - len = mg_vxprintf(out, ptr, fmt, &ap); - va_end(ap); - return len; -} - -size_t mg_vxprintf(void (*out)(char, void*), void* param, const char* fmt, - va_list* ap) -{ - size_t i = 0, n = 0; - while (fmt[i] != '\0') { - if (fmt[i] == '%') { - size_t j, k, x = 0, is_long = 0, w = 0 /* width */, pr = ~0U /* prec */; - char pad = ' ', minus = 0, c = fmt[++i]; - if (c == '#') - x++, c = fmt[++i]; - if (c == '-') - minus++, c = fmt[++i]; - if (c == '0') - pad = '0', c = fmt[++i]; - while (is_digit(c)) - w *= 10, w += (size_t)(c - '0'), c = fmt[++i]; - if (c == '.') { - c = fmt[++i]; - if (c == '*') { - pr = (size_t)va_arg(*ap, int); - c = fmt[++i]; - } else { - pr = 0; - while (is_digit(c)) - pr *= 10, pr += (size_t)(c - '0'), c = fmt[++i]; - } - } - while (c == 'h') - c = fmt[++i]; // Treat h and hh as int - if (c == 'l') { - is_long++, c = fmt[++i]; - if (c == 'l') - is_long++, c = fmt[++i]; - } - if (c == 'p') - x = 1, is_long = 1; - if (c == 'd' || c == 'u' || c == 'x' || c == 'X' || c == 'p' || c == 'g' || c == 'f') { - bool s = (c == 'd'), h = (c == 'x' || c == 'X' || c == 'p'); - char tmp[40]; - size_t xl = x ? 2 : 0; - if (c == 'g' || c == 'f') { - double v = va_arg(*ap, double); - if (pr == ~0U) - pr = 6; - k = mg_dtoa(tmp, sizeof(tmp), v, (int)pr, c == 'g'); - } else if (is_long == 2) { - int64_t v = va_arg(*ap, int64_t); - k = mg_lld(tmp, v, s, h); - } else if (is_long == 1) { - long v = va_arg(*ap, long); - k = mg_lld(tmp, s ? (int64_t)v : (int64_t)(unsigned long)v, s, h); - } else { - int v = va_arg(*ap, int); - k = mg_lld(tmp, s ? (int64_t)v : (int64_t)(unsigned)v, s, h); - } - for (j = 0; j < xl && w > 0; j++) - w--; - for (j = 0; pad == ' ' && !minus && k < w && j + k < w; j++) - n += scpy(out, param, &pad, 1); - n += scpy(out, param, (char*)"0x", xl); - for (j = 0; pad == '0' && k < w && j + k < w; j++) - n += scpy(out, param, &pad, 1); - n += scpy(out, param, tmp, k); - for (j = 0; pad == ' ' && minus && k < w && j + k < w; j++) - n += scpy(out, param, &pad, 1); - } else if (c == 'm' || c == 'M') { - mg_pm_t f = va_arg(*ap, mg_pm_t); - if (c == 'm') - out('"', param); - n += f(out, param, ap); - if (c == 'm') - n += 2, out('"', param); - } else if (c == 'c') { - int ch = va_arg(*ap, int); - out((char)ch, param); - n++; - } else if (c == 's') { - char* p = va_arg(*ap, char*); - if (pr == ~0U) - pr = p == NULL ? 0 : strlen(p); - for (j = 0; !minus && pr < w && j + pr < w; j++) - n += scpy(out, param, &pad, 1); - n += scpy(out, param, p, pr); - for (j = 0; minus && pr < w && j + pr < w; j++) - n += scpy(out, param, &pad, 1); - } else if (c == '%') { - out('%', param); - n++; - } else { - out('%', param); - out(c, param); - n += 2; - } - i++; - } else { - out(fmt[i], param), n++, i++; - } - } - return n; -} - -#ifdef MG_ENABLE_LINES -#line 1 "src/fs.c" -#endif - -struct mg_fd* mg_fs_open(struct mg_fs* fs, const char* path, int flags) -{ - struct mg_fd* fd = (struct mg_fd*)calloc(1, sizeof(*fd)); - if (fd != NULL) { - fd->fd = calloc(1, sizeof(int)); - *(int*)fd->fd = PrivOpen(path, 0); - MG_DEBUG(("open path: %s, fd: %d", path, *(int*)fd->fd)); - fd->fs = fs; - if (fd->fd == NULL) { - free(fd); - fd = NULL; - } - } - return fd; -} - -void mg_fs_close(struct mg_fd* fd) -{ - if (fd != NULL) { - fd->fs->cl(fd->fd); - free(fd); - } -} - -char* mg_file_read(struct mg_fs* fs, const char* path, size_t* sizep) -{ - struct mg_fd* fd; - char* data = NULL; - size_t size = 0; - fs->st(path, &size, NULL); - if ((fd = mg_fs_open(fs, path, MG_FS_READ)) != NULL) { - data = (char*)calloc(1, size + 1); - if (data != NULL) { - if (fs->rd(fd->fd, data, size) != size) { - free(data); - data = NULL; - } else { - data[size] = '\0'; - if (sizep != NULL) - *sizep = size; - } - } - mg_fs_close(fd); - } - return data; -} - -bool mg_file_write(struct mg_fs* fs, const char* path, const void* buf, - size_t len) -{ - bool result = false; - struct mg_fd* fd; - char tmp[MG_PATH_MAX]; - mg_snprintf(tmp, sizeof(tmp), "%s..%d", path, rand()); - if ((fd = mg_fs_open(fs, tmp, MG_FS_WRITE)) != NULL) { - result = fs->wr(fd->fd, buf, len) == len; - mg_fs_close(fd); - if (result) { - fs->rm(path); - fs->mv(tmp, path); - } else { - fs->rm(tmp); - } - } - return result; -} - -bool mg_file_printf(struct mg_fs* fs, const char* path, const char* fmt, ...) -{ - va_list ap; - char* data; - bool result = false; - va_start(ap, fmt); - data = mg_vmprintf(fmt, &ap); - va_end(ap); - result = mg_file_write(fs, path, data, strlen(data)); - free(data); - return result; -} - -#ifdef MG_ENABLE_LINES -#line 1 "src/fs_fat.c" -#endif - -#if MG_ENABLE_FATFS -#include - -static int mg_days_from_epoch(int y, int m, int d) -{ - y -= m <= 2; - int era = y / 400; - int yoe = y - era * 400; - int doy = (153 * (m + (m > 2 ? -3 : 9)) + 2) / 5 + d - 1; - int doe = yoe * 365 + yoe / 4 - yoe / 100 + doy; - return era * 146097 + doe - 719468; -} - -static time_t mg_timegm(const struct tm* t) -{ - int year = t->tm_year + 1900; - int month = t->tm_mon; // 0-11 - if (month > 11) { - year += month / 12; - month %= 12; - } else if (month < 0) { - int years_diff = (11 - month) / 12; - year -= years_diff; - month += 12 * years_diff; - } - int x = mg_days_from_epoch(year, month + 1, t->tm_mday); - return 60 * (60 * (24L * x + t->tm_hour) + t->tm_min) + t->tm_sec; -} - -static time_t ff_time_to_epoch(uint16_t fdate, uint16_t ftime) -{ - struct tm tm; - memset(&tm, 0, sizeof(struct tm)); - tm.tm_sec = (ftime << 1) & 0x3e; - tm.tm_min = ((ftime >> 5) & 0x3f); - tm.tm_hour = ((ftime >> 11) & 0x1f); - tm.tm_mday = (fdate & 0x1f); - tm.tm_mon = ((fdate >> 5) & 0x0f) - 1; - tm.tm_year = ((fdate >> 9) & 0x7f) + 80; - return mg_timegm(&tm); -} - -static int ff_stat(const char* path, size_t* size, time_t* mtime) -{ - MG_DEBUG(("%s fatstat for %s", __func__, path)); - FILINFO fi; - if (path[0] == '\0') { - if (size) - *size = 0; - if (mtime) - *mtime = 0; - return MG_FS_DIR; - } else if (f_stat(path, &fi) == 0) { - if (size) - *size = (size_t)fi.fsize; - if (mtime) - *mtime = ff_time_to_epoch(fi.fdate, fi.ftime); - MG_DEBUG(("%s successful fatstat, file size: %u", __func__, *size)); - return MG_FS_READ | MG_FS_WRITE | ((fi.fattrib & AM_DIR) ? MG_FS_DIR : 0); - } else { - return 0; - } -} - -static void ff_list(const char* dir, void (*fn)(const char*, void*), - void* userdata) -{ - DIR d; - FILINFO fi; - if (f_opendir(&d, dir) == FR_OK) { - while (f_readdir(&d, &fi) == FR_OK && fi.fname[0] != '\0') { - if (!strcmp(fi.fname, ".") || !strcmp(fi.fname, "..")) - continue; - fn(fi.fname, userdata); - } - f_closedir(&d); - } -} - -static void* ff_open(const char* path, int flags) -{ - FIL f; - unsigned char mode = FA_READ; - if (flags & MG_FS_WRITE) - mode |= FA_WRITE | FA_OPEN_ALWAYS | FA_OPEN_APPEND; - if (f_open(&f, path, mode) == 0) { - FIL* fp; - if ((fp = calloc(1, sizeof(*fp))) != NULL) { - memcpy(fp, &f, sizeof(*fp)); - return fp; - } - } - return NULL; -} - -static void ff_close(void* fp) -{ - if (fp != NULL) { - f_close((FIL*)fp); - free(fp); - } -} - -static size_t ff_read(void* fp, void* buf, size_t len) -{ - UINT n = 0, misalign = ((size_t)buf) & 3; - if (misalign) { - char aligned[4]; - f_read((FIL*)fp, aligned, len > misalign ? misalign : len, &n); - memcpy(buf, aligned, n); - } else { - f_read((FIL*)fp, buf, len, &n); - } - return n; -} - -static size_t ff_write(void* fp, const void* buf, size_t len) -{ - UINT n = 0; - return f_write((FIL*)fp, (char*)buf, len, &n) == FR_OK ? n : 0; -} - -static size_t ff_seek(void* fp, size_t offset) -{ - f_lseek((FIL*)fp, offset); - return offset; -} - -static bool ff_rename(const char* from, const char* to) -{ - return f_rename(from, to) == FR_OK; -} - -static bool ff_remove(const char* path) -{ - return f_unlink(path) == FR_OK; -} - -static bool ff_mkdir(const char* path) -{ - return f_mkdir(path) == FR_OK; -} - -struct mg_fs mg_fs_fat = { ff_stat, ff_list, ff_open, ff_close, ff_read, - ff_write, ff_seek, ff_rename, ff_remove, ff_mkdir }; -#endif - -#ifdef MG_ENABLE_LINES -#line 1 "src/fs_packed.c" -#endif - -struct packed_file { - const char* data; - size_t size; - size_t pos; -}; - -#if MG_ENABLE_PACKED_FS -#else -const char* mg_unpack(const char* path, size_t* size, time_t* mtime) -{ - *size = 0, *mtime = 0; - (void)path; - return NULL; -} -const char* mg_unlist(size_t no) -{ - (void)no; - return NULL; -} -#endif - -struct mg_str mg_unpacked(const char* path) -{ - size_t len = 0; - const char* buf = mg_unpack(path, &len, NULL); - return mg_str_n(buf, len); -} - -static int is_dir_prefix(const char* prefix, size_t n, const char* path) -{ - // MG_INFO(("[%.*s] [%s] %c", (int) n, prefix, path, path[n])); - return n < strlen(path) && strncmp(prefix, path, n) == 0 && (n == 0 || path[n] == '/' || path[n - 1] == '/'); -} - -static int packed_stat(const char* path, size_t* size, time_t* mtime) -{ - const char* p; - size_t i, n = strlen(path); - if (mg_unpack(path, size, mtime)) - return MG_FS_READ; // Regular file - // Scan all files. If `path` is a dir prefix for any of them, it's a dir - for (i = 0; (p = mg_unlist(i)) != NULL; i++) { - if (is_dir_prefix(path, n, p)) - return MG_FS_DIR; - } - return 0; -} - -static void packed_list(const char* dir, void (*fn)(const char*, void*), - void* userdata) -{ - char buf[MG_PATH_MAX], tmp[sizeof(buf)]; - const char *path, *begin, *end; - size_t i, n = strlen(dir); - tmp[0] = '\0'; // Previously listed entry - for (i = 0; (path = mg_unlist(i)) != NULL; i++) { - if (!is_dir_prefix(dir, n, path)) - continue; - begin = &path[n + 1]; - end = strchr(begin, '/'); - if (end == NULL) - end = begin + strlen(begin); - mg_snprintf(buf, sizeof(buf), "%.*s", (int)(end - begin), begin); - buf[sizeof(buf) - 1] = '\0'; - // If this entry has been already listed, skip - // NOTE: we're assuming that file list is sorted alphabetically - if (strcmp(buf, tmp) == 0) - continue; - fn(buf, userdata); // Not yet listed, call user function - strcpy(tmp, buf); // And save this entry as listed - } -} - -static void* packed_open(const char* path, int flags) -{ - size_t size = 0; - const char* data = mg_unpack(path, &size, NULL); - struct packed_file* fp = NULL; - if (data == NULL) - return NULL; - if (flags & MG_FS_WRITE) - return NULL; - if ((fp = (struct packed_file*)calloc(1, sizeof(*fp))) != NULL) { - fp->size = size; - fp->data = data; - } - return (void*)fp; -} - -static void packed_close(void* fp) -{ - if (fp != NULL) - free(fp); -} - -static size_t packed_read(void* fd, void* buf, size_t len) -{ - struct packed_file* fp = (struct packed_file*)fd; - if (fp->pos + len > fp->size) - len = fp->size - fp->pos; - memcpy(buf, &fp->data[fp->pos], len); - fp->pos += len; - return len; -} - -static size_t packed_write(void* fd, const void* buf, size_t len) -{ - (void)fd, (void)buf, (void)len; - return 0; -} - -static size_t packed_seek(void* fd, size_t offset) -{ - struct packed_file* fp = (struct packed_file*)fd; - fp->pos = offset; - if (fp->pos > fp->size) - fp->pos = fp->size; - return fp->pos; -} - -static bool packed_rename(const char* from, const char* to) -{ - (void)from, (void)to; - return false; -} - -static bool packed_remove(const char* path) -{ - (void)path; - return false; -} - -static bool packed_mkdir(const char* path) -{ - (void)path; - return false; -} - -struct mg_fs mg_fs_packed = { - packed_stat, packed_list, packed_open, packed_close, packed_read, - packed_write, packed_seek, packed_rename, packed_remove, packed_mkdir -}; - -#ifdef MG_ENABLE_LINES -#line 1 "src/fs_posix.c" -#endif - -#if MG_ENABLE_FILE - -#ifndef MG_STAT_STRUCT -#define MG_STAT_STRUCT stat -#endif - -#ifndef MG_STAT_FUNC -#define MG_STAT_FUNC stat -#endif - -static int p_stat(const char* path, size_t* size, time_t* mtime) -{ -#if !defined(S_ISDIR) - MG_ERROR(("stat() API is not supported. %p %p %p", path, size, mtime)); - return 0; -#else -#if MG_ARCH == MG_ARCH_WIN32 - struct _stati64 st; - wchar_t tmp[MG_PATH_MAX]; - MultiByteToWideChar(CP_UTF8, 0, path, -1, tmp, sizeof(tmp) / sizeof(tmp[0])); - if (_wstati64(tmp, &st) != 0) - return 0; - // If path is a symlink, windows reports 0 in st.st_size. - // Get a real file size by opening it and jumping to the end - if (st.st_size == 0 && (st.st_mode & _S_IFREG)) { - FILE* fp = _wfopen(tmp, L"rb"); - if (fp != NULL) { - fseek(fp, 0, SEEK_END); - if (ftell(fp) > 0) - st.st_size = ftell(fp); // Use _ftelli64 on win10+ - fclose(fp); - } - } -#else - struct MG_STAT_STRUCT st; - if (MG_STAT_FUNC(path, &st) != 0) - return 0; -#endif - if (size) - *size = (size_t)st.st_size; - if (mtime) - *mtime = st.st_mtime; - return MG_FS_READ | MG_FS_WRITE | (S_ISDIR(st.st_mode) ? MG_FS_DIR : 0); -#endif -} - -#if MG_ARCH == MG_ARCH_WIN32 -struct dirent { - char d_name[MAX_PATH]; -}; - -typedef struct win32_dir { - HANDLE handle; - WIN32_FIND_DATAW info; - struct dirent result; -} DIR; - -int gettimeofday(struct timeval* tv, void* tz) -{ - FILETIME ft; - unsigned __int64 tmpres = 0; - - if (tv != NULL) { - GetSystemTimeAsFileTime(&ft); - tmpres |= ft.dwHighDateTime; - tmpres <<= 32; - tmpres |= ft.dwLowDateTime; - tmpres /= 10; // convert into microseconds - tmpres -= (int64_t)11644473600000000; - tv->tv_sec = (long)(tmpres / 1000000UL); - tv->tv_usec = (long)(tmpres % 1000000UL); - } - (void)tz; - return 0; -} - -static int to_wchar(const char* path, wchar_t* wbuf, size_t wbuf_len) -{ - int ret; - char buf[MAX_PATH * 2], buf2[MAX_PATH * 2], *p; - strncpy(buf, path, sizeof(buf)); - buf[sizeof(buf) - 1] = '\0'; - // Trim trailing slashes. Leave backslash for paths like "X:\" - p = buf + strlen(buf) - 1; - while (p > buf && p[-1] != ':' && (p[0] == '\\' || p[0] == '/')) - *p-- = '\0'; - memset(wbuf, 0, wbuf_len * sizeof(wchar_t)); - ret = MultiByteToWideChar(CP_UTF8, 0, buf, -1, wbuf, (int)wbuf_len); - // Convert back to Unicode. If doubly-converted string does not match the - // original, something is fishy, reject. - WideCharToMultiByte(CP_UTF8, 0, wbuf, (int)wbuf_len, buf2, sizeof(buf2), - NULL, NULL); - if (strcmp(buf, buf2) != 0) { - wbuf[0] = L'\0'; - ret = 0; - } - return ret; -} - -DIR* opendir(const char* name) -{ - DIR* d = NULL; - wchar_t wpath[MAX_PATH]; - DWORD attrs; - - if (name == NULL) { - SetLastError(ERROR_BAD_ARGUMENTS); - } else if ((d = (DIR*)calloc(1, sizeof(*d))) == NULL) { - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - } else { - to_wchar(name, wpath, sizeof(wpath) / sizeof(wpath[0])); - attrs = GetFileAttributesW(wpath); - if (attrs != 0Xffffffff && (attrs & FILE_ATTRIBUTE_DIRECTORY)) { - (void)wcscat(wpath, L"\\*"); - d->handle = FindFirstFileW(wpath, &d->info); - d->result.d_name[0] = '\0'; - } else { - free(d); - d = NULL; - } - } - return d; -} - -int closedir(DIR* d) -{ - int result = 0; - if (d != NULL) { - if (d->handle != INVALID_HANDLE_VALUE) - result = FindClose(d->handle) ? 0 : -1; - free(d); - } else { - result = -1; - SetLastError(ERROR_BAD_ARGUMENTS); - } - return result; -} - -struct dirent* readdir(DIR* d) -{ - struct dirent* result = NULL; - if (d != NULL) { - memset(&d->result, 0, sizeof(d->result)); - if (d->handle != INVALID_HANDLE_VALUE) { - result = &d->result; - WideCharToMultiByte(CP_UTF8, 0, d->info.cFileName, -1, result->d_name, - sizeof(result->d_name), NULL, NULL); - if (!FindNextFileW(d->handle, &d->info)) { - FindClose(d->handle); - d->handle = INVALID_HANDLE_VALUE; - } - } else { - SetLastError(ERROR_FILE_NOT_FOUND); - } - } else { - SetLastError(ERROR_BAD_ARGUMENTS); - } - return result; -} -#endif - -static void p_list(const char* dir, void (*fn)(const char*, void*), - void* userdata) -{ -#if MG_ENABLE_DIRLIST - struct dirent* dp; - DIR* dirp; - if ((dirp = (opendir(dir))) == NULL) - return; - while ((dp = readdir(dirp)) != NULL) { - if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, "..")) - continue; - fn(dp->d_name, userdata); - } - closedir(dirp); -#else - (void)dir, (void)fn, (void)userdata; -#endif -} - -static void* p_open(const char* path, int flags) -{ -#if MG_ARCH == MG_ARCH_WIN32 - const char* mode = flags == MG_FS_READ ? "rb" : "a+b"; - wchar_t b1[MG_PATH_MAX], b2[10]; - MultiByteToWideChar(CP_UTF8, 0, path, -1, b1, sizeof(b1) / sizeof(b1[0])); - MultiByteToWideChar(CP_UTF8, 0, mode, -1, b2, sizeof(b2) / sizeof(b2[0])); - return (void*)_wfopen(b1, b2); -#else - const char* mode = flags == MG_FS_READ ? "rbe" : "a+be"; // e for CLOEXEC - return (void*)fopen(path, mode); -#endif -} - -static void p_close(void* fp) -{ - // fclose((FILE*)fp); - PrivClose(*(int*)fp); -} - -static size_t p_read(void* fp, void* buf, size_t len) -{ - // return fread(buf, 1, len, (FILE*)fp); - int read_len = PrivRead(*(int*)fp, buf, len); - MG_DEBUG(("read len: %d", read_len)); - return read_len; -} - -static size_t p_write(void* fp, const void* buf, size_t len) -{ - int write_len = PrivWrite(*(int*)fp, buf, len); - MG_DEBUG(("write len: %d", write_len)); - return write_len; -} - -static size_t p_seek(void* fp, size_t offset) -{ - MG_DEBUG(("lseek offset: %d", offset)); - if (PrivLseek(*(int*)fp, (long)offset, SEEK_SET) != 0) - (void)0; - return PrivLseek(*(int*)fp, 0, SEEK_CUR); -} - -static bool p_rename(const char* from, const char* to) -{ - return rename(from, to) == 0; -} - -static bool p_remove(const char* path) -{ - return remove(path) == 0; -} - -static bool p_mkdir(const char* path) -{ - return mkdir(path, 0775) == 0; -} - -#else - -static int p_stat(const char* path, size_t* size, time_t* mtime) -{ - (void)path, (void)size, (void)mtime; - return 0; -} -static void p_list(const char* path, void (*fn)(const char*, void*), - void* userdata) -{ - (void)path, (void)fn, (void)userdata; -} -static void* p_open(const char* path, int flags) -{ - (void)path, (void)flags; - return NULL; -} -static void p_close(void* fp) -{ - (void)fp; -} -static size_t p_read(void* fd, void* buf, size_t len) -{ - (void)fd, (void)buf, (void)len; - return 0; -} -static size_t p_write(void* fd, const void* buf, size_t len) -{ - (void)fd, (void)buf, (void)len; - return 0; -} -static size_t p_seek(void* fd, size_t offset) -{ - (void)fd, (void)offset; - return (size_t)~0; -} -static bool p_rename(const char* from, const char* to) -{ - (void)from, (void)to; - return false; -} -static bool p_remove(const char* path) -{ - (void)path; - return false; -} -static bool p_mkdir(const char* path) -{ - (void)path; - return false; -} -#endif - -struct mg_fs mg_fs_posix = { p_stat, p_list, p_open, p_close, p_read, - p_write, p_seek, p_rename, p_remove, p_mkdir }; - -#ifdef MG_ENABLE_LINES -#line 1 "src/http.c" -#endif - -bool mg_to_size_t(struct mg_str str, size_t* val); -bool mg_to_size_t(struct mg_str str, size_t* val) -{ - size_t i = 0, max = (size_t)-1, max2 = max / 10, result = 0, ndigits = 0; - while (i < str.len && (str.ptr[i] == ' ' || str.ptr[i] == '\t')) - i++; - if (i < str.len && str.ptr[i] == '-') - return false; - while (i < str.len && str.ptr[i] >= '0' && str.ptr[i] <= '9') { - size_t digit = (size_t)(str.ptr[i] - '0'); - if (result > max2) - return false; // Overflow - result *= 10; - if (result > max - digit) - return false; // Overflow - result += digit; - i++, ndigits++; - } - while (i < str.len && (str.ptr[i] == ' ' || str.ptr[i] == '\t')) - i++; - if (ndigits == 0) - return false; // #2322: Content-Length = 1 * DIGIT - if (i != str.len) - return false; // Ditto - *val = (size_t)result; - return true; -} - -// Chunk deletion marker is the MSB in the "processed" counter -#define MG_DMARK ((size_t)1 << (sizeof(size_t) * 8 - 1)) - -// Multipart POST example: -// --xyz -// Content-Disposition: form-data; name="val" -// -// abcdef -// --xyz -// Content-Disposition: form-data; name="foo"; filename="a.txt" -// Content-Type: text/plain -// -// hello world -// -// --xyz-- -size_t mg_http_next_multipart(struct mg_str body, size_t ofs, - struct mg_http_part* part) -{ - struct mg_str cd = mg_str_n("Content-Disposition", 19); - const char* s = body.ptr; - size_t b = ofs, h1, h2, b1, b2, max = body.len; - - // Init part params - if (part != NULL) - part->name = part->filename = part->body = mg_str_n(0, 0); - - // Skip boundary - while (b + 2 < max && s[b] != '\r' && s[b + 1] != '\n') - b++; - if (b <= ofs || b + 2 >= max) - return 0; - // MG_INFO(("B: %zu %zu [%.*s]", ofs, b - ofs, (int) (b - ofs), s)); - - // Skip headers - h1 = h2 = b + 2; - for (;;) { - while (h2 + 2 < max && s[h2] != '\r' && s[h2 + 1] != '\n') - h2++; - if (h2 == h1) - break; - if (h2 + 2 >= max) - return 0; - // MG_INFO(("Header: [%.*s]", (int) (h2 - h1), &s[h1])); - if (part != NULL && h1 + cd.len + 2 < h2 && s[h1 + cd.len] == ':' && mg_ncasecmp(&s[h1], cd.ptr, cd.len) == 0) { - struct mg_str v = mg_str_n(&s[h1 + cd.len + 2], h2 - (h1 + cd.len + 2)); - part->name = mg_http_get_header_var(v, mg_str_n("name", 4)); - part->filename = mg_http_get_header_var(v, mg_str_n("filename", 8)); - } - h1 = h2 = h2 + 2; - } - b1 = b2 = h2 + 2; - while (b2 + 2 + (b - ofs) + 2 < max && !(s[b2] == '\r' && s[b2 + 1] == '\n' && memcmp(&s[b2 + 2], s, b - ofs) == 0)) - b2++; - - if (b2 + 2 >= max) - return 0; - if (part != NULL) - part->body = mg_str_n(&s[b1], b2 - b1); - // MG_INFO(("Body: [%.*s]", (int) (b2 - b1), &s[b1])); - return b2 + 2; -} - -void mg_http_bauth(struct mg_connection* c, const char* user, - const char* pass) -{ - struct mg_str u = mg_str(user), p = mg_str(pass); - size_t need = c->send.len + 36 + (u.len + p.len) * 2; - if (c->send.size < need) - mg_iobuf_resize(&c->send, need); - if (c->send.size >= need) { - size_t i, n = 0; - char* buf = (char*)&c->send.buf[c->send.len]; - memcpy(buf, "Authorization: Basic ", 21); // DON'T use mg_send! - for (i = 0; i < u.len; i++) { - n = mg_base64_update(((unsigned char*)u.ptr)[i], buf + 21, n); - } - if (p.len > 0) { - n = mg_base64_update(':', buf + 21, n); - for (i = 0; i < p.len; i++) { - n = mg_base64_update(((unsigned char*)p.ptr)[i], buf + 21, n); - } - } - n = mg_base64_final(buf + 21, n); - c->send.len += 21 + (size_t)n + 2; - memcpy(&c->send.buf[c->send.len - 2], "\r\n", 2); - } else { - MG_ERROR(("%lu oom %d->%d ", c->id, (int)c->send.size, (int)need)); - } -} - -struct mg_str mg_http_var(struct mg_str buf, struct mg_str name) -{ - struct mg_str k, v, result = mg_str_n(NULL, 0); - while (mg_split(&buf, &k, &v, '&')) { - if (name.len == k.len && mg_ncasecmp(name.ptr, k.ptr, k.len) == 0) { - result = v; - break; - } - } - return result; -} - -int mg_http_get_var(const struct mg_str* buf, const char* name, char* dst, - size_t dst_len) -{ - int len; - if (dst == NULL || dst_len == 0) { - len = -2; // Bad destination - } else if (buf->ptr == NULL || name == NULL || buf->len == 0) { - len = -1; // Bad source - dst[0] = '\0'; - } else { - struct mg_str v = mg_http_var(*buf, mg_str(name)); - if (v.ptr == NULL) { - len = -4; // Name does not exist - } else { - len = mg_url_decode(v.ptr, v.len, dst, dst_len, 1); - if (len < 0) - len = -3; // Failed to decode - } - } - return len; -} - -static bool isx(int c) -{ - return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'); -} - -int mg_url_decode(const char* src, size_t src_len, char* dst, size_t dst_len, - int is_form_url_encoded) -{ - size_t i, j; - for (i = j = 0; i < src_len && j + 1 < dst_len; i++, j++) { - if (src[i] == '%') { - // Use `i + 2 < src_len`, not `i < src_len - 2`, note small src_len - if (i + 2 < src_len && isx(src[i + 1]) && isx(src[i + 2])) { - mg_unhex(src + i + 1, 2, (uint8_t*)&dst[j]); - i += 2; - } else { - return -1; - } - } else if (is_form_url_encoded && src[i] == '+') { - dst[j] = ' '; - } else { - dst[j] = src[i]; - } - } - if (j < dst_len) - dst[j] = '\0'; // Null-terminate the destination - return i >= src_len && j < dst_len ? (int)j : -1; -} - -static bool isok(uint8_t c) -{ - return c == '\n' || c == '\r' || c >= ' '; -} - -int mg_http_get_request_len(const unsigned char* buf, size_t buf_len) -{ - size_t i; - for (i = 0; i < buf_len; i++) { - if (!isok(buf[i])) - return -1; - if ((i > 0 && buf[i] == '\n' && buf[i - 1] == '\n') || (i > 3 && buf[i] == '\n' && buf[i - 1] == '\r' && buf[i - 2] == '\n')) - return (int)i + 1; - } - return 0; -} -struct mg_str* mg_http_get_header(struct mg_http_message* h, const char* name) -{ - size_t i, n = strlen(name), max = sizeof(h->headers) / sizeof(h->headers[0]); - for (i = 0; i < max && h->headers[i].name.len > 0; i++) { - struct mg_str *k = &h->headers[i].name, *v = &h->headers[i].value; - if (n == k->len && mg_ncasecmp(k->ptr, name, n) == 0) - return v; - } - return NULL; -} - -// Get character length. Used to parse method, URI, headers -static size_t clen(const char* s) -{ - uint8_t c = *(uint8_t*)s; - if (c > ' ' && c < '~') - return 1; // Usual ascii printed char - if ((c & 0xe0) == 0xc0) - return 2; // 2-byte UTF8 - if ((c & 0xf0) == 0xe0) - return 3; // 3-byte UTF8 - if ((c & 0xf8) == 0xf0) - return 4; // 4-byte UTF8 - return 0; -} - -// Skip until the newline. Return advanced `s`, or NULL on error -static const char* skiptorn(const char* s, const char* end, struct mg_str* v) -{ - v->ptr = s; - while (s < end && s[0] != '\n' && s[0] != '\r') - s++, v->len++; // To newline - if (s >= end || (s[0] == '\r' && s[1] != '\n')) - return NULL; // Stray \r - if (s < end && s[0] == '\r') - s++; // Skip \r - if (s >= end || *s++ != '\n') - return NULL; // Skip \n - return s; -} - -static bool mg_http_parse_headers(const char* s, const char* end, - struct mg_http_header* h, size_t max_hdrs) -{ - size_t i, n; - for (i = 0; i < max_hdrs; i++) { - struct mg_str k = { NULL, 0 }, v = { NULL, 0 }; - if (s >= end) - return false; - if (s[0] == '\n' || (s[0] == '\r' && s[1] == '\n')) - break; - k.ptr = s; - while (s < end && s[0] != ':' && (n = clen(s)) > 0) - s += n, k.len += n; - if (k.len == 0) - return false; // Empty name - if (s >= end || *s++ != ':') - return false; // Invalid, not followed by : - while (s < end && s[0] == ' ') - s++; // Skip spaces - if ((s = skiptorn(s, end, &v)) == NULL) - return false; - while (v.len > 0 && v.ptr[v.len - 1] == ' ') - v.len--; // Trim spaces - // MG_INFO(("--HH [%.*s] [%.*s]", (int) k.len, k.ptr, (int) v.len, v.ptr)); - h[i].name = k, h[i].value = v; // Success. Assign values - } - return true; -} - -int mg_http_parse(const char* s, size_t len, struct mg_http_message* hm) -{ - int is_response, req_len = mg_http_get_request_len((unsigned char*)s, len); - const char *end = s == NULL ? NULL : s + req_len, *qs; // Cannot add to NULL - struct mg_str* cl; - size_t n; - - memset(hm, 0, sizeof(*hm)); - if (req_len <= 0) - return req_len; - - hm->message.ptr = hm->head.ptr = s; - hm->body.ptr = end; - hm->head.len = (size_t)req_len; - hm->chunk.ptr = end; - hm->message.len = hm->body.len = (size_t)~0; // Set body length to infinite - - // Parse request line - hm->method.ptr = s; - while (s < end && (n = clen(s)) > 0) - s += n, hm->method.len += n; - while (s < end && s[0] == ' ') - s++; // Skip spaces - hm->uri.ptr = s; - while (s < end && (n = clen(s)) > 0) - s += n, hm->uri.len += n; - while (s < end && s[0] == ' ') - s++; // Skip spaces - if ((s = skiptorn(s, end, &hm->proto)) == NULL) - return false; - - // If URI contains '?' character, setup query string - if ((qs = (const char*)memchr(hm->uri.ptr, '?', hm->uri.len)) != NULL) { - hm->query.ptr = qs + 1; - hm->query.len = (size_t)(&hm->uri.ptr[hm->uri.len] - (qs + 1)); - hm->uri.len = (size_t)(qs - hm->uri.ptr); - } - - // Sanity check. Allow protocol/reason to be empty - // Do this check after hm->method.len and hm->uri.len are finalised - if (hm->method.len == 0 || hm->uri.len == 0) - return -1; - - if (!mg_http_parse_headers(s, end, hm->headers, - sizeof(hm->headers) / sizeof(hm->headers[0]))) - return -1; // error when parsing - if ((cl = mg_http_get_header(hm, "Content-Length")) != NULL) { - if (mg_to_size_t(*cl, &hm->body.len) == false) - return -1; - hm->message.len = (size_t)req_len + hm->body.len; - } - - // mg_http_parse() is used to parse both HTTP requests and HTTP - // responses. If HTTP response does not have Content-Length set, then - // body is read until socket is closed, i.e. body.len is infinite (~0). - // - // For HTTP requests though, according to - // http://tools.ietf.org/html/rfc7231#section-8.1.3, - // only POST and PUT methods have defined body semantics. - // Therefore, if Content-Length is not specified and methods are - // not one of PUT or POST, set body length to 0. - // - // So, if it is HTTP request, and Content-Length is not set, - // and method is not (PUT or POST) then reset body length to zero. - is_response = mg_ncasecmp(hm->method.ptr, "HTTP/", 5) == 0; - if (hm->body.len == (size_t)~0 && !is_response && mg_vcasecmp(&hm->method, "PUT") != 0 && mg_vcasecmp(&hm->method, "POST") != 0) { - hm->body.len = 0; - hm->message.len = (size_t)req_len; - } - - // The 204 (No content) responses also have 0 body length - if (hm->body.len == (size_t)~0 && is_response && mg_vcasecmp(&hm->uri, "204") == 0) { - hm->body.len = 0; - hm->message.len = (size_t)req_len; - } - if (hm->message.len < (size_t)req_len) - return -1; // Overflow protection - - return req_len; -} - -static void mg_http_vprintf_chunk(struct mg_connection* c, const char* fmt, - va_list* ap) -{ - size_t len = c->send.len; - mg_send(c, " \r\n", 10); - mg_vxprintf(mg_pfn_iobuf, &c->send, fmt, ap); - if (c->send.len >= len + 10) { - mg_snprintf((char*)c->send.buf + len, 9, "%08lx", c->send.len - len - 10); - c->send.buf[len + 8] = '\r'; - if (c->send.len == len + 10) - c->is_resp = 0; // Last chunk, reset marker - } - mg_send(c, "\r\n", 2); -} - -void mg_http_printf_chunk(struct mg_connection* c, const char* fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - mg_http_vprintf_chunk(c, fmt, &ap); - va_end(ap); -} - -void mg_http_write_chunk(struct mg_connection* c, const char* buf, size_t len) -{ - mg_printf(c, "%lx\r\n", (unsigned long)len); - mg_send(c, buf, len); - mg_send(c, "\r\n", 2); - if (len == 0) - c->is_resp = 0; -} - -// clang-format off -static const char *mg_http_status_code_str(int status_code) { - switch (status_code) { - case 100: return "Continue"; - case 101: return "Switching Protocols"; - case 102: return "Processing"; - case 200: return "OK"; - case 201: return "Created"; - case 202: return "Accepted"; - case 203: return "Non-authoritative Information"; - case 204: return "No Content"; - case 205: return "Reset Content"; - case 206: return "Partial Content"; - case 207: return "Multi-Status"; - case 208: return "Already Reported"; - case 226: return "IM Used"; - case 300: return "Multiple Choices"; - case 301: return "Moved Permanently"; - case 302: return "Found"; - case 303: return "See Other"; - case 304: return "Not Modified"; - case 305: return "Use Proxy"; - case 307: return "Temporary Redirect"; - case 308: return "Permanent Redirect"; - case 400: return "Bad Request"; - case 401: return "Unauthorized"; - case 402: return "Payment Required"; - case 403: return "Forbidden"; - case 404: return "Not Found"; - case 405: return "Method Not Allowed"; - case 406: return "Not Acceptable"; - case 407: return "Proxy Authentication Required"; - case 408: return "Request Timeout"; - case 409: return "Conflict"; - case 410: return "Gone"; - case 411: return "Length Required"; - case 412: return "Precondition Failed"; - case 413: return "Payload Too Large"; - case 414: return "Request-URI Too Long"; - case 415: return "Unsupported Media Type"; - case 416: return "Requested Range Not Satisfiable"; - case 417: return "Expectation Failed"; - case 418: return "I'm a teapot"; - case 421: return "Misdirected Request"; - case 422: return "Unprocessable Entity"; - case 423: return "Locked"; - case 424: return "Failed Dependency"; - case 426: return "Upgrade Required"; - case 428: return "Precondition Required"; - case 429: return "Too Many Requests"; - case 431: return "Request Header Fields Too Large"; - case 444: return "Connection Closed Without Response"; - case 451: return "Unavailable For Legal Reasons"; - case 499: return "Client Closed Request"; - case 500: return "Internal Server Error"; - case 501: return "Not Implemented"; - case 502: return "Bad Gateway"; - case 503: return "Service Unavailable"; - case 504: return "Gateway Timeout"; - case 505: return "HTTP Version Not Supported"; - case 506: return "Variant Also Negotiates"; - case 507: return "Insufficient Storage"; - case 508: return "Loop Detected"; - case 510: return "Not Extended"; - case 511: return "Network Authentication Required"; - case 599: return "Network Connect Timeout Error"; - default: return ""; - } -} -// clang-format on - -void mg_http_reply(struct mg_connection* c, int code, const char* headers, - const char* fmt, ...) -{ - va_list ap; - size_t len; - mg_printf(c, "HTTP/1.1 %d %s\r\n%sContent-Length: \r\n\r\n", code, - mg_http_status_code_str(code), headers == NULL ? "" : headers); - len = c->send.len; - va_start(ap, fmt); - mg_vxprintf(mg_pfn_iobuf, &c->send, fmt, &ap); - va_end(ap); - if (c->send.len > 16) { - size_t n = mg_snprintf((char*)&c->send.buf[len - 15], 11, "%-10lu", - (unsigned long)(c->send.len - len)); - c->send.buf[len - 15 + n] = ' '; // Change ending 0 to space - } - c->is_resp = 0; -} - -static void http_cb(struct mg_connection*, int, void*, void*); -static void restore_http_cb(struct mg_connection* c) -{ - mg_fs_close((struct mg_fd*)c->pfn_data); - c->pfn_data = NULL; - c->pfn = http_cb; - c->is_resp = 0; -} - -char* mg_http_etag(char* buf, size_t len, size_t size, time_t mtime); -char* mg_http_etag(char* buf, size_t len, size_t size, time_t mtime) -{ - mg_snprintf(buf, len, "\"%lld.%lld\"", (int64_t)mtime, (int64_t)size); - return buf; -} - -static void static_cb(struct mg_connection* c, int ev, void* ev_data, - void* fn_data) -{ - if (ev == MG_EV_WRITE || ev == MG_EV_POLL) { - struct mg_fd* fd = (struct mg_fd*)fn_data; - // Read to send IO buffer directly, avoid extra on-stack buffer - size_t n, max = MG_IO_SIZE, space; - size_t* cl = (size_t*)&c->data[(sizeof(c->data) - sizeof(size_t)) / sizeof(size_t) * sizeof(size_t)]; - if (c->send.size < max) - mg_iobuf_resize(&c->send, max); - if (c->send.len >= c->send.size) - return; // Rate limit - if ((space = c->send.size - c->send.len) > *cl) - space = *cl; - n = fd->fs->rd(fd->fd, c->send.buf + c->send.len, space); - c->send.len += n; - *cl -= n; - if (n == 0) - restore_http_cb(c); - } else if (ev == MG_EV_CLOSE) { - restore_http_cb(c); - } - (void)ev_data; -} - -// Known mime types. Keep it outside guess_content_type() function, since -// some environments don't like it defined there. -// clang-format off -static struct mg_str s_known_types[] = { - MG_C_STR("html"), MG_C_STR("text/html; charset=utf-8"), - MG_C_STR("htm"), MG_C_STR("text/html; charset=utf-8"), - MG_C_STR("css"), MG_C_STR("text/css; charset=utf-8"), - MG_C_STR("js"), MG_C_STR("text/javascript; charset=utf-8"), - MG_C_STR("gif"), MG_C_STR("image/gif"), - MG_C_STR("png"), MG_C_STR("image/png"), - MG_C_STR("jpg"), MG_C_STR("image/jpeg"), - MG_C_STR("jpeg"), MG_C_STR("image/jpeg"), - MG_C_STR("woff"), MG_C_STR("font/woff"), - MG_C_STR("ttf"), MG_C_STR("font/ttf"), - MG_C_STR("svg"), MG_C_STR("image/svg+xml"), - MG_C_STR("txt"), MG_C_STR("text/plain; charset=utf-8"), - MG_C_STR("avi"), MG_C_STR("video/x-msvideo"), - MG_C_STR("csv"), MG_C_STR("text/csv"), - MG_C_STR("doc"), MG_C_STR("application/msword"), - MG_C_STR("exe"), MG_C_STR("application/octet-stream"), - MG_C_STR("gz"), MG_C_STR("application/gzip"), - MG_C_STR("ico"), MG_C_STR("image/x-icon"), - MG_C_STR("json"), MG_C_STR("application/json"), - MG_C_STR("mov"), MG_C_STR("video/quicktime"), - MG_C_STR("mp3"), MG_C_STR("audio/mpeg"), - MG_C_STR("mp4"), MG_C_STR("video/mp4"), - MG_C_STR("mpeg"), MG_C_STR("video/mpeg"), - MG_C_STR("pdf"), MG_C_STR("application/pdf"), - MG_C_STR("shtml"), MG_C_STR("text/html; charset=utf-8"), - MG_C_STR("tgz"), MG_C_STR("application/tar-gz"), - MG_C_STR("wav"), MG_C_STR("audio/wav"), - MG_C_STR("webp"), MG_C_STR("image/webp"), - MG_C_STR("zip"), MG_C_STR("application/zip"), - MG_C_STR("3gp"), MG_C_STR("video/3gpp"), - {0, 0}, -}; -// clang-format on - -static struct mg_str guess_content_type(struct mg_str path, const char* extra) -{ - struct mg_str k, v, s = mg_str(extra); - size_t i = 0; - - // Shrink path to its extension only - while (i < path.len && path.ptr[path.len - i - 1] != '.') - i++; - path.ptr += path.len - i; - path.len = i; - - // Process user-provided mime type overrides, if any - while (mg_commalist(&s, &k, &v)) { - if (mg_strcmp(path, k) == 0) - return v; - } - - // Process built-in mime types - for (i = 0; s_known_types[i].ptr != NULL; i += 2) { - if (mg_strcmp(path, s_known_types[i]) == 0) - return s_known_types[i + 1]; - } - - return mg_str("text/plain; charset=utf-8"); -} - -static int getrange(struct mg_str* s, size_t* a, size_t* b) -{ - size_t i, numparsed = 0; - for (i = 0; i + 6 < s->len; i++) { - struct mg_str k, v = mg_str_n(s->ptr + i + 6, s->len - i - 6); - if (memcmp(&s->ptr[i], "bytes=", 6) != 0) - continue; - if (mg_split(&v, &k, NULL, '-')) { - if (mg_to_size_t(k, a)) - numparsed++; - if (v.len > 0 && mg_to_size_t(v, b)) - numparsed++; - } else { - if (mg_to_size_t(v, a)) - numparsed++; - } - break; - } - return (int)numparsed; -} - -void mg_http_serve_file(struct mg_connection* c, struct mg_http_message* hm, - const char* path, - const struct mg_http_serve_opts* opts) -{ - char etag[64], tmp[MG_PATH_MAX]; - struct mg_fs* fs = opts->fs == NULL ? &mg_fs_posix : opts->fs; - struct mg_fd* fd = NULL; - size_t size = 0; - time_t mtime = 0; - struct mg_str* inm = NULL; - struct mg_str mime = guess_content_type(mg_str(path), opts->mime_types); - bool gzip = false; - - if (path != NULL) { - // If a browser sends us "Accept-Encoding: gzip", try to open .gz first - // struct mg_str* ae = mg_http_get_header(hm, "Accept-Encoding"); - // if (ae != NULL && mg_strstr(*ae, mg_str("gzip")) != NULL) { - // mg_snprintf(tmp, sizeof(tmp), "%s.gz", path); - // fd = mg_fs_open(fs, tmp, MG_FS_READ); - // if (fd != NULL) - // gzip = true, path = tmp; - // } - // No luck opening .gz? Open what we've told to open - // if (fd == NULL) - fd = mg_fs_open(fs, path, MG_FS_READ); - } - - // Failed to open, and page404 is configured? Open it, then - if (fd == NULL && opts->page404 != NULL) { - fd = mg_fs_open(fs, opts->page404, MG_FS_READ); - mime = guess_content_type(mg_str(path), opts->mime_types); - path = opts->page404; - } - - if (fd == NULL || fs->st(path, &size, &mtime) == 0) { - mg_http_reply(c, 404, opts->extra_headers, "Not found\n"); - mg_fs_close(fd); - // NOTE: mg_http_etag() call should go first! - } else if (mg_http_etag(etag, sizeof(etag), size, mtime) != NULL && (inm = mg_http_get_header(hm, "If-None-Match")) != NULL && mg_vcasecmp(inm, etag) == 0) { - mg_fs_close(fd); - mg_http_reply(c, 304, opts->extra_headers, ""); - } else { - int n, status = 200; - char range[100]; - size_t r1 = 0, r2 = 0, cl = size; - - // Handle Range header - struct mg_str* rh = mg_http_get_header(hm, "Range"); - range[0] = '\0'; - if (rh != NULL && (n = getrange(rh, &r1, &r2)) > 0) { - // If range is specified like "400-", set second limit to content len - if (n == 1) - r2 = cl - 1; - if (r1 > r2 || r2 >= cl) { - status = 416; - cl = 0; - mg_snprintf(range, sizeof(range), "Content-Range: bytes */%lld\r\n", - (int64_t)size); - } else { - status = 206; - cl = r2 - r1 + 1; - mg_snprintf(range, sizeof(range), - "Content-Range: bytes %llu-%llu/%llu\r\n", (uint64_t)r1, - (uint64_t)(r1 + cl - 1), (uint64_t)size); - fs->sk(fd->fd, r1); - } - } - mg_printf(c, - "HTTP/1.1 %d %s\r\n" - "Content-Type: %.*s\r\n" - "Etag: %s\r\n" - "Content-Length: %llu\r\n" - "%s%s%s\r\n", - status, mg_http_status_code_str(status), (int)mime.len, mime.ptr, - etag, (uint64_t)cl, gzip ? "Content-Encoding: gzip\r\n" : "", - range, opts->extra_headers ? opts->extra_headers : ""); - if (mg_vcasecmp(&hm->method, "HEAD") == 0) { - c->is_draining = 1; - c->is_resp = 0; - mg_fs_close(fd); - } else { - // Track to-be-sent content length at the end of c->data, aligned - size_t* clp = (size_t*)&c->data[(sizeof(c->data) - sizeof(size_t)) / sizeof(size_t) * sizeof(size_t)]; - c->pfn = static_cb; - c->pfn_data = fd; - *clp = cl; - } - } -} - -struct printdirentrydata { - struct mg_connection* c; - struct mg_http_message* hm; - const struct mg_http_serve_opts* opts; - const char* dir; -}; - -#if MG_ENABLE_DIRLIST -static void printdirentry(const char* name, void* userdata) -{ - struct printdirentrydata* d = (struct printdirentrydata*)userdata; - struct mg_fs* fs = d->opts->fs == NULL ? &mg_fs_posix : d->opts->fs; - size_t size = 0; - time_t t = 0; - char path[MG_PATH_MAX], sz[40], mod[40]; - int flags, n = 0; - - // MG_DEBUG(("[%s] [%s]", d->dir, name)); - if (mg_snprintf(path, sizeof(path), "%s%c%s", d->dir, '/', name) > sizeof(path)) { - MG_ERROR(("%s truncated", name)); - } else if ((flags = fs->st(path, &size, &t)) == 0) { - MG_ERROR(("%lu stat(%s): %d", d->c->id, path, errno)); - } else { - const char* slash = flags & MG_FS_DIR ? "/" : ""; - if (flags & MG_FS_DIR) { - mg_snprintf(sz, sizeof(sz), "%s", "[DIR]"); - } else { - mg_snprintf(sz, sizeof(sz), "%lld", (uint64_t)size); - } -#if defined(MG_HTTP_DIRLIST_TIME_FMT) - { - char time_str[40]; - struct tm* time_info = localtime(&t); - strftime(time_str, sizeof time_str, "%Y/%m/%d %H:%M:%S", time_info); - mg_snprintf(mod, sizeof(mod), "%s", time_str); - } -#else - mg_snprintf(mod, sizeof(mod), "%lu", (unsigned long)t); -#endif - n = (int)mg_url_encode(name, strlen(name), path, sizeof(path)); - mg_printf(d->c, - " %s%s" - "%s%s\n", - n, path, slash, name, slash, (unsigned long)t, mod, - flags & MG_FS_DIR ? (int64_t)-1 : (int64_t)size, sz); - } -} - -static void listdir(struct mg_connection* c, struct mg_http_message* hm, - const struct mg_http_serve_opts* opts, char* dir) -{ - const char* sort_js_code = ""; - struct mg_fs* fs = opts->fs == NULL ? &mg_fs_posix : opts->fs; - struct printdirentrydata d = { c, hm, opts, dir }; - char tmp[10], buf[MG_PATH_MAX]; - size_t off, n; - int len = mg_url_decode(hm->uri.ptr, hm->uri.len, buf, sizeof(buf), 0); - struct mg_str uri = len > 0 ? mg_str_n(buf, (size_t)len) : hm->uri; - - mg_printf(c, - "HTTP/1.1 200 OK\r\n" - "Content-Type: text/html; charset=utf-8\r\n" - "%s" - "Content-Length: \r\n\r\n", - opts->extra_headers == NULL ? "" : opts->extra_headers); - off = c->send.len; // Start of body - mg_printf(c, - "Index of %.*s%s%s" - "" - "

Index of %.*s

" - "" - "" - "" - "" - "\n", - (int)uri.len, uri.ptr, sort_js_code, sort_js_code2, (int)uri.len, - uri.ptr); - mg_printf(c, "%s", - " " - "\n"); - - fs->ls(dir, printdirentry, &d); - mg_printf(c, - "" - "
Name" - "ModifiedSize

..[DIR]

Mongoose v.%s
\n", - MG_VERSION); - n = mg_snprintf(tmp, sizeof(tmp), "%lu", (unsigned long)(c->send.len - off)); - if (n > sizeof(tmp)) - n = 0; - memcpy(c->send.buf + off - 12, tmp, n); // Set content length - c->is_resp = 0; // Mark response end -} -#endif - -// Resolve requested file into `path` and return its fs->st() result -static int uri_to_path2(struct mg_connection* c, struct mg_http_message* hm, - struct mg_fs* fs, struct mg_str url, struct mg_str dir, - char* path, size_t path_size) -{ - int flags, tmp; - // Append URI to the root_dir, and sanitize it - size_t n = mg_snprintf(path, path_size, "%.*s", (int)dir.len, dir.ptr); - if (n + 2 >= path_size) { - mg_http_reply(c, 400, "", "Exceeded path size"); - return -1; - } - path[path_size - 1] = '\0'; - // Terminate root dir with slash - if (n > 0 && path[n - 1] != '/') - path[n++] = '/', path[n] = '\0'; - if (url.len < hm->uri.len) { - mg_url_decode(hm->uri.ptr + url.len, hm->uri.len - url.len, path + n, - path_size - n, 0); - } - path[path_size - 1] = '\0'; // Double-check - if (!mg_path_is_sane(path)) { - mg_http_reply(c, 400, "", "Invalid path"); - return -1; - } - n = strlen(path); - while (n > 1 && path[n - 1] == '/') - path[--n] = 0; // Trim trailing slashes - flags = mg_vcmp(&hm->uri, "/") == 0 ? MG_FS_DIR : fs->st(path, NULL, NULL); - MG_VERBOSE(("%lu %.*s -> %s %d", c->id, (int)hm->uri.len, hm->uri.ptr, path, - flags)); - if (flags == 0) { - // Do nothing - let's caller decide - } else if ((flags & MG_FS_DIR) && hm->uri.len > 0 && hm->uri.ptr[hm->uri.len - 1] != '/') { - mg_printf(c, - "HTTP/1.1 301 Moved\r\n" - "Location: %.*s/\r\n" - "Content-Length: 0\r\n" - "\r\n", - (int)hm->uri.len, hm->uri.ptr); - c->is_resp = 0; - flags = -1; - } else if (flags & MG_FS_DIR) { - if (((mg_snprintf(path + n, path_size - n, "/" MG_HTTP_INDEX) > 0 && (tmp = fs->st(path, NULL, NULL)) != 0) || (mg_snprintf(path + n, path_size - n, "/index.shtml") > 0 && (tmp = fs->st(path, NULL, NULL)) != 0))) { - flags = tmp; - } else if ((mg_snprintf(path + n, path_size - n, "/" MG_HTTP_INDEX ".gz") > 0 && (tmp = fs->st(path, NULL, NULL)) != 0)) { // check for gzipped index - flags = tmp; - path[n + 1 + strlen(MG_HTTP_INDEX)] = '\0'; // Remove appended .gz in index file name - } else { - path[n] = '\0'; // Remove appended index file name - } - } - return flags; -} - -static int uri_to_path(struct mg_connection* c, struct mg_http_message* hm, - const struct mg_http_serve_opts* opts, char* path, - size_t path_size) -{ - struct mg_fs* fs = opts->fs == NULL ? &mg_fs_posix : opts->fs; - struct mg_str k, v, s = mg_str(opts->root_dir), u = { 0, 0 }, p = { 0, 0 }; - while (mg_commalist(&s, &k, &v)) { - if (v.len == 0) - v = k, k = mg_str("/"), u = k, p = v; - if (hm->uri.len < k.len) - continue; - if (mg_strcmp(k, mg_str_n(hm->uri.ptr, k.len)) != 0) - continue; - u = k, p = v; - } - return uri_to_path2(c, hm, fs, u, p, path, path_size); -} - -void mg_http_serve_dir(struct mg_connection* c, struct mg_http_message* hm, - const struct mg_http_serve_opts* opts) -{ - char path[MG_PATH_MAX]; - const char* sp = opts->ssi_pattern; - int flags = uri_to_path(c, hm, opts, path, sizeof(path)); - MG_DEBUG(("path: %s", path)); - if (flags < 0) { - // Do nothing: the response has already been sent by uri_to_path() - } else if (flags & MG_FS_DIR) { -#if MG_ENABLE_DIRLIST - listdir(c, hm, opts, path); -#else - mg_http_reply(c, 403, "", "Forbidden\n"); -#endif - } else if (flags && sp != NULL && mg_globmatch(sp, strlen(sp), path, strlen(path))) { - mg_http_serve_ssi(c, opts->root_dir, path); - } else { - mg_http_serve_file(c, hm, path, opts); - } -} - -static bool mg_is_url_safe(int c) -{ - return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '.' || c == '_' || c == '-' || c == '~'; -} - -size_t mg_url_encode(const char* s, size_t sl, char* buf, size_t len) -{ - size_t i, n = 0; - for (i = 0; i < sl; i++) { - int c = *(unsigned char*)&s[i]; - if (n + 4 >= len) - return 0; - if (mg_is_url_safe(c)) { - buf[n++] = s[i]; - } else { - buf[n++] = '%'; - mg_hex(&s[i], 1, &buf[n]); - n += 2; - } - } - if (len > 0 && n < len - 1) - buf[n] = '\0'; // Null-terminate the destination - if (len > 0) - buf[len - 1] = '\0'; // Always. - return n; -} - -void mg_http_creds(struct mg_http_message* hm, char* user, size_t userlen, - char* pass, size_t passlen) -{ - struct mg_str* v = mg_http_get_header(hm, "Authorization"); - user[0] = pass[0] = '\0'; - if (v != NULL && v->len > 6 && memcmp(v->ptr, "Basic ", 6) == 0) { - char buf[256]; - size_t n = mg_base64_decode(v->ptr + 6, v->len - 6, buf, sizeof(buf)); - const char* p = (const char*)memchr(buf, ':', n > 0 ? n : 0); - if (p != NULL) { - mg_snprintf(user, userlen, "%.*s", p - buf, buf); - mg_snprintf(pass, passlen, "%.*s", n - (size_t)(p - buf) - 1, p + 1); - } - } else if (v != NULL && v->len > 7 && memcmp(v->ptr, "Bearer ", 7) == 0) { - mg_snprintf(pass, passlen, "%.*s", (int)v->len - 7, v->ptr + 7); - } else if ((v = mg_http_get_header(hm, "Cookie")) != NULL) { - struct mg_str t = mg_http_get_header_var(*v, mg_str_n("access_token", 12)); - if (t.len > 0) - mg_snprintf(pass, passlen, "%.*s", (int)t.len, t.ptr); - } else { - mg_http_get_var(&hm->query, "access_token", pass, passlen); - } -} - -static struct mg_str stripquotes(struct mg_str s) -{ - return s.len > 1 && s.ptr[0] == '"' && s.ptr[s.len - 1] == '"' - ? mg_str_n(s.ptr + 1, s.len - 2) - : s; -} - -struct mg_str mg_http_get_header_var(struct mg_str s, struct mg_str v) -{ - size_t i; - for (i = 0; v.len > 0 && i + v.len + 2 < s.len; i++) { - if (s.ptr[i + v.len] == '=' && memcmp(&s.ptr[i], v.ptr, v.len) == 0) { - const char *p = &s.ptr[i + v.len + 1], *b = p, *x = &s.ptr[s.len]; - int q = p < x && *p == '"' ? 1 : 0; - while (p < x && (q ? p == b || *p != '"' : *p != ';' && *p != ' ' && *p != ',')) - p++; - // MG_INFO(("[%.*s] [%.*s] [%.*s]", (int) s.len, s.ptr, (int) v.len, - // v.ptr, (int) (p - b), b)); - return stripquotes(mg_str_n(b, (size_t)(p - b + q))); - } - } - return mg_str_n(NULL, 0); -} - -bool mg_http_match_uri(const struct mg_http_message* hm, const char* glob) -{ - return mg_match(hm->uri, mg_str(glob), NULL); -} - -long mg_http_upload(struct mg_connection* c, struct mg_http_message* hm, - struct mg_fs* fs, const char* path, size_t max_size) -{ - char buf[20] = "0"; - long res = 0, offset; - mg_http_get_var(&hm->query, "offset", buf, sizeof(buf)); - offset = strtol(buf, NULL, 0); - if (hm->body.len == 0) { - mg_http_reply(c, 200, "", "%ld", res); // Nothing to write - } else { - struct mg_fd* fd; - size_t current_size = 0; - MG_DEBUG(("%s -> %d bytes @ %ld", path, (int)hm->body.len, offset)); - if (offset == 0) - fs->rm(path); // If offset if 0, truncate file - fs->st(path, ¤t_size, NULL); - if (offset < 0) { - mg_http_reply(c, 400, "", "offset required"); - res = -1; - } else if (offset > 0 && current_size != (size_t)offset) { - mg_http_reply(c, 400, "", "%s: offset mismatch", path); - res = -2; - } else if ((size_t)offset + hm->body.len > max_size) { - mg_http_reply(c, 400, "", "%s: over max size of %lu", path, - (unsigned long)max_size); - res = -3; - } else if ((fd = mg_fs_open(fs, path, MG_FS_WRITE)) == NULL) { - mg_http_reply(c, 400, "", "open(%s): %d", path, errno); - res = -4; - } else { - res = offset + (long)fs->wr(fd->fd, hm->body.ptr, hm->body.len); - mg_fs_close(fd); - mg_http_reply(c, 200, "", "%ld", res); - } - } - return res; -} - -int mg_http_status(const struct mg_http_message* hm) -{ - return atoi(hm->uri.ptr); -} - -static bool is_hex_digit(int c) -{ - return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'); -} - -// If a server sends data to the client using chunked encoding, Mongoose strips -// off the chunking prefix (hex length and \r\n) and suffix (\r\n), appends the -// stripped data to the body, and fires the MG_EV_HTTP_CHUNK event. When zero -// chunk is received, we fire MG_EV_HTTP_MSG, and the body already has all -// chunking prefixes/suffixes stripped. -// -// If a server sends data without chunked encoding, we also fire a series of -// MG_EV_HTTP_CHUNK events for every received piece of data, and then we fire -// MG_EV_HTTP_MSG event in the end. -// -// We track total processed length in the c->pfn_data, which is a void * -// pointer: we store a size_t value there. -static bool getchunk(struct mg_str s, size_t* prefixlen, size_t* datalen) -{ - size_t i = 0, n; - while (i < s.len && is_hex_digit(s.ptr[i])) - i++; - n = mg_unhexn(s.ptr, i); - // MG_INFO(("%d %d", (int) (i + n + 4), (int) s.len)); - if (s.len < i + n + 4) - return false; // Chunk not yet fully buffered - if (s.ptr[i] != '\r' || s.ptr[i + 1] != '\n') - return false; - if (s.ptr[i + n + 2] != '\r' || s.ptr[i + n + 3] != '\n') - return false; - *prefixlen = i + 2; - *datalen = n; - return true; -} - -static bool mg_is_chunked(struct mg_http_message* hm) -{ - const char* needle = "chunked"; - struct mg_str* te = mg_http_get_header(hm, "Transfer-Encoding"); - return te != NULL && mg_vcasecmp(te, needle) == 0; -} - -void mg_http_delete_chunk(struct mg_connection* c, struct mg_http_message* hm) -{ - size_t ofs = (size_t)(hm->chunk.ptr - (char*)c->recv.buf); - mg_iobuf_del(&c->recv, ofs, hm->chunk.len); - c->pfn_data = (void*)((size_t)c->pfn_data | MG_DMARK); -} - -static void deliver_chunked_chunks(struct mg_connection* c, size_t hlen, - struct mg_http_message* hm, bool* next) -{ - // | ... headers ... | HEXNUM\r\n ..data.. \r\n | ...... - // +------------------+--------------------------+---- - // | hlen | chunk1 | ...... - char *buf = (char*)&c->recv.buf[hlen], *p = buf; - size_t len = c->recv.len - hlen; - size_t processed = ((size_t)c->pfn_data) & ~MG_DMARK; - size_t mark, pl, dl, del = 0, ofs = 0; - bool last = false; - if (processed <= len) - len -= processed, buf += processed; - while (!last && getchunk(mg_str_n(buf + ofs, len - ofs), &pl, &dl)) { - size_t saved = c->recv.len; - memmove(p + processed, buf + ofs + pl, dl); - // MG_INFO(("P2 [%.*s]", (int) (processed + dl), p)); - hm->chunk = mg_str_n(p + processed, dl); - mg_call(c, MG_EV_HTTP_CHUNK, hm); - ofs += pl + dl + 2, del += pl + 2; // 2 is for \r\n suffix - processed += dl; - if (c->recv.len != saved) - processed -= dl, buf -= dl; - // mg_hexdump(c->recv.buf, hlen + processed); - last = (dl == 0); - } - mg_iobuf_del(&c->recv, hlen + processed, del); - mark = ((size_t)c->pfn_data) & MG_DMARK; - c->pfn_data = (void*)(processed | mark); - if (last) { - hm->body.len = processed; - hm->message.len = hlen + processed; - c->pfn_data = NULL; - if (mark) - mg_iobuf_del(&c->recv, 0, hlen), *next = true; - // MG_INFO(("LAST, mark: %lx", mark)); - // mg_hexdump(c->recv.buf, c->recv.len); - } -} - -static void deliver_normal_chunks(struct mg_connection* c, size_t hlen, - struct mg_http_message* hm, bool* next) -{ - size_t left, processed = ((size_t)c->pfn_data) & ~MG_DMARK; - size_t deleted = ((size_t)c->pfn_data) & MG_DMARK; - hm->chunk = mg_str_n((char*)&c->recv.buf[hlen], c->recv.len - hlen); - if (processed <= hm->chunk.len && !deleted) { - hm->chunk.len -= processed; - hm->chunk.ptr += processed; - } - left = hm->body.len < processed ? 0 : hm->body.len - processed; - if (hm->chunk.len > left) - hm->chunk.len = left; - if (hm->chunk.len > 0) - mg_call(c, MG_EV_HTTP_CHUNK, hm); - processed += hm->chunk.len; - deleted = ((size_t)c->pfn_data) & MG_DMARK; // Re-evaluate after user call - if (processed >= hm->body.len) { // Last, 0-len chunk - hm->chunk.len = 0; // Reset length - mg_call(c, MG_EV_HTTP_CHUNK, hm); // Call user handler - c->pfn_data = NULL; // Reset processed counter - if (processed && deleted) - mg_iobuf_del(&c->recv, 0, hlen), *next = true; - } else { - c->pfn_data = (void*)(processed | deleted); // if it is set - } -} - -static void http_cb(struct mg_connection* c, int ev, void* evd, void* fnd) -{ - if (ev == MG_EV_READ || ev == MG_EV_CLOSE) { - struct mg_http_message hm; - while (c->recv.buf != NULL && c->recv.len > 0) { - bool next = false; - int hlen = mg_http_parse((char*)c->recv.buf, c->recv.len, &hm); - if (hlen < 0) { - mg_error(c, "HTTP parse:\n%.*s", (int)c->recv.len, c->recv.buf); - break; - } - if (c->is_resp) - break; // Response is still generated - if (hlen == 0) - break; // Request is not buffered yet - if (ev == MG_EV_CLOSE) { // If client did not set Content-Length - hm.message.len = c->recv.len; // and closes now, deliver a MSG - hm.body.len = hm.message.len - (size_t)(hm.body.ptr - hm.message.ptr); - } - if (mg_is_chunked(&hm)) { - deliver_chunked_chunks(c, (size_t)hlen, &hm, &next); - } else { - deliver_normal_chunks(c, (size_t)hlen, &hm, &next); - } - if (next) - continue; // Chunks & request were deleted - // Chunk events are delivered. If we have full body, deliver MSG - if (c->recv.len < hm.message.len) - break; - if (c->is_accepted) - c->is_resp = 1; // Start generating response - mg_call(c, MG_EV_HTTP_MSG, &hm); // User handler can clear is_resp - mg_iobuf_del(&c->recv, 0, hm.message.len); - } - } - (void)evd, (void)fnd; -} - -static void mg_hfn(struct mg_connection* c, int ev, void* ev_data, void* fnd) -{ - if (ev == MG_EV_HTTP_MSG) { - struct mg_http_message* hm = (struct mg_http_message*)ev_data; - if (mg_http_match_uri(hm, "/quit")) { - mg_http_reply(c, 200, "", "ok\n"); - c->is_draining = 1; - c->data[0] = 'X'; - } else if (mg_http_match_uri(hm, "/debug")) { - int level = (int)mg_json_get_long(hm->body, "$.level", MG_LL_DEBUG); - mg_log_set(level); - mg_http_reply(c, 200, "", "Debug level set to %d\n", level); - } else { - mg_http_reply(c, 200, "", "hi\n"); - } - } else if (ev == MG_EV_CLOSE) { - if (c->data[0] == 'X') - *(bool*)fnd = true; - } -} - -void mg_hello(const char* url) -{ - struct mg_mgr mgr; - bool done = false; - mg_mgr_init(&mgr); - if (mg_http_listen(&mgr, url, mg_hfn, &done) == NULL) - done = true; - while (done == false) - mg_mgr_poll(&mgr, 100); - mg_mgr_free(&mgr); -} - -struct mg_connection* mg_http_connect(struct mg_mgr* mgr, const char* url, - mg_event_handler_t fn, void* fn_data) -{ - struct mg_connection* c = mg_connect(mgr, url, fn, fn_data); - if (c != NULL) - c->pfn = http_cb; - return c; -} - -struct mg_connection* mg_http_listen(struct mg_mgr* mgr, const char* url, - mg_event_handler_t fn, void* fn_data) -{ - struct mg_connection* c = mg_listen(mgr, url, fn, fn_data); - if (c != NULL) - c->pfn = http_cb; - return c; -} - -#ifdef MG_ENABLE_LINES -#line 1 "src/iobuf.c" -#endif - -static size_t roundup(size_t size, size_t align) -{ - return align == 0 ? size : (size + align - 1) / align * align; -} - -int mg_iobuf_resize(struct mg_iobuf* io, size_t new_size) -{ - int ok = 1; - new_size = roundup(new_size, io->align); - if (new_size == 0) { - mg_bzero(io->buf, io->size); - free(io->buf); - io->buf = NULL; - io->len = io->size = 0; - } else if (new_size != io->size) { - // NOTE(lsm): do not use realloc here. Use calloc/free only, to ease the - // porting to some obscure platforms like FreeRTOS - void* p = calloc(1, new_size); - if (p != NULL) { - size_t len = new_size < io->len ? new_size : io->len; - if (len > 0 && io->buf != NULL) - memmove(p, io->buf, len); - mg_bzero(io->buf, io->size); - free(io->buf); - io->buf = (unsigned char*)p; - io->size = new_size; - } else { - ok = 0; - MG_ERROR(("%lld->%lld", (uint64_t)io->size, (uint64_t)new_size)); - } - } - return ok; -} - -int mg_iobuf_init(struct mg_iobuf* io, size_t size, size_t align) -{ - io->buf = NULL; - io->align = align; - io->size = io->len = 0; - return mg_iobuf_resize(io, size); -} - -size_t mg_iobuf_add(struct mg_iobuf* io, size_t ofs, const void* buf, - size_t len) -{ - size_t new_size = roundup(io->len + len, io->align); - mg_iobuf_resize(io, new_size); // Attempt to resize - if (new_size != io->size) - len = 0; // Resize failure, append nothing - if (ofs < io->len) - memmove(io->buf + ofs + len, io->buf + ofs, io->len - ofs); - if (buf != NULL) - memmove(io->buf + ofs, buf, len); - if (ofs > io->len) - io->len += ofs - io->len; - io->len += len; - return len; -} - -size_t mg_iobuf_del(struct mg_iobuf* io, size_t ofs, size_t len) -{ - if (ofs > io->len) - ofs = io->len; - if (ofs + len > io->len) - len = io->len - ofs; - if (io->buf) - memmove(io->buf + ofs, io->buf + ofs + len, io->len - ofs - len); - if (io->buf) - mg_bzero(io->buf + io->len - len, len); - io->len -= len; - return len; -} - -void mg_iobuf_free(struct mg_iobuf* io) -{ - mg_iobuf_resize(io, 0); -} - -#ifdef MG_ENABLE_LINES -#line 1 "src/json.c" -#endif - -static const char* escapeseq(int esc) -{ - return esc ? "\b\f\n\r\t\\\"" : "bfnrt\\\""; -} - -static char json_esc(int c, int esc) -{ - const char *p, *esc1 = escapeseq(esc), *esc2 = escapeseq(!esc); - for (p = esc1; *p != '\0'; p++) { - if (*p == c) - return esc2[p - esc1]; - } - return 0; -} - -static int mg_pass_string(const char* s, int len) -{ - int i; - for (i = 0; i < len; i++) { - if (s[i] == '\\' && i + 1 < len && json_esc(s[i + 1], 1)) { - i++; - } else if (s[i] == '\0') { - return MG_JSON_INVALID; - } else if (s[i] == '"') { - return i; - } - } - return MG_JSON_INVALID; -} - -static double mg_atod(const char* p, int len, int* numlen) -{ - double d = 0.0; - int i = 0, sign = 1; - - // Sign - if (i < len && *p == '-') { - sign = -1, i++; - } else if (i < len && *p == '+') { - i++; - } - - // Decimal - for (; i < len && p[i] >= '0' && p[i] <= '9'; i++) { - d *= 10.0; - d += p[i] - '0'; - } - d *= sign; - - // Fractional - if (i < len && p[i] == '.') { - double frac = 0.0, base = 0.1; - i++; - for (; i < len && p[i] >= '0' && p[i] <= '9'; i++) { - frac += base * (p[i] - '0'); - base /= 10.0; - } - d += frac * sign; - } - - // Exponential - if (i < len && (p[i] == 'e' || p[i] == 'E')) { - int j, exp = 0, minus = 0; - i++; - if (i < len && p[i] == '-') - minus = 1, i++; - if (i < len && p[i] == '+') - i++; - while (i < len && p[i] >= '0' && p[i] <= '9' && exp < 308) - exp = exp * 10 + (p[i++] - '0'); - if (minus) - exp = -exp; - for (j = 0; j < exp; j++) - d *= 10.0; - for (j = 0; j < -exp; j++) - d /= 10.0; - } - - if (numlen != NULL) - *numlen = i; - return d; -} - -int mg_json_get(struct mg_str json, const char* path, int* toklen) -{ - const char* s = json.ptr; - int len = (int)json.len; - enum { S_VALUE, - S_KEY, - S_COLON, - S_COMMA_OR_EOO } expecting - = S_VALUE; - unsigned char nesting[MG_JSON_MAX_DEPTH]; - int i = 0; // Current offset in `s` - int j = 0; // Offset in `s` we're looking for (return value) - int depth = 0; // Current depth (nesting level) - int ed = 0; // Expected depth - int pos = 1; // Current position in `path` - int ci = -1, ei = -1; // Current and expected index in array - - if (toklen) - *toklen = 0; - if (path[0] != '$') - return MG_JSON_INVALID; - -#define MG_CHECKRET(x) \ - do { \ - if (depth == ed && path[pos] == '\0' && ci == ei) { \ - if (toklen) \ - *toklen = i - j + 1; \ - return j; \ - } \ - } while (0) - -// In the ascii table, the distance between `[` and `]` is 2. -// Ditto for `{` and `}`. Hence +2 in the code below. -#define MG_EOO(x) \ - do { \ - if (depth == ed && ci != ei) \ - return MG_JSON_NOT_FOUND; \ - if (c != nesting[depth - 1] + 2) \ - return MG_JSON_INVALID; \ - depth--; \ - MG_CHECKRET(x); \ - } while (0) - - for (i = 0; i < len; i++) { - unsigned char c = ((unsigned char*)s)[i]; - if (c == ' ' || c == '\t' || c == '\n' || c == '\r') - continue; - switch (expecting) { - case S_VALUE: - // p("V %s [%.*s] %d %d %d %d\n", path, pos, path, depth, ed, ci, ei); - if (depth == ed) - j = i; - if (c == '{') { - if (depth >= (int)sizeof(nesting)) - return MG_JSON_TOO_DEEP; - if (depth == ed && path[pos] == '.' && ci == ei) { - // If we start the object, reset array indices - ed++, pos++, ci = ei = -1; - } - nesting[depth++] = c; - expecting = S_KEY; - break; - } else if (c == '[') { - if (depth >= (int)sizeof(nesting)) - return MG_JSON_TOO_DEEP; - if (depth == ed && path[pos] == '[' && ei == ci) { - ed++, pos++, ci = 0; - for (ei = 0; path[pos] != ']' && path[pos] != '\0'; pos++) { - ei *= 10; - ei += path[pos] - '0'; - } - if (path[pos] != 0) - pos++; - } - nesting[depth++] = c; - break; - } else if (c == ']' && depth > 0) { // Empty array - MG_EOO(']'); - } else if (c == 't' && i + 3 < len && memcmp(&s[i], "true", 4) == 0) { - i += 3; - } else if (c == 'n' && i + 3 < len && memcmp(&s[i], "null", 4) == 0) { - i += 3; - } else if (c == 'f' && i + 4 < len && memcmp(&s[i], "false", 5) == 0) { - i += 4; - } else if (c == '-' || ((c >= '0' && c <= '9'))) { - int numlen = 0; - mg_atod(&s[i], len - i, &numlen); - i += numlen - 1; - } else if (c == '"') { - int n = mg_pass_string(&s[i + 1], len - i - 1); - if (n < 0) - return n; - i += n + 1; - } else { - return MG_JSON_INVALID; - } - MG_CHECKRET('V'); - if (depth == ed && ei >= 0) - ci++; - expecting = S_COMMA_OR_EOO; - break; - - case S_KEY: - if (c == '"') { - int n = mg_pass_string(&s[i + 1], len - i - 1); - if (n < 0) - return n; - if (i + 1 + n >= len) - return MG_JSON_NOT_FOUND; - if (depth < ed) - return MG_JSON_NOT_FOUND; - if (depth == ed && path[pos - 1] != '.') - return MG_JSON_NOT_FOUND; - // printf("K %s [%.*s] [%.*s] %d %d %d %d %d\n", path, pos, path, n, - // &s[i + 1], n, depth, ed, ci, ei); - // NOTE(cpq): in the check sequence below is important. - // strncmp() must go first: it fails fast if the remaining length of - // the path is smaller than `n`. - if (depth == ed && path[pos - 1] == '.' && strncmp(&s[i + 1], &path[pos], (size_t)n) == 0 && (path[pos + n] == '\0' || path[pos + n] == '.' || path[pos + n] == '[')) { - pos += n; - } - i += n + 1; - expecting = S_COLON; - } else if (c == '}') { // Empty object - MG_EOO('}'); - expecting = S_COMMA_OR_EOO; - if (depth == ed && ei >= 0) - ci++; - } else { - return MG_JSON_INVALID; - } - break; - - case S_COLON: - if (c == ':') { - expecting = S_VALUE; - } else { - return MG_JSON_INVALID; - } - break; - - case S_COMMA_OR_EOO: - if (depth <= 0) { - return MG_JSON_INVALID; - } else if (c == ',') { - expecting = (nesting[depth - 1] == '{') ? S_KEY : S_VALUE; - } else if (c == ']' || c == '}') { - if (depth == ed && c == '}' && path[pos - 1] == '.') - return MG_JSON_NOT_FOUND; - if (depth == ed && c == ']' && path[pos - 1] == ',') - return MG_JSON_NOT_FOUND; - MG_EOO('O'); - if (depth == ed && ei >= 0) - ci++; - } else { - return MG_JSON_INVALID; - } - break; - } - } - return MG_JSON_NOT_FOUND; -} - -bool mg_json_get_num(struct mg_str json, const char* path, double* v) -{ - int n, toklen, found = 0; - if ((n = mg_json_get(json, path, &toklen)) >= 0 && (json.ptr[n] == '-' || (json.ptr[n] >= '0' && json.ptr[n] <= '9'))) { - if (v != NULL) - *v = mg_atod(json.ptr + n, toklen, NULL); - found = 1; - } - return found; -} - -bool mg_json_get_bool(struct mg_str json, const char* path, bool* v) -{ - int found = 0, off = mg_json_get(json, path, NULL); - if (off >= 0 && (json.ptr[off] == 't' || json.ptr[off] == 'f')) { - if (v != NULL) - *v = json.ptr[off] == 't'; - found = 1; - } - return found; -} - -bool mg_json_unescape(struct mg_str s, char* to, size_t n) -{ - size_t i, j; - for (i = 0, j = 0; i < s.len && j < n; i++, j++) { - if (s.ptr[i] == '\\' && i + 5 < s.len && s.ptr[i + 1] == 'u') { - // \uXXXX escape. We could process a simple one-byte chars - // \u00xx from the ASCII range. More complex chars would require - // dragging in a UTF8 library, which is too much for us - if (s.ptr[i + 2] != '0' || s.ptr[i + 3] != '0') - return false; // Give up - ((unsigned char*)to)[j] = (unsigned char)mg_unhexn(s.ptr + i + 4, 2); - - i += 5; - } else if (s.ptr[i] == '\\' && i + 1 < s.len) { - char c = json_esc(s.ptr[i + 1], 0); - if (c == 0) - return false; - to[j] = c; - i++; - } else { - to[j] = s.ptr[i]; - } - } - if (j >= n) - return false; - if (n > 0) - to[j] = '\0'; - return true; -} - -char* mg_json_get_str(struct mg_str json, const char* path) -{ - char* result = NULL; - int len = 0, off = mg_json_get(json, path, &len); - if (off >= 0 && len > 1 && json.ptr[off] == '"') { - if ((result = (char*)calloc(1, (size_t)len)) != NULL && !mg_json_unescape(mg_str_n(json.ptr + off + 1, (size_t)(len - 2)), result, (size_t)len)) { - free(result); - result = NULL; - } - } - return result; -} - -char* mg_json_get_b64(struct mg_str json, const char* path, int* slen) -{ - char* result = NULL; - int len = 0, off = mg_json_get(json, path, &len); - if (off >= 0 && json.ptr[off] == '"' && len > 1 && (result = (char*)calloc(1, (size_t)len)) != NULL) { - size_t k = mg_base64_decode(json.ptr + off + 1, (size_t)(len - 2), result, - (size_t)len); - if (slen != NULL) - *slen = (int)k; - } - return result; -} - -char* mg_json_get_hex(struct mg_str json, const char* path, int* slen) -{ - char* result = NULL; - int len = 0, off = mg_json_get(json, path, &len); - if (off >= 0 && json.ptr[off] == '"' && len > 1 && (result = (char*)calloc(1, (size_t)len / 2)) != NULL) { - mg_unhex(json.ptr + off + 1, (size_t)(len - 2), (uint8_t*)result); - result[len / 2 - 1] = '\0'; - if (slen != NULL) - *slen = len / 2 - 1; - } - return result; -} - -long mg_json_get_long(struct mg_str json, const char* path, long dflt) -{ - double dv; - long result = dflt; - if (mg_json_get_num(json, path, &dv)) - result = (long)dv; - return result; -} - -#ifdef MG_ENABLE_LINES -#line 1 "src/log.c" -#endif - -static int s_level = MG_LL_INFO; -static mg_pfn_t s_log_func = mg_pfn_stdout; -static void* s_log_func_param = NULL; - -void mg_log_set_fn(mg_pfn_t fn, void* param) -{ - s_log_func = fn; - s_log_func_param = param; -} - -static void logc(unsigned char c) -{ - s_log_func((char)c, s_log_func_param); -} - -static void logs(const char* buf, size_t len) -{ - size_t i; - for (i = 0; i < len; i++) - logc(((unsigned char*)buf)[i]); -} - -void mg_log_set(int log_level) -{ - MG_DEBUG(("Setting log level to %d", log_level)); - s_level = log_level; -} - -bool mg_log_prefix(int level, const char* file, int line, const char* fname) -{ - if (level <= s_level) { - const char* p = strrchr(file, '/'); - char buf[51]; - size_t n; - if (p == NULL) - p = strrchr(file, '\\'); - n = mg_snprintf(buf, sizeof(buf), "%-6llx %d %s:%d:%s", mg_millis(), level, - p == NULL ? file : p + 1, line, fname); - if (n > sizeof(buf) - 2) - n = sizeof(buf) - 2; - while (n < sizeof(buf)) - buf[n++] = ' '; - logs(buf, n - 1); - return true; - } else { - return false; - } -} - -void mg_log(const char* fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - mg_vxprintf(s_log_func, s_log_func_param, fmt, &ap); - va_end(ap); - logs("\r\n", 2); -} - -static unsigned char nibble(unsigned c) -{ - return (unsigned char)(c < 10 ? c + '0' : c + 'W'); -} - -#define ISPRINT(x) ((x) >= ' ' && (x) <= '~') -void mg_hexdump(const void* buf, size_t len) -{ - const unsigned char* p = (const unsigned char*)buf; - unsigned char ascii[16], alen = 0; - size_t i; - for (i = 0; i < len; i++) { - if ((i % 16) == 0) { - // Print buffered ascii chars - if (i > 0) - logs(" ", 2), logs((char*)ascii, 16), logc('\n'), alen = 0; - // Print hex address, then \t - logc(nibble((i >> 12) & 15)), logc(nibble((i >> 8) & 15)), - logc(nibble((i >> 4) & 15)), logc('0'), logs(" ", 3); - } - logc(nibble(p[i] >> 4)), logc(nibble(p[i] & 15)); // Two nibbles, e.g. c5 - logc(' '); // Space after hex number - ascii[alen++] = ISPRINT(p[i]) ? p[i] : '.'; // Add to the ascii buf - } - while (alen < 16) - logs(" ", 3), ascii[alen++] = ' '; - logs(" ", 2), logs((char*)ascii, 16), logc('\n'); -} - -#ifdef MG_ENABLE_LINES -#line 1 "src/md5.c" -#endif - -#if defined(MG_ENABLE_MD5) && MG_ENABLE_MD5 - -static void mg_byte_reverse(unsigned char* buf, unsigned longs) -{ - if (MG_BIG_ENDIAN) { - do { - uint32_t t = (uint32_t)((unsigned)buf[3] << 8 | buf[2]) << 16 | ((unsigned)buf[1] << 8 | buf[0]); - *(uint32_t*)buf = t; - buf += 4; - } while (--longs); - } else { - (void)buf, (void)longs; // Little endian. Do nothing - } -} - -#define F1(x, y, z) (z ^ (x & (y ^ z))) -#define F2(x, y, z) F1(z, x, y) -#define F3(x, y, z) (x ^ y ^ z) -#define F4(x, y, z) (y ^ (x | ~z)) - -#define MD5STEP(f, w, x, y, z, data, s) \ - (w += f(x, y, z) + data, w = w << s | w >> (32 - s), w += x) - -/* - * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious - * initialization constants. - */ -void mg_md5_init(mg_md5_ctx* ctx) -{ - ctx->buf[0] = 0x67452301; - ctx->buf[1] = 0xefcdab89; - ctx->buf[2] = 0x98badcfe; - ctx->buf[3] = 0x10325476; - - ctx->bits[0] = 0; - ctx->bits[1] = 0; -} - -static void mg_md5_transform(uint32_t buf[4], uint32_t const in[16]) -{ - uint32_t a, b, c, d; - - a = buf[0]; - b = buf[1]; - c = buf[2]; - d = buf[3]; - - MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7); - MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12); - MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17); - MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22); - MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7); - MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12); - MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17); - MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22); - MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7); - MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12); - MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); - MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); - MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); - MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); - MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); - MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); - - MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5); - MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9); - MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); - MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); - MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5); - MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); - MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); - MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); - MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5); - MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); - MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14); - MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20); - MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); - MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); - MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14); - MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); - - MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4); - MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11); - MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); - MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); - MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4); - MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); - MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); - MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); - MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); - MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11); - MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16); - MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23); - MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4); - MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); - MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); - MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23); - - MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6); - MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10); - MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); - MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21); - MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); - MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); - MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); - MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21); - MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); - MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); - MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15); - MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); - MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6); - MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); - MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); - MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21); - - buf[0] += a; - buf[1] += b; - buf[2] += c; - buf[3] += d; -} - -void mg_md5_update(mg_md5_ctx* ctx, const unsigned char* buf, size_t len) -{ - uint32_t t; - - t = ctx->bits[0]; - if ((ctx->bits[0] = t + ((uint32_t)len << 3)) < t) - ctx->bits[1]++; - ctx->bits[1] += (uint32_t)len >> 29; - - t = (t >> 3) & 0x3f; - - if (t) { - unsigned char* p = (unsigned char*)ctx->in + t; - - t = 64 - t; - if (len < t) { - memcpy(p, buf, len); - return; - } - memcpy(p, buf, t); - mg_byte_reverse(ctx->in, 16); - mg_md5_transform(ctx->buf, (uint32_t*)ctx->in); - buf += t; - len -= t; - } - - while (len >= 64) { - memcpy(ctx->in, buf, 64); - mg_byte_reverse(ctx->in, 16); - mg_md5_transform(ctx->buf, (uint32_t*)ctx->in); - buf += 64; - len -= 64; - } - - memcpy(ctx->in, buf, len); -} - -void mg_md5_final(mg_md5_ctx* ctx, unsigned char digest[16]) -{ - unsigned count; - unsigned char* p; - uint32_t* a; - - count = (ctx->bits[0] >> 3) & 0x3F; - - p = ctx->in + count; - *p++ = 0x80; - count = 64 - 1 - count; - if (count < 8) { - memset(p, 0, count); - mg_byte_reverse(ctx->in, 16); - mg_md5_transform(ctx->buf, (uint32_t*)ctx->in); - memset(ctx->in, 0, 56); - } else { - memset(p, 0, count - 8); - } - mg_byte_reverse(ctx->in, 14); - - a = (uint32_t*)ctx->in; - a[14] = ctx->bits[0]; - a[15] = ctx->bits[1]; - - mg_md5_transform(ctx->buf, (uint32_t*)ctx->in); - mg_byte_reverse((unsigned char*)ctx->buf, 4); - memcpy(digest, ctx->buf, 16); - memset((char*)ctx, 0, sizeof(*ctx)); -} -#endif - -#ifdef MG_ENABLE_LINES -#line 1 "src/mqtt.c" -#endif - -#define MQTT_CLEAN_SESSION 0x02 -#define MQTT_HAS_WILL 0x04 -#define MQTT_WILL_RETAIN 0x20 -#define MQTT_HAS_PASSWORD 0x40 -#define MQTT_HAS_USER_NAME 0x80 - -struct mg_mqtt_pmap { - uint8_t id; - uint8_t type; -}; - -static const struct mg_mqtt_pmap s_prop_map[] = { - { MQTT_PROP_PAYLOAD_FORMAT_INDICATOR, MQTT_PROP_TYPE_BYTE }, - { MQTT_PROP_MESSAGE_EXPIRY_INTERVAL, MQTT_PROP_TYPE_INT }, - { MQTT_PROP_CONTENT_TYPE, MQTT_PROP_TYPE_STRING }, - { MQTT_PROP_RESPONSE_TOPIC, MQTT_PROP_TYPE_STRING }, - { MQTT_PROP_CORRELATION_DATA, MQTT_PROP_TYPE_BINARY_DATA }, - { MQTT_PROP_SUBSCRIPTION_IDENTIFIER, MQTT_PROP_TYPE_VARIABLE_INT }, - { MQTT_PROP_SESSION_EXPIRY_INTERVAL, MQTT_PROP_TYPE_INT }, - { MQTT_PROP_ASSIGNED_CLIENT_IDENTIFIER, MQTT_PROP_TYPE_STRING }, - { MQTT_PROP_SERVER_KEEP_ALIVE, MQTT_PROP_TYPE_SHORT }, - { MQTT_PROP_AUTHENTICATION_METHOD, MQTT_PROP_TYPE_STRING }, - { MQTT_PROP_AUTHENTICATION_DATA, MQTT_PROP_TYPE_BINARY_DATA }, - { MQTT_PROP_REQUEST_PROBLEM_INFORMATION, MQTT_PROP_TYPE_BYTE }, - { MQTT_PROP_WILL_DELAY_INTERVAL, MQTT_PROP_TYPE_INT }, - { MQTT_PROP_REQUEST_RESPONSE_INFORMATION, MQTT_PROP_TYPE_BYTE }, - { MQTT_PROP_RESPONSE_INFORMATION, MQTT_PROP_TYPE_STRING }, - { MQTT_PROP_SERVER_REFERENCE, MQTT_PROP_TYPE_STRING }, - { MQTT_PROP_REASON_STRING, MQTT_PROP_TYPE_STRING }, - { MQTT_PROP_RECEIVE_MAXIMUM, MQTT_PROP_TYPE_SHORT }, - { MQTT_PROP_TOPIC_ALIAS_MAXIMUM, MQTT_PROP_TYPE_SHORT }, - { MQTT_PROP_TOPIC_ALIAS, MQTT_PROP_TYPE_SHORT }, - { MQTT_PROP_MAXIMUM_QOS, MQTT_PROP_TYPE_BYTE }, - { MQTT_PROP_RETAIN_AVAILABLE, MQTT_PROP_TYPE_BYTE }, - { MQTT_PROP_USER_PROPERTY, MQTT_PROP_TYPE_STRING_PAIR }, - { MQTT_PROP_MAXIMUM_PACKET_SIZE, MQTT_PROP_TYPE_INT }, - { MQTT_PROP_WILDCARD_SUBSCRIPTION_AVAILABLE, MQTT_PROP_TYPE_BYTE }, - { MQTT_PROP_SUBSCRIPTION_IDENTIFIER_AVAILABLE, MQTT_PROP_TYPE_BYTE }, - { MQTT_PROP_SHARED_SUBSCRIPTION_AVAILABLE, MQTT_PROP_TYPE_BYTE } -}; - -void mg_mqtt_send_header(struct mg_connection* c, uint8_t cmd, uint8_t flags, - uint32_t len) -{ - uint8_t buf[1 + sizeof(len)], *vlen = &buf[1]; - buf[0] = (uint8_t)((cmd << 4) | flags); - do { - *vlen = len % 0x80; - len /= 0x80; - if (len > 0) - *vlen |= 0x80; - vlen++; - } while (len > 0 && vlen < &buf[sizeof(buf)]); - mg_send(c, buf, (size_t)(vlen - buf)); -} - -static void mg_send_u16(struct mg_connection* c, uint16_t value) -{ - mg_send(c, &value, sizeof(value)); -} - -static void mg_send_u32(struct mg_connection* c, uint32_t value) -{ - mg_send(c, &value, sizeof(value)); -} - -static uint8_t varint_size(size_t length) -{ - uint8_t bytes_needed = 0; - do { - bytes_needed++; - length /= 0x80; - } while (length > 0); - return bytes_needed; -} - -static size_t encode_varint(uint8_t* buf, size_t value) -{ - size_t len = 0; - - do { - uint8_t byte = (uint8_t)(value % 128); - value /= 128; - if (value > 0) - byte |= 0x80; - buf[len++] = byte; - } while (value > 0); - - return len; -} - -static size_t decode_varint(const uint8_t* buf, size_t len, size_t* value) -{ - size_t multiplier = 1, offset; - *value = 0; - - for (offset = 0; offset < 4 && offset < len; offset++) { - uint8_t encoded_byte = buf[offset]; - *value += (encoded_byte & 0x7f) * multiplier; - multiplier *= 128; - - if ((encoded_byte & 0x80) == 0) - return offset + 1; - } - - return 0; -} - -static int mqtt_prop_type_by_id(uint8_t prop_id) -{ - size_t i, num_properties = sizeof(s_prop_map) / sizeof(s_prop_map[0]); - for (i = 0; i < num_properties; ++i) { - if (s_prop_map[i].id == prop_id) - return s_prop_map[i].type; - } - return -1; // Property ID not found -} - -// Returns the size of the properties section, without the -// size of the content's length -static size_t get_properties_length(struct mg_mqtt_prop* props, size_t count) -{ - size_t i, size = 0; - for (i = 0; i < count; i++) { - size++; // identifier - switch (mqtt_prop_type_by_id(props[i].id)) { - case MQTT_PROP_TYPE_STRING_PAIR: - size += (uint32_t)(props[i].val.len + props[i].key.len + 2 * sizeof(uint16_t)); - break; - case MQTT_PROP_TYPE_STRING: - size += (uint32_t)(props[i].val.len + sizeof(uint16_t)); - break; - case MQTT_PROP_TYPE_BINARY_DATA: - size += (uint32_t)(props[i].val.len + sizeof(uint16_t)); - break; - case MQTT_PROP_TYPE_VARIABLE_INT: - size += varint_size((uint32_t)props[i].iv); - break; - case MQTT_PROP_TYPE_INT: - size += (uint32_t)sizeof(uint32_t); - break; - case MQTT_PROP_TYPE_SHORT: - size += (uint32_t)sizeof(uint16_t); - break; - case MQTT_PROP_TYPE_BYTE: - size += (uint32_t)sizeof(uint8_t); - break; - default: - return size; // cannot parse further down - } - } - - return size; -} - -// returns the entire size of the properties section, including the -// size of the variable length of the content -static size_t get_props_size(struct mg_mqtt_prop* props, size_t count) -{ - size_t size = get_properties_length(props, count); - size += varint_size(size); - return size; -} - -static void mg_send_mqtt_properties(struct mg_connection* c, - struct mg_mqtt_prop* props, size_t nprops) -{ - size_t total_size = get_properties_length(props, nprops); - uint8_t buf_v[4] = { 0, 0, 0, 0 }; - uint8_t buf[4] = { 0, 0, 0, 0 }; - size_t i, len = encode_varint(buf, total_size); - - mg_send(c, buf, (size_t)len); - for (i = 0; i < nprops; i++) { - mg_send(c, &props[i].id, sizeof(props[i].id)); - switch (mqtt_prop_type_by_id(props[i].id)) { - case MQTT_PROP_TYPE_STRING_PAIR: - mg_send_u16(c, mg_htons((uint16_t)props[i].key.len)); - mg_send(c, props[i].key.ptr, props[i].key.len); - mg_send_u16(c, mg_htons((uint16_t)props[i].val.len)); - mg_send(c, props[i].val.ptr, props[i].val.len); - break; - case MQTT_PROP_TYPE_BYTE: - mg_send(c, &props[i].iv, sizeof(uint8_t)); - break; - case MQTT_PROP_TYPE_SHORT: - mg_send_u16(c, mg_htons((uint16_t)props[i].iv)); - break; - case MQTT_PROP_TYPE_INT: - mg_send_u32(c, mg_htonl((uint32_t)props[i].iv)); - break; - case MQTT_PROP_TYPE_STRING: - mg_send_u16(c, mg_htons((uint16_t)props[i].val.len)); - mg_send(c, props[i].val.ptr, props[i].val.len); - break; - case MQTT_PROP_TYPE_BINARY_DATA: - mg_send_u16(c, mg_htons((uint16_t)props[i].val.len)); - mg_send(c, props[i].val.ptr, props[i].val.len); - break; - case MQTT_PROP_TYPE_VARIABLE_INT: - len = encode_varint(buf_v, props[i].iv); - mg_send(c, buf_v, (size_t)len); - break; - } - } -} - -size_t mg_mqtt_next_prop(struct mg_mqtt_message* msg, struct mg_mqtt_prop* prop, - size_t ofs) -{ - uint8_t* i = (uint8_t*)msg->dgram.ptr + msg->props_start + ofs; - uint8_t* end = (uint8_t*)msg->dgram.ptr + msg->dgram.len; - size_t new_pos = ofs, len; - prop->id = i[0]; - - if (ofs >= msg->dgram.len || ofs >= msg->props_start + msg->props_size) - return 0; - i++, new_pos++; - - switch (mqtt_prop_type_by_id(prop->id)) { - case MQTT_PROP_TYPE_STRING_PAIR: - prop->key.len = (uint16_t)((((uint16_t)i[0]) << 8) | i[1]); - prop->key.ptr = (char*)i + 2; - i += 2 + prop->key.len; - prop->val.len = (uint16_t)((((uint16_t)i[0]) << 8) | i[1]); - prop->val.ptr = (char*)i + 2; - new_pos += 2 * sizeof(uint16_t) + prop->val.len + prop->key.len; - break; - case MQTT_PROP_TYPE_BYTE: - prop->iv = (uint8_t)i[0]; - new_pos++; - break; - case MQTT_PROP_TYPE_SHORT: - prop->iv = (uint16_t)((((uint16_t)i[0]) << 8) | i[1]); - new_pos += sizeof(uint16_t); - break; - case MQTT_PROP_TYPE_INT: - prop->iv = ((uint32_t)i[0] << 24) | ((uint32_t)i[1] << 16) | ((uint32_t)i[2] << 8) | i[3]; - new_pos += sizeof(uint32_t); - break; - case MQTT_PROP_TYPE_STRING: - prop->val.len = (uint16_t)((((uint16_t)i[0]) << 8) | i[1]); - prop->val.ptr = (char*)i + 2; - new_pos += 2 + prop->val.len; - break; - case MQTT_PROP_TYPE_BINARY_DATA: - prop->val.len = (uint16_t)((((uint16_t)i[0]) << 8) | i[1]); - prop->val.ptr = (char*)i + 2; - new_pos += 2 + prop->val.len; - break; - case MQTT_PROP_TYPE_VARIABLE_INT: - len = decode_varint(i, (size_t)(end - i), (size_t*)&prop->iv); - new_pos = (!len) ? 0 : new_pos + len; - break; - default: - new_pos = 0; - } - - return new_pos; -} - -void mg_mqtt_login(struct mg_connection* c, const struct mg_mqtt_opts* opts) -{ - char rnd[10], client_id[21]; - struct mg_str cid = opts->client_id; - size_t total_len = 7 + 1 + 2 + 2; - uint8_t hdr[8] = { 0, 4, 'M', 'Q', 'T', 'T', opts->version, 0 }; - - if (cid.len == 0) { - mg_random(rnd, sizeof(rnd)); - mg_hex(rnd, sizeof(rnd), client_id); - client_id[sizeof(client_id) - 1] = '\0'; - cid = mg_str(client_id); - } - - if (hdr[6] == 0) - hdr[6] = 4; // If version is not set, use 4 (3.1.1) - c->is_mqtt5 = hdr[6] == 5; // Set version 5 flag - hdr[7] = (uint8_t)((opts->qos & 3) << 3); // Connection flags - if (opts->user.len > 0) { - total_len += 2 + (uint32_t)opts->user.len; - hdr[7] |= MQTT_HAS_USER_NAME; - } - if (opts->pass.len > 0) { - total_len += 2 + (uint32_t)opts->pass.len; - hdr[7] |= MQTT_HAS_PASSWORD; - } - if (opts->topic.len > 0 && opts->message.len > 0) { - total_len += 4 + (uint32_t)opts->topic.len + (uint32_t)opts->message.len; - hdr[7] |= MQTT_HAS_WILL; - } - if (opts->clean || cid.len == 0) - hdr[7] |= MQTT_CLEAN_SESSION; - if (opts->retain) - hdr[7] |= MQTT_WILL_RETAIN; - total_len += (uint32_t)cid.len; - if (c->is_mqtt5) { - total_len += get_props_size(opts->props, opts->num_props); - if (hdr[7] & MQTT_HAS_WILL) - total_len += get_props_size(opts->will_props, opts->num_will_props); - } - - mg_mqtt_send_header(c, MQTT_CMD_CONNECT, 0, (uint32_t)total_len); - mg_send(c, hdr, sizeof(hdr)); - // keepalive == 0 means "do not disconnect us!" - mg_send_u16(c, mg_htons((uint16_t)opts->keepalive)); - - if (c->is_mqtt5) - mg_send_mqtt_properties(c, opts->props, opts->num_props); - - mg_send_u16(c, mg_htons((uint16_t)cid.len)); - mg_send(c, cid.ptr, cid.len); - - if (hdr[7] & MQTT_HAS_WILL) { - if (c->is_mqtt5) - mg_send_mqtt_properties(c, opts->will_props, opts->num_will_props); - - mg_send_u16(c, mg_htons((uint16_t)opts->topic.len)); - mg_send(c, opts->topic.ptr, opts->topic.len); - mg_send_u16(c, mg_htons((uint16_t)opts->message.len)); - mg_send(c, opts->message.ptr, opts->message.len); - } - if (opts->user.len > 0) { - mg_send_u16(c, mg_htons((uint16_t)opts->user.len)); - mg_send(c, opts->user.ptr, opts->user.len); - } - if (opts->pass.len > 0) { - mg_send_u16(c, mg_htons((uint16_t)opts->pass.len)); - mg_send(c, opts->pass.ptr, opts->pass.len); - } -} - -void mg_mqtt_pub(struct mg_connection* c, const struct mg_mqtt_opts* opts) -{ - uint8_t flags = (uint8_t)(((opts->qos & 3) << 1) | (opts->retain ? 1 : 0)); - size_t len = 2 + opts->topic.len + opts->message.len; - MG_DEBUG(("%lu [%.*s] -> [%.*s]", c->id, (int)opts->topic.len, - (char*)opts->topic.ptr, (int)opts->message.len, - (char*)opts->message.ptr)); - if (opts->qos > 0) - len += 2; - if (c->is_mqtt5) - len += get_props_size(opts->props, opts->num_props); - - mg_mqtt_send_header(c, MQTT_CMD_PUBLISH, flags, (uint32_t)len); - mg_send_u16(c, mg_htons((uint16_t)opts->topic.len)); - mg_send(c, opts->topic.ptr, opts->topic.len); - if (opts->qos > 0) { - if (++c->mgr->mqtt_id == 0) - ++c->mgr->mqtt_id; - mg_send_u16(c, mg_htons(c->mgr->mqtt_id)); - } - - if (c->is_mqtt5) - mg_send_mqtt_properties(c, opts->props, opts->num_props); - - mg_send(c, opts->message.ptr, opts->message.len); -} - -void mg_mqtt_sub(struct mg_connection* c, const struct mg_mqtt_opts* opts) -{ - uint8_t qos_ = opts->qos & 3; - size_t plen = c->is_mqtt5 ? get_props_size(opts->props, opts->num_props) : 0; - size_t len = 2 + opts->topic.len + 2 + 1 + plen; - - mg_mqtt_send_header(c, MQTT_CMD_SUBSCRIBE, 2, (uint32_t)len); - if (++c->mgr->mqtt_id == 0) - ++c->mgr->mqtt_id; - mg_send_u16(c, mg_htons(c->mgr->mqtt_id)); - if (c->is_mqtt5) - mg_send_mqtt_properties(c, opts->props, opts->num_props); - - mg_send_u16(c, mg_htons((uint16_t)opts->topic.len)); - mg_send(c, opts->topic.ptr, opts->topic.len); - mg_send(c, &qos_, sizeof(qos_)); -} - -int mg_mqtt_parse(const uint8_t* buf, size_t len, uint8_t version, - struct mg_mqtt_message* m) -{ - uint8_t lc = 0, *p, *end; - uint32_t n = 0, len_len = 0; - - memset(m, 0, sizeof(*m)); - m->dgram.ptr = (char*)buf; - if (len < 2) - return MQTT_INCOMPLETE; - m->cmd = (uint8_t)(buf[0] >> 4); - m->qos = (buf[0] >> 1) & 3; - - n = len_len = 0; - p = (uint8_t*)buf + 1; - while ((size_t)(p - buf) < len) { - lc = *((uint8_t*)p++); - n += (uint32_t)((lc & 0x7f) << 7 * len_len); - len_len++; - if (!(lc & 0x80)) - break; - if (len_len >= 4) - return MQTT_MALFORMED; - } - end = p + n; - if ((lc & 0x80) || (end > buf + len)) - return MQTT_INCOMPLETE; - m->dgram.len = (size_t)(end - buf); - - switch (m->cmd) { - case MQTT_CMD_CONNACK: - if (end - p < 2) - return MQTT_MALFORMED; - m->ack = p[1]; - break; - case MQTT_CMD_PUBACK: - case MQTT_CMD_PUBREC: - case MQTT_CMD_PUBREL: - case MQTT_CMD_PUBCOMP: - case MQTT_CMD_SUBSCRIBE: - case MQTT_CMD_SUBACK: - case MQTT_CMD_UNSUBSCRIBE: - case MQTT_CMD_UNSUBACK: - if (p + 2 > end) - return MQTT_MALFORMED; - m->id = (uint16_t)((((uint16_t)p[0]) << 8) | p[1]); - p += 2; - break; - case MQTT_CMD_PUBLISH: { - if (p + 2 > end) - return MQTT_MALFORMED; - m->topic.len = (uint16_t)((((uint16_t)p[0]) << 8) | p[1]); - m->topic.ptr = (char*)p + 2; - p += 2 + m->topic.len; - if (p > end) - return MQTT_MALFORMED; - if (m->qos > 0) { - if (p + 2 > end) - return MQTT_MALFORMED; - m->id = (uint16_t)((((uint16_t)p[0]) << 8) | p[1]); - p += 2; - } - if (p > end) - return MQTT_MALFORMED; - if (version == 5 && p + 2 < end) { - len_len = (uint32_t)decode_varint(p, (size_t)(end - p), &m->props_size); - if (!len_len) - return MQTT_MALFORMED; - m->props_start = (size_t)(p + len_len - buf); - p += len_len + m->props_size; - } - if (p > end) - return MQTT_MALFORMED; - m->data.ptr = (char*)p; - m->data.len = (size_t)(end - p); - break; - } - default: - break; - } - return MQTT_OK; -} - -static void mqtt_cb(struct mg_connection* c, int ev, void* ev_data, - void* fn_data) -{ - if (ev == MG_EV_READ) { - for (;;) { - uint8_t version = c->is_mqtt5 ? 5 : 4; - struct mg_mqtt_message mm; - int rc = mg_mqtt_parse(c->recv.buf, c->recv.len, version, &mm); - if (rc == MQTT_MALFORMED) { - MG_ERROR(("%lu MQTT malformed message", c->id)); - c->is_closing = 1; - break; - } else if (rc == MQTT_OK) { - MG_VERBOSE(("%lu MQTT CMD %d len %d [%.*s]", c->id, mm.cmd, - (int)mm.dgram.len, (int)mm.data.len, mm.data.ptr)); - switch (mm.cmd) { - case MQTT_CMD_CONNACK: - mg_call(c, MG_EV_MQTT_OPEN, &mm.ack); - if (mm.ack == 0) { - MG_DEBUG(("%lu Connected", c->id)); - } else { - MG_ERROR(("%lu MQTT auth failed, code %d", c->id, mm.ack)); - c->is_closing = 1; - } - break; - case MQTT_CMD_PUBLISH: { - MG_DEBUG(("%lu [%.*s] -> [%.*s]", c->id, (int)mm.topic.len, - mm.topic.ptr, (int)mm.data.len, mm.data.ptr)); - if (mm.qos > 0) { - uint16_t id = mg_ntohs(mm.id); - uint32_t remaining_len = sizeof(id); - if (c->is_mqtt5) - remaining_len += 2; // 3.4.2 - - mg_mqtt_send_header( - c, - (uint8_t)(mm.qos == 2 ? MQTT_CMD_PUBREC : MQTT_CMD_PUBACK), - 0, remaining_len); - mg_send(c, &id, sizeof(id)); - - if (c->is_mqtt5) { - uint16_t zero = 0; - mg_send(c, &zero, sizeof(zero)); - } - } - mg_call(c, MG_EV_MQTT_MSG, &mm); // let the app handle qos stuff - break; - } - case MQTT_CMD_PUBREC: { // MQTT5: 3.5.2-1 TODO(): variable header rc - uint16_t id = mg_ntohs(mm.id); - uint32_t remaining_len = sizeof(id); // MQTT5 3.6.2-1 - mg_mqtt_send_header(c, MQTT_CMD_PUBREL, 2, remaining_len); - mg_send(c, &id, sizeof(id)); // MQTT5 3.6.1-1, flags = 2 - break; - } - case MQTT_CMD_PUBREL: { // MQTT5: 3.6.2-1 TODO(): variable header rc - uint16_t id = mg_ntohs(mm.id); - uint32_t remaining_len = sizeof(id); // MQTT5 3.7.2-1 - mg_mqtt_send_header(c, MQTT_CMD_PUBCOMP, 0, remaining_len); - mg_send(c, &id, sizeof(id)); - break; - } - } - mg_call(c, MG_EV_MQTT_CMD, &mm); - mg_iobuf_del(&c->recv, 0, mm.dgram.len); - } else { - break; - } - } - } - (void)ev_data; - (void)fn_data; -} - -void mg_mqtt_ping(struct mg_connection* nc) -{ - mg_mqtt_send_header(nc, MQTT_CMD_PINGREQ, 0, 0); -} - -void mg_mqtt_pong(struct mg_connection* nc) -{ - mg_mqtt_send_header(nc, MQTT_CMD_PINGRESP, 0, 0); -} - -void mg_mqtt_disconnect(struct mg_connection* c, - const struct mg_mqtt_opts* opts) -{ - size_t len = 0; - if (c->is_mqtt5) - len = 1 + get_props_size(opts->props, opts->num_props); - mg_mqtt_send_header(c, MQTT_CMD_DISCONNECT, 0, (uint32_t)len); - - if (c->is_mqtt5) { - uint8_t zero = 0; - mg_send(c, &zero, sizeof(zero)); // reason code - mg_send_mqtt_properties(c, opts->props, opts->num_props); - } -} - -struct mg_connection* mg_mqtt_connect(struct mg_mgr* mgr, const char* url, - const struct mg_mqtt_opts* opts, - mg_event_handler_t fn, void* fn_data) -{ - struct mg_connection* c = mg_connect(mgr, url, fn, fn_data); - if (c != NULL) { - struct mg_mqtt_opts empty; - memset(&empty, 0, sizeof(empty)); - mg_mqtt_login(c, opts == NULL ? &empty : opts); - c->pfn = mqtt_cb; - } - return c; -} - -struct mg_connection* mg_mqtt_listen(struct mg_mgr* mgr, const char* url, - mg_event_handler_t fn, void* fn_data) -{ - struct mg_connection* c = mg_listen(mgr, url, fn, fn_data); - if (c != NULL) - c->pfn = mqtt_cb, c->pfn_data = mgr; - return c; -} - -#ifdef MG_ENABLE_LINES -#line 1 "src/net.c" -#endif - -size_t mg_vprintf(struct mg_connection* c, const char* fmt, va_list* ap) -{ - size_t old = c->send.len; - mg_vxprintf(mg_pfn_iobuf, &c->send, fmt, ap); - return c->send.len - old; -} - -size_t mg_printf(struct mg_connection* c, const char* fmt, ...) -{ - size_t len = 0; - va_list ap; - va_start(ap, fmt); - len = mg_vprintf(c, fmt, &ap); - va_end(ap); - return len; -} - -static bool mg_atonl(struct mg_str str, struct mg_addr* addr) -{ - uint32_t localhost = mg_htonl(0x7f000001); - if (mg_vcasecmp(&str, "localhost") != 0) - return false; - memcpy(addr->ip, &localhost, sizeof(uint32_t)); - addr->is_ip6 = false; - return true; -} - -static bool mg_atone(struct mg_str str, struct mg_addr* addr) -{ - if (str.len > 0) - return false; - memset(addr->ip, 0, sizeof(addr->ip)); - addr->is_ip6 = false; - return true; -} - -static bool mg_aton4(struct mg_str str, struct mg_addr* addr) -{ - uint8_t data[4] = { 0, 0, 0, 0 }; - size_t i, num_dots = 0; - for (i = 0; i < str.len; i++) { - if (str.ptr[i] >= '0' && str.ptr[i] <= '9') { - int octet = data[num_dots] * 10 + (str.ptr[i] - '0'); - if (octet > 255) - return false; - data[num_dots] = (uint8_t)octet; - } else if (str.ptr[i] == '.') { - if (num_dots >= 3 || i == 0 || str.ptr[i - 1] == '.') - return false; - num_dots++; - } else { - return false; - } - } - if (num_dots != 3 || str.ptr[i - 1] == '.') - return false; - memcpy(&addr->ip, data, sizeof(data)); - addr->is_ip6 = false; - return true; -} - -static bool mg_v4mapped(struct mg_str str, struct mg_addr* addr) -{ - int i; - uint32_t ipv4; - if (str.len < 14) - return false; - if (str.ptr[0] != ':' || str.ptr[1] != ':' || str.ptr[6] != ':') - return false; - for (i = 2; i < 6; i++) { - if (str.ptr[i] != 'f' && str.ptr[i] != 'F') - return false; - } - // struct mg_str s = mg_str_n(&str.ptr[7], str.len - 7); - if (!mg_aton4(mg_str_n(&str.ptr[7], str.len - 7), addr)) - return false; - memcpy(&ipv4, addr->ip, sizeof(ipv4)); - memset(addr->ip, 0, sizeof(addr->ip)); - addr->ip[10] = addr->ip[11] = 255; - memcpy(&addr->ip[12], &ipv4, 4); - addr->is_ip6 = true; - return true; -} - -static bool mg_aton6(struct mg_str str, struct mg_addr* addr) -{ - size_t i, j = 0, n = 0, dc = 42; - if (str.len > 2 && str.ptr[0] == '[') - str.ptr++, str.len -= 2; - if (mg_v4mapped(str, addr)) - return true; - for (i = 0; i < str.len; i++) { - if ((str.ptr[i] >= '0' && str.ptr[i] <= '9') || (str.ptr[i] >= 'a' && str.ptr[i] <= 'f') || (str.ptr[i] >= 'A' && str.ptr[i] <= 'F')) { - unsigned long val; - if (i > j + 3) - return false; - // MG_DEBUG(("%zu %zu [%.*s]", i, j, (int) (i - j + 1), &str.ptr[j])); - val = mg_unhexn(&str.ptr[j], i - j + 1); - addr->ip[n] = (uint8_t)((val >> 8) & 255); - addr->ip[n + 1] = (uint8_t)(val & 255); - } else if (str.ptr[i] == ':') { - j = i + 1; - if (i > 0 && str.ptr[i - 1] == ':') { - dc = n; // Double colon - if (i > 1 && str.ptr[i - 2] == ':') - return false; - } else if (i > 0) { - n += 2; - } - if (n > 14) - return false; - addr->ip[n] = addr->ip[n + 1] = 0; // For trailing :: - } else { - return false; - } - } - if (n < 14 && dc == 42) - return false; - if (n < 14) { - memmove(&addr->ip[dc + (14 - n)], &addr->ip[dc], n - dc + 2); - memset(&addr->ip[dc], 0, 14 - n); - } - - addr->is_ip6 = true; - return true; -} - -bool mg_aton(struct mg_str str, struct mg_addr* addr) -{ - // MG_INFO(("[%.*s]", (int) str.len, str.ptr)); - return mg_atone(str, addr) || mg_atonl(str, addr) || mg_aton4(str, addr) || mg_aton6(str, addr); -} - -struct mg_connection* mg_alloc_conn(struct mg_mgr* mgr) -{ - struct mg_connection* c = (struct mg_connection*)calloc(1, sizeof(*c) + mgr->extraconnsize); - if (c != NULL) { - c->mgr = mgr; - c->send.align = c->recv.align = MG_IO_SIZE; - c->id = ++mgr->nextid; - } - return c; -} - -void mg_close_conn(struct mg_connection* c) -{ - mg_resolve_cancel(c); // Close any pending DNS query - LIST_DELETE(struct mg_connection, &c->mgr->conns, c); - if (c == c->mgr->dns4.c) - c->mgr->dns4.c = NULL; - if (c == c->mgr->dns6.c) - c->mgr->dns6.c = NULL; - // Order of operations is important. `MG_EV_CLOSE` event must be fired - // before we deallocate received data, see #1331 - mg_call(c, MG_EV_CLOSE, NULL); - MG_DEBUG(("%lu %ld closed", c->id, c->fd)); - - mg_tls_free(c); - mg_iobuf_free(&c->recv); - mg_iobuf_free(&c->send); - mg_bzero((unsigned char*)c, sizeof(*c)); - free(c); -} - -struct mg_connection* mg_connect(struct mg_mgr* mgr, const char* url, - mg_event_handler_t fn, void* fn_data) -{ - struct mg_connection* c = NULL; - if (url == NULL || url[0] == '\0') { - MG_ERROR(("null url")); - } else if ((c = mg_alloc_conn(mgr)) == NULL) { - MG_ERROR(("OOM")); - } else { - LIST_ADD_HEAD(struct mg_connection, &mgr->conns, c); - c->is_udp = (strncmp(url, "udp:", 4) == 0); - c->fd = (void*)(size_t)MG_INVALID_SOCKET; - c->fn = fn; - c->is_client = true; - c->fn_data = fn_data; - MG_DEBUG(("%lu %ld %s", c->id, c->fd, url)); - mg_call(c, MG_EV_OPEN, (void*)url); - mg_resolve(c, url); - } - return c; -} - -struct mg_connection* mg_listen(struct mg_mgr* mgr, const char* url, - mg_event_handler_t fn, void* fn_data) -{ - struct mg_connection* c = NULL; - if ((c = mg_alloc_conn(mgr)) == NULL) { - MG_ERROR(("OOM %s", url)); - } else if (!mg_open_listener(c, url)) { - MG_ERROR(("Failed: %s, errno %d", url, errno)); - free(c); - c = NULL; - } else { - c->is_listening = 1; - c->is_udp = strncmp(url, "udp:", 4) == 0; - LIST_ADD_HEAD(struct mg_connection, &mgr->conns, c); - c->fn = fn; - c->fn_data = fn_data; - mg_call(c, MG_EV_OPEN, NULL); - if (mg_url_is_ssl(url)) - c->is_tls = 1; // Accepted connection must - MG_DEBUG(("%lu %ld %s", c->id, c->fd, url)); - } - return c; -} - -struct mg_connection* mg_wrapfd(struct mg_mgr* mgr, int fd, - mg_event_handler_t fn, void* fn_data) -{ - struct mg_connection* c = mg_alloc_conn(mgr); - if (c != NULL) { - c->fd = (void*)(size_t)fd; - c->fn = fn; - c->fn_data = fn_data; - MG_EPOLL_ADD(c); - mg_call(c, MG_EV_OPEN, NULL); - LIST_ADD_HEAD(struct mg_connection, &mgr->conns, c); - } - return c; -} - -struct mg_timer* mg_timer_add(struct mg_mgr* mgr, uint64_t milliseconds, - unsigned flags, void (*fn)(void*), void* arg) -{ - struct mg_timer* t = (struct mg_timer*)calloc(1, sizeof(*t)); - if (t != NULL) { - mg_timer_init(&mgr->timers, t, milliseconds, flags, fn, arg); - t->id = mgr->timerid++; - } - return t; -} - -void mg_mgr_free(struct mg_mgr* mgr) -{ - struct mg_connection* c; - struct mg_timer *tmp, *t = mgr->timers; - while (t != NULL) - tmp = t->next, free(t), t = tmp; - mgr->timers = NULL; // Important. Next call to poll won't touch timers - for (c = mgr->conns; c != NULL; c = c->next) - c->is_closing = 1; - mg_mgr_poll(mgr, 0); -#if MG_ENABLE_FREERTOS_TCP - FreeRTOS_DeleteSocketSet(mgr->ss); -#endif - MG_DEBUG(("All connections closed")); -#if MG_ENABLE_EPOLL - if (mgr->epoll_fd >= 0) - close(mgr->epoll_fd), mgr->epoll_fd = -1; -#endif - mg_tls_ctx_free(mgr); -} - -void mg_mgr_init(struct mg_mgr* mgr) -{ - memset(mgr, 0, sizeof(*mgr)); -#if MG_ENABLE_EPOLL - if ((mgr->epoll_fd = epoll_create1(EPOLL_CLOEXEC)) < 0) - MG_ERROR(("epoll_create1 errno %d", errno)); -#else - mgr->epoll_fd = -1; -#endif -#if MG_ARCH == MG_ARCH_WIN32 && MG_ENABLE_WINSOCK - // clang-format off - { WSADATA data; WSAStartup(MAKEWORD(2, 2), &data); } - // clang-format on -#elif MG_ENABLE_FREERTOS_TCP - mgr->ss = FreeRTOS_CreateSocketSet(); -#elif defined(__unix) || defined(__unix__) || defined(__APPLE__) - // Ignore SIGPIPE signal, so if client cancels the request, it - // won't kill the whole process. - signal(SIGPIPE, SIG_IGN); -#endif - mgr->dnstimeout = 3000; - mgr->dns4.url = "udp://8.8.8.8:53"; - mgr->dns6.url = "udp://[2001:4860:4860::8888]:53"; - mg_tls_ctx_init(mgr); -} - -#ifdef MG_ENABLE_LINES -#line 1 "src/net_builtin.c" -#endif - -#if defined(MG_ENABLE_TCPIP) && MG_ENABLE_TCPIP -#define MG_EPHEMERAL_PORT_BASE 32768 -#define PDIFF(a, b) ((size_t)(((char*)(b)) - ((char*)(a)))) - -#ifndef MIP_TCP_KEEPALIVE_MS -#define MIP_TCP_KEEPALIVE_MS 45000 // TCP keep-alive period, ms -#endif - -#define MIP_TCP_ACK_MS 150 // Timeout for ACKing -#define MIP_TCP_ARP_MS 100 // Timeout for ARP response -#define MIP_TCP_SYN_MS 15000 // Timeout for connection establishment -#define MIP_TCP_FIN_MS 1000 // Timeout for closing connection - -struct connstate { - uint32_t seq, ack; // TCP seq/ack counters - uint64_t timer; // TCP keep-alive / ACK timer - uint8_t mac[6]; // Peer MAC address - uint8_t ttype; // Timer type. 0: ack, 1: keep-alive -#define MIP_TTYPE_KEEPALIVE 0 // Connection is idle for long, send keepalive -#define MIP_TTYPE_ACK 1 // Peer sent us data, we have to ack it soon -#define MIP_TTYPE_ARP 2 // ARP resolve sent, waiting for response -#define MIP_TTYPE_SYN 3 // SYN sent, waiting for response -#define MIP_TTYPE_FIN 4 // FIN sent, waiting until terminating the connection - uint8_t tmiss; // Number of keep-alive misses - struct mg_iobuf raw; // For TLS only. Incoming raw data -}; - -#pragma pack(push, 1) - -struct lcp { - uint8_t addr, ctrl, proto[2], code, id, len[2]; -}; - -struct eth { - uint8_t dst[6]; // Destination MAC address - uint8_t src[6]; // Source MAC address - uint16_t type; // Ethernet type -}; - -struct ip { - uint8_t ver; // Version - uint8_t tos; // Unused - uint16_t len; // Length - uint16_t id; // Unused - uint16_t frag; // Fragmentation -#define IP_FRAG_OFFSET_MSK 0xFF1F -#define IP_MORE_FRAGS_MSK 0x20 - uint8_t ttl; // Time to live - uint8_t proto; // Upper level protocol - uint16_t csum; // Checksum - uint32_t src; // Source IP - uint32_t dst; // Destination IP -}; - -struct ip6 { - uint8_t ver; // Version - uint8_t opts[3]; // Options - uint16_t len; // Length - uint8_t proto; // Upper level protocol - uint8_t ttl; // Time to live - uint8_t src[16]; // Source IP - uint8_t dst[16]; // Destination IP -}; - -struct icmp { - uint8_t type; - uint8_t code; - uint16_t csum; -}; - -struct arp { - uint16_t fmt; // Format of hardware address - uint16_t pro; // Format of protocol address - uint8_t hlen; // Length of hardware address - uint8_t plen; // Length of protocol address - uint16_t op; // Operation - uint8_t sha[6]; // Sender hardware address - uint32_t spa; // Sender protocol address - uint8_t tha[6]; // Target hardware address - uint32_t tpa; // Target protocol address -}; - -struct tcp { - uint16_t sport; // Source port - uint16_t dport; // Destination port - uint32_t seq; // Sequence number - uint32_t ack; // Acknowledgement number - uint8_t off; // Data offset - uint8_t flags; // TCP flags -#define TH_FIN 0x01 -#define TH_SYN 0x02 -#define TH_RST 0x04 -#define TH_PUSH 0x08 -#define TH_ACK 0x10 -#define TH_URG 0x20 -#define TH_ECE 0x40 -#define TH_CWR 0x80 - uint16_t win; // Window - uint16_t csum; // Checksum - uint16_t urp; // Urgent pointer -}; - -struct udp { - uint16_t sport; // Source port - uint16_t dport; // Destination port - uint16_t len; // UDP length - uint16_t csum; // UDP checksum -}; - -struct dhcp { - uint8_t op, htype, hlen, hops; - uint32_t xid; - uint16_t secs, flags; - uint32_t ciaddr, yiaddr, siaddr, giaddr; - uint8_t hwaddr[208]; - uint32_t magic; - uint8_t options[32]; -}; - -#pragma pack(pop) - -struct pkt { - struct mg_str raw; // Raw packet data - struct mg_str pay; // Payload data - struct eth* eth; - struct llc* llc; - struct arp* arp; - struct ip* ip; - struct ip6* ip6; - struct icmp* icmp; - struct tcp* tcp; - struct udp* udp; - struct dhcp* dhcp; -}; - -static void send_syn(struct mg_connection* c); - -static void mkpay(struct pkt* pkt, void* p) -{ - pkt->pay = mg_str_n((char*)p, (size_t)(&pkt->raw.ptr[pkt->raw.len] - (char*)p)); -} - -static uint32_t csumup(uint32_t sum, const void* buf, size_t len) -{ - const uint8_t* p = (const uint8_t*)buf; - for (size_t i = 0; i < len; i++) - sum += i & 1 ? p[i] : (uint32_t)(p[i] << 8); - return sum; -} - -static uint16_t csumfin(uint32_t sum) -{ - while (sum >> 16) - sum = (sum & 0xffff) + (sum >> 16); - return mg_htons(~sum & 0xffff); -} - -static uint16_t ipcsum(const void* buf, size_t len) -{ - uint32_t sum = csumup(0, buf, len); - return csumfin(sum); -} - -static void settmout(struct mg_connection* c, uint8_t type) -{ - struct mg_tcpip_if* ifp = (struct mg_tcpip_if*)c->mgr->priv; - struct connstate* s = (struct connstate*)(c + 1); - unsigned n = type == MIP_TTYPE_ACK ? MIP_TCP_ACK_MS - : type == MIP_TTYPE_ARP ? MIP_TCP_ARP_MS - : type == MIP_TTYPE_SYN ? MIP_TCP_SYN_MS - : type == MIP_TTYPE_FIN ? MIP_TCP_FIN_MS - : MIP_TCP_KEEPALIVE_MS; - s->timer = ifp->now + n; - s->ttype = type; - MG_VERBOSE(("%lu %d -> %llx", c->id, type, s->timer)); -} - -static size_t ether_output(struct mg_tcpip_if* ifp, size_t len) -{ - // size_t min = 64; // Pad short frames to 64 bytes (minimum Ethernet size) - // if (len < min) memset(ifp->tx.ptr + len, 0, min - len), len = min; - // mg_hexdump(ifp->tx.ptr, len); - size_t n = ifp->driver->tx(ifp->tx.ptr, len, ifp); - if (n == len) - ifp->nsent++; - return n; -} - -static void arp_ask(struct mg_tcpip_if* ifp, uint32_t ip) -{ - struct eth* eth = (struct eth*)ifp->tx.ptr; - struct arp* arp = (struct arp*)(eth + 1); - memset(eth->dst, 255, sizeof(eth->dst)); - memcpy(eth->src, ifp->mac, sizeof(eth->src)); - eth->type = mg_htons(0x806); - memset(arp, 0, sizeof(*arp)); - arp->fmt = mg_htons(1), arp->pro = mg_htons(0x800), arp->hlen = 6, - arp->plen = 4; - arp->op = mg_htons(1), arp->tpa = ip, arp->spa = ifp->ip; - memcpy(arp->sha, ifp->mac, sizeof(arp->sha)); - ether_output(ifp, PDIFF(eth, arp + 1)); -} - -static void onstatechange(struct mg_tcpip_if* ifp) -{ - if (ifp->state == MG_TCPIP_STATE_READY) { - MG_INFO(("READY, IP: %M", mg_print_ip4, &ifp->ip)); - MG_INFO((" GW: %M", mg_print_ip4, &ifp->gw)); - MG_INFO((" MAC: %M", mg_print_mac, &ifp->mac)); - arp_ask(ifp, ifp->gw); - } else if (ifp->state == MG_TCPIP_STATE_UP) { - MG_ERROR(("Link up")); - srand((unsigned int)mg_millis()); - } else if (ifp->state == MG_TCPIP_STATE_DOWN) { - MG_ERROR(("Link down")); - } -} - -static struct ip* tx_ip(struct mg_tcpip_if* ifp, uint8_t* mac_dst, - uint8_t proto, uint32_t ip_src, uint32_t ip_dst, - size_t plen) -{ - struct eth* eth = (struct eth*)ifp->tx.ptr; - struct ip* ip = (struct ip*)(eth + 1); - memcpy(eth->dst, mac_dst, sizeof(eth->dst)); - memcpy(eth->src, ifp->mac, sizeof(eth->src)); // Use our MAC - eth->type = mg_htons(0x800); - memset(ip, 0, sizeof(*ip)); - ip->ver = 0x45; // Version 4, header length 5 words - ip->frag = 0x40; // Don't fragment - ip->len = mg_htons((uint16_t)(sizeof(*ip) + plen)); - ip->ttl = 64; - ip->proto = proto; - ip->src = ip_src; - ip->dst = ip_dst; - ip->csum = ipcsum(ip, sizeof(*ip)); - return ip; -} - -static void tx_udp(struct mg_tcpip_if* ifp, uint8_t* mac_dst, uint32_t ip_src, - uint16_t sport, uint32_t ip_dst, uint16_t dport, - const void* buf, size_t len) -{ - struct ip* ip = tx_ip(ifp, mac_dst, 17, ip_src, ip_dst, len + sizeof(struct udp)); - struct udp* udp = (struct udp*)(ip + 1); - // MG_DEBUG(("UDP XX LEN %d %d", (int) len, (int) ifp->tx.len)); - udp->sport = sport; - udp->dport = dport; - udp->len = mg_htons((uint16_t)(sizeof(*udp) + len)); - udp->csum = 0; - uint32_t cs = csumup(0, udp, sizeof(*udp)); - cs = csumup(cs, buf, len); - cs = csumup(cs, &ip->src, sizeof(ip->src)); - cs = csumup(cs, &ip->dst, sizeof(ip->dst)); - cs += (uint32_t)(ip->proto + sizeof(*udp) + len); - udp->csum = csumfin(cs); - memmove(udp + 1, buf, len); - // MG_DEBUG(("UDP LEN %d %d", (int) len, (int) ifp->frame_len)); - ether_output(ifp, sizeof(struct eth) + sizeof(*ip) + sizeof(*udp) + len); -} - -static void tx_dhcp(struct mg_tcpip_if* ifp, uint8_t* mac_dst, uint32_t ip_src, - uint32_t ip_dst, uint8_t* opts, size_t optslen, - bool ciaddr) -{ - // https://datatracker.ietf.org/doc/html/rfc2132#section-9.6 - struct dhcp dhcp = { 1, 1, 6, 0, 0, 0, 0, 0, 0, 0, 0, { 0 }, 0, { 0 } }; - dhcp.magic = mg_htonl(0x63825363); - memcpy(&dhcp.hwaddr, ifp->mac, sizeof(ifp->mac)); - memcpy(&dhcp.xid, ifp->mac + 2, sizeof(dhcp.xid)); - memcpy(&dhcp.options, opts, optslen); - if (ciaddr) - dhcp.ciaddr = ip_src; - tx_udp(ifp, mac_dst, ip_src, mg_htons(68), ip_dst, mg_htons(67), &dhcp, - sizeof(dhcp)); -} - -static const uint8_t broadcast[] = { 255, 255, 255, 255, 255, 255 }; - -// RFC-2131 #4.3.6, #4.4.1 -static void tx_dhcp_request_sel(struct mg_tcpip_if* ifp, uint32_t ip_req, - uint32_t ip_srv) -{ - uint8_t opts[] = { - 53, 1, 3, // Type: DHCP request - 55, 2, 1, 3, // GW and mask - 12, 3, 'm', 'i', 'p', // Host name: "mip" - 54, 4, 0, 0, 0, 0, // DHCP server ID - 50, 4, 0, 0, 0, 0, // Requested IP - 255 // End of options - }; - memcpy(opts + 14, &ip_srv, sizeof(ip_srv)); - memcpy(opts + 20, &ip_req, sizeof(ip_req)); - tx_dhcp(ifp, (uint8_t*)broadcast, 0, 0xffffffff, opts, sizeof(opts), false); - MG_DEBUG(("DHCP req sent")); -} - -// RFC-2131 #4.3.6, #4.4.5 (renewing: unicast, rebinding: bcast) -static void tx_dhcp_request_re(struct mg_tcpip_if* ifp, uint8_t* mac_dst, - uint32_t ip_src, uint32_t ip_dst) -{ - uint8_t opts[] = { - 53, 1, 3, // Type: DHCP request - 255 // End of options - }; - tx_dhcp(ifp, mac_dst, ip_src, ip_dst, opts, sizeof(opts), true); - MG_DEBUG(("DHCP req sent")); -} - -static void tx_dhcp_discover(struct mg_tcpip_if* ifp) -{ - uint8_t opts[] = { - 53, 1, 1, // Type: DHCP discover - 55, 2, 1, 3, // Parameters: ip, mask - 255 // End of options - }; - tx_dhcp(ifp, (uint8_t*)broadcast, 0, 0xffffffff, opts, sizeof(opts), false); - MG_DEBUG(("DHCP discover sent. Our MAC: %M", mg_print_mac, ifp->mac)); -} - -static struct mg_connection* getpeer(struct mg_mgr* mgr, struct pkt* pkt, - bool lsn) -{ - struct mg_connection* c = NULL; - for (c = mgr->conns; c != NULL; c = c->next) { - if (c->is_arplooking && pkt->arp && memcmp(&pkt->arp->spa, c->rem.ip, sizeof(pkt->arp->spa)) == 0) - break; - if (c->is_udp && pkt->udp && c->loc.port == pkt->udp->dport) - break; - if (!c->is_udp && pkt->tcp && c->loc.port == pkt->tcp->dport && lsn == c->is_listening && (lsn || c->rem.port == pkt->tcp->sport)) - break; - } - return c; -} - -static void rx_arp(struct mg_tcpip_if* ifp, struct pkt* pkt) -{ - if (pkt->arp->op == mg_htons(1) && pkt->arp->tpa == ifp->ip) { - // ARP request. Make a response, then send - // MG_DEBUG(("ARP op %d %M: %M", mg_ntohs(pkt->arp->op), mg_print_ip4, - // &pkt->arp->spa, mg_print_ip4, &pkt->arp->tpa)); - struct eth* eth = (struct eth*)ifp->tx.ptr; - struct arp* arp = (struct arp*)(eth + 1); - memcpy(eth->dst, pkt->eth->src, sizeof(eth->dst)); - memcpy(eth->src, ifp->mac, sizeof(eth->src)); - eth->type = mg_htons(0x806); - *arp = *pkt->arp; - arp->op = mg_htons(2); - memcpy(arp->tha, pkt->arp->sha, sizeof(pkt->arp->tha)); - memcpy(arp->sha, ifp->mac, sizeof(pkt->arp->sha)); - arp->tpa = pkt->arp->spa; - arp->spa = ifp->ip; - MG_DEBUG(("ARP: tell %M we're %M", mg_print_ip4, &arp->tpa, mg_print_mac, - &ifp->mac)); - ether_output(ifp, PDIFF(eth, arp + 1)); - } else if (pkt->arp->op == mg_htons(2)) { - if (memcmp(pkt->arp->tha, ifp->mac, sizeof(pkt->arp->tha)) != 0) - return; - if (pkt->arp->spa == ifp->gw) { - // Got response for the GW ARP request. Set ifp->gwmac - memcpy(ifp->gwmac, pkt->arp->sha, sizeof(ifp->gwmac)); - } else { - struct mg_connection* c = getpeer(ifp->mgr, pkt, false); - if (c != NULL && c->is_arplooking) { - struct connstate* s = (struct connstate*)(c + 1); - memcpy(s->mac, pkt->arp->sha, sizeof(s->mac)); - MG_DEBUG(("%lu ARP resolved %M -> %M", c->id, mg_print_ip4, c->rem.ip, - mg_print_mac, s->mac)); - c->is_arplooking = 0; - send_syn(c); - settmout(c, MIP_TTYPE_SYN); - } - } - } -} - -static void rx_icmp(struct mg_tcpip_if* ifp, struct pkt* pkt) -{ - // MG_DEBUG(("ICMP %d", (int) len)); - if (pkt->icmp->type == 8 && pkt->ip != NULL && pkt->ip->dst == ifp->ip) { - size_t hlen = sizeof(struct eth) + sizeof(struct ip) + sizeof(struct icmp); - size_t space = ifp->tx.len - hlen, plen = pkt->pay.len; - if (plen > space) - plen = space; - struct ip* ip = tx_ip(ifp, pkt->eth->src, 1, ifp->ip, pkt->ip->src, - sizeof(struct icmp) + plen); - struct icmp* icmp = (struct icmp*)(ip + 1); - memset(icmp, 0, sizeof(*icmp)); // Set csum to 0 - memcpy(icmp + 1, pkt->pay.ptr, plen); // Copy RX payload to TX - icmp->csum = ipcsum(icmp, sizeof(*icmp) + plen); - ether_output(ifp, hlen + plen); - } -} - -static void rx_dhcp_client(struct mg_tcpip_if* ifp, struct pkt* pkt) -{ - uint32_t ip = 0, gw = 0, mask = 0, lease = 0; - uint8_t msgtype = 0, state = ifp->state; - // perform size check first, then access fields - uint8_t *p = pkt->dhcp->options, - *end = (uint8_t*)&pkt->raw.ptr[pkt->raw.len]; - if (end < (uint8_t*)(pkt->dhcp + 1)) - return; - if (memcmp(&pkt->dhcp->xid, ifp->mac + 2, sizeof(pkt->dhcp->xid))) - return; - while (p + 1 < end && p[0] != 255) { // Parse options RFC-1533 #9 - if (p[0] == 1 && p[1] == sizeof(ifp->mask) && p + 6 < end) { // Mask - memcpy(&mask, p + 2, sizeof(mask)); - } else if (p[0] == 3 && p[1] == sizeof(ifp->gw) && p + 6 < end) { // GW - memcpy(&gw, p + 2, sizeof(gw)); - ip = pkt->dhcp->yiaddr; - } else if (p[0] == 51 && p[1] == 4 && p + 6 < end) { // Lease - memcpy(&lease, p + 2, sizeof(lease)); - lease = mg_ntohl(lease); - } else if (p[0] == 53 && p[1] == 1 && p + 6 < end) { // Msg Type - msgtype = p[2]; - } - p += p[1] + 2; - } - // Process message type, RFC-1533 (9.4); RFC-2131 (3.1, 4) - if (msgtype == 6 && ifp->ip == ip) { // DHCPNACK, release IP - ifp->state = MG_TCPIP_STATE_UP, ifp->ip = 0; - } else if (msgtype == 2 && ifp->state == MG_TCPIP_STATE_UP && ip && gw && lease) { // DHCPOFFER - tx_dhcp_request_sel(ifp, ip, pkt->dhcp->siaddr); // select IP, (4.4.1) - ifp->state = MG_TCPIP_STATE_REQ; // REQUESTING state - } else if (msgtype == 5) { // DHCPACK - if (ifp->state == MG_TCPIP_STATE_REQ && ip && gw && lease) { // got an IP - ifp->lease_expire = ifp->now + lease * 1000; - MG_INFO(("Lease: %u sec (%lld)", lease, ifp->lease_expire / 1000)); - // assume DHCP server = router until ARP resolves - memcpy(ifp->gwmac, pkt->eth->src, sizeof(ifp->gwmac)); - ifp->ip = ip, ifp->gw = gw, ifp->mask = mask; - ifp->state = MG_TCPIP_STATE_READY; // BOUND state - uint64_t rand; - mg_random(&rand, sizeof(rand)); - srand((unsigned int)(rand + mg_millis())); - } else if (ifp->state == MG_TCPIP_STATE_READY && ifp->ip == ip) { // renew - ifp->lease_expire = ifp->now + lease * 1000; - MG_INFO(("Lease: %u sec (%lld)", lease, ifp->lease_expire / 1000)); - } // TODO(): accept provided T1/T2 and store server IP for renewal (4.4) - } - if (ifp->state != state) - onstatechange(ifp); -} - -// Simple DHCP server that assigns a next IP address: ifp->ip + 1 -static void rx_dhcp_server(struct mg_tcpip_if* ifp, struct pkt* pkt) -{ - uint8_t op = 0, *p = pkt->dhcp->options, - *end = (uint8_t*)&pkt->raw.ptr[pkt->raw.len]; - if (end < (uint8_t*)(pkt->dhcp + 1)) - return; - // struct dhcp *req = pkt->dhcp; - struct dhcp res = { 2, 1, 6, 0, 0, 0, 0, 0, 0, 0, 0, { 0 }, 0, { 0 } }; - res.yiaddr = ifp->ip; - ((uint8_t*)(&res.yiaddr))[3]++; // Offer our IP + 1 - while (p + 1 < end && p[0] != 255) { // Parse options - if (p[0] == 53 && p[1] == 1 && p + 2 < end) { // Message type - op = p[2]; - } - p += p[1] + 2; - } - if (op == 1 || op == 3) { // DHCP Discover or DHCP Request - uint8_t msg = op == 1 ? 2 : 5; // Message type: DHCP OFFER or DHCP ACK - uint8_t opts[] = { - 53, 1, msg, // Message type - 1, 4, 0, 0, 0, 0, // Subnet mask - 54, 4, 0, 0, 0, 0, // Server ID - 12, 3, 'm', 'i', 'p', // Host name: "mip" - 51, 4, 255, 255, 255, 255, // Lease time - 255 // End of options - }; - memcpy(&res.hwaddr, pkt->dhcp->hwaddr, 6); - memcpy(opts + 5, &ifp->mask, sizeof(ifp->mask)); - memcpy(opts + 11, &ifp->ip, sizeof(ifp->ip)); - memcpy(&res.options, opts, sizeof(opts)); - res.magic = pkt->dhcp->magic; - res.xid = pkt->dhcp->xid; - // memcpy(ifp->gwmac, pkt->eth->src, sizeof(ifp->gwmac)); - tx_udp(ifp, pkt->eth->src, ifp->ip, mg_htons(67), - op == 1 ? ~0U : res.yiaddr, mg_htons(68), &res, sizeof(res)); - } -} - -static void rx_udp(struct mg_tcpip_if* ifp, struct pkt* pkt) -{ - struct mg_connection* c = getpeer(ifp->mgr, pkt, true); - if (c == NULL) { - // No UDP listener on this port. Should send ICMP, but keep silent. - } else { - c->rem.port = pkt->udp->sport; - memcpy(c->rem.ip, &pkt->ip->src, sizeof(uint32_t)); - struct connstate* s = (struct connstate*)(c + 1); - memcpy(s->mac, pkt->eth->src, sizeof(s->mac)); - if (c->recv.len >= MG_MAX_RECV_SIZE) { - mg_error(c, "max_recv_buf_size reached"); - } else if (c->recv.size - c->recv.len < pkt->pay.len && !mg_iobuf_resize(&c->recv, c->recv.len + pkt->pay.len)) { - mg_error(c, "oom"); - } else { - memcpy(&c->recv.buf[c->recv.len], pkt->pay.ptr, pkt->pay.len); - c->recv.len += pkt->pay.len; - mg_call(c, MG_EV_READ, &pkt->pay.len); - } - } -} - -static size_t tx_tcp(struct mg_tcpip_if* ifp, uint8_t* dst_mac, uint32_t dst_ip, - uint8_t flags, uint16_t sport, uint16_t dport, - uint32_t seq, uint32_t ack, const void* buf, size_t len) -{ - struct ip* ip = tx_ip(ifp, dst_mac, 6, ifp->ip, dst_ip, sizeof(struct tcp) + len); - struct tcp* tcp = (struct tcp*)(ip + 1); - memset(tcp, 0, sizeof(*tcp)); - if (buf != NULL && len) - memmove(tcp + 1, buf, len); - tcp->sport = sport; - tcp->dport = dport; - tcp->seq = seq; - tcp->ack = ack; - tcp->flags = flags; - tcp->win = mg_htons(8192); - tcp->off = (uint8_t)(sizeof(*tcp) / 4 << 4); - uint32_t cs = 0; - uint16_t n = (uint16_t)(sizeof(*tcp) + len); - uint8_t pseudo[] = { 0, ip->proto, (uint8_t)(n >> 8), (uint8_t)(n & 255) }; - cs = csumup(cs, tcp, n); - cs = csumup(cs, &ip->src, sizeof(ip->src)); - cs = csumup(cs, &ip->dst, sizeof(ip->dst)); - cs = csumup(cs, pseudo, sizeof(pseudo)); - tcp->csum = csumfin(cs); - MG_VERBOSE(("TCP %M:%hu -> %M:%hu fl %x len %u", mg_print_ip4, &ip->src, - mg_ntohs(tcp->sport), mg_print_ip4, &ip->dst, - mg_ntohs(tcp->dport), tcp->flags, (int)len)); - // mg_hexdump(ifp->tx.ptr, PDIFF(ifp->tx.ptr, tcp + 1) + len); - return ether_output(ifp, PDIFF(ifp->tx.ptr, tcp + 1) + len); -} - -static size_t tx_tcp_pkt(struct mg_tcpip_if* ifp, struct pkt* pkt, - uint8_t flags, uint32_t seq, const void* buf, - size_t len) -{ - uint32_t delta = (pkt->tcp->flags & (TH_SYN | TH_FIN)) ? 1 : 0; - return tx_tcp(ifp, pkt->eth->src, pkt->ip->src, flags, pkt->tcp->dport, - pkt->tcp->sport, seq, mg_htonl(mg_ntohl(pkt->tcp->seq) + delta), - buf, len); -} - -static struct mg_connection* accept_conn(struct mg_connection* lsn, - struct pkt* pkt) -{ - struct mg_connection* c = mg_alloc_conn(lsn->mgr); - if (c == NULL) { - MG_ERROR(("OOM")); - return NULL; - } - struct connstate* s = (struct connstate*)(c + 1); - s->seq = mg_ntohl(pkt->tcp->ack), s->ack = mg_ntohl(pkt->tcp->seq); - memcpy(s->mac, pkt->eth->src, sizeof(s->mac)); - settmout(c, MIP_TTYPE_KEEPALIVE); - memcpy(c->rem.ip, &pkt->ip->src, sizeof(uint32_t)); - c->rem.port = pkt->tcp->sport; - MG_DEBUG(("%lu accepted %M", c->id, mg_print_ip_port, &c->rem)); - LIST_ADD_HEAD(struct mg_connection, &lsn->mgr->conns, c); - c->is_accepted = 1; - c->is_hexdumping = lsn->is_hexdumping; - c->pfn = lsn->pfn; - c->loc = lsn->loc; - c->pfn_data = lsn->pfn_data; - c->fn = lsn->fn; - c->fn_data = lsn->fn_data; - mg_call(c, MG_EV_OPEN, NULL); - mg_call(c, MG_EV_ACCEPT, NULL); - return c; -} - -static size_t trim_len(struct mg_connection* c, size_t len) -{ - struct mg_tcpip_if* ifp = (struct mg_tcpip_if*)c->mgr->priv; - size_t eth_h_len = 14, ip_max_h_len = 24, tcp_max_h_len = 60, udp_h_len = 8; - size_t max_headers_len = eth_h_len + ip_max_h_len + (c->is_udp ? udp_h_len : tcp_max_h_len); - size_t min_mtu = c->is_udp ? 68 /* RFC-791 */ : max_headers_len - eth_h_len; - - // If the frame exceeds the available buffer, trim the length - if (len + max_headers_len > ifp->tx.len) { - len = ifp->tx.len - max_headers_len; - } - // Ensure the MTU isn't lower than the minimum allowed value - if (ifp->mtu < min_mtu) { - MG_ERROR(("MTU is lower than minimum possible value. Setting it to %d.", - min_mtu)); - ifp->mtu = (uint16_t)min_mtu; - } - // If the total packet size exceeds the MTU, trim the length - if (len + max_headers_len - eth_h_len > ifp->mtu) { - len = ifp->mtu - max_headers_len + eth_h_len; - if (c->is_udp) { - MG_ERROR(("UDP datagram exceeds MTU. Truncating it.")); - } - } - - return len; -} - -long mg_io_send(struct mg_connection* c, const void* buf, size_t len) -{ - struct mg_tcpip_if* ifp = (struct mg_tcpip_if*)c->mgr->priv; - struct connstate* s = (struct connstate*)(c + 1); - uint32_t rem_ip; - memcpy(&rem_ip, c->rem.ip, sizeof(uint32_t)); - len = trim_len(c, len); - if (c->is_udp) { - tx_udp(ifp, s->mac, ifp->ip, c->loc.port, rem_ip, c->rem.port, buf, len); - } else { - if (tx_tcp(ifp, s->mac, rem_ip, TH_PUSH | TH_ACK, c->loc.port, c->rem.port, - mg_htonl(s->seq), mg_htonl(s->ack), buf, len) - > 0) { - s->seq += (uint32_t)len; - if (s->ttype == MIP_TTYPE_ACK) - settmout(c, MIP_TTYPE_KEEPALIVE); - } else { - return MG_IO_ERR; - } - } - return (long)len; -} - -long mg_io_recv(struct mg_connection* c, void* buf, size_t len) -{ - struct connstate* s = (struct connstate*)(c + 1); - if (s->raw.len == 0) - return MG_IO_WAIT; - if (len > s->raw.len) - len = s->raw.len; - memcpy(buf, s->raw.buf, len); - mg_iobuf_del(&s->raw, 0, len); - return (long)len; -} - -static void read_conn(struct mg_connection* c, struct pkt* pkt) -{ - struct connstate* s = (struct connstate*)(c + 1); - struct mg_iobuf* io = c->is_tls ? &s->raw : &c->recv; - uint32_t seq = mg_ntohl(pkt->tcp->seq); - s->raw.align = c->recv.align; - uint32_t rem_ip; - memcpy(&rem_ip, c->rem.ip, sizeof(uint32_t)); - if (pkt->tcp->flags & TH_FIN) { - // If we initiated the closure, we reply with ACK upon receiving FIN - // If we didn't initiate it, we reply with FIN as part of the normal TCP - // closure process - uint8_t flags = TH_ACK; - s->ack = (uint32_t)(mg_htonl(pkt->tcp->seq) + pkt->pay.len + 1); - if (c->is_draining && s->ttype == MIP_TTYPE_FIN) { - if (s->seq == mg_htonl(pkt->tcp->ack)) { // Simultaneous closure ? - s->seq++; // Yes. Increment our SEQ - } else { // Otherwise, - s->seq = mg_htonl(pkt->tcp->ack); // Set to peer's ACK - } - } else { - flags |= TH_FIN; - c->is_draining = 1; - settmout(c, MIP_TTYPE_FIN); - } - tx_tcp((struct mg_tcpip_if*)c->mgr->priv, s->mac, rem_ip, flags, - c->loc.port, c->rem.port, mg_htonl(s->seq), mg_htonl(s->ack), "", 0); - } else if (pkt->pay.len == 0) { - // TODO(cpq): handle this peer's ACK - } else if (seq != s->ack) { - uint32_t ack = (uint32_t)(mg_htonl(pkt->tcp->seq) + pkt->pay.len); - if (s->ack == ack) { - MG_VERBOSE(("ignoring duplicate pkt")); - } else { - MG_VERBOSE(("SEQ != ACK: %x %x %x", seq, s->ack, ack)); - tx_tcp((struct mg_tcpip_if*)c->mgr->priv, s->mac, rem_ip, TH_ACK, - c->loc.port, c->rem.port, mg_htonl(s->seq), mg_htonl(s->ack), "", - 0); - } - } else if (io->size - io->len < pkt->pay.len && !mg_iobuf_resize(io, io->len + pkt->pay.len)) { - mg_error(c, "oom"); - } else { - // Copy TCP payload into the IO buffer. If the connection is plain text, - // we copy to c->recv. If the connection is TLS, this data is encrypted, - // therefore we copy that encrypted data to the s->raw iobuffer instead, - // and then call mg_tls_recv() to decrypt it. NOTE: mg_tls_recv() will - // call back mg_io_recv() which grabs raw data from s->raw - memcpy(&io->buf[io->len], pkt->pay.ptr, pkt->pay.len); - io->len += pkt->pay.len; - - MG_VERBOSE(("%lu SEQ %x -> %x", c->id, mg_htonl(pkt->tcp->seq), s->ack)); - // Advance ACK counter - s->ack = (uint32_t)(mg_htonl(pkt->tcp->seq) + pkt->pay.len); -#if 0 - // Send ACK immediately - uint32_t rem_ip; - memcpy(&rem_ip, c->rem.ip, sizeof(uint32_t)); - MG_DEBUG((" imm ACK", c->id, mg_htonl(pkt->tcp->seq), s->ack)); - tx_tcp((struct mg_tcpip_if *) c->mgr->priv, s->mac, rem_ip, TH_ACK, c->loc.port, - c->rem.port, mg_htonl(s->seq), mg_htonl(s->ack), "", 0); -#else - // if not already running, setup a timer to send an ACK later - if (s->ttype != MIP_TTYPE_ACK) - settmout(c, MIP_TTYPE_ACK); -#endif - - if (c->is_tls) { - // TLS connection. Make room for decrypted data in c->recv - io = &c->recv; - if (io->size - io->len < pkt->pay.len && !mg_iobuf_resize(io, io->len + pkt->pay.len)) { - mg_error(c, "oom"); - } else { - // Decrypt data directly into c->recv - long n = mg_tls_recv(c, &io->buf[io->len], io->size - io->len); - if (n == MG_IO_ERR) { - mg_error(c, "TLS recv error"); - } else if (n > 0) { - // Decrypted successfully - trigger MG_EV_READ - io->len += (size_t)n; - mg_call(c, MG_EV_READ, &n); - } - } - } else { - // Plain text connection, data is already in c->recv, trigger - // MG_EV_READ - mg_call(c, MG_EV_READ, &pkt->pay.len); - } - } -} - -static void rx_tcp(struct mg_tcpip_if* ifp, struct pkt* pkt) -{ - struct mg_connection* c = getpeer(ifp->mgr, pkt, false); - struct connstate* s = c == NULL ? NULL : (struct connstate*)(c + 1); -#if 0 - MG_INFO(("%lu %hhu %d", c ? c->id : 0, pkt->tcp->flags, (int) pkt->pay.len)); -#endif - if (c != NULL && c->is_connecting && pkt->tcp->flags == (TH_SYN | TH_ACK)) { - s->seq = mg_ntohl(pkt->tcp->ack), s->ack = mg_ntohl(pkt->tcp->seq) + 1; - tx_tcp_pkt(ifp, pkt, TH_ACK, pkt->tcp->ack, NULL, 0); - c->is_connecting = 0; // Client connected - settmout(c, MIP_TTYPE_KEEPALIVE); - mg_call(c, MG_EV_CONNECT, NULL); // Let user know - } else if (c != NULL && c->is_connecting && pkt->tcp->flags != TH_ACK) { - // mg_hexdump(pkt->raw.ptr, pkt->raw.len); - tx_tcp_pkt(ifp, pkt, TH_RST | TH_ACK, pkt->tcp->ack, NULL, 0); - } else if (c != NULL && pkt->tcp->flags & TH_RST) { - mg_error(c, "peer RST"); // RFC-1122 4.2.2.13 - } else if (c != NULL) { -#if 0 - MG_DEBUG(("%lu %d %M:%hu -> %M:%hu", c->id, (int) pkt->raw.len, - mg_print_ip4, &pkt->ip->src, mg_ntohs(pkt->tcp->sport), - mg_print_ip4, &pkt->ip->dst, mg_ntohs(pkt->tcp->dport))); - mg_hexdump(pkt->pay.ptr, pkt->pay.len); -#endif - s->tmiss = 0; // Reset missed keep-alive counter - if (s->ttype == MIP_TTYPE_KEEPALIVE) // Advance keep-alive timer - settmout(c, - MIP_TTYPE_KEEPALIVE); // unless a former ACK timeout is pending - read_conn(c, pkt); // Override timer with ACK timeout if needed - } else if ((c = getpeer(ifp->mgr, pkt, true)) == NULL) { - tx_tcp_pkt(ifp, pkt, TH_RST | TH_ACK, pkt->tcp->ack, NULL, 0); - } else if (pkt->tcp->flags & TH_RST) { - if (c->is_accepted) - mg_error(c, "peer RST"); // RFC-1122 4.2.2.13 - // ignore RST if not connected - } else if (pkt->tcp->flags & TH_SYN) { - // Use peer's source port as ISN, in order to recognise the handshake - uint32_t isn = mg_htonl((uint32_t)mg_ntohs(pkt->tcp->sport)); - tx_tcp_pkt(ifp, pkt, TH_SYN | TH_ACK, isn, NULL, 0); - } else if (pkt->tcp->flags & TH_FIN) { - tx_tcp_pkt(ifp, pkt, TH_FIN | TH_ACK, pkt->tcp->ack, NULL, 0); - } else if (mg_htonl(pkt->tcp->ack) == mg_htons(pkt->tcp->sport) + 1U) { - accept_conn(c, pkt); - } else if (!c->is_accepted) { // no peer - tx_tcp_pkt(ifp, pkt, TH_RST | TH_ACK, pkt->tcp->ack, NULL, 0); - } else { - // MG_VERBOSE(("dropped silently..")); - } -} - -static void rx_ip(struct mg_tcpip_if* ifp, struct pkt* pkt) -{ - if (pkt->ip->frag & IP_MORE_FRAGS_MSK || pkt->ip->frag & IP_FRAG_OFFSET_MSK) { - if (pkt->ip->proto == 17) - pkt->udp = (struct udp*)(pkt->ip + 1); - if (pkt->ip->proto == 6) - pkt->tcp = (struct tcp*)(pkt->ip + 1); - struct mg_connection* c = getpeer(ifp->mgr, pkt, false); - if (c) - mg_error(c, "Received fragmented packet"); - } else if (pkt->ip->proto == 1) { - pkt->icmp = (struct icmp*)(pkt->ip + 1); - if (pkt->pay.len < sizeof(*pkt->icmp)) - return; - mkpay(pkt, pkt->icmp + 1); - rx_icmp(ifp, pkt); - } else if (pkt->ip->proto == 17) { - pkt->udp = (struct udp*)(pkt->ip + 1); - if (pkt->pay.len < sizeof(*pkt->udp)) - return; - mkpay(pkt, pkt->udp + 1); - MG_VERBOSE(("UDP %M:%hu -> %M:%hu len %u", mg_print_ip4, &pkt->ip->src, - mg_ntohs(pkt->udp->sport), mg_print_ip4, &pkt->ip->dst, - mg_ntohs(pkt->udp->dport), (int)pkt->pay.len)); - if (ifp->enable_dhcp_client && pkt->udp->dport == mg_htons(68)) { - pkt->dhcp = (struct dhcp*)(pkt->udp + 1); - mkpay(pkt, pkt->dhcp + 1); - rx_dhcp_client(ifp, pkt); - } else if (ifp->enable_dhcp_server && pkt->udp->dport == mg_htons(67)) { - pkt->dhcp = (struct dhcp*)(pkt->udp + 1); - mkpay(pkt, pkt->dhcp + 1); - rx_dhcp_server(ifp, pkt); - } else { - rx_udp(ifp, pkt); - } - } else if (pkt->ip->proto == 6) { - pkt->tcp = (struct tcp*)(pkt->ip + 1); - if (pkt->pay.len < sizeof(*pkt->tcp)) - return; - mkpay(pkt, pkt->tcp + 1); - uint16_t iplen = mg_ntohs(pkt->ip->len); - uint16_t off = (uint16_t)(sizeof(*pkt->ip) + ((pkt->tcp->off >> 4) * 4U)); - if (iplen >= off) - pkt->pay.len = (size_t)(iplen - off); - MG_VERBOSE(("TCP %M:%hu -> %M:%hu len %u", mg_print_ip4, &pkt->ip->src, - mg_ntohs(pkt->tcp->sport), mg_print_ip4, &pkt->ip->dst, - mg_ntohs(pkt->tcp->dport), (int)pkt->pay.len)); - rx_tcp(ifp, pkt); - } -} - -static void rx_ip6(struct mg_tcpip_if* ifp, struct pkt* pkt) -{ - // MG_DEBUG(("IP %d", (int) len)); - if (pkt->ip6->proto == 1 || pkt->ip6->proto == 58) { - pkt->icmp = (struct icmp*)(pkt->ip6 + 1); - if (pkt->pay.len < sizeof(*pkt->icmp)) - return; - mkpay(pkt, pkt->icmp + 1); - rx_icmp(ifp, pkt); - } else if (pkt->ip6->proto == 17) { - pkt->udp = (struct udp*)(pkt->ip6 + 1); - if (pkt->pay.len < sizeof(*pkt->udp)) - return; - // MG_DEBUG((" UDP %u %u -> %u", len, mg_htons(udp->sport), - // mg_htons(udp->dport))); - mkpay(pkt, pkt->udp + 1); - } -} - -static void mg_tcpip_rx(struct mg_tcpip_if* ifp, void* buf, size_t len) -{ - struct pkt pkt; - memset(&pkt, 0, sizeof(pkt)); - pkt.raw.ptr = (char*)buf; - pkt.raw.len = len; - pkt.eth = (struct eth*)buf; - // mg_hexdump(buf, len > 16 ? 16: len); - if (pkt.raw.len < sizeof(*pkt.eth)) - return; // Truncated - runt? - if (ifp->enable_mac_check && memcmp(pkt.eth->dst, ifp->mac, sizeof(pkt.eth->dst)) != 0 && memcmp(pkt.eth->dst, broadcast, sizeof(pkt.eth->dst)) != 0) - return; - if (ifp->enable_crc32_check && len > 4) { - len -= 4; // TODO(scaprile): check on bigendian - uint32_t crc = mg_crc32(0, (const char*)buf, len); - if (memcmp((void*)((size_t)buf + len), &crc, sizeof(crc))) - return; - } - if (pkt.eth->type == mg_htons(0x806)) { - pkt.arp = (struct arp*)(pkt.eth + 1); - if (sizeof(*pkt.eth) + sizeof(*pkt.arp) > pkt.raw.len) - return; // Truncated - rx_arp(ifp, &pkt); - } else if (pkt.eth->type == mg_htons(0x86dd)) { - pkt.ip6 = (struct ip6*)(pkt.eth + 1); - if (pkt.raw.len < sizeof(*pkt.eth) + sizeof(*pkt.ip6)) - return; // Truncated - if ((pkt.ip6->ver >> 4) != 0x6) - return; // Not IP - mkpay(&pkt, pkt.ip6 + 1); - rx_ip6(ifp, &pkt); - } else if (pkt.eth->type == mg_htons(0x800)) { - pkt.ip = (struct ip*)(pkt.eth + 1); - if (pkt.raw.len < sizeof(*pkt.eth) + sizeof(*pkt.ip)) - return; // Truncated - // Truncate frame to what IP header tells us - if ((size_t)mg_ntohs(pkt.ip->len) + sizeof(struct eth) < pkt.raw.len) { - pkt.raw.len = (size_t)mg_ntohs(pkt.ip->len) + sizeof(struct eth); - } - if (pkt.raw.len < sizeof(*pkt.eth) + sizeof(*pkt.ip)) - return; // Truncated - if ((pkt.ip->ver >> 4) != 4) - return; // Not IP - mkpay(&pkt, pkt.ip + 1); - rx_ip(ifp, &pkt); - } else { - MG_DEBUG(("Unknown eth type %x", mg_htons(pkt.eth->type))); - mg_hexdump(buf, len >= 32 ? 32 : len); - } -} - -static void mg_tcpip_poll(struct mg_tcpip_if* ifp, uint64_t uptime_ms) -{ - if (ifp == NULL || ifp->driver == NULL) - return; - bool expired_1000ms = mg_timer_expired(&ifp->timer_1000ms, 1000, uptime_ms); - ifp->now = uptime_ms; - - // Handle physical interface up/down status - if (expired_1000ms && ifp->driver->up) { - bool up = ifp->driver->up(ifp); - bool current = ifp->state != MG_TCPIP_STATE_DOWN; - if (up != current) { - ifp->state = up == false ? MG_TCPIP_STATE_DOWN - : ifp->enable_dhcp_client ? MG_TCPIP_STATE_UP - : MG_TCPIP_STATE_READY; - if (!up && ifp->enable_dhcp_client) - ifp->ip = 0; - onstatechange(ifp); - } - } - if (ifp->state == MG_TCPIP_STATE_DOWN) - return; - - // DHCP RFC-2131 (4.4) - if (ifp->state == MG_TCPIP_STATE_UP && expired_1000ms) { - tx_dhcp_discover(ifp); // INIT (4.4.1) - } else if (expired_1000ms && ifp->state == MG_TCPIP_STATE_READY && ifp->lease_expire > 0) { // BOUND / RENEWING / REBINDING - if (ifp->now >= ifp->lease_expire) { - ifp->state = MG_TCPIP_STATE_UP, ifp->ip = 0; // expired, release IP - onstatechange(ifp); - } else if (ifp->now + 30UL * 60UL * 1000UL > ifp->lease_expire && ((ifp->now / 1000) % 60) == 0) { - // hack: 30 min before deadline, try to rebind (4.3.6) every min - tx_dhcp_request_re(ifp, (uint8_t*)broadcast, ifp->ip, 0xffffffff); - } // TODO(): Handle T1 (RENEWING) and T2 (REBINDING) (4.4.5) - } - - // Read data from the network - if (ifp->driver->rx != NULL) { // Polling driver. We must call it - size_t len = ifp->driver->rx(ifp->recv_queue.buf, ifp->recv_queue.size, ifp); - if (len > 0) - mg_tcpip_rx(ifp, ifp->recv_queue.buf, len); - } else { // Interrupt-based driver. Fills recv queue itself - char* buf; - size_t len = mg_queue_next(&ifp->recv_queue, &buf); - if (len > 0) { - mg_tcpip_rx(ifp, buf, len); - mg_queue_del(&ifp->recv_queue, len); - } - } - - // Process timeouts - for (struct mg_connection* c = ifp->mgr->conns; c != NULL; c = c->next) { - if (c->is_udp || c->is_listening || c->is_resolving) - continue; - struct connstate* s = (struct connstate*)(c + 1); - uint32_t rem_ip; - memcpy(&rem_ip, c->rem.ip, sizeof(uint32_t)); - if (uptime_ms > s->timer) { - if (s->ttype == MIP_TTYPE_ACK) { - MG_VERBOSE(("%lu ack %x %x", c->id, s->seq, s->ack)); - tx_tcp(ifp, s->mac, rem_ip, TH_ACK, c->loc.port, c->rem.port, - mg_htonl(s->seq), mg_htonl(s->ack), "", 0); - } else if (s->ttype == MIP_TTYPE_ARP) { - mg_error(c, "ARP timeout"); - } else if (s->ttype == MIP_TTYPE_SYN) { - mg_error(c, "Connection timeout"); - } else if (s->ttype == MIP_TTYPE_FIN) { - c->is_closing = 1; - continue; - } else { - if (s->tmiss++ > 2) { - mg_error(c, "keepalive"); - } else { - MG_VERBOSE(("%lu keepalive", c->id)); - tx_tcp(ifp, s->mac, rem_ip, TH_ACK, c->loc.port, c->rem.port, - mg_htonl(s->seq - 1), mg_htonl(s->ack), "", 0); - } - } - - settmout(c, MIP_TTYPE_KEEPALIVE); - } - } -} - -// This function executes in interrupt context, thus it should copy data -// somewhere fast. Note that newlib's malloc is not thread safe, thus use -// our lock-free queue with preallocated buffer to copy data and return asap -void mg_tcpip_qwrite(void* buf, size_t len, struct mg_tcpip_if* ifp) -{ - char* p; - if (mg_queue_book(&ifp->recv_queue, &p, len) >= len) { - memcpy(p, buf, len); - mg_queue_add(&ifp->recv_queue, len); - ifp->nrecv++; - } else { - ifp->ndrop++; - } -} - -void mg_tcpip_init(struct mg_mgr* mgr, struct mg_tcpip_if* ifp) -{ - // If MAC address is not set, make a random one - if (ifp->mac[0] == 0 && ifp->mac[1] == 0 && ifp->mac[2] == 0 && ifp->mac[3] == 0 && ifp->mac[4] == 0 && ifp->mac[5] == 0) { - ifp->mac[0] = 0x02; // Locally administered, unicast - mg_random(&ifp->mac[1], sizeof(ifp->mac) - 1); - MG_INFO(("MAC not set. Generated random: %M", mg_print_mac, ifp->mac)); - } - - if (ifp->driver->init && !ifp->driver->init(ifp)) { - MG_ERROR(("driver init failed")); - } else { - size_t framesize = 1540; - ifp->tx.ptr = (char*)calloc(1, framesize), ifp->tx.len = framesize; - if (ifp->recv_queue.size == 0) - ifp->recv_queue.size = ifp->driver->rx ? framesize : 8192; - ifp->recv_queue.buf = (char*)calloc(1, ifp->recv_queue.size); - ifp->timer_1000ms = mg_millis(); - mgr->priv = ifp; - ifp->mgr = mgr; - ifp->mtu = MG_TCPIP_MTU_DEFAULT; - mgr->extraconnsize = sizeof(struct connstate); - if (ifp->ip == 0) - ifp->enable_dhcp_client = true; - memset(ifp->gwmac, 255, sizeof(ifp->gwmac)); // Set to broadcast - mg_random(&ifp->eport, sizeof(ifp->eport)); // Random from 0 to 65535 - ifp->eport |= MG_EPHEMERAL_PORT_BASE; // Random from - // MG_EPHEMERAL_PORT_BASE to 65535 - if (ifp->tx.ptr == NULL || ifp->recv_queue.buf == NULL) - MG_ERROR(("OOM")); - } -} - -void mg_tcpip_free(struct mg_tcpip_if* ifp) -{ - free(ifp->recv_queue.buf); - free((char*)ifp->tx.ptr); -} - -int mg_mkpipe(struct mg_mgr* m, mg_event_handler_t fn, void* d, bool udp) -{ - (void)m, (void)fn, (void)d, (void)udp; - MG_ERROR(("Not implemented")); - return -1; -} - -static void send_syn(struct mg_connection* c) -{ - struct connstate* s = (struct connstate*)(c + 1); - uint32_t isn = mg_htonl((uint32_t)mg_ntohs(c->loc.port)); - struct mg_tcpip_if* ifp = (struct mg_tcpip_if*)c->mgr->priv; - uint32_t rem_ip; - memcpy(&rem_ip, c->rem.ip, sizeof(uint32_t)); - tx_tcp(ifp, s->mac, rem_ip, TH_SYN, c->loc.port, c->rem.port, isn, 0, NULL, - 0); -} - -void mg_connect_resolved(struct mg_connection* c) -{ - struct mg_tcpip_if* ifp = (struct mg_tcpip_if*)c->mgr->priv; - uint32_t rem_ip; - memcpy(&rem_ip, c->rem.ip, sizeof(uint32_t)); - c->is_resolving = 0; - if (ifp->eport < MG_EPHEMERAL_PORT_BASE) - ifp->eport = MG_EPHEMERAL_PORT_BASE; - memcpy(c->loc.ip, &ifp->ip, sizeof(uint32_t)); - c->loc.port = mg_htons(ifp->eport++); - MG_DEBUG(("%lu %M -> %M", c->id, mg_print_ip_port, &c->loc, mg_print_ip_port, - &c->rem)); - mg_call(c, MG_EV_RESOLVE, NULL); - if (((rem_ip & ifp->mask) == (ifp->ip & ifp->mask))) { - // If we're in the same LAN, fire an ARP lookup. - MG_DEBUG(("%lu ARP lookup...", c->id)); - arp_ask(ifp, rem_ip); - settmout(c, MIP_TTYPE_ARP); - c->is_arplooking = 1; - c->is_connecting = 1; - } else if (rem_ip == (ifp->ip | ~ifp->mask)) { - struct connstate* s = (struct connstate*)(c + 1); - memset(s->mac, 0xFF, sizeof(s->mac)); // local broadcast - } else if ((*((uint8_t*)&rem_ip) & 0xE0) == 0xE0) { - struct connstate* s = (struct connstate*)(c + 1); // 224 to 239, E0 to EF - uint8_t mcastp[3] = { 0x01, 0x00, 0x5E }; // multicast group - memcpy(s->mac, mcastp, 3); - memcpy(s->mac + 3, ((uint8_t*)&rem_ip) + 1, 3); // 23 LSb - s->mac[3] &= 0x7F; - } else { - struct connstate* s = (struct connstate*)(c + 1); - memcpy(s->mac, ifp->gwmac, sizeof(ifp->gwmac)); - if (c->is_udp) { - mg_call(c, MG_EV_CONNECT, NULL); - } else { - send_syn(c); - settmout(c, MIP_TTYPE_SYN); - c->is_connecting = 1; - } - } -} - -bool mg_open_listener(struct mg_connection* c, const char* url) -{ - c->loc.port = mg_htons(mg_url_port(url)); - return true; -} - -static void write_conn(struct mg_connection* c) -{ - long len = c->is_tls ? mg_tls_send(c, c->send.buf, c->send.len) - : mg_io_send(c, c->send.buf, c->send.len); - if (len > 0) { - mg_iobuf_del(&c->send, 0, (size_t)len); - mg_call(c, MG_EV_WRITE, &len); - } -} - -static void init_closure(struct mg_connection* c) -{ - struct connstate* s = (struct connstate*)(c + 1); - if (c->is_udp == false && c->is_listening == false && c->is_connecting == false) { // For TCP conns, - struct mg_tcpip_if* ifp = (struct mg_tcpip_if*)c->mgr->priv; // send TCP FIN - uint32_t rem_ip; - memcpy(&rem_ip, c->rem.ip, sizeof(uint32_t)); - tx_tcp(ifp, s->mac, rem_ip, TH_FIN | TH_ACK, c->loc.port, c->rem.port, - mg_htonl(s->seq), mg_htonl(s->ack), NULL, 0); - settmout(c, MIP_TTYPE_FIN); - } -} - -static void close_conn(struct mg_connection* c) -{ - struct connstate* s = (struct connstate*)(c + 1); - mg_iobuf_free(&s->raw); // For TLS connections, release raw data - mg_close_conn(c); -} - -static bool can_write(struct mg_connection* c) -{ - return c->is_connecting == 0 && c->is_resolving == 0 && c->send.len > 0 && c->is_tls_hs == 0 && c->is_arplooking == 0; -} - -void mg_mgr_poll(struct mg_mgr* mgr, int ms) -{ - struct mg_connection *c, *tmp; - uint64_t now = mg_millis(); - mg_tcpip_poll((struct mg_tcpip_if*)mgr->priv, now); - mg_timer_poll(&mgr->timers, now); - for (c = mgr->conns; c != NULL; c = tmp) { - tmp = c->next; - struct connstate* s = (struct connstate*)(c + 1); - mg_call(c, MG_EV_POLL, &now); - MG_VERBOSE(("%lu .. %c%c%c%c%c", c->id, c->is_tls ? 'T' : 't', - c->is_connecting ? 'C' : 'c', c->is_tls_hs ? 'H' : 'h', - c->is_resolving ? 'R' : 'r', c->is_closing ? 'C' : 'c')); - if (c->is_tls_hs) - mg_tls_handshake(c); - if (can_write(c)) - write_conn(c); - if (c->is_draining && c->send.len == 0 && s->ttype != MIP_TTYPE_FIN) - init_closure(c); - if (c->is_closing) - close_conn(c); - } - (void)ms; -} - -bool mg_send(struct mg_connection* c, const void* buf, size_t len) -{ - struct mg_tcpip_if* ifp = (struct mg_tcpip_if*)c->mgr->priv; - bool res = false; - uint32_t rem_ip; - memcpy(&rem_ip, c->rem.ip, sizeof(uint32_t)); - if (ifp->ip == 0 || ifp->state != MG_TCPIP_STATE_READY) { - mg_error(c, "net down"); - } else if (c->is_udp) { - struct connstate* s = (struct connstate*)(c + 1); - len = trim_len(c, len); // Trimming length if necessary - tx_udp(ifp, s->mac, ifp->ip, c->loc.port, rem_ip, c->rem.port, buf, len); - res = true; - } else { - res = mg_iobuf_add(&c->send, c->send.len, buf, len); - } - return res; -} -#endif // MG_ENABLE_TCPIP - -#ifdef MG_ENABLE_LINES -#line 1 "src/ota_dummy.c" -#endif - -#if MG_OTA == MG_OTA_NONE -bool mg_ota_begin(size_t new_firmware_size) -{ - (void)new_firmware_size; - return true; -} -bool mg_ota_write(const void* buf, size_t len) -{ - (void)buf, (void)len; - return true; -} -bool mg_ota_end(void) -{ - return true; -} -bool mg_ota_commit(void) -{ - return true; -} -bool mg_ota_rollback(void) -{ - return true; -} -int mg_ota_status(int fw) -{ - (void)fw; - return 0; -} -uint32_t mg_ota_crc32(int fw) -{ - (void)fw; - return 0; -} -uint32_t mg_ota_timestamp(int fw) -{ - (void)fw; - return 0; -} -size_t mg_ota_size(int fw) -{ - (void)fw; - return 0; -} -#endif - -#ifdef MG_ENABLE_LINES -#line 1 "src/ota_flash.c" -#endif - -// This OTA implementation uses the internal flash API outlined in sys.h -// It splits flash into 2 equal partitions, and stores OTA status in the -// last sector of the partition. - -#if MG_OTA == MG_OTA_FLASH - -#define MG_OTADATA_KEY 0xb07afed0 - -static char* s_addr; // Current address to write to -static size_t s_size; // Firmware size to flash. In-progress indicator -static uint32_t s_crc32; // Firmware checksum - -struct mg_otadata { - uint32_t crc32, size, timestamp, status; -}; - -bool mg_ota_begin(size_t new_firmware_size) -{ - bool ok = false; - if (s_size) { - MG_ERROR(("OTA already in progress. Call mg_ota_end()")); - } else { - size_t half = mg_flash_size() / 2, max = half - mg_flash_sector_size(); - s_crc32 = 0; - s_addr = (char*)mg_flash_start() + half; - MG_DEBUG(("Firmware %lu bytes, max %lu", s_size, max)); - if (new_firmware_size < max) { - ok = true; - s_size = new_firmware_size; - MG_INFO(("Starting OTA, firmware size %lu", s_size)); - } else { - MG_ERROR(("Firmware %lu is too big to fit %lu", new_firmware_size, max)); - } - } - return ok; -} - -bool mg_ota_write(const void* buf, size_t len) -{ - bool ok = false; - if (s_size == 0) { - MG_ERROR(("OTA is not started, call mg_ota_begin()")); - } else { - size_t align = mg_flash_write_align(); - size_t len_aligned_down = MG_ROUND_DOWN(len, align); - if (len_aligned_down) - ok = mg_flash_write(s_addr, buf, len_aligned_down); - if (len_aligned_down < len) { - size_t left = len - len_aligned_down; - char tmp[align]; - memset(tmp, 0xff, sizeof(tmp)); - memcpy(tmp, (char*)buf + len_aligned_down, left); - ok = mg_flash_write(s_addr + len_aligned_down, tmp, sizeof(tmp)); - } - s_crc32 = mg_crc32(s_crc32, (char*)buf, len); // Update CRC - MG_DEBUG(("%#x %p %lu -> %d", s_addr - len, buf, len, ok)); - s_addr += len; - } - return ok; -} - -bool mg_ota_end(void) -{ - char* base = (char*)mg_flash_start() + mg_flash_size() / 2; - bool ok = false; - if (s_size) { - size_t size = s_addr - base; - uint32_t crc32 = mg_crc32(0, base, s_size); - if (size == s_size && crc32 == s_crc32) { - uint32_t now = (uint32_t)(mg_now() / 1000); - struct mg_otadata od = { crc32, size, now, MG_OTA_FIRST_BOOT }; - uint32_t key = MG_OTADATA_KEY + (mg_flash_bank() == 2 ? 1 : 2); - ok = mg_flash_save(NULL, key, &od, sizeof(od)); - } - MG_DEBUG(("CRC: %x/%x, size: %lu/%lu, status: %s", s_crc32, crc32, s_size, - size, ok ? "ok" : "fail")); - s_size = 0; - if (ok) - ok = mg_flash_swap_bank(); - } - MG_INFO(("Finishing OTA: %s", ok ? "ok" : "fail")); - return ok; -} - -static struct mg_otadata mg_otadata(int fw) -{ - struct mg_otadata od = {}; - int bank = mg_flash_bank(); - uint32_t key = MG_OTADATA_KEY + 1; - if ((fw == MG_FIRMWARE_CURRENT && bank == 2)) - key++; - if ((fw == MG_FIRMWARE_PREVIOUS && bank == 1)) - key++; - mg_flash_load(NULL, key, &od, sizeof(od)); - // MG_DEBUG(("Loaded OTA data. fw %d, bank %d, key %p", fw, bank, key)); - // mg_hexdump(&od, sizeof(od)); - return od; -} - -int mg_ota_status(int fw) -{ - struct mg_otadata od = mg_otadata(fw); - return od.status; -} -uint32_t mg_ota_crc32(int fw) -{ - struct mg_otadata od = mg_otadata(fw); - return od.crc32; -} -uint32_t mg_ota_timestamp(int fw) -{ - struct mg_otadata od = mg_otadata(fw); - return od.timestamp; -} -size_t mg_ota_size(int fw) -{ - struct mg_otadata od = mg_otadata(fw); - return od.size; -} - -bool mg_ota_commit(void) -{ - struct mg_otadata od = mg_otadata(MG_FIRMWARE_CURRENT); - od.status = MG_OTA_COMMITTED; - uint32_t key = MG_OTADATA_KEY + mg_flash_bank(); - return mg_flash_save(NULL, key, &od, sizeof(od)); -} - -bool mg_ota_rollback(void) -{ - MG_DEBUG(("Rolling firmware back")); - return mg_flash_swap_bank(); -} -#endif - -#ifdef MG_ENABLE_LINES -#line 1 "src/printf.c" -#endif - -size_t mg_queue_vprintf(struct mg_queue* q, const char* fmt, va_list* ap) -{ - size_t len = mg_snprintf(NULL, 0, fmt, ap); - char* buf; - if (len == 0 || mg_queue_book(q, &buf, len + 1) < len + 1) { - len = 0; // Nah. Not enough space - } else { - len = mg_vsnprintf((char*)buf, len + 1, fmt, ap); - mg_queue_add(q, len); - } - return len; -} - -size_t mg_queue_printf(struct mg_queue* q, const char* fmt, ...) -{ - va_list ap; - size_t len; - va_start(ap, fmt); - len = mg_queue_vprintf(q, fmt, &ap); - va_end(ap); - return len; -} - -static void mg_pfn_iobuf_private(char ch, void* param, bool expand) -{ - struct mg_iobuf* io = (struct mg_iobuf*)param; - if (expand && io->len + 2 > io->size) - mg_iobuf_resize(io, io->len + 2); - if (io->len + 2 <= io->size) { - io->buf[io->len++] = (uint8_t)ch; - io->buf[io->len] = 0; - } else if (io->len < io->size) { - io->buf[io->len++] = 0; // Guarantee to 0-terminate - } -} - -static void mg_putchar_iobuf_static(char ch, void* param) -{ - mg_pfn_iobuf_private(ch, param, false); -} - -void mg_pfn_iobuf(char ch, void* param) -{ - mg_pfn_iobuf_private(ch, param, true); -} - -size_t mg_vsnprintf(char* buf, size_t len, const char* fmt, va_list* ap) -{ - struct mg_iobuf io = { (uint8_t*)buf, len, 0, 0 }; - size_t n = mg_vxprintf(mg_putchar_iobuf_static, &io, fmt, ap); - if (n < len) - buf[n] = '\0'; - return n; -} - -size_t mg_snprintf(char* buf, size_t len, const char* fmt, ...) -{ - va_list ap; - size_t n; - va_start(ap, fmt); - n = mg_vsnprintf(buf, len, fmt, &ap); - va_end(ap); - return n; -} - -char* mg_vmprintf(const char* fmt, va_list* ap) -{ - struct mg_iobuf io = { 0, 0, 0, 256 }; - mg_vxprintf(mg_pfn_iobuf, &io, fmt, ap); - return (char*)io.buf; -} - -char* mg_mprintf(const char* fmt, ...) -{ - char* s; - va_list ap; - va_start(ap, fmt); - s = mg_vmprintf(fmt, &ap); - va_end(ap); - return s; -} - -void mg_pfn_stdout(char c, void* param) -{ - putchar(c); - (void)param; -} - -static size_t print_ip4(void (*out)(char, void*), void* arg, uint8_t* p) -{ - return mg_xprintf(out, arg, "%d.%d.%d.%d", p[0], p[1], p[2], p[3]); -} - -static size_t print_ip6(void (*out)(char, void*), void* arg, uint16_t* p) -{ - return mg_xprintf(out, arg, "[%x:%x:%x:%x:%x:%x:%x:%x]", mg_ntohs(p[0]), - mg_ntohs(p[1]), mg_ntohs(p[2]), mg_ntohs(p[3]), - mg_ntohs(p[4]), mg_ntohs(p[5]), mg_ntohs(p[6]), - mg_ntohs(p[7])); -} - -size_t mg_print_ip4(void (*out)(char, void*), void* arg, va_list* ap) -{ - uint8_t* p = va_arg(*ap, uint8_t*); - return print_ip4(out, arg, p); -} - -size_t mg_print_ip6(void (*out)(char, void*), void* arg, va_list* ap) -{ - uint16_t* p = va_arg(*ap, uint16_t*); - return print_ip6(out, arg, p); -} - -size_t mg_print_ip(void (*out)(char, void*), void* arg, va_list* ap) -{ - struct mg_addr* addr = va_arg(*ap, struct mg_addr*); - if (addr->is_ip6) - return print_ip6(out, arg, (uint16_t*)addr->ip); - return print_ip4(out, arg, (uint8_t*)&addr->ip); -} - -size_t mg_print_ip_port(void (*out)(char, void*), void* arg, va_list* ap) -{ - struct mg_addr* a = va_arg(*ap, struct mg_addr*); - return mg_xprintf(out, arg, "%M:%hu", mg_print_ip, a, mg_ntohs(a->port)); -} - -size_t mg_print_mac(void (*out)(char, void*), void* arg, va_list* ap) -{ - uint8_t* p = va_arg(*ap, uint8_t*); - return mg_xprintf(out, arg, "%02x:%02x:%02x:%02x:%02x:%02x", p[0], p[1], p[2], - p[3], p[4], p[5]); -} - -static char mg_esc(int c, bool esc) -{ - const char *p, *esc1 = "\b\f\n\r\t\\\"", *esc2 = "bfnrt\\\""; - for (p = esc ? esc1 : esc2; *p != '\0'; p++) { - if (*p == c) - return esc ? esc2[p - esc1] : esc1[p - esc2]; - } - return 0; -} - -static char mg_escape(int c) -{ - return mg_esc(c, true); -} - -static size_t qcpy(void (*out)(char, void*), void* ptr, char* buf, - size_t len) -{ - size_t i = 0, extra = 0; - for (i = 0; i < len && buf[i] != '\0'; i++) { - char c = mg_escape(buf[i]); - if (c) { - out('\\', ptr), out(c, ptr), extra++; - } else { - out(buf[i], ptr); - } - } - return i + extra; -} - -static size_t bcpy(void (*out)(char, void*), void* arg, uint8_t* buf, - size_t len) -{ - size_t i, j, n = 0; - const char* t = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - for (i = 0; i < len; i += 3) { - uint8_t c1 = buf[i], c2 = i + 1 < len ? buf[i + 1] : 0, - c3 = i + 2 < len ? buf[i + 2] : 0; - char tmp[4] = { t[c1 >> 2], t[(c1 & 3) << 4 | (c2 >> 4)], '=', '=' }; - if (i + 1 < len) - tmp[2] = t[(c2 & 15) << 2 | (c3 >> 6)]; - if (i + 2 < len) - tmp[3] = t[c3 & 63]; - for (j = 0; j < sizeof(tmp) && tmp[j] != '\0'; j++) - out(tmp[j], arg); - n += j; - } - return n; -} - -size_t mg_print_hex(void (*out)(char, void*), void* arg, va_list* ap) -{ - size_t bl = (size_t)va_arg(*ap, int); - uint8_t* p = va_arg(*ap, uint8_t*); - const char* hex = "0123456789abcdef"; - size_t j; - for (j = 0; j < bl; j++) { - out(hex[(p[j] >> 4) & 0x0F], arg); - out(hex[p[j] & 0x0F], arg); - } - return 2 * bl; -} -size_t mg_print_base64(void (*out)(char, void*), void* arg, va_list* ap) -{ - size_t len = (size_t)va_arg(*ap, int); - uint8_t* buf = va_arg(*ap, uint8_t*); - return bcpy(out, arg, buf, len); -} - -size_t mg_print_esc(void (*out)(char, void*), void* arg, va_list* ap) -{ - size_t len = (size_t)va_arg(*ap, int); - char* p = va_arg(*ap, char*); - if (len == 0) - len = p == NULL ? 0 : strlen(p); - return qcpy(out, arg, p, len); -} - -#ifdef MG_ENABLE_LINES -#line 1 "src/queue.c" -#endif - -#if defined(__GNUC__) || defined(__clang__) -#define MG_MEMORY_BARRIER() __sync_synchronize() -#elif defined(_MSC_VER) && _MSC_VER >= 1700 -#define MG_MEMORY_BARRIER() MemoryBarrier() -#elif !defined(MG_MEMORY_BARRIER) -#define MG_MEMORY_BARRIER() -#endif - -// Every message in a queue is prepended by a 32-bit message length (ML). -// If ML is 0, then it is the end, and reader must wrap to the beginning. -// -// Queue when q->tail <= q->head: -// |----- free -----| ML | message1 | ML | message2 | ----- free ------| -// ^ ^ ^ ^ -// buf tail head len -// -// Queue when q->tail > q->head: -// | ML | message2 |----- free ------| ML | message1 | 0 |---- free ----| -// ^ ^ ^ ^ -// buf head tail len - -void mg_queue_init(struct mg_queue* q, char* buf, size_t size) -{ - q->size = size; - q->buf = buf; - q->head = q->tail = 0; -} - -static size_t mg_queue_read_len(struct mg_queue* q) -{ - uint32_t n = 0; - MG_MEMORY_BARRIER(); - memcpy(&n, q->buf + q->tail, sizeof(n)); - assert(q->tail + n + sizeof(n) <= q->size); - return n; -} - -static void mg_queue_write_len(struct mg_queue* q, size_t len) -{ - uint32_t n = (uint32_t)len; - memcpy(q->buf + q->head, &n, sizeof(n)); - MG_MEMORY_BARRIER(); -} - -size_t mg_queue_book(struct mg_queue* q, char** buf, size_t len) -{ - size_t space = 0, hs = sizeof(uint32_t) * 2; // *2 is for the 0 marker - if (q->head >= q->tail && q->head + len + hs <= q->size) { - space = q->size - q->head - hs; // There is enough space - } else if (q->head >= q->tail && q->tail > hs) { - mg_queue_write_len(q, 0); // Not enough space ahead - q->head = 0; // Wrap head to the beginning - } - if (q->head + hs + len < q->tail) - space = q->tail - q->head - hs; - if (buf != NULL) - *buf = q->buf + q->head + sizeof(uint32_t); - return space; -} - -size_t mg_queue_next(struct mg_queue* q, char** buf) -{ - size_t len = 0; - if (q->tail != q->head) { - len = mg_queue_read_len(q); - if (len == 0) { // Zero (head wrapped) ? - q->tail = 0; // Reset tail to the start - if (q->head > q->tail) - len = mg_queue_read_len(q); // Read again - } - } - if (buf != NULL) - *buf = q->buf + q->tail + sizeof(uint32_t); - assert(q->tail + len <= q->size); - return len; -} - -void mg_queue_add(struct mg_queue* q, size_t len) -{ - assert(len > 0); - mg_queue_write_len(q, len); - assert(q->head + sizeof(uint32_t) * 2 + len <= q->size); - q->head += len + sizeof(uint32_t); -} - -void mg_queue_del(struct mg_queue* q, size_t len) -{ - q->tail += len + sizeof(uint32_t); - assert(q->tail + sizeof(uint32_t) <= q->size); -} - -#ifdef MG_ENABLE_LINES -#line 1 "src/rpc.c" -#endif - -void mg_rpc_add(struct mg_rpc** head, struct mg_str method, - void (*fn)(struct mg_rpc_req*), void* fn_data) -{ - struct mg_rpc* rpc = (struct mg_rpc*)calloc(1, sizeof(*rpc)); - if (rpc != NULL) { - rpc->method = mg_strdup(method), rpc->fn = fn, rpc->fn_data = fn_data; - rpc->next = *head, *head = rpc; - } -} - -void mg_rpc_del(struct mg_rpc** head, void (*fn)(struct mg_rpc_req*)) -{ - struct mg_rpc* r; - while ((r = *head) != NULL) { - if (r->fn == fn || fn == NULL) { - *head = r->next; - free((void*)r->method.ptr); - free(r); - } else { - head = &(*head)->next; - } - } -} - -static void mg_rpc_call(struct mg_rpc_req* r, struct mg_str method) -{ - struct mg_rpc* h = r->head == NULL ? NULL : *r->head; - while (h != NULL && !mg_match(method, h->method, NULL)) - h = h->next; - if (h != NULL) { - r->rpc = h; - h->fn(r); - } else { - mg_rpc_err(r, -32601, "\"%.*s not found\"", (int)method.len, method.ptr); - } -} - -void mg_rpc_process(struct mg_rpc_req* r) -{ - int len, off = mg_json_get(r->frame, "$.method", &len); - if (off > 0 && r->frame.ptr[off] == '"') { - struct mg_str method = mg_str_n(&r->frame.ptr[off + 1], (size_t)len - 2); - mg_rpc_call(r, method); - } else if ((off = mg_json_get(r->frame, "$.result", &len)) > 0 || (off = mg_json_get(r->frame, "$.error", &len)) > 0) { - mg_rpc_call(r, mg_str("")); // JSON response! call "" method handler - } else { - mg_rpc_err(r, -32700, "%m", mg_print_esc, (int)r->frame.len, - r->frame.ptr); // Invalid - } -} - -void mg_rpc_vok(struct mg_rpc_req* r, const char* fmt, va_list* ap) -{ - int len, off = mg_json_get(r->frame, "$.id", &len); - if (off > 0) { - mg_xprintf(r->pfn, r->pfn_data, "{%m:%.*s,%m:", mg_print_esc, 0, "id", len, - &r->frame.ptr[off], mg_print_esc, 0, "result"); - mg_vxprintf(r->pfn, r->pfn_data, fmt == NULL ? "null" : fmt, ap); - mg_xprintf(r->pfn, r->pfn_data, "}"); - } -} - -void mg_rpc_ok(struct mg_rpc_req* r, const char* fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - mg_rpc_vok(r, fmt, &ap); - va_end(ap); -} - -void mg_rpc_verr(struct mg_rpc_req* r, int code, const char* fmt, va_list* ap) -{ - int len, off = mg_json_get(r->frame, "$.id", &len); - mg_xprintf(r->pfn, r->pfn_data, "{"); - if (off > 0) { - mg_xprintf(r->pfn, r->pfn_data, "%m:%.*s,", mg_print_esc, 0, "id", len, - &r->frame.ptr[off]); - } - mg_xprintf(r->pfn, r->pfn_data, "%m:{%m:%d,%m:", mg_print_esc, 0, "error", - mg_print_esc, 0, "code", code, mg_print_esc, 0, "message"); - mg_vxprintf(r->pfn, r->pfn_data, fmt == NULL ? "null" : fmt, ap); - mg_xprintf(r->pfn, r->pfn_data, "}}"); -} - -void mg_rpc_err(struct mg_rpc_req* r, int code, const char* fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - mg_rpc_verr(r, code, fmt, &ap); - va_end(ap); -} - -static size_t print_methods(mg_pfn_t pfn, void* pfn_data, va_list* ap) -{ - struct mg_rpc *h, **head = (struct mg_rpc**)va_arg(*ap, void**); - size_t len = 0; - for (h = *head; h != NULL; h = h->next) { - if (h->method.len == 0) - continue; // Ignore response handler - len += mg_xprintf(pfn, pfn_data, "%s%m", h == *head ? "" : ",", - mg_print_esc, (int)h->method.len, h->method.ptr); - } - return len; -} - -void mg_rpc_list(struct mg_rpc_req* r) -{ - mg_rpc_ok(r, "[%M]", print_methods, r->head); -} - -#ifdef MG_ENABLE_LINES -#line 1 "src/sha1.c" -#endif -/* Copyright(c) By Steve Reid */ -/* 100% Public Domain */ - -union char64long16 { - unsigned char c[64]; - uint32_t l[16]; -}; - -#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) - -static uint32_t blk0(union char64long16* block, int i) -{ - if (MG_BIG_ENDIAN) { - } else { - block->l[i] = (rol(block->l[i], 24) & 0xFF00FF00) | (rol(block->l[i], 8) & 0x00FF00FF); - } - return block->l[i]; -} - -/* Avoid redefine warning (ARM /usr/include/sys/ucontext.h define R0~R4) */ -#undef blk -#undef R0 -#undef R1 -#undef R2 -#undef R3 -#undef R4 - -#define blk(i) \ - (block->l[i & 15] = rol(block->l[(i + 13) & 15] ^ block->l[(i + 8) & 15] ^ block->l[(i + 2) & 15] ^ block->l[i & 15], \ - 1)) -#define R0(v, w, x, y, z, i) \ - z += ((w & (x ^ y)) ^ y) + blk0(block, i) + 0x5A827999 + rol(v, 5); \ - w = rol(w, 30); -#define R1(v, w, x, y, z, i) \ - z += ((w & (x ^ y)) ^ y) + blk(i) + 0x5A827999 + rol(v, 5); \ - w = rol(w, 30); -#define R2(v, w, x, y, z, i) \ - z += (w ^ x ^ y) + blk(i) + 0x6ED9EBA1 + rol(v, 5); \ - w = rol(w, 30); -#define R3(v, w, x, y, z, i) \ - z += (((w | x) & y) | (w & x)) + blk(i) + 0x8F1BBCDC + rol(v, 5); \ - w = rol(w, 30); -#define R4(v, w, x, y, z, i) \ - z += (w ^ x ^ y) + blk(i) + 0xCA62C1D6 + rol(v, 5); \ - w = rol(w, 30); - -static void mg_sha1_transform(uint32_t state[5], - const unsigned char* buffer) -{ - uint32_t a, b, c, d, e; - union char64long16 block[1]; - - memcpy(block, buffer, 64); - a = state[0]; - b = state[1]; - c = state[2]; - d = state[3]; - e = state[4]; - R0(a, b, c, d, e, 0); - R0(e, a, b, c, d, 1); - R0(d, e, a, b, c, 2); - R0(c, d, e, a, b, 3); - R0(b, c, d, e, a, 4); - R0(a, b, c, d, e, 5); - R0(e, a, b, c, d, 6); - R0(d, e, a, b, c, 7); - R0(c, d, e, a, b, 8); - R0(b, c, d, e, a, 9); - R0(a, b, c, d, e, 10); - R0(e, a, b, c, d, 11); - R0(d, e, a, b, c, 12); - R0(c, d, e, a, b, 13); - R0(b, c, d, e, a, 14); - R0(a, b, c, d, e, 15); - R1(e, a, b, c, d, 16); - R1(d, e, a, b, c, 17); - R1(c, d, e, a, b, 18); - R1(b, c, d, e, a, 19); - R2(a, b, c, d, e, 20); - R2(e, a, b, c, d, 21); - R2(d, e, a, b, c, 22); - R2(c, d, e, a, b, 23); - R2(b, c, d, e, a, 24); - R2(a, b, c, d, e, 25); - R2(e, a, b, c, d, 26); - R2(d, e, a, b, c, 27); - R2(c, d, e, a, b, 28); - R2(b, c, d, e, a, 29); - R2(a, b, c, d, e, 30); - R2(e, a, b, c, d, 31); - R2(d, e, a, b, c, 32); - R2(c, d, e, a, b, 33); - R2(b, c, d, e, a, 34); - R2(a, b, c, d, e, 35); - R2(e, a, b, c, d, 36); - R2(d, e, a, b, c, 37); - R2(c, d, e, a, b, 38); - R2(b, c, d, e, a, 39); - R3(a, b, c, d, e, 40); - R3(e, a, b, c, d, 41); - R3(d, e, a, b, c, 42); - R3(c, d, e, a, b, 43); - R3(b, c, d, e, a, 44); - R3(a, b, c, d, e, 45); - R3(e, a, b, c, d, 46); - R3(d, e, a, b, c, 47); - R3(c, d, e, a, b, 48); - R3(b, c, d, e, a, 49); - R3(a, b, c, d, e, 50); - R3(e, a, b, c, d, 51); - R3(d, e, a, b, c, 52); - R3(c, d, e, a, b, 53); - R3(b, c, d, e, a, 54); - R3(a, b, c, d, e, 55); - R3(e, a, b, c, d, 56); - R3(d, e, a, b, c, 57); - R3(c, d, e, a, b, 58); - R3(b, c, d, e, a, 59); - R4(a, b, c, d, e, 60); - R4(e, a, b, c, d, 61); - R4(d, e, a, b, c, 62); - R4(c, d, e, a, b, 63); - R4(b, c, d, e, a, 64); - R4(a, b, c, d, e, 65); - R4(e, a, b, c, d, 66); - R4(d, e, a, b, c, 67); - R4(c, d, e, a, b, 68); - R4(b, c, d, e, a, 69); - R4(a, b, c, d, e, 70); - R4(e, a, b, c, d, 71); - R4(d, e, a, b, c, 72); - R4(c, d, e, a, b, 73); - R4(b, c, d, e, a, 74); - R4(a, b, c, d, e, 75); - R4(e, a, b, c, d, 76); - R4(d, e, a, b, c, 77); - R4(c, d, e, a, b, 78); - R4(b, c, d, e, a, 79); - state[0] += a; - state[1] += b; - state[2] += c; - state[3] += d; - state[4] += e; - /* Erase working structures. The order of operations is important, - * used to ensure that compiler doesn't optimize those out. */ - memset(block, 0, sizeof(block)); - a = b = c = d = e = 0; - (void)a; - (void)b; - (void)c; - (void)d; - (void)e; -} - -void mg_sha1_init(mg_sha1_ctx* context) -{ - context->state[0] = 0x67452301; - context->state[1] = 0xEFCDAB89; - context->state[2] = 0x98BADCFE; - context->state[3] = 0x10325476; - context->state[4] = 0xC3D2E1F0; - context->count[0] = context->count[1] = 0; -} - -void mg_sha1_update(mg_sha1_ctx* context, const unsigned char* data, - size_t len) -{ - size_t i, j; - - j = context->count[0]; - if ((context->count[0] += (uint32_t)len << 3) < j) - context->count[1]++; - context->count[1] += (uint32_t)(len >> 29); - j = (j >> 3) & 63; - if ((j + len) > 63) { - memcpy(&context->buffer[j], data, (i = 64 - j)); - mg_sha1_transform(context->state, context->buffer); - for (; i + 63 < len; i += 64) { - mg_sha1_transform(context->state, &data[i]); - } - j = 0; - } else - i = 0; - memcpy(&context->buffer[j], &data[i], len - i); -} - -void mg_sha1_final(unsigned char digest[20], mg_sha1_ctx* context) -{ - unsigned i; - unsigned char finalcount[8], c; - - for (i = 0; i < 8; i++) { - finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)] >> ((3 - (i & 3)) * 8)) & 255); - } - c = 0200; - mg_sha1_update(context, &c, 1); - while ((context->count[0] & 504) != 448) { - c = 0000; - mg_sha1_update(context, &c, 1); - } - mg_sha1_update(context, finalcount, 8); - for (i = 0; i < 20; i++) { - digest[i] = (unsigned char)((context->state[i >> 2] >> ((3 - (i & 3)) * 8)) & 255); - } - memset(context, '\0', sizeof(*context)); - memset(&finalcount, '\0', sizeof(finalcount)); -} - -#ifdef MG_ENABLE_LINES -#line 1 "src/sntp.c" -#endif - -#define SNTP_TIME_OFFSET 2208988800U // (1970 - 1900) in seconds -#define SNTP_MAX_FRAC 4294967295.0 // 2 ** 32 - 1 - -static int64_t gettimestamp(const uint32_t* data) -{ - uint32_t sec = mg_ntohl(data[0]), frac = mg_ntohl(data[1]); - if (sec) - sec -= SNTP_TIME_OFFSET; - return ((int64_t)sec) * 1000 + (int64_t)(frac / SNTP_MAX_FRAC * 1000.0); -} - -int64_t mg_sntp_parse(const unsigned char* buf, size_t len) -{ - int64_t res = -1; - int mode = len > 0 ? buf[0] & 7 : 0; - int version = len > 0 ? (buf[0] >> 3) & 7 : 0; - if (len < 48) { - MG_ERROR(("%s", "corrupt packet")); - } else if (mode != 4 && mode != 5) { - MG_ERROR(("%s", "not a server reply")); - } else if (buf[1] == 0) { - MG_ERROR(("%s", "server sent a kiss of death")); - } else if (version == 4 || version == 3) { - // int64_t ref = gettimestamp((uint32_t *) &buf[16]); - int64_t t0 = gettimestamp((uint32_t*)&buf[24]); - int64_t t1 = gettimestamp((uint32_t*)&buf[32]); - int64_t t2 = gettimestamp((uint32_t*)&buf[40]); - int64_t t3 = (int64_t)mg_millis(); - int64_t delta = (t3 - t0) - (t2 - t1); - MG_VERBOSE(("%lld %lld %lld %lld delta:%lld", t0, t1, t2, t3, delta)); - res = t2 + delta / 2; - } else { - MG_ERROR(("unexpected version: %d", version)); - } - return res; -} - -static void sntp_cb(struct mg_connection* c, int ev, void* evd, void* fnd) -{ - if (ev == MG_EV_READ) { - int64_t milliseconds = mg_sntp_parse(c->recv.buf, c->recv.len); - if (milliseconds > 0) { - MG_INFO(("%lu got time: %lld ms from epoch", c->id, milliseconds)); - mg_call(c, MG_EV_SNTP_TIME, (uint64_t*)&milliseconds); - MG_VERBOSE(("%u.%u", (unsigned)(milliseconds / 1000), - (unsigned)(milliseconds % 1000))); - } - mg_iobuf_del(&c->recv, 0, c->recv.len); // Free receive buffer - } else if (ev == MG_EV_CONNECT) { - mg_sntp_request(c); - } else if (ev == MG_EV_CLOSE) { - } - (void)fnd; - (void)evd; -} - -void mg_sntp_request(struct mg_connection* c) -{ - if (c->is_resolving) { - MG_ERROR(("%lu wait until resolved", c->id)); - } else { - int64_t now = (int64_t)mg_millis(); // Use int64_t, for vc98 - uint8_t buf[48] = { 0 }; - uint32_t* t = (uint32_t*)&buf[40]; - double frac = ((double)(now % 1000)) / 1000.0 * SNTP_MAX_FRAC; - buf[0] = (0 << 6) | (4 << 3) | 3; - t[0] = mg_htonl((uint32_t)(now / 1000) + SNTP_TIME_OFFSET); - t[1] = mg_htonl((uint32_t)frac); - mg_send(c, buf, sizeof(buf)); - } -} - -struct mg_connection* mg_sntp_connect(struct mg_mgr* mgr, const char* url, - mg_event_handler_t fn, void* fnd) -{ - struct mg_connection* c = NULL; - if (url == NULL) - url = "udp://time.google.com:123"; - if ((c = mg_connect(mgr, url, fn, fnd)) != NULL) - c->pfn = sntp_cb; - return c; -} - -#ifdef MG_ENABLE_LINES -#line 1 "src/sock.c" -#endif - -#if MG_ENABLE_SOCKET - -#ifndef closesocket -#define closesocket(x) close(x) -#endif - -#define FD(c_) ((MG_SOCKET_TYPE)(size_t)(c_)->fd) -#define S2PTR(s_) ((void*)(size_t)(s_)) - -#ifndef MSG_NONBLOCKING -#define MSG_NONBLOCKING 0 -#endif - -#ifndef AF_INET6 -#define AF_INET6 10 -#endif - -#ifndef MG_SOCK_ERR -#define MG_SOCK_ERR(errcode) ((errcode) < 0 ? errno : 0) -#endif - -#ifndef MG_SOCK_INTR -#define MG_SOCK_INTR(fd) (fd == MG_INVALID_SOCKET && MG_SOCK_ERR(-1) == EINTR) -#endif - -#ifndef MG_SOCK_PENDING -#define MG_SOCK_PENDING(errcode) \ - (((errcode) < 0) && (errno == EINPROGRESS || errno == EWOULDBLOCK)) -#endif - -#ifndef MG_SOCK_RESET -#define MG_SOCK_RESET(errcode) \ - (((errcode) < 0) && (errno == EPIPE || errno == ECONNRESET)) -#endif - -union usa { - struct sockaddr sa; - struct sockaddr_in sin; -#if MG_ENABLE_IPV6 - struct sockaddr_in6 sin6; -#endif -}; - -static socklen_t tousa(struct mg_addr* a, union usa* usa) -{ - socklen_t len = sizeof(usa->sin); - memset(usa, 0, sizeof(*usa)); - usa->sin.sin_family = AF_INET; - usa->sin.sin_port = a->port; - memcpy(&usa->sin.sin_addr, a->ip, sizeof(uint32_t)); -#if MG_ENABLE_IPV6 - if (a->is_ip6) { - usa->sin.sin_family = AF_INET6; - usa->sin6.sin6_port = a->port; - memcpy(&usa->sin6.sin6_addr, a->ip, sizeof(a->ip)); - len = sizeof(usa->sin6); - } -#endif - return len; -} - -static void tomgaddr(union usa* usa, struct mg_addr* a, bool is_ip6) -{ - a->is_ip6 = is_ip6; - a->port = usa->sin.sin_port; - memcpy(&a->ip, &usa->sin.sin_addr, sizeof(uint32_t)); -#if MG_ENABLE_IPV6 - if (is_ip6) { - memcpy(a->ip, &usa->sin6.sin6_addr, sizeof(a->ip)); - a->port = usa->sin6.sin6_port; - } -#endif -} - -static void setlocaddr(MG_SOCKET_TYPE fd, struct mg_addr* addr) -{ - union usa usa; - socklen_t n = sizeof(usa); - if (getsockname(fd, &usa.sa, &n) == 0) { - tomgaddr(&usa, addr, n != sizeof(usa.sin)); - } -} - -static void iolog(struct mg_connection* c, char* buf, long n, bool r) -{ - if (n == MG_IO_WAIT) { - // Do nothing - } else if (n <= 0) { - c->is_closing = 1; // Termination. Don't call mg_error(): #1529 - } else if (n > 0) { - if (c->is_hexdumping) { - union usa usa; - socklen_t slen = sizeof(usa.sin); - if (getsockname(FD(c), &usa.sa, &slen) < 0) - (void)0; // Ignore result - MG_INFO(("\n-- %lu %M %s %M %ld", c->id, mg_print_ip_port, &c->loc, - r ? "<-" : "->", mg_print_ip_port, &c->rem, n)); - - mg_hexdump(buf, (size_t)n); - } - if (r) { - c->recv.len += (size_t)n; - mg_call(c, MG_EV_READ, &n); - } else { - mg_iobuf_del(&c->send, 0, (size_t)n); - // if (c->send.len == 0) mg_iobuf_resize(&c->send, 0); - if (c->send.len == 0) { - MG_EPOLL_MOD(c, 0); - } - mg_call(c, MG_EV_WRITE, &n); - } - } -} - -long mg_io_send(struct mg_connection* c, const void* buf, size_t len) -{ - long n; - if (c->is_udp) { - union usa usa; - socklen_t slen = tousa(&c->rem, &usa); - n = sendto(FD(c), (char*)buf, len, 0, &usa.sa, slen); - if (n > 0) - setlocaddr(FD(c), &c->loc); - } else { - n = send(FD(c), (char*)buf, len, MSG_NONBLOCKING); - } - if (MG_SOCK_PENDING(n)) - return MG_IO_WAIT; - if (MG_SOCK_RESET(n)) - return MG_IO_RESET; - if (n <= 0) - return MG_IO_ERR; - return n; -} - -bool mg_send(struct mg_connection* c, const void* buf, size_t len) -{ - if (c->is_udp) { - long n = mg_io_send(c, buf, len); - MG_DEBUG(("%lu %ld %d:%d %ld err %d", c->id, c->fd, (int)c->send.len, - (int)c->recv.len, n, MG_SOCK_ERR(n))); - iolog(c, (char*)buf, n, false); - return n > 0; - } else { - return mg_iobuf_add(&c->send, c->send.len, buf, len); - } -} - -static void mg_set_non_blocking_mode(MG_SOCKET_TYPE fd) -{ -#if defined(MG_CUSTOM_NONBLOCK) - MG_CUSTOM_NONBLOCK(fd); -#elif MG_ARCH == MG_ARCH_WIN32 && MG_ENABLE_WINSOCK - unsigned long on = 1; - ioctlsocket(fd, FIONBIO, &on); -#elif MG_ENABLE_RL - unsigned long on = 1; - ioctlsocket(fd, FIONBIO, &on); -#elif MG_ENABLE_FREERTOS_TCP - const BaseType_t off = 0; - if (setsockopt(fd, 0, FREERTOS_SO_RCVTIMEO, &off, sizeof(off)) != 0) - (void)0; - if (setsockopt(fd, 0, FREERTOS_SO_SNDTIMEO, &off, sizeof(off)) != 0) - (void)0; -#elif MG_ENABLE_LWIP - lwip_fcntl(fd, F_SETFL, O_NONBLOCK); -#elif MG_ARCH == MG_ARCH_AZURERTOS - fcntl(fd, F_SETFL, O_NONBLOCK); -#elif MG_ARCH == MG_ARCH_TIRTOS - int val = 0; - setsockopt(fd, SOL_SOCKET, SO_BLOCKING, &val, sizeof(val)); - // SPRU524J section 3.3.3 page 63, SO_SNDLOWAT - int sz = sizeof(val); - getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &val, &sz); - val /= 2; // set send low-water mark at half send buffer size - setsockopt(fd, SOL_SOCKET, SO_SNDLOWAT, &val, sizeof(val)); -#else - fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK); // Non-blocking mode - fcntl(fd, F_SETFD, FD_CLOEXEC); // Set close-on-exec -#endif -} - -bool mg_open_listener(struct mg_connection* c, const char* url) -{ - MG_SOCKET_TYPE fd = MG_INVALID_SOCKET; - bool success = false; - c->loc.port = mg_htons(mg_url_port(url)); - if (!mg_aton(mg_url_host(url), &c->loc)) { - MG_ERROR(("invalid listening URL: %s", url)); - } else { - union usa usa; - socklen_t slen = tousa(&c->loc, &usa); - int rc, on = 1, af = c->loc.is_ip6 ? AF_INET6 : AF_INET; - int type = strncmp(url, "udp:", 4) == 0 ? SOCK_DGRAM : SOCK_STREAM; - int proto = type == SOCK_DGRAM ? IPPROTO_UDP : IPPROTO_TCP; - (void)on; - - if ((fd = socket(af, type, proto)) == MG_INVALID_SOCKET) { - MG_ERROR(("socket: %d", MG_SOCK_ERR(-1))); -#if defined(SO_EXCLUSIVEADDRUSE) - } else if ((rc = setsockopt(fd, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, - (char*)&on, sizeof(on))) - != 0) { - // "Using SO_REUSEADDR and SO_EXCLUSIVEADDRUSE" - MG_ERROR(("setsockopt(SO_EXCLUSIVEADDRUSE): %d %d", on, MG_SOCK_ERR(rc))); -#elif defined(SO_REUSEADDR) && (!defined(LWIP_SOCKET) || SO_REUSE) - } else if ((rc = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&on, - sizeof(on))) - != 0) { - // 1. SO_REUSEADDR semantics on UNIX and Windows is different. On - // Windows, SO_REUSEADDR allows to bind a socket to a port without error - // even if the port is already open by another program. This is not the - // behavior SO_REUSEADDR was designed for, and leads to hard-to-track - // failure scenarios. - // - // 2. For LWIP, SO_REUSEADDR should be explicitly enabled by defining - // SO_REUSE = 1 in lwipopts.h, otherwise the code below will compile but - // won't work! (setsockopt will return EINVAL) - MG_ERROR(("setsockopt(SO_REUSEADDR): %d", MG_SOCK_ERR(rc))); -#endif -#if MG_IPV6_V6ONLY - // Bind only to the V6 address, not V4 address on this port - } else if (c->loc.is_ip6 && (rc = setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&on, sizeof(on))) != 0) { - // See #2089. Allow to bind v4 and v6 sockets on the same port - MG_ERROR(("setsockopt(IPV6_V6ONLY): %d", MG_SOCK_ERR(rc))); -#endif - } else if ((rc = bind(fd, &usa.sa, slen)) != 0) { - MG_ERROR(("bind: %d", MG_SOCK_ERR(rc))); - } else if ((type == SOCK_STREAM && (rc = listen(fd, MG_SOCK_LISTEN_BACKLOG_SIZE)) != 0)) { - // NOTE(lsm): FreeRTOS uses backlog value as a connection limit - // In case port was set to 0, get the real port number - MG_ERROR(("listen: %d", MG_SOCK_ERR(rc))); - } else { - setlocaddr(fd, &c->loc); - mg_set_non_blocking_mode(fd); - c->fd = S2PTR(fd); - MG_EPOLL_ADD(c); - success = true; - } - } - if (success == false && fd != MG_INVALID_SOCKET) - closesocket(fd); - return success; -} - -long mg_io_recv(struct mg_connection* c, void* buf, size_t len) -{ - long n = 0; - if (c->is_udp) { - union usa usa; - socklen_t slen = tousa(&c->rem, &usa); - n = recvfrom(FD(c), (char*)buf, len, 0, &usa.sa, &slen); - if (n > 0) - tomgaddr(&usa, &c->rem, slen != sizeof(usa.sin)); - } else { - n = recv(FD(c), (char*)buf, len, MSG_NONBLOCKING); - } - if (MG_SOCK_PENDING(n)) - return MG_IO_WAIT; - if (MG_SOCK_RESET(n)) - return MG_IO_RESET; - if (n <= 0) - return MG_IO_ERR; - return n; -} - -// NOTE(lsm): do only one iteration of reads, cause some systems -// (e.g. FreeRTOS stack) return 0 instead of -1/EWOULDBLOCK when no data -static void read_conn(struct mg_connection* c) -{ - long n = -1; - if (c->recv.len >= MG_MAX_RECV_SIZE) { - mg_error(c, "max_recv_buf_size reached"); - } else if (c->recv.size <= c->recv.len && !mg_iobuf_resize(&c->recv, c->recv.size + MG_IO_SIZE)) { - mg_error(c, "oom"); - } else { - char* buf = (char*)&c->recv.buf[c->recv.len]; - size_t len = c->recv.size - c->recv.len; - n = c->is_tls ? mg_tls_recv(c, buf, len) : mg_io_recv(c, buf, len); - MG_DEBUG(("%lu %ld snd %ld/%ld rcv %ld/%ld n=%ld err=%d", c->id, c->fd, - (long)c->send.len, (long)c->send.size, (long)c->recv.len, - (long)c->recv.size, n, MG_SOCK_ERR(n))); - iolog(c, buf, n, true); - } -} - -static void write_conn(struct mg_connection* c) -{ - char* buf = (char*)c->send.buf; - size_t len = c->send.len; - long n = c->is_tls ? mg_tls_send(c, buf, len) : mg_io_send(c, buf, len); - MG_DEBUG(("%lu %ld snd %ld/%ld rcv %ld/%ld n=%ld err=%d", c->id, c->fd, - (long)c->send.len, (long)c->send.size, (long)c->recv.len, - (long)c->recv.size, n, MG_SOCK_ERR(n))); - iolog(c, buf, n, false); -} - -static void close_conn(struct mg_connection* c) -{ - if (FD(c) != MG_INVALID_SOCKET) { -#if MG_ENABLE_EPOLL - epoll_ctl(c->mgr->epoll_fd, EPOLL_CTL_DEL, FD(c), NULL); -#endif - closesocket(FD(c)); -#if MG_ENABLE_FREERTOS_TCP - FreeRTOS_FD_CLR(c->fd, c->mgr->ss, eSELECT_ALL); -#endif - } - mg_close_conn(c); -} - -static void connect_conn(struct mg_connection* c) -{ - union usa usa; - socklen_t n = sizeof(usa); - // Use getpeername() to test whether we have connected - if (getpeername(FD(c), &usa.sa, &n) == 0) { - c->is_connecting = 0; - mg_call(c, MG_EV_CONNECT, NULL); - MG_EPOLL_MOD(c, 0); - if (c->is_tls_hs) - mg_tls_handshake(c); - } else { - mg_error(c, "socket error"); - } -} - -static void setsockopts(struct mg_connection* c) -{ -#if MG_ENABLE_FREERTOS_TCP || MG_ARCH == MG_ARCH_AZURERTOS || MG_ARCH == MG_ARCH_TIRTOS - (void)c; -#else - int on = 1; -#if !defined(SOL_TCP) -#define SOL_TCP IPPROTO_TCP -#endif - if (setsockopt(FD(c), SOL_TCP, TCP_NODELAY, (char*)&on, sizeof(on)) != 0) - (void)0; - if (setsockopt(FD(c), SOL_SOCKET, SO_KEEPALIVE, (char*)&on, sizeof(on)) != 0) - (void)0; -#endif -} - -void mg_connect_resolved(struct mg_connection* c) -{ - int type = c->is_udp ? SOCK_DGRAM : SOCK_STREAM; - int rc, af = c->rem.is_ip6 ? AF_INET6 : AF_INET; // c->rem has resolved IP - c->fd = S2PTR(socket(af, type, 0)); // Create outbound socket - c->is_resolving = 0; // Clear resolving flag - if (FD(c) == MG_INVALID_SOCKET) { - mg_error(c, "socket(): %d", MG_SOCK_ERR(-1)); - } else if (c->is_udp) { - MG_EPOLL_ADD(c); -#if MG_ARCH == MG_ARCH_TIRTOS - union usa usa; // TI-RTOS NDK requires binding to receive on UDP sockets - socklen_t slen = tousa(&c->loc, &usa); - if ((rc = bind(c->fd, &usa.sa, slen)) != 0) - MG_ERROR(("bind: %d", MG_SOCK_ERR(rc))); -#endif - mg_call(c, MG_EV_RESOLVE, NULL); - mg_call(c, MG_EV_CONNECT, NULL); - } else { - union usa usa; - socklen_t slen = tousa(&c->rem, &usa); - mg_set_non_blocking_mode(FD(c)); - setsockopts(c); - MG_EPOLL_ADD(c); - mg_call(c, MG_EV_RESOLVE, NULL); - rc = connect(FD(c), &usa.sa, slen); // Attempt to connect - if (rc == 0) { // Success - mg_call(c, MG_EV_CONNECT, NULL); // Send MG_EV_CONNECT to the user - } else if (MG_SOCK_PENDING(rc)) { // Need to wait for TCP handshake - MG_DEBUG(("%lu %ld -> %M pend", c->id, c->fd, mg_print_ip_port, &c->rem)); - c->is_connecting = 1; - } else { - mg_error(c, "connect: %d", MG_SOCK_ERR(rc)); - } - } -} - -static MG_SOCKET_TYPE raccept(MG_SOCKET_TYPE sock, union usa* usa, - socklen_t* len) -{ - MG_SOCKET_TYPE fd = MG_INVALID_SOCKET; - do { - memset(usa, 0, sizeof(*usa)); - fd = accept(sock, &usa->sa, len); - } while (MG_SOCK_INTR(fd)); - return fd; -} - -static void accept_conn(struct mg_mgr* mgr, struct mg_connection* lsn) -{ - struct mg_connection* c = NULL; - union usa usa; - socklen_t sa_len = sizeof(usa); - MG_SOCKET_TYPE fd = raccept(FD(lsn), &usa, &sa_len); - if (fd == MG_INVALID_SOCKET) { -#if MG_ARCH == MG_ARCH_AZURERTOS - // AzureRTOS, in non-block socket mode can mark listening socket readable - // even it is not. See comment for 'select' func implementation in - // nx_bsd.c That's not an error, just should try later - if (errno != EAGAIN) -#endif - MG_ERROR(("%lu accept failed, errno %d", lsn->id, MG_SOCK_ERR(-1))); -#if (MG_ARCH != MG_ARCH_WIN32) && !MG_ENABLE_FREERTOS_TCP && (MG_ARCH != MG_ARCH_TIRTOS) && !MG_ENABLE_POLL && !MG_ENABLE_EPOLL - } else if ((long)fd >= FD_SETSIZE) { - MG_ERROR(("%ld > %ld", (long)fd, (long)FD_SETSIZE)); - closesocket(fd); -#endif - } else if ((c = mg_alloc_conn(mgr)) == NULL) { - MG_ERROR(("%lu OOM", lsn->id)); - closesocket(fd); - } else { - tomgaddr(&usa, &c->rem, sa_len != sizeof(usa.sin)); - LIST_ADD_HEAD(struct mg_connection, &mgr->conns, c); - c->fd = S2PTR(fd); - MG_EPOLL_ADD(c); - mg_set_non_blocking_mode(FD(c)); - setsockopts(c); - c->is_accepted = 1; - c->is_hexdumping = lsn->is_hexdumping; - c->loc = lsn->loc; - c->pfn = lsn->pfn; - c->pfn_data = lsn->pfn_data; - c->fn = lsn->fn; - c->fn_data = lsn->fn_data; - MG_DEBUG(("%lu %ld accepted %M -> %M", c->id, c->fd, mg_print_ip_port, - &c->rem, mg_print_ip_port, &c->loc)); - mg_call(c, MG_EV_OPEN, NULL); - mg_call(c, MG_EV_ACCEPT, NULL); - } -} - -static bool can_read(const struct mg_connection* c) -{ - return c->is_full == false; -} - -static bool can_write(const struct mg_connection* c) -{ - return c->is_connecting || (c->send.len > 0 && c->is_tls_hs == 0); -} - -static bool skip_iotest(const struct mg_connection* c) -{ - return (c->is_closing || c->is_resolving || FD(c) == MG_INVALID_SOCKET) || (can_read(c) == false && can_write(c) == false); -} - -static void mg_iotest(struct mg_mgr* mgr, int ms) -{ -#if MG_ENABLE_FREERTOS_TCP - struct mg_connection* c; - for (c = mgr->conns; c != NULL; c = c->next) { - c->is_readable = c->is_writable = 0; - if (skip_iotest(c)) - continue; - if (can_read(c)) - FreeRTOS_FD_SET(c->fd, mgr->ss, eSELECT_READ | eSELECT_EXCEPT); - if (can_write(c)) - FreeRTOS_FD_SET(c->fd, mgr->ss, eSELECT_WRITE); - } - FreeRTOS_select(mgr->ss, pdMS_TO_TICKS(ms)); - for (c = mgr->conns; c != NULL; c = c->next) { - EventBits_t bits = FreeRTOS_FD_ISSET(c->fd, mgr->ss); - c->is_readable = bits & (eSELECT_READ | eSELECT_EXCEPT) ? 1U : 0; - c->is_writable = bits & eSELECT_WRITE ? 1U : 0; - if (c->fd != MG_INVALID_SOCKET) - FreeRTOS_FD_CLR(c->fd, mgr->ss, - eSELECT_READ | eSELECT_EXCEPT | eSELECT_WRITE); - } -#elif MG_ENABLE_EPOLL - size_t max = 1; - for (struct mg_connection* c = mgr->conns; c != NULL; c = c->next) { - c->is_readable = c->is_writable = 0; - if (mg_tls_pending(c) > 0) - ms = 1, c->is_readable = 1; - if (can_write(c)) - MG_EPOLL_MOD(c, 1); - max++; - } - struct epoll_event* evs = (struct epoll_event*)alloca(max * sizeof(evs[0])); - int n = epoll_wait(mgr->epoll_fd, evs, (int)max, ms); - for (int i = 0; i < n; i++) { - struct mg_connection* c = (struct mg_connection*)evs[i].data.ptr; - if (evs[i].events & EPOLLERR) { - mg_error(c, "socket error"); - } else if (c->is_readable == 0) { - bool rd = evs[i].events & (EPOLLIN | EPOLLHUP); - bool wr = evs[i].events & EPOLLOUT; - c->is_readable = can_read(c) && rd ? 1U : 0; - c->is_writable = can_write(c) && wr ? 1U : 0; - } - } - (void)skip_iotest; -#elif MG_ENABLE_POLL - nfds_t n = 0; - for (struct mg_connection* c = mgr->conns; c != NULL; c = c->next) - n++; - struct pollfd* fds = (struct pollfd*)alloca(n * sizeof(fds[0])); - memset(fds, 0, n * sizeof(fds[0])); - n = 0; - for (struct mg_connection* c = mgr->conns; c != NULL; c = c->next) { - c->is_readable = c->is_writable = 0; - if (skip_iotest(c)) { - // Socket not valid, ignore - } else if (mg_tls_pending(c) > 0) { - ms = 1; // Don't wait if TLS is ready - } else { - fds[n].fd = FD(c); - if (can_read(c)) - fds[n].events |= POLLIN; - if (can_write(c)) - fds[n].events |= POLLOUT; - n++; - } - } - - // MG_INFO(("poll n=%d ms=%d", (int) n, ms)); - if (poll(fds, n, ms) < 0) { -#if MG_ARCH == MG_ARCH_WIN32 - if (n == 0) - Sleep(ms); // On Windows, poll fails if no sockets -#endif - memset(fds, 0, n * sizeof(fds[0])); - } - n = 0; - for (struct mg_connection* c = mgr->conns; c != NULL; c = c->next) { - if (skip_iotest(c)) { - // Socket not valid, ignore - } else if (mg_tls_pending(c) > 0) { - c->is_readable = 1; - } else { - if (fds[n].revents & POLLERR) { - mg_error(c, "socket error"); - } else { - c->is_readable = (unsigned)(fds[n].revents & (POLLIN | POLLHUP) ? 1 : 0); - c->is_writable = (unsigned)(fds[n].revents & POLLOUT ? 1 : 0); - } - n++; - } - } -#else - struct timeval tv = { ms / 1000, (ms % 1000) * 1000 }, tv_zero = { 0, 0 }, *tvp; - struct mg_connection* c; - fd_set rset, wset, eset; - MG_SOCKET_TYPE maxfd = 0; - int rc; - - FD_ZERO(&rset); - FD_ZERO(&wset); - FD_ZERO(&eset); - tvp = ms < 0 ? NULL : &tv; - for (c = mgr->conns; c != NULL; c = c->next) { - c->is_readable = c->is_writable = 0; - if (skip_iotest(c)) - continue; - FD_SET(FD(c), &eset); - if (can_read(c)) - FD_SET(FD(c), &rset); - if (can_write(c)) - FD_SET(FD(c), &wset); - if (mg_tls_pending(c) > 0) - tvp = &tv_zero; - if (FD(c) > maxfd) - maxfd = FD(c); - } - - if ((rc = select((int)maxfd + 1, &rset, &wset, &eset, tvp)) < 0) { -#if MG_ARCH == MG_ARCH_WIN32 - if (maxfd == 0) - Sleep(ms); // On Windows, select fails if no sockets -#else - MG_ERROR(("select: %d %d", rc, MG_SOCK_ERR(rc))); -#endif - FD_ZERO(&rset); - FD_ZERO(&wset); - FD_ZERO(&eset); - } - - for (c = mgr->conns; c != NULL; c = c->next) { - if (FD(c) != MG_INVALID_SOCKET && FD_ISSET(FD(c), &eset)) { - mg_error(c, "socket error"); - } else { - c->is_readable = FD(c) != MG_INVALID_SOCKET && FD_ISSET(FD(c), &rset); - c->is_writable = FD(c) != MG_INVALID_SOCKET && FD_ISSET(FD(c), &wset); - if (mg_tls_pending(c) > 0) - c->is_readable = 1; - } - } -#endif -} - -void mg_mgr_poll(struct mg_mgr* mgr, int ms) -{ - struct mg_connection *c, *tmp; - uint64_t now; - - mg_iotest(mgr, ms); - now = mg_millis(); - mg_timer_poll(&mgr->timers, now); - - for (c = mgr->conns; c != NULL; c = tmp) { - bool is_resp = c->is_resp; - tmp = c->next; - mg_call(c, MG_EV_POLL, &now); - if (is_resp && !c->is_resp) { - long n = 0; - mg_call(c, MG_EV_READ, &n); - } - MG_VERBOSE(("%lu %c%c %c%c%c%c%c", c->id, c->is_readable ? 'r' : '-', - c->is_writable ? 'w' : '-', c->is_tls ? 'T' : 't', - c->is_connecting ? 'C' : 'c', c->is_tls_hs ? 'H' : 'h', - c->is_resolving ? 'R' : 'r', c->is_closing ? 'C' : 'c')); - if (c->is_resolving || c->is_closing) { - // Do nothing - } else if (c->is_listening && c->is_udp == 0) { - if (c->is_readable) - accept_conn(mgr, c); - } else if (c->is_connecting) { - if (c->is_readable || c->is_writable) - connect_conn(c); - } else if (c->is_tls_hs) { - if ((c->is_readable || c->is_writable)) - mg_tls_handshake(c); - } else { - if (c->is_readable) - read_conn(c); - if (c->is_writable) - write_conn(c); - } - - if (c->is_draining && c->send.len == 0) - c->is_closing = 1; - if (c->is_closing) - close_conn(c); - } -} -#endif - -#ifdef MG_ENABLE_LINES -#line 1 "src/ssi.c" -#endif - -#ifndef MG_MAX_SSI_DEPTH -#define MG_MAX_SSI_DEPTH 5 -#endif - -#ifndef MG_SSI_BUFSIZ -#define MG_SSI_BUFSIZ 1024 -#endif - -#if MG_ENABLE_SSI -static char* mg_ssi(const char* path, const char* root, int depth) -{ - struct mg_iobuf b = { NULL, 0, 0, MG_IO_SIZE }; - FILE* fp = fopen(path, "rb"); - if (fp != NULL) { - char buf[MG_SSI_BUFSIZ], arg[sizeof(buf)]; - int ch, intag = 0; - size_t len = 0; - buf[0] = arg[0] = '\0'; - while ((ch = fgetc(fp)) != EOF) { - if (intag && ch == '>' && buf[len - 1] == '-' && buf[len - 2] == '-') { - buf[len++] = (char)(ch & 0xff); - buf[len] = '\0'; - if (sscanf(buf, " %#x %#x", s_txdesc[s_txno][1], tsr)); - if (!(s_txdesc[s_txno][1] & BIT(31))) - s_txdesc[s_txno][1] |= BIT(31); - } - - GMAC_REGS->GMAC_RSR = rsr; - GMAC_REGS->GMAC_TSR = tsr; -} - -struct mg_tcpip_driver mg_tcpip_driver_same54 = { - mg_tcpip_driver_same54_init, mg_tcpip_driver_same54_tx, NULL, - mg_tcpip_driver_same54_up -}; -#endif - -#ifdef MG_ENABLE_LINES -#line 1 "src/drivers/stm32.c" -#endif - -#if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_STM32) && MG_ENABLE_DRIVER_STM32 -struct stm32_eth { - volatile uint32_t MACCR, MACFFR, MACHTHR, MACHTLR, MACMIIAR, MACMIIDR, MACFCR, - MACVLANTR, RESERVED0[2], MACRWUFFR, MACPMTCSR, RESERVED1, MACDBGR, MACSR, - MACIMR, MACA0HR, MACA0LR, MACA1HR, MACA1LR, MACA2HR, MACA2LR, MACA3HR, - MACA3LR, RESERVED2[40], MMCCR, MMCRIR, MMCTIR, MMCRIMR, MMCTIMR, - RESERVED3[14], MMCTGFSCCR, MMCTGFMSCCR, RESERVED4[5], MMCTGFCR, - RESERVED5[10], MMCRFCECR, MMCRFAECR, RESERVED6[10], MMCRGUFCR, - RESERVED7[334], PTPTSCR, PTPSSIR, PTPTSHR, PTPTSLR, PTPTSHUR, PTPTSLUR, - PTPTSAR, PTPTTHR, PTPTTLR, RESERVED8, PTPTSSR, PTPPPSCR, RESERVED9[564], - DMABMR, DMATPDR, DMARPDR, DMARDLAR, DMATDLAR, DMASR, DMAOMR, DMAIER, - DMAMFBOCR, DMARSWTR, RESERVED10[8], DMACHTDR, DMACHRDR, DMACHTBAR, - DMACHRBAR; -}; -#undef ETH -#define ETH ((struct stm32_eth*)(uintptr_t)0x40028000) - -#undef DSB -#if defined(__CC_ARM) -#define DSB() __dsb(0xF) -#elif defined(__ARMCC_VERSION) -#define DSB() __builtin_arm_dsb(0xF) -#elif defined(__GNUC__) && defined(__arm__) && defined(__thumb__) -#define DSB() asm("DSB 0xF") -#elif defined(__ICCARM__) -#define DSB() __iar_builtin_DSB() -#else -#define DSB() -#endif - -#undef BIT -#define BIT(x) ((uint32_t)1 << (x)) -#define ETH_PKT_SIZE 1540 // Max frame size -#define ETH_DESC_CNT 4 // Descriptors count -#define ETH_DS 4 // Descriptor size (words) - -static uint32_t s_rxdesc[ETH_DESC_CNT][ETH_DS]; // RX descriptors -static uint32_t s_txdesc[ETH_DESC_CNT][ETH_DS]; // TX descriptors -static uint8_t s_rxbuf[ETH_DESC_CNT][ETH_PKT_SIZE]; // RX ethernet buffers -static uint8_t s_txbuf[ETH_DESC_CNT][ETH_PKT_SIZE]; // TX ethernet buffers -static uint8_t s_txno; // Current TX descriptor -static uint8_t s_rxno; // Current RX descriptor - -static struct mg_tcpip_if* s_ifp; // MIP interface -enum { PHY_ADDR = 0, - PHY_BCR = 0, - PHY_BSR = 1, - PHY_CSCR = 31 }; - -static uint32_t eth_read_phy(uint8_t addr, uint8_t reg) -{ - ETH->MACMIIAR &= (7 << 2); - ETH->MACMIIAR |= ((uint32_t)addr << 11) | ((uint32_t)reg << 6); - ETH->MACMIIAR |= BIT(0); - while (ETH->MACMIIAR & BIT(0)) - (void)0; - return ETH->MACMIIDR; -} - -static void eth_write_phy(uint8_t addr, uint8_t reg, uint32_t val) -{ - ETH->MACMIIDR = val; - ETH->MACMIIAR &= (7 << 2); - ETH->MACMIIAR |= ((uint32_t)addr << 11) | ((uint32_t)reg << 6) | BIT(1); - ETH->MACMIIAR |= BIT(0); - while (ETH->MACMIIAR & BIT(0)) - (void)0; -} - -static uint32_t get_hclk(void) -{ - struct rcc { - volatile uint32_t CR, PLLCFGR, CFGR; - }* rcc = (struct rcc*)0x40023800; - uint32_t clk = 0, hsi = 16000000 /* 16 MHz */, hse = 8000000 /* 8MHz */; - - if (rcc->CFGR & (1 << 2)) { - clk = hse; - } else if (rcc->CFGR & (1 << 3)) { - uint32_t vco, m, n, p; - m = (rcc->PLLCFGR & (0x3f << 0)) >> 0; - n = (rcc->PLLCFGR & (0x1ff << 6)) >> 6; - p = (((rcc->PLLCFGR & (3 << 16)) >> 16) + 1) * 2; - clk = (rcc->PLLCFGR & (1 << 22)) ? hse : hsi; - vco = (uint32_t)((uint64_t)clk * n / m); - clk = vco / p; - } else { - clk = hsi; - } - uint32_t hpre = (rcc->CFGR & (15 << 4)) >> 4; - if (hpre < 8) - return clk; - - uint8_t ahbptab[8] = { 1, 2, 3, 4, 6, 7, 8, 9 }; // log2(div) - return ((uint32_t)clk) >> ahbptab[hpre - 8]; -} - -// Guess CR from HCLK. MDC clock is generated from HCLK (AHB); as per 802.3, -// it must not exceed 2.5MHz As the AHB clock can be (and usually is) derived -// from the HSI (internal RC), and it can go above specs, the datasheets -// specify a range of frequencies and activate one of a series of dividers to -// keep the MDC clock safely below 2.5MHz. We guess a divider setting based on -// HCLK with a +5% drift. If the user uses a different clock from our -// defaults, needs to set the macros on top Valid for STM32F74xxx/75xxx -// (38.8.1) and STM32F42xxx/43xxx (33.8.1) (both 4.5% worst case drift) -static int guess_mdc_cr(void) -{ - uint8_t crs[] = { 2, 3, 0, 1, 4, 5 }; // ETH->MACMIIAR::CR values - uint8_t div[] = { 16, 26, 42, 62, 102, 124 }; // Respective HCLK dividers - uint32_t hclk = get_hclk(); // Guess system HCLK - int result = -1; // Invalid CR value - if (hclk < 25000000) { - MG_ERROR(("HCLK too low")); - } else { - for (int i = 0; i < 6; i++) { - if (hclk / div[i] <= 2375000UL /* 2.5MHz - 5% */) { - result = crs[i]; - break; - } - } - if (result < 0) - MG_ERROR(("HCLK too high")); - } - MG_DEBUG(("HCLK: %u, CR: %d", hclk, result)); - return result; -} - -static bool mg_tcpip_driver_stm32_init(struct mg_tcpip_if* ifp) -{ - struct mg_tcpip_driver_stm32_data* d = (struct mg_tcpip_driver_stm32_data*)ifp->driver_data; - s_ifp = ifp; - - // Init RX descriptors - for (int i = 0; i < ETH_DESC_CNT; i++) { - s_rxdesc[i][0] = BIT(31); // Own - s_rxdesc[i][1] = sizeof(s_rxbuf[i]) | BIT(14); // 2nd address chained - s_rxdesc[i][2] = (uint32_t)(uintptr_t)s_rxbuf[i]; // Point to data buffer - s_rxdesc[i][3] = (uint32_t)(uintptr_t)s_rxdesc[(i + 1) % ETH_DESC_CNT]; // Chain - } - - // Init TX descriptors - for (int i = 0; i < ETH_DESC_CNT; i++) { - s_txdesc[i][2] = (uint32_t)(uintptr_t)s_txbuf[i]; // Buf pointer - s_txdesc[i][3] = (uint32_t)(uintptr_t)s_txdesc[(i + 1) % ETH_DESC_CNT]; // Chain - } - - ETH->DMABMR |= BIT(0); // Software reset - while ((ETH->DMABMR & BIT(0)) != 0) - (void)0; // Wait until done - - // Set MDC clock divider. If user told us the value, use it. Otherwise, guess - int cr = (d == NULL || d->mdc_cr < 0) ? guess_mdc_cr() : d->mdc_cr; - ETH->MACMIIAR = ((uint32_t)cr & 7) << 2; - - // NOTE(cpq): we do not use extended descriptor bit 7, and do not use - // hardware checksum. Therefore, descriptor size is 4, not 8 - // ETH->DMABMR = BIT(13) | BIT(16) | BIT(22) | BIT(23) | BIT(25); - ETH->MACIMR = BIT(3) | BIT(9); // Mask timestamp & PMT IT - ETH->MACFCR = BIT(7); // Disable zero quarta pause - // ETH->MACFFR = BIT(31); // Receive all - eth_write_phy(PHY_ADDR, PHY_BCR, BIT(15)); // Reset PHY - eth_write_phy(PHY_ADDR, PHY_BCR, BIT(12)); // Set autonegotiation - ETH->DMARDLAR = (uint32_t)(uintptr_t)s_rxdesc; // RX descriptors - ETH->DMATDLAR = (uint32_t)(uintptr_t)s_txdesc; // RX descriptors - ETH->DMAIER = BIT(6) | BIT(16); // RIE, NISE - ETH->MACCR = BIT(2) | BIT(3) | BIT(11) | BIT(14); // RE, TE, Duplex, Fast - ETH->DMAOMR = BIT(1) | BIT(13) | BIT(21) | BIT(25); // SR, ST, TSF, RSF - - // MAC address filtering - ETH->MACA0HR = ((uint32_t)ifp->mac[5] << 8U) | ifp->mac[4]; - ETH->MACA0LR = (uint32_t)(ifp->mac[3] << 24) | ((uint32_t)ifp->mac[2] << 16) | ((uint32_t)ifp->mac[1] << 8) | ifp->mac[0]; - return true; -} - -static size_t mg_tcpip_driver_stm32_tx(const void* buf, size_t len, - struct mg_tcpip_if* ifp) -{ - if (len > sizeof(s_txbuf[s_txno])) { - MG_ERROR(("Frame too big, %ld", (long)len)); - len = 0; // Frame is too big - } else if ((s_txdesc[s_txno][0] & BIT(31))) { - ifp->nerr++; - MG_ERROR(("No free descriptors")); - // printf("D0 %lx SR %lx\n", (long) s_txdesc[0][0], (long) ETH->DMASR); - len = 0; // All descriptors are busy, fail - } else { - memcpy(s_txbuf[s_txno], buf, len); // Copy data - s_txdesc[s_txno][1] = (uint32_t)len; // Set data len - s_txdesc[s_txno][0] = BIT(20) | BIT(28) | BIT(29); // Chain,FS,LS - s_txdesc[s_txno][0] |= BIT(31); // Set OWN bit - let DMA take over - if (++s_txno >= ETH_DESC_CNT) - s_txno = 0; - } - DSB(); // ensure descriptors have been written - ETH->DMASR = BIT(2) | BIT(5); // Clear any prior TBUS/TUS - ETH->DMATPDR = 0; // and resume - return len; -} - -static bool mg_tcpip_driver_stm32_up(struct mg_tcpip_if* ifp) -{ - uint32_t bsr = eth_read_phy(PHY_ADDR, PHY_BSR); - bool up = bsr & BIT(2) ? 1 : 0; - if ((ifp->state == MG_TCPIP_STATE_DOWN) && up) { // link state just went up - uint32_t scsr = eth_read_phy(PHY_ADDR, PHY_CSCR); - uint32_t maccr = ETH->MACCR | BIT(14) | BIT(11); // 100M, Full-duplex - if ((scsr & BIT(3)) == 0) - maccr &= ~BIT(14); // 10M - if ((scsr & BIT(4)) == 0) - maccr &= ~BIT(11); // Half-duplex - ETH->MACCR = maccr; // IRQ handler does not fiddle with this register - MG_DEBUG(("Link is %uM %s-duplex", maccr & BIT(14) ? 100 : 10, - maccr & BIT(11) ? "full" : "half")); - } - return up; -} - -void ETH_IRQHandler(void); -void ETH_IRQHandler(void) -{ - if (ETH->DMASR & BIT(6)) { // Frame received, loop - ETH->DMASR = BIT(16) | BIT(6); // Clear flag - for (uint32_t i = 0; i < 10; i++) { // read as they arrive but not forever - if (s_rxdesc[s_rxno][0] & BIT(31)) - break; // exit when done - if (((s_rxdesc[s_rxno][0] & (BIT(8) | BIT(9))) == (BIT(8) | BIT(9))) && !(s_rxdesc[s_rxno][0] & BIT(15))) { // skip partial/errored frames - uint32_t len = ((s_rxdesc[s_rxno][0] >> 16) & (BIT(14) - 1)); - // printf("%lx %lu %lx %.8lx\n", s_rxno, len, s_rxdesc[s_rxno][0], - // ETH->DMASR); - mg_tcpip_qwrite(s_rxbuf[s_rxno], len > 4 ? len - 4 : len, s_ifp); - } - s_rxdesc[s_rxno][0] = BIT(31); - if (++s_rxno >= ETH_DESC_CNT) - s_rxno = 0; - } - } - ETH->DMASR = BIT(7); // Clear possible RBUS while processing - ETH->DMARPDR = 0; // and resume RX -} - -struct mg_tcpip_driver mg_tcpip_driver_stm32 = { mg_tcpip_driver_stm32_init, - mg_tcpip_driver_stm32_tx, NULL, - mg_tcpip_driver_stm32_up }; -#endif - -#ifdef MG_ENABLE_LINES -#line 1 "src/drivers/stm32h.c" -#endif - -#if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_STM32H) && MG_ENABLE_DRIVER_STM32H -struct stm32h_eth { - volatile uint32_t MACCR, MACECR, MACPFR, MACWTR, MACHT0R, MACHT1R, - RESERVED1[14], MACVTR, RESERVED2, MACVHTR, RESERVED3, MACVIR, MACIVIR, - RESERVED4[2], MACTFCR, RESERVED5[7], MACRFCR, RESERVED6[7], MACISR, - MACIER, MACRXTXSR, RESERVED7, MACPCSR, MACRWKPFR, RESERVED8[2], MACLCSR, - MACLTCR, MACLETR, MAC1USTCR, RESERVED9[12], MACVR, MACDR, RESERVED10, - MACHWF0R, MACHWF1R, MACHWF2R, RESERVED11[54], MACMDIOAR, MACMDIODR, - RESERVED12[2], MACARPAR, RESERVED13[59], MACA0HR, MACA0LR, MACA1HR, - MACA1LR, MACA2HR, MACA2LR, MACA3HR, MACA3LR, RESERVED14[248], MMCCR, - MMCRIR, MMCTIR, MMCRIMR, MMCTIMR, RESERVED15[14], MMCTSCGPR, MMCTMCGPR, - RESERVED16[5], MMCTPCGR, RESERVED17[10], MMCRCRCEPR, MMCRAEPR, - RESERVED18[10], MMCRUPGR, RESERVED19[9], MMCTLPIMSTR, MMCTLPITCR, - MMCRLPIMSTR, MMCRLPITCR, RESERVED20[65], MACL3L4C0R, MACL4A0R, - RESERVED21[2], MACL3A0R0R, MACL3A1R0R, MACL3A2R0R, MACL3A3R0R, - RESERVED22[4], MACL3L4C1R, MACL4A1R, RESERVED23[2], MACL3A0R1R, - MACL3A1R1R, MACL3A2R1R, MACL3A3R1R, RESERVED24[108], MACTSCR, MACSSIR, - MACSTSR, MACSTNR, MACSTSUR, MACSTNUR, MACTSAR, RESERVED25, MACTSSR, - RESERVED26[3], MACTTSSNR, MACTTSSSR, RESERVED27[2], MACACR, RESERVED28, - MACATSNR, MACATSSR, MACTSIACR, MACTSEACR, MACTSICNR, MACTSECNR, - RESERVED29[4], MACPPSCR, RESERVED30[3], MACPPSTTSR, MACPPSTTNR, MACPPSIR, - MACPPSWR, RESERVED31[12], MACPOCR, MACSPI0R, MACSPI1R, MACSPI2R, MACLMIR, - RESERVED32[11], MTLOMR, RESERVED33[7], MTLISR, RESERVED34[55], MTLTQOMR, - MTLTQUR, MTLTQDR, RESERVED35[8], MTLQICSR, MTLRQOMR, MTLRQMPOCR, MTLRQDR, - RESERVED36[177], DMAMR, DMASBMR, DMAISR, DMADSR, RESERVED37[60], DMACCR, - DMACTCR, DMACRCR, RESERVED38[2], DMACTDLAR, RESERVED39, DMACRDLAR, - DMACTDTPR, RESERVED40, DMACRDTPR, DMACTDRLR, DMACRDRLR, DMACIER, - DMACRIWTR, DMACSFCSR, RESERVED41, DMACCATDR, RESERVED42, DMACCARDR, - RESERVED43, DMACCATBR, RESERVED44, DMACCARBR, DMACSR, RESERVED45[2], - DMACMFCR; -}; -#undef ETH -#define ETH \ - ((struct stm32h_eth*)(uintptr_t)(0x40000000UL + 0x00020000UL + 0x8000UL)) - -#undef BIT -#define BIT(x) ((uint32_t)1 << (x)) -#define ETH_PKT_SIZE 1540 // Max frame size -#define ETH_DESC_CNT 4 // Descriptors count -#define ETH_DS 4 // Descriptor size (words) - -static volatile uint32_t s_rxdesc[ETH_DESC_CNT][ETH_DS]; // RX descriptors -static volatile uint32_t s_txdesc[ETH_DESC_CNT][ETH_DS]; // TX descriptors -static uint8_t s_rxbuf[ETH_DESC_CNT][ETH_PKT_SIZE]; // RX ethernet buffers -static uint8_t s_txbuf[ETH_DESC_CNT][ETH_PKT_SIZE]; // TX ethernet buffers -static struct mg_tcpip_if* s_ifp; // MIP interface -enum { - PHY_ADDR = 0, - PHY_BCR = 0, - PHY_BSR = 1, - PHY_CSCR = 31 -}; // PHY constants - -static uint32_t eth_read_phy(uint8_t addr, uint8_t reg) -{ - ETH->MACMDIOAR &= (0xF << 8); - ETH->MACMDIOAR |= ((uint32_t)addr << 21) | ((uint32_t)reg << 16) | 3 << 2; - ETH->MACMDIOAR |= BIT(0); - while (ETH->MACMDIOAR & BIT(0)) - (void)0; - return ETH->MACMDIODR; -} - -static void eth_write_phy(uint8_t addr, uint8_t reg, uint32_t val) -{ - ETH->MACMDIODR = val; - ETH->MACMDIOAR &= (0xF << 8); - ETH->MACMDIOAR |= ((uint32_t)addr << 21) | ((uint32_t)reg << 16) | 1 << 2; - ETH->MACMDIOAR |= BIT(0); - while (ETH->MACMDIOAR & BIT(0)) - (void)0; -} - -static uint32_t get_hclk(void) -{ - struct rcc { - volatile uint32_t CR, HSICFGR, CRRCR, CSICFGR, CFGR, RESERVED1, D1CFGR, - D2CFGR, D3CFGR, RESERVED2, PLLCKSELR, PLLCFGR, PLL1DIVR, PLL1FRACR, - PLL2DIVR, PLL2FRACR, PLL3DIVR, PLL3FRACR, RESERVED3, D1CCIPR, D2CCIP1R, - D2CCIP2R, D3CCIPR, RESERVED4, CIER, CIFR, CICR, RESERVED5, BDCR, CSR, - RESERVED6, AHB3RSTR, AHB1RSTR, AHB2RSTR, AHB4RSTR, APB3RSTR, APB1LRSTR, - APB1HRSTR, APB2RSTR, APB4RSTR, GCR, RESERVED8, D3AMR, RESERVED11[9], - RSR, AHB3ENR, AHB1ENR, AHB2ENR, AHB4ENR, APB3ENR, APB1LENR, APB1HENR, - APB2ENR, APB4ENR, RESERVED12, AHB3LPENR, AHB1LPENR, AHB2LPENR, - AHB4LPENR, APB3LPENR, APB1LLPENR, APB1HLPENR, APB2LPENR, APB4LPENR, - RESERVED13[4]; - }* rcc = ((struct rcc*)(0x40000000 + 0x18020000 + 0x4400)); - uint32_t clk = 0, hsi = 64000000 /* 64 MHz */, hse = 8000000 /* 8MHz */, - csi = 4000000 /* 4MHz */; - unsigned int sel = (rcc->CFGR & (7 << 3)) >> 3; - - if (sel == 1) { - clk = csi; - } else if (sel == 2) { - clk = hse; - } else if (sel == 3) { - uint32_t vco, m, n, p; - unsigned int src = (rcc->PLLCKSELR & (3 << 0)) >> 0; - m = ((rcc->PLLCKSELR & (0x3F << 4)) >> 4); - n = ((rcc->PLL1DIVR & (0x1FF << 0)) >> 0) + 1 + ((rcc->PLLCFGR & BIT(0)) ? 1 : 0); // round-up in fractional mode - p = ((rcc->PLL1DIVR & (0x7F << 9)) >> 9) + 1; - if (src == 1) { - clk = csi; - } else if (src == 2) { - clk = hse; - } else { - clk = hsi; - clk >>= ((rcc->CR & 3) >> 3); - } - vco = (uint32_t)((uint64_t)clk * n / m); - clk = vco / p; - } else { - clk = hsi; - clk >>= ((rcc->CR & 3) >> 3); - } - const uint8_t cptab[12] = { 1, 2, 3, 4, 6, 7, 8, 9 }; // log2(div) - uint32_t d1cpre = (rcc->D1CFGR & (0x0F << 8)) >> 8; - if (d1cpre >= 8) - clk >>= cptab[d1cpre - 8]; - MG_DEBUG(("D1 CLK: %u", clk)); - uint32_t hpre = (rcc->D1CFGR & (0x0F << 0)) >> 0; - if (hpre < 8) - return clk; - return ((uint32_t)clk) >> cptab[hpre - 8]; -} - -// Guess CR from AHB1 clock. MDC clock is generated from the ETH peripheral -// clock (AHB1); as per 802.3, it must not exceed 2. As the AHB clock can -// be derived from HSI or CSI (internal RC) clocks, and those can go above -// specs, the datasheets specify a range of frequencies and activate one of a -// series of dividers to keep the MDC clock safely below 2.5MHz. We guess a -// divider setting based on HCLK with some drift. If the user uses a different -// clock from our defaults, needs to set the macros on top. Valid for -// STM32H74xxx/75xxx (58.11.4)(4.5% worst case drift)(CSI clock has a 7.5 % -// worst case drift @ max temp) -static int guess_mdc_cr(void) -{ - const uint8_t crs[] = { 2, 3, 0, 1, 4, 5 }; // ETH->MACMDIOAR::CR values - const uint8_t div[] = { 16, 26, 42, 62, 102, 124 }; // Respective HCLK dividers - uint32_t hclk = get_hclk(); // Guess system HCLK - int result = -1; // Invalid CR value - for (int i = 0; i < 6; i++) { - if (hclk / div[i] <= 2375000UL /* 2.5MHz - 5% */) { - result = crs[i]; - break; - } - } - if (result < 0) - MG_ERROR(("HCLK too high")); - MG_DEBUG(("HCLK: %u, CR: %d", hclk, result)); - return result; -} - -static bool mg_tcpip_driver_stm32h_init(struct mg_tcpip_if* ifp) -{ - struct mg_tcpip_driver_stm32h_data* d = (struct mg_tcpip_driver_stm32h_data*)ifp->driver_data; - s_ifp = ifp; - - // Init RX descriptors - for (int i = 0; i < ETH_DESC_CNT; i++) { - s_rxdesc[i][0] = (uint32_t)(uintptr_t)s_rxbuf[i]; // Point to data buffer - s_rxdesc[i][3] = BIT(31) | BIT(30) | BIT(24); // OWN, IOC, BUF1V - } - - // Init TX descriptors - for (int i = 0; i < ETH_DESC_CNT; i++) { - s_txdesc[i][0] = (uint32_t)(uintptr_t)s_txbuf[i]; // Buf pointer - } - - ETH->DMAMR |= BIT(0); // Software reset - while ((ETH->DMAMR & BIT(0)) != 0) - (void)0; // Wait until done - - // Set MDC clock divider. If user told us the value, use it. Otherwise, guess - int cr = (d == NULL || d->mdc_cr < 0) ? guess_mdc_cr() : d->mdc_cr; - ETH->MACMDIOAR = ((uint32_t)cr & 0xF) << 8; - - // NOTE(scaprile): We do not use timing facilities so the DMA engine does not - // re-write buffer address - ETH->DMAMR = 0 << 16; // use interrupt mode 0 (58.8.1) (reset value) - ETH->DMASBMR |= BIT(12); // AAL NOTE(scaprile): is this actually needed - ETH->MACIER = 0; // Do not enable additional irq sources (reset value) - ETH->MACTFCR = BIT(7); // Disable zero-quanta pause - // ETH->MACPFR = BIT(31); // Receive all - eth_write_phy(PHY_ADDR, PHY_BCR, BIT(15)); // Reset PHY - eth_write_phy(PHY_ADDR, PHY_BCR, BIT(12)); // Set autonegotiation - ETH->DMACRDLAR = (uint32_t)(uintptr_t)s_rxdesc; // RX descriptors start address - ETH->DMACRDRLR = ETH_DESC_CNT - 1; // ring length - ETH->DMACRDTPR = (uint32_t)(uintptr_t)&s_rxdesc[ETH_DESC_CNT - 1]; // last valid descriptor address - ETH->DMACTDLAR = (uint32_t)(uintptr_t)s_txdesc; // TX descriptors start address - ETH->DMACTDRLR = ETH_DESC_CNT - 1; // ring length - ETH->DMACTDTPR = (uint32_t)(uintptr_t)s_txdesc; // first available descriptor address - ETH->DMACCR = 0; // DSL = 0 (contiguous descriptor table) (reset value) - ETH->DMACIER = BIT(6) | BIT(15); // RIE, NIE - ETH->MACCR = BIT(0) | BIT(1) | BIT(13) | BIT(14) | BIT(15); // RE, TE, Duplex, Fast, Reserved - ETH->MTLTQOMR |= BIT(1); // TSF - ETH->MTLRQOMR |= BIT(5); // RSF - ETH->DMACTCR |= BIT(0); // ST - ETH->DMACRCR |= BIT(0); // SR - - // MAC address filtering - ETH->MACA0HR = ((uint32_t)ifp->mac[5] << 8U) | ifp->mac[4]; - ETH->MACA0LR = (uint32_t)(ifp->mac[3] << 24) | ((uint32_t)ifp->mac[2] << 16) | ((uint32_t)ifp->mac[1] << 8) | ifp->mac[0]; - return true; -} - -static uint32_t s_txno; -static size_t mg_tcpip_driver_stm32h_tx(const void* buf, size_t len, - struct mg_tcpip_if* ifp) -{ - if (len > sizeof(s_txbuf[s_txno])) { - MG_ERROR(("Frame too big, %ld", (long)len)); - len = 0; // Frame is too big - } else if ((s_txdesc[s_txno][3] & BIT(31))) { - MG_ERROR(("No free descriptors: %u %08X %08X %08X", s_txno, - s_txdesc[s_txno][3], ETH->DMACSR, ETH->DMACTCR)); - for (int i = 0; i < ETH_DESC_CNT; i++) - MG_ERROR(("%08X", s_txdesc[i][3])); - len = 0; // All descriptors are busy, fail - } else { - memcpy(s_txbuf[s_txno], buf, len); // Copy data - s_txdesc[s_txno][2] = (uint32_t)len; // Set data len - s_txdesc[s_txno][3] = BIT(28) | BIT(29); // FD, LD - s_txdesc[s_txno][3] |= BIT(31); // Set OWN bit - let DMA take over - if (++s_txno >= ETH_DESC_CNT) - s_txno = 0; - } - ETH->DMACSR |= BIT(2) | BIT(1); // Clear any prior TBU, TPS - ETH->DMACTDTPR = (uint32_t)(uintptr_t)&s_txdesc[s_txno]; // and resume - return len; - (void)ifp; -} - -static bool mg_tcpip_driver_stm32h_up(struct mg_tcpip_if* ifp) -{ - uint32_t bsr = eth_read_phy(PHY_ADDR, PHY_BSR); - bool up = bsr & BIT(2) ? 1 : 0; - if ((ifp->state == MG_TCPIP_STATE_DOWN) && up) { // link state just went up - uint32_t scsr = eth_read_phy(PHY_ADDR, PHY_CSCR); - uint32_t maccr = ETH->MACCR | BIT(14) | BIT(13); // 100M, Full-duplex - if ((scsr & BIT(3)) == 0) - maccr &= ~BIT(14); // 10M - if ((scsr & BIT(4)) == 0) - maccr &= ~BIT(13); // Half-duplex - ETH->MACCR = maccr; // IRQ handler does not fiddle with this register - MG_DEBUG(("Link is %uM %s-duplex", maccr & BIT(14) ? 100 : 10, - maccr & BIT(13) ? "full" : "half")); - } - return up; -} - -void ETH_IRQHandler(void); -static uint32_t s_rxno; -void ETH_IRQHandler(void) -{ - if (ETH->DMACSR & BIT(6)) { // Frame received, loop - ETH->DMACSR = BIT(15) | BIT(6); // Clear flag - for (uint32_t i = 0; i < 10; i++) { // read as they arrive but not forever - if (s_rxdesc[s_rxno][3] & BIT(31)) - break; // exit when done - if (((s_rxdesc[s_rxno][3] & (BIT(28) | BIT(29))) == (BIT(28) | BIT(29))) && !(s_rxdesc[s_rxno][3] & BIT(15))) { // skip partial/errored frames - uint32_t len = s_rxdesc[s_rxno][3] & (BIT(15) - 1); - // MG_DEBUG(("%lx %lu %lx %08lx", s_rxno, len, s_rxdesc[s_rxno][3], - // ETH->DMACSR)); - mg_tcpip_qwrite(s_rxbuf[s_rxno], len > 4 ? len - 4 : len, s_ifp); - } - s_rxdesc[s_rxno][3] = BIT(31) | BIT(30) | BIT(24); // OWN, IOC, BUF1V - if (++s_rxno >= ETH_DESC_CNT) - s_rxno = 0; - } - } - ETH->DMACSR = BIT(7) | BIT(8); // Clear possible RBU RPS while processing - ETH->DMACRDTPR = (uint32_t)(uintptr_t)&s_rxdesc[ETH_DESC_CNT - 1]; // and resume RX -} - -struct mg_tcpip_driver mg_tcpip_driver_stm32h = { - mg_tcpip_driver_stm32h_init, mg_tcpip_driver_stm32h_tx, NULL, - mg_tcpip_driver_stm32h_up -}; -#endif - -#ifdef MG_ENABLE_LINES -#line 1 "src/drivers/tm4c.c" -#endif - -#if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_TM4C) && MG_ENABLE_DRIVER_TM4C -struct tm4c_emac { - volatile uint32_t EMACCFG, EMACFRAMEFLTR, EMACHASHTBLH, EMACHASHTBLL, - EMACMIIADDR, EMACMIIDATA, EMACFLOWCTL, EMACVLANTG, RESERVED0, EMACSTATUS, - EMACRWUFF, EMACPMTCTLSTAT, RESERVED1[2], EMACRIS, EMACIM, EMACADDR0H, - EMACADDR0L, EMACADDR1H, EMACADDR1L, EMACADDR2H, EMACADDR2L, EMACADDR3H, - EMACADDR3L, RESERVED2[31], EMACWDOGTO, RESERVED3[8], EMACMMCCTRL, - EMACMMCRXRIS, EMACMMCTXRIS, EMACMMCRXIM, EMACMMCTXIM, RESERVED4, - EMACTXCNTGB, RESERVED5[12], EMACTXCNTSCOL, EMACTXCNTMCOL, RESERVED6[4], - EMACTXOCTCNTG, RESERVED7[6], EMACRXCNTGB, RESERVED8[4], EMACRXCNTCRCERR, - EMACRXCNTALGNERR, RESERVED9[10], EMACRXCNTGUNI, RESERVED10[239], - EMACVLNINCREP, EMACVLANHASH, RESERVED11[93], EMACTIMSTCTRL, EMACSUBSECINC, - EMACTIMSEC, EMACTIMNANO, EMACTIMSECU, EMACTIMNANOU, EMACTIMADD, - EMACTARGSEC, EMACTARGNANO, EMACHWORDSEC, EMACTIMSTAT, EMACPPSCTRL, - RESERVED12[12], EMACPPS0INTVL, EMACPPS0WIDTH, RESERVED13[294], - EMACDMABUSMOD, EMACTXPOLLD, EMACRXPOLLD, EMACRXDLADDR, EMACTXDLADDR, - EMACDMARIS, EMACDMAOPMODE, EMACDMAIM, EMACMFBOC, EMACRXINTWDT, - RESERVED14[8], EMACHOSTXDESC, EMACHOSRXDESC, EMACHOSTXBA, EMACHOSRXBA, - RESERVED15[218], EMACPP, EMACPC, EMACCC, RESERVED16, EMACEPHYRIS, - EMACEPHYIM, EMACEPHYIMSC; -}; -#undef EMAC -#define EMAC ((struct tm4c_emac*)(uintptr_t)0x400EC000) - -#undef BIT -#define BIT(x) ((uint32_t)1 << (x)) -#define ETH_PKT_SIZE 1540 // Max frame size -#define ETH_DESC_CNT 4 // Descriptors count -#define ETH_DS 4 // Descriptor size (words) - -static uint32_t s_rxdesc[ETH_DESC_CNT][ETH_DS]; // RX descriptors -static uint32_t s_txdesc[ETH_DESC_CNT][ETH_DS]; // TX descriptors -static uint8_t s_rxbuf[ETH_DESC_CNT][ETH_PKT_SIZE]; // RX ethernet buffers -static uint8_t s_txbuf[ETH_DESC_CNT][ETH_PKT_SIZE]; // TX ethernet buffers -static struct mg_tcpip_if* s_ifp; // MIP interface -enum { - EPHY_ADDR = 0, - EPHYBMCR = 0, - EPHYBMSR = 1, - EPHYSTS = 16 -}; // PHY constants - -static inline void tm4cspin(volatile uint32_t count) -{ - while (count--) - (void)0; -} - -static uint32_t emac_read_phy(uint8_t addr, uint8_t reg) -{ - EMAC->EMACMIIADDR &= (0xf << 2); - EMAC->EMACMIIADDR |= ((uint32_t)addr << 11) | ((uint32_t)reg << 6); - EMAC->EMACMIIADDR |= BIT(0); - while (EMAC->EMACMIIADDR & BIT(0)) - tm4cspin(1); - return EMAC->EMACMIIDATA; -} - -static void emac_write_phy(uint8_t addr, uint8_t reg, uint32_t val) -{ - EMAC->EMACMIIDATA = val; - EMAC->EMACMIIADDR &= (0xf << 2); - EMAC->EMACMIIADDR |= ((uint32_t)addr << 11) | ((uint32_t)reg << 6) | BIT(1); - EMAC->EMACMIIADDR |= BIT(0); - while (EMAC->EMACMIIADDR & BIT(0)) - tm4cspin(1); -} - -static uint32_t get_sysclk(void) -{ - struct sysctl { - volatile uint32_t DONTCARE0[44], RSCLKCFG, DONTCARE1[43], PLLFREQ0, - PLLFREQ1; - }* sysctl = (struct sysctl*)0x400FE000; - uint32_t clk = 0, piosc = 16000000 /* 16 MHz */, mosc = 25000000 /* 25MHz */; - if (sysctl->RSCLKCFG & (1 << 28)) { // USEPLL - uint32_t fin, vco, mdiv, n, q, psysdiv; - uint32_t pllsrc = (sysctl->RSCLKCFG & (0xf << 24)) >> 24; - if (pllsrc == 0) { - clk = piosc; - } else if (pllsrc == 3) { - clk = mosc; - } else { - MG_ERROR(("Unsupported clock source")); - } - q = (sysctl->PLLFREQ1 & (0x1f << 8)) >> 8; - n = (sysctl->PLLFREQ1 & (0x1f << 0)) >> 0; - fin = clk / ((q + 1) * (n + 1)); - mdiv = (sysctl->PLLFREQ0 & (0x3ff << 0)) >> 0; // mint + (mfrac / 1024); MFRAC not supported - psysdiv = (sysctl->RSCLKCFG & (0x3f << 0)) >> 0; - vco = (uint32_t)((uint64_t)fin * mdiv); - return vco / (psysdiv + 1); - } - uint32_t oscsrc = (sysctl->RSCLKCFG & (0xf << 20)) >> 20; - if (oscsrc == 0) { - clk = piosc; - } else if (oscsrc == 3) { - clk = mosc; - } else { - MG_ERROR(("Unsupported clock source")); - } - uint32_t osysdiv = (sysctl->RSCLKCFG & (0xf << 16)) >> 16; - return clk / (osysdiv + 1); -} - -// Guess CR from SYSCLK. MDC clock is generated from SYSCLK (AHB); as per -// 802.3, it must not exceed 2.5MHz (also 20.4.2.6) As the AHB clock can be -// derived from the PIOSC (internal RC), and it can go above specs, the -// datasheets specify a range of frequencies and activate one of a series of -// dividers to keep the MDC clock safely below 2.5MHz. We guess a divider -// setting based on SYSCLK with a +5% drift. If the user uses a different clock -// from our defaults, needs to set the macros on top Valid for TM4C129x (20.7) -// (4.5% worst case drift) -// The PHY receives the main oscillator (MOSC) (20.3.1) -static int guess_mdc_cr(void) -{ - uint8_t crs[] = { 2, 3, 0, 1 }; // EMAC->MACMIIAR::CR values - uint8_t div[] = { 16, 26, 42, 62 }; // Respective HCLK dividers - uint32_t sysclk = get_sysclk(); // Guess system SYSCLK - int result = -1; // Invalid CR value - if (sysclk < 25000000) { - MG_ERROR(("SYSCLK too low")); - } else { - for (int i = 0; i < 4; i++) { - if (sysclk / div[i] <= 2375000UL /* 2.5MHz - 5% */) { - result = crs[i]; - break; - } - } - if (result < 0) - MG_ERROR(("SYSCLK too high")); - } - MG_DEBUG(("SYSCLK: %u, CR: %d", sysclk, result)); - return result; -} - -static bool mg_tcpip_driver_tm4c_init(struct mg_tcpip_if* ifp) -{ - struct mg_tcpip_driver_tm4c_data* d = (struct mg_tcpip_driver_tm4c_data*)ifp->driver_data; - s_ifp = ifp; - - // Init RX descriptors - for (int i = 0; i < ETH_DESC_CNT; i++) { - s_rxdesc[i][0] = BIT(31); // Own - s_rxdesc[i][1] = sizeof(s_rxbuf[i]) | BIT(14); // 2nd address chained - s_rxdesc[i][2] = (uint32_t)(uintptr_t)s_rxbuf[i]; // Point to data buffer - s_rxdesc[i][3] = (uint32_t)(uintptr_t)s_rxdesc[(i + 1) % ETH_DESC_CNT]; // Chain - // MG_DEBUG(("%d %p", i, s_rxdesc[i])); - } - - // Init TX descriptors - for (int i = 0; i < ETH_DESC_CNT; i++) { - s_txdesc[i][2] = (uint32_t)(uintptr_t)s_txbuf[i]; // Buf pointer - s_txdesc[i][3] = (uint32_t)(uintptr_t)s_txdesc[(i + 1) % ETH_DESC_CNT]; // Chain - } - - EMAC->EMACDMABUSMOD |= BIT(0); // Software reset - while ((EMAC->EMACDMABUSMOD & BIT(0)) != 0) - tm4cspin(1); // Wait until done - - // Set MDC clock divider. If user told us the value, use it. Otherwise, guess - int cr = (d == NULL || d->mdc_cr < 0) ? guess_mdc_cr() : d->mdc_cr; - EMAC->EMACMIIADDR = ((uint32_t)cr & 0xf) << 2; - - // NOTE(cpq): we do not use extended descriptor bit 7, and do not use - // hardware checksum. Therefore, descriptor size is 4, not 8 - // EMAC->EMACDMABUSMOD = BIT(13) | BIT(16) | BIT(22) | BIT(23) | BIT(25); - EMAC->EMACIM = BIT(3) | BIT(9); // Mask timestamp & PMT IT - EMAC->EMACFLOWCTL = BIT(7); // Disable zero-quanta pause - // EMAC->EMACFRAMEFLTR = BIT(31); // Receive all - // EMAC->EMACPC defaults to internal PHY (EPHY) in MMI mode - emac_write_phy(EPHY_ADDR, EPHYBMCR, BIT(15)); // Reset internal PHY (EPHY) - emac_write_phy(EPHY_ADDR, EPHYBMCR, BIT(12)); // Set autonegotiation - EMAC->EMACRXDLADDR = (uint32_t)(uintptr_t)s_rxdesc; // RX descriptors - EMAC->EMACTXDLADDR = (uint32_t)(uintptr_t)s_txdesc; // TX descriptors - EMAC->EMACDMAIM = BIT(6) | BIT(16); // RIE, NIE - EMAC->EMACCFG = BIT(2) | BIT(3) | BIT(11) | BIT(14); // RE, TE, Duplex, Fast - EMAC->EMACDMAOPMODE = BIT(1) | BIT(13) | BIT(21) | BIT(25); // SR, ST, TSF, RSF - EMAC->EMACADDR0H = ((uint32_t)ifp->mac[5] << 8U) | ifp->mac[4]; - EMAC->EMACADDR0L = (uint32_t)(ifp->mac[3] << 24) | ((uint32_t)ifp->mac[2] << 16) | ((uint32_t)ifp->mac[1] << 8) | ifp->mac[0]; - // NOTE(scaprile) There are 3 additional slots for filtering, disabled by - // default. This also applies to the STM32 driver (at least for F7) - return true; -} - -static uint32_t s_txno; -static size_t mg_tcpip_driver_tm4c_tx(const void* buf, size_t len, - struct mg_tcpip_if* ifp) -{ - if (len > sizeof(s_txbuf[s_txno])) { - MG_ERROR(("Frame too big, %ld", (long)len)); - len = 0; // fail - } else if ((s_txdesc[s_txno][0] & BIT(31))) { - MG_ERROR(("No descriptors available")); - // printf("D0 %lx SR %lx\n", (long) s_txdesc[0][0], (long) - // EMAC->EMACDMARIS); - len = 0; // fail - } else { - memcpy(s_txbuf[s_txno], buf, len); // Copy data - s_txdesc[s_txno][1] = (uint32_t)len; // Set data len - s_txdesc[s_txno][0] = BIT(20) | BIT(28) | BIT(29) | BIT(30); // Chain,FS,LS,IC - s_txdesc[s_txno][0] |= BIT(31); // Set OWN bit - let DMA take over - if (++s_txno >= ETH_DESC_CNT) - s_txno = 0; - } - EMAC->EMACDMARIS = BIT(2) | BIT(5); // Clear any prior TU/UNF - EMAC->EMACTXPOLLD = 0; // and resume - return len; - (void)ifp; -} - -static bool mg_tcpip_driver_tm4c_up(struct mg_tcpip_if* ifp) -{ - uint32_t bmsr = emac_read_phy(EPHY_ADDR, EPHYBMSR); - bool up = (bmsr & BIT(2)) ? 1 : 0; - if ((ifp->state == MG_TCPIP_STATE_DOWN) && up) { // link state just went up - uint32_t sts = emac_read_phy(EPHY_ADDR, EPHYSTS); - uint32_t emaccfg = EMAC->EMACCFG | BIT(14) | BIT(11); // 100M, Full-duplex - if (sts & BIT(1)) - emaccfg &= ~BIT(14); // 10M - if ((sts & BIT(2)) == 0) - emaccfg &= ~BIT(11); // Half-duplex - EMAC->EMACCFG = emaccfg; // IRQ handler does not fiddle with this register - MG_DEBUG(("Link is %uM %s-duplex", emaccfg & BIT(14) ? 100 : 10, - emaccfg & BIT(11) ? "full" : "half")); - } - return up; -} - -void EMAC0_IRQHandler(void); -static uint32_t s_rxno; -void EMAC0_IRQHandler(void) -{ - if (EMAC->EMACDMARIS & BIT(6)) { // Frame received, loop - EMAC->EMACDMARIS = BIT(16) | BIT(6); // Clear flag - for (uint32_t i = 0; i < 10; i++) { // read as they arrive but not forever - if (s_rxdesc[s_rxno][0] & BIT(31)) - break; // exit when done - if (((s_rxdesc[s_rxno][0] & (BIT(8) | BIT(9))) == (BIT(8) | BIT(9))) && !(s_rxdesc[s_rxno][0] & BIT(15))) { // skip partial/errored frames - uint32_t len = ((s_rxdesc[s_rxno][0] >> 16) & (BIT(14) - 1)); - // printf("%lx %lu %lx %.8lx\n", s_rxno, len, s_rxdesc[s_rxno][0], - // EMAC->EMACDMARIS); - mg_tcpip_qwrite(s_rxbuf[s_rxno], len > 4 ? len - 4 : len, s_ifp); - } - s_rxdesc[s_rxno][0] = BIT(31); - if (++s_rxno >= ETH_DESC_CNT) - s_rxno = 0; - } - } - EMAC->EMACDMARIS = BIT(7); // Clear possible RU while processing - EMAC->EMACRXPOLLD = 0; // and resume RX -} - -struct mg_tcpip_driver mg_tcpip_driver_tm4c = { mg_tcpip_driver_tm4c_init, - mg_tcpip_driver_tm4c_tx, NULL, - mg_tcpip_driver_tm4c_up }; -#endif - -#ifdef MG_ENABLE_LINES -#line 1 "src/drivers/w5500.c" -#endif - -#if MG_ENABLE_TCPIP - -enum { W5500_CR = 0, - W5500_S0 = 1, - W5500_TX0 = 2, - W5500_RX0 = 3 }; - -static void w5500_txn(struct mg_tcpip_spi* s, uint8_t block, uint16_t addr, bool wr, - void* buf, size_t len) -{ - uint8_t* p = (uint8_t*)buf; - uint8_t cmd[] = { (uint8_t)(addr >> 8), (uint8_t)(addr & 255), - (uint8_t)((block << 3) | (wr ? 4 : 0)) }; - s->begin(s->spi); - for (size_t i = 0; i < sizeof(cmd); i++) - s->txn(s->spi, cmd[i]); - for (size_t i = 0; i < len; i++) { - uint8_t r = s->txn(s->spi, p[i]); - if (!wr) - p[i] = r; - } - s->end(s->spi); -} - -// clang-format off -static void w5500_wn(struct mg_tcpip_spi *s, uint8_t block, uint16_t addr, void *buf, size_t len) { w5500_txn(s, block, addr, true, buf, len); } -static void w5500_w1(struct mg_tcpip_spi *s, uint8_t block, uint16_t addr, uint8_t val) { w5500_wn(s, block, addr, &val, 1); } -static void w5500_w2(struct mg_tcpip_spi *s, uint8_t block, uint16_t addr, uint16_t val) { uint8_t buf[2] = {(uint8_t) (val >> 8), (uint8_t) (val & 255)}; w5500_wn(s, block, addr, buf, sizeof(buf)); } -static void w5500_rn(struct mg_tcpip_spi *s, uint8_t block, uint16_t addr, void *buf, size_t len) { w5500_txn(s, block, addr, false, buf, len); } -static uint8_t w5500_r1(struct mg_tcpip_spi *s, uint8_t block, uint16_t addr) { uint8_t r = 0; w5500_rn(s, block, addr, &r, 1); return r; } -static uint16_t w5500_r2(struct mg_tcpip_spi *s, uint8_t block, uint16_t addr) { uint8_t buf[2] = {0, 0}; w5500_rn(s, block, addr, buf, sizeof(buf)); return (uint16_t) ((buf[0] << 8) | buf[1]); } -// clang-format on - -static size_t w5500_rx(void* buf, size_t buflen, struct mg_tcpip_if* ifp) -{ - struct mg_tcpip_spi* s = (struct mg_tcpip_spi*)ifp->driver_data; - uint16_t r = 0, n = 0, len = (uint16_t)buflen, n2; // Read recv len - while ((n2 = w5500_r2(s, W5500_S0, 0x26)) > n) - n = n2; // Until it is stable - // printf("RSR: %d\n", (int) n); - if (n > 0) { - uint16_t ptr = w5500_r2(s, W5500_S0, 0x28); // Get read pointer - n = w5500_r2(s, W5500_RX0, ptr); // Read frame length - if (n <= len + 2 && n > 1) { - r = (uint16_t)(n - 2); - w5500_rn(s, W5500_RX0, (uint16_t)(ptr + 2), buf, r); - } - w5500_w2(s, W5500_S0, 0x28, (uint16_t)(ptr + n)); // Advance read pointer - w5500_w1(s, W5500_S0, 1, 0x40); // Sock0 CR -> RECV - // printf(" RX_RD: tot=%u n=%u r=%u\n", n2, n, r); - } - return r; -} - -static size_t w5500_tx(const void* buf, size_t buflen, struct mg_tcpip_if* ifp) -{ - struct mg_tcpip_spi* s = (struct mg_tcpip_spi*)ifp->driver_data; - uint16_t n = 0, len = (uint16_t)buflen; - while (n < len) - n = w5500_r2(s, W5500_S0, 0x20); // Wait for space - uint16_t ptr = w5500_r2(s, W5500_S0, 0x24); // Get write pointer - w5500_wn(s, W5500_TX0, ptr, (void*)buf, len); // Write data - w5500_w2(s, W5500_S0, 0x24, (uint16_t)(ptr + len)); // Advance write pointer - w5500_w1(s, W5500_S0, 1, 0x20); // Sock0 CR -> SEND - for (int i = 0; i < 40; i++) { - uint8_t ir = w5500_r1(s, W5500_S0, 2); // Read S0 IR - if (ir == 0) - continue; - // printf("IR %d, len=%d, free=%d, ptr %d\n", ir, (int) len, (int) n, ptr); - w5500_w1(s, W5500_S0, 2, ir); // Write S0 IR: clear it! - if (ir & 8) - len = 0; // Timeout. Report error - if (ir & (16 | 8)) - break; // Stop on SEND_OK or timeout - } - return len; -} - -static bool w5500_init(struct mg_tcpip_if* ifp) -{ - struct mg_tcpip_spi* s = (struct mg_tcpip_spi*)ifp->driver_data; - s->end(s->spi); - w5500_w1(s, W5500_CR, 0, 0x80); // Reset chip: CR -> 0x80 - w5500_w1(s, W5500_CR, 0x2e, 0); // CR PHYCFGR -> reset - w5500_w1(s, W5500_CR, 0x2e, 0xf8); // CR PHYCFGR -> set - // w5500_wn(s, W5500_CR, 9, s->mac, 6); // Set source MAC - w5500_w1(s, W5500_S0, 0x1e, 16); // Sock0 RX buf size - w5500_w1(s, W5500_S0, 0x1f, 16); // Sock0 TX buf size - w5500_w1(s, W5500_S0, 0, 4); // Sock0 MR -> MACRAW - w5500_w1(s, W5500_S0, 1, 1); // Sock0 CR -> OPEN - return w5500_r1(s, W5500_S0, 3) == 0x42; // Sock0 SR == MACRAW -} - -static bool w5500_up(struct mg_tcpip_if* ifp) -{ - struct mg_tcpip_spi* spi = (struct mg_tcpip_spi*)ifp->driver_data; - uint8_t phycfgr = w5500_r1(spi, W5500_CR, 0x2e); - return phycfgr & 1; // Bit 0 of PHYCFGR is LNK (0 - down, 1 - up) -} - -struct mg_tcpip_driver mg_tcpip_driver_w5500 = { w5500_init, w5500_tx, w5500_rx, w5500_up }; -#endif \ No newline at end of file diff --git a/APP_Framework/Applications/mongoose/netsetting.c b/APP_Framework/Applications/mongoose/netsetting.c deleted file mode 100644 index 5e16fe9e4..000000000 --- a/APP_Framework/Applications/mongoose/netsetting.c +++ /dev/null @@ -1,102 +0,0 @@ -// Copyright (c) 2022 Cesanta Software Limited -// All rights reserved -// -// UI example -// It implements the following endpoints: -// /api/config/get - respond with current config -// /api/config/set - POST a config change -// any other URI serves static files from s_root_dir -// Data and results are JSON strings - -#include "ip_addr.h" -#include "mongoose.h" -#include "netdev.h" - -static const char* s_http_addr = "http://0.0.0.0:8000"; // HTTP port -static const char* s_root_dir = "netsetting"; - -static struct netdev* p_netdev; - -static struct config { - char *ip, *mask, *gw, *dns; -} s_config; - -// Try to update a single configuration value -static void update_config(struct mg_str json, const char* path, char** value) -{ - char* jval; - if ((jval = mg_json_get_str(json, path)) != NULL) { - free(*value); - *value = strdup(jval); - } -} - -static void fn(struct mg_connection* c, int ev, void* ev_data, void* fn_data) -{ - if (ev == MG_EV_OPEN && c->is_listening) { - s_config.ip = strdup(inet_ntoa(p_netdev->ip_addr)); - s_config.mask = strdup(inet_ntoa(p_netdev->netmask)); - s_config.gw = strdup(inet_ntoa(p_netdev->gw)); - s_config.dns = strdup(inet_ntoa(p_netdev->dns_servers[0])); - } else if (ev == MG_EV_HTTP_MSG) { - struct mg_http_message* hm = (struct mg_http_message*)ev_data; - if (mg_http_match_uri(hm, "/api/config/get")) { - mg_http_reply(c, 200, "Content-Type: application/json\r\n", - "{%m:%m,%m:%m,%m:%m,%m:%m}\n", - MG_ESC("ip"), MG_ESC(s_config.ip), - MG_ESC("mask"), MG_ESC(s_config.mask), - MG_ESC("gw"), MG_ESC(s_config.gw), - MG_ESC("dns"), MG_ESC(s_config.dns)); - } else if (mg_http_match_uri(hm, "/api/config/set")) { - struct mg_str json = hm->body; - printf("json: %s\n", json.ptr); - update_config(json, "$.ip", &s_config.ip); - update_config(json, "$.mask", &s_config.mask); - update_config(json, "$.gw", &s_config.gw); - update_config(json, "$.dns", &s_config.dns); - mg_http_reply(c, 200, "", "ok\n"); - - ip_addr_t ipaddr, maskaddr, gwaddr; - inet_aton(s_config.ip, &ipaddr); - inet_aton(s_config.mask, &maskaddr); - inet_aton(s_config.gw, &gwaddr); - p_netdev->ops->set_addr_info(p_netdev, &ipaddr, &maskaddr, &gwaddr); - - printf("Board Net Configuration changed to [IP: %s, Mask: %s, GW: %s]\n", - s_config.ip, - s_config.mask, - s_config.gw); - } else { - struct mg_http_serve_opts opts = { .root_dir = s_root_dir }; - mg_http_serve_dir(c, ev_data, &opts); - } - } - (void)fn_data; -} - -static void* do_net_setting_demo(void* none) -{ - p_netdev = NETDEV_DEFAULT; - - struct mg_mgr mgr; // Event manager - mg_log_set(MG_LL_DEBUG); // Set to 3 to enable debug - mg_mgr_init(&mgr); // Initialise event manager - mg_http_listen(&mgr, s_http_addr, fn, NULL); // Create HTTP listener - for (;;) - mg_mgr_poll(&mgr, 10); // Infinite event loop - mg_mgr_free(&mgr); - return NULL; -} - -int net_setting_demo(int argc, char* argv[]) -{ - pthread_t tid = -1; - pthread_attr_t attr; - attr.schedparam.sched_priority = 30; - attr.stacksize = 16384; - - PrivTaskCreate(&tid, &attr, do_net_setting_demo, NULL); - - return 0; -} -SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_PARAM_NUM(5), NetSettingDemo, net_setting_demo, webserver to set net configurations); \ No newline at end of file diff --git a/APP_Framework/Applications/mongoose/project.c b/APP_Framework/Applications/mongoose/project.c index ab3ba96db..cf05a4af9 100644 --- a/APP_Framework/Applications/mongoose/project.c +++ b/APP_Framework/Applications/mongoose/project.c @@ -14,7 +14,7 @@ char index_path[] = "login.html"; -static const char* s_http_addr = "http://0.0.0.0:8000"; // HTTP port +static const char* s_http_addr = "http://192.168.131.88:8000"; // HTTP port static const char* s_root_dir = "webserver"; static const char* s_enable_hexdump = "no"; static const char* s_ssi_pattern = "#.html"; @@ -104,18 +104,22 @@ static void fn(struct mg_connection* c, int ev, void* ev_data, void* fn_data) (void)fn_data; } -extern void LwipSetIPTest(int argc, char* argv[]); static void* do_webserver_demo(void* none) { - p_netdev = NETDEV_DEFAULT; - s_config.ip = strdup(inet_ntoa(p_netdev->ip_addr)); - s_config.mask = strdup(inet_ntoa(p_netdev->netmask)); - s_config.gw = strdup(inet_ntoa(p_netdev->gw)); + p_netdev = netdev_get_by_name("wz"); + if (p_netdev == NULL) { + MG_INFO(("Did nto find wz netdev, use default.\n")); + p_netdev = NETDEV_DEFAULT; + } + MG_INFO(("Use Netdev %s", p_netdev->name)); + s_config.ip = strdup(inet_ntoa(*p_netdev->ip_addr)); + s_config.mask = strdup(inet_ntoa(*p_netdev->netmask)); + s_config.gw = strdup(inet_ntoa(*p_netdev->gw)); s_config.dns = strdup(inet_ntoa(p_netdev->dns_servers[0])); struct mg_mgr mgr; // Event manager - mg_log_set(MG_LL_INFO); // Set to 3 to enable debug - // mg_log_set(MG_LL_DEBUG); // Set to 3 to enable debug + // mg_log_set(MG_LL_INFO); // Set to 3 to enable debug + mg_log_set(MG_LL_DEBUG); // Set to 3 to enable debug mg_mgr_init(&mgr); // Initialise event manager mg_http_listen(&mgr, s_http_addr, fn, NULL); // Create HTTP listener for (;;) @@ -126,12 +130,10 @@ static void* do_webserver_demo(void* none) int webserver_demo(int argc, char* argv[]) { - LwipSetIPTest(1, NULL); - pthread_t tid = -1; pthread_attr_t attr; attr.schedparam.sched_priority = 30; - attr.stacksize = 0x4000; + attr.stacksize = 0x2000; PrivTaskCreate(&tid, &attr, do_webserver_demo, NULL); diff --git a/Ubiquitous/XiZi_IIoT/Makefile b/Ubiquitous/XiZi_IIoT/Makefile index de3ea3e86..4ecef27a7 100755 --- a/Ubiquitous/XiZi_IIoT/Makefile +++ b/Ubiquitous/XiZi_IIoT/Makefile @@ -50,6 +50,7 @@ export SRC_DIR:= $(SRC_APP_DIR) $(SRC_KERNEL_DIR) export LIBCC export MUSL_DIR := $(KERNEL_ROOT)/lib/musllib export LWIP_DIR := $(KERNEL_ROOT)/resources/ethernet +export MONGOOSE_DIR := $(KERNEL_ROOT)/../../APP_Framework/Applications/mongoose/lib PART:= @@ -74,6 +75,10 @@ ifeq ($(CONFIG_RESOURCES_LWIP), y) PART += COMPILE_LWIP endif +ifeq ($(CONFIG_USE_MONGOOSE), y) +# PART += COMPILE_MONGOOSE +endif + ifeq ($(CONFIG_MCUBOOT_BOOTLOADER), y) PART += COMPILE_BOOTLOADER else ifeq ($(CONFIG_MCUBOOT_APPLICATION), y) @@ -130,6 +135,15 @@ COMPILE_LWIP: @cp build/liblwip.a $(KERNEL_ROOT)/resources/ethernet/LwIP/liblwip.a @rm build/Makefile build/make.obj +COMPILE_MONGOOSE: + @for dir in $(MONGOOSE_DIR);do \ + $(MAKE) -C $$dir COMPILE_TYPE=$@; \ + done + @cp link_mongoose.mk build/Makefile + @$(MAKE) -C build TARGET=mongoose.a LINK_FLAGS=LFLAGS + @cp build/mongoose.a $(KERNEL_ROOT)/../../APP_Framework/Applications/mongoose/mongoose.a + @rm build/Makefile build/make.obj + COMPILE_KERNEL: @for dir in $(SRC_KERNEL_DIR);do \ $(MAKE) -C $$dir; \ diff --git a/Ubiquitous/XiZi_IIoT/board/edu-arm32/third_party_driver/ethernet/eth_driver.c b/Ubiquitous/XiZi_IIoT/board/edu-arm32/third_party_driver/ethernet/eth_driver.c index 25d106209..9b07b399d 100644 --- a/Ubiquitous/XiZi_IIoT/board/edu-arm32/third_party_driver/ethernet/eth_driver.c +++ b/Ubiquitous/XiZi_IIoT/board/edu-arm32/third_party_driver/ethernet/eth_driver.c @@ -278,10 +278,7 @@ struct pbuf* low_level_input(struct netif* netif) return p; } -extern void LwipSetIPTest(int argc, char* argv[]); int HwEthInit(void) { - // lwip_config_tcp(0, lwip_ipaddr, lwip_netmask, lwip_gwaddr); - LwipSetIPTest(1, NULL); return EOK; } diff --git a/Ubiquitous/XiZi_IIoT/board/edu-arm32/third_party_driver/ethernet/eth_netdev.c b/Ubiquitous/XiZi_IIoT/board/edu-arm32/third_party_driver/ethernet/eth_netdev.c index 1c5c9d3c5..875a35db0 100644 --- a/Ubiquitous/XiZi_IIoT/board/edu-arm32/third_party_driver/ethernet/eth_netdev.c +++ b/Ubiquitous/XiZi_IIoT/board/edu-arm32/third_party_driver/ethernet/eth_netdev.c @@ -76,6 +76,7 @@ static int lwip_netdev_set_addr_info(struct netdev* netdev, ip_addr_t* ip_addr, netif_set_gw((struct netif*)netdev->user_data, ip_2_ip4(gw)); } } + return 0; } #ifdef LWIP_DNS @@ -92,7 +93,7 @@ static int lwip_netdev_set_dns_server(struct netdev* netdev, uint8_t dns_num, ip } #endif -#ifdef LWIP_DHCP +#if LWIP_DHCP static int lwip_netdev_set_dhcp(struct netdev* netdev, bool is_enabled) { netdev_low_level_set_dhcp_status(netdev, is_enabled); @@ -120,7 +121,7 @@ static const struct netdev_ops lwip_netdev_ops = { #ifdef LWIP_DNS .set_dns_server = lwip_netdev_set_dns_server, #endif -#ifdef LWIP_DHCP +#if LWIP_DHCP .set_dhcp = lwip_netdev_set_dhcp, #endif .set_default = lwip_netdev_set_default, @@ -179,9 +180,9 @@ int lwip_netdev_add(struct netif* lwip_netif) netdev->ops = &lwip_netdev_ops; netdev->hwaddr_len = lwip_netif->hwaddr_len; memcpy(netdev->hwaddr, lwip_netif->hwaddr, lwip_netif->hwaddr_len); - netdev->ip_addr = lwip_netif->ip_addr; - netdev->gw = lwip_netif->gw; - netdev->netmask = lwip_netif->netmask; + netdev->ip_addr = &lwip_netif->ip_addr; + netdev->gw = &lwip_netif->gw; + netdev->netmask = &lwip_netif->netmask; return result; } diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/Makefile b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/Makefile index e994ce1ad..a7dae3fce 100644 --- a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/Makefile +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/Makefile @@ -1,4 +1,4 @@ # SRC_FILES := socket.c connect_w5500.c w5500.c wizchip_conf.c spi_interface.c wiz_ping.c connect_w5500_test.c wiz_iperf.c -SRC_FILES := socket.c connect_w5500.c w5500.c wizchip_conf.c spi_interface.c wiz_ping.c connect_w5500_test.c w5x00_lwip.c wiz_iperf.c +SRC_FILES := socket.c connect_w5500.c w5500.c wizchip_conf.c spi_interface.c w5x00_lwip.c include $(KERNEL_ROOT)/compiler.mk \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/connect_w5500.c b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/connect_w5500.c index dc29ff22d..ee99dcb78 100644 --- a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/connect_w5500.c +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/connect_w5500.c @@ -328,8 +328,12 @@ int HwWiznetInit(void) setSHAR(wiz_mac); ctlwizchip(CW_RESET_PHY, 0); + network_init(); + wiz_interrupt_init(0, wiz_irq_handler); + network_init(); + setSn_RXBUF_SIZE(0, 16); setSn_TXBUF_SIZE(0, 16); #define SOCK_ANY_PORT_NUM 0xC000 @@ -349,7 +353,5 @@ int HwWiznetInit(void) } } - network_init(); - return EOK; } \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/connect_w5500_test.c b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/test/connect_w5500_test.c similarity index 100% rename from Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/connect_w5500_test.c rename to Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/test/connect_w5500_test.c diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/wiz_iperf.c b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/test/wiz_iperf.c similarity index 100% rename from Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/wiz_iperf.c rename to Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/test/wiz_iperf.c diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/wiz_ping.c b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/test/wiz_ping.c similarity index 100% rename from Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/wiz_ping.c rename to Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/test/wiz_ping.c diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/wiz_ping.h b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/test/wiz_ping.h similarity index 100% rename from Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/wiz_ping.h rename to Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/test/wiz_ping.h diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/spi/connect_spi.c b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/spi/connect_spi.c index 8811d2856..75e666a6b 100644 --- a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/spi/connect_spi.c +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/spi/connect_spi.c @@ -152,6 +152,9 @@ static uint32 SpiDrvConfigure(void *drv, struct BusConfigureInfo *configure_info static uint32 SpiWriteData(struct SpiHardwareDevice *spi_dev, struct SpiDataStandard *spi_datacfg) { +#define WRITE_BUF_SIZE 1600 + static uint32_t write_buf[4 * WRITE_BUF_SIZE] = { 0 }; + SpiDeviceParam *dev_param = (SpiDeviceParam *)(spi_dev->haldev.private_data); uint8 device_id = dev_param->spi_slave_param->spi_slave_id; @@ -184,10 +187,15 @@ static uint32 SpiWriteData(struct SpiHardwareDevice *spi_dev, struct SpiDataStan dmac_set_single_mode(dev_param->spi_dma_param->spi_dmac_txchannel, &dummy, (void *)(&spi_instance[device_master_id]->dr[0]), DMAC_ADDR_NOCHANGE, DMAC_ADDR_NOCHANGE, DMAC_MSIZE_4, DMAC_TRANS_WIDTH_32, spi_datacfg->length); } else { - tx_buff = x_malloc(spi_datacfg->length * 4); - if (!tx_buff) { - goto transfer_done; + if (spi_datacfg->length > WRITE_BUF_SIZE) { + tx_buff = x_malloc(spi_datacfg->length * 4); + if (!tx_buff) { + goto transfer_done; + } + } else { + tx_buff = write_buf; } + for (i = 0; i < spi_datacfg->length; i++) { tx_buff[i] = ((uint8_t *)spi_datacfg->tx_buff)[i]; } @@ -201,10 +209,10 @@ static uint32 SpiWriteData(struct SpiHardwareDevice *spi_dev, struct SpiDataStan spi_instance[device_master_id]->ser = 0x00; spi_instance[device_master_id]->ssienr = 0x00; - transfer_done: - if (tx_buff != NULL) { - x_free(tx_buff); - } + transfer_done: + if (tx_buff != NULL && spi_datacfg->length > WRITE_BUF_SIZE) { + x_free(tx_buff); + } } if (spi_datacfg->spi_cs_release) { @@ -219,6 +227,9 @@ static uint32 SpiWriteData(struct SpiHardwareDevice *spi_dev, struct SpiDataStan static uint32 SpiReadData(struct SpiHardwareDevice *spi_dev, struct SpiDataStandard *spi_datacfg) { +#define READ_BUF_SIZE 1600 + static uint32_t read_buf[4 * READ_BUF_SIZE] = { 0 }; + SpiDeviceParam *dev_param = (SpiDeviceParam *)(spi_dev->haldev.private_data); uint32 spi_read_length = 0;; @@ -251,12 +262,15 @@ static uint32 SpiReadData(struct SpiHardwareDevice *spi_dev, struct SpiDataStand dmac_set_single_mode(dev_param->spi_dma_param->spi_dmac_rxchannel, (void *)(&spi_instance[device_master_id]->dr[0]), &dummy, DMAC_ADDR_NOCHANGE, DMAC_ADDR_NOCHANGE, DMAC_MSIZE_1, DMAC_TRANS_WIDTH_32, spi_datacfg->length); } else { - rx_buff = x_calloc(spi_datacfg->length * 4, 1); - if(!rx_buff) - { - goto transfer_done; + if (spi_datacfg->length > READ_BUF_SIZE) { + rx_buff = x_calloc(spi_datacfg->length * 4, 1); + if (!rx_buff) { + goto transfer_done; + } + } else { + rx_buff = read_buf; } - + dmac_set_single_mode(dev_param->spi_dma_param->spi_dmac_rxchannel, (void *)(&spi_instance[device_master_id]->dr[0]), rx_buff, DMAC_ADDR_NOCHANGE, DMAC_ADDR_INCREMENT, DMAC_MSIZE_1, DMAC_TRANS_WIDTH_32, spi_datacfg->length); } @@ -273,8 +287,8 @@ static uint32 SpiReadData(struct SpiHardwareDevice *spi_dev, struct SpiDataStand } } - transfer_done: - if (rx_buff) { + transfer_done: + if (rx_buff && spi_datacfg->length > READ_BUF_SIZE) { x_free(rx_buff); } } diff --git a/Ubiquitous/XiZi_IIoT/board/imxrt1176-sbc/third_party_driver/ethernet/eth_netdev.c b/Ubiquitous/XiZi_IIoT/board/imxrt1176-sbc/third_party_driver/ethernet/eth_netdev.c index 03ca27594..09957b854 100644 --- a/Ubiquitous/XiZi_IIoT/board/imxrt1176-sbc/third_party_driver/ethernet/eth_netdev.c +++ b/Ubiquitous/XiZi_IIoT/board/imxrt1176-sbc/third_party_driver/ethernet/eth_netdev.c @@ -76,6 +76,7 @@ static int lwip_netdev_set_addr_info(struct netdev* netdev, ip_addr_t* ip_addr, netif_set_gw((struct netif*)netdev->user_data, ip_2_ip4(gw)); } } + return 0; } #ifdef LWIP_DNS @@ -92,7 +93,7 @@ static int lwip_netdev_set_dns_server(struct netdev* netdev, uint8_t dns_num, ip } #endif -#ifdef LWIP_DHCP +#if LWIP_DHCP static int lwip_netdev_set_dhcp(struct netdev* netdev, bool is_enabled) { netdev_low_level_set_dhcp_status(netdev, is_enabled); @@ -120,7 +121,7 @@ static const struct netdev_ops lwip_netdev_ops = { #ifdef LWIP_DNS .set_dns_server = lwip_netdev_set_dns_server, #endif -#ifdef LWIP_DHCP +#if LWIP_DHCP .set_dhcp = lwip_netdev_set_dhcp, #endif .set_default = lwip_netdev_set_default, @@ -180,9 +181,9 @@ int lwip_netdev_add(struct netif* lwip_netif) netdev->ops = &lwip_netdev_ops; netdev->hwaddr_len = lwip_netif->hwaddr_len; memcpy(netdev->hwaddr, lwip_netif->hwaddr, lwip_netif->hwaddr_len); - netdev->ip_addr = lwip_netif->ip_addr; - netdev->gw = lwip_netif->gw; - netdev->netmask = lwip_netif->netmask; + netdev->ip_addr = &lwip_netif->ip_addr; + netdev->gw = &lwip_netif->gw; + netdev->netmask = &lwip_netif->netmask; return result; } diff --git a/Ubiquitous/XiZi_IIoT/board/ok1052-c/third_party_driver/ethernet/eth_netdev.c b/Ubiquitous/XiZi_IIoT/board/ok1052-c/third_party_driver/ethernet/eth_netdev.c index 03ca27594..09957b854 100644 --- a/Ubiquitous/XiZi_IIoT/board/ok1052-c/third_party_driver/ethernet/eth_netdev.c +++ b/Ubiquitous/XiZi_IIoT/board/ok1052-c/third_party_driver/ethernet/eth_netdev.c @@ -76,6 +76,7 @@ static int lwip_netdev_set_addr_info(struct netdev* netdev, ip_addr_t* ip_addr, netif_set_gw((struct netif*)netdev->user_data, ip_2_ip4(gw)); } } + return 0; } #ifdef LWIP_DNS @@ -92,7 +93,7 @@ static int lwip_netdev_set_dns_server(struct netdev* netdev, uint8_t dns_num, ip } #endif -#ifdef LWIP_DHCP +#if LWIP_DHCP static int lwip_netdev_set_dhcp(struct netdev* netdev, bool is_enabled) { netdev_low_level_set_dhcp_status(netdev, is_enabled); @@ -120,7 +121,7 @@ static const struct netdev_ops lwip_netdev_ops = { #ifdef LWIP_DNS .set_dns_server = lwip_netdev_set_dns_server, #endif -#ifdef LWIP_DHCP +#if LWIP_DHCP .set_dhcp = lwip_netdev_set_dhcp, #endif .set_default = lwip_netdev_set_default, @@ -180,9 +181,9 @@ int lwip_netdev_add(struct netif* lwip_netif) netdev->ops = &lwip_netdev_ops; netdev->hwaddr_len = lwip_netif->hwaddr_len; memcpy(netdev->hwaddr, lwip_netif->hwaddr, lwip_netif->hwaddr_len); - netdev->ip_addr = lwip_netif->ip_addr; - netdev->gw = lwip_netif->gw; - netdev->netmask = lwip_netif->netmask; + netdev->ip_addr = &lwip_netif->ip_addr; + netdev->gw = &lwip_netif->gw; + netdev->netmask = &lwip_netif->netmask; return result; } diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/ethernet/eth_netdev.c b/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/ethernet/eth_netdev.c index 03ca27594..09957b854 100644 --- a/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/ethernet/eth_netdev.c +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/ethernet/eth_netdev.c @@ -76,6 +76,7 @@ static int lwip_netdev_set_addr_info(struct netdev* netdev, ip_addr_t* ip_addr, netif_set_gw((struct netif*)netdev->user_data, ip_2_ip4(gw)); } } + return 0; } #ifdef LWIP_DNS @@ -92,7 +93,7 @@ static int lwip_netdev_set_dns_server(struct netdev* netdev, uint8_t dns_num, ip } #endif -#ifdef LWIP_DHCP +#if LWIP_DHCP static int lwip_netdev_set_dhcp(struct netdev* netdev, bool is_enabled) { netdev_low_level_set_dhcp_status(netdev, is_enabled); @@ -120,7 +121,7 @@ static const struct netdev_ops lwip_netdev_ops = { #ifdef LWIP_DNS .set_dns_server = lwip_netdev_set_dns_server, #endif -#ifdef LWIP_DHCP +#if LWIP_DHCP .set_dhcp = lwip_netdev_set_dhcp, #endif .set_default = lwip_netdev_set_default, @@ -180,9 +181,9 @@ int lwip_netdev_add(struct netif* lwip_netif) netdev->ops = &lwip_netdev_ops; netdev->hwaddr_len = lwip_netif->hwaddr_len; memcpy(netdev->hwaddr, lwip_netif->hwaddr, lwip_netif->hwaddr_len); - netdev->ip_addr = lwip_netif->ip_addr; - netdev->gw = lwip_netif->gw; - netdev->netmask = lwip_netif->netmask; + netdev->ip_addr = &lwip_netif->ip_addr; + netdev->gw = &lwip_netif->gw; + netdev->netmask = &lwip_netif->netmask; return result; } diff --git a/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/config.mk b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/config.mk index af0254884..ad12a5c9b 100644 --- a/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/config.mk +++ b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/config.mk @@ -15,4 +15,8 @@ ifeq ($(CONFIG_RESOURCES_LWIP), y) export LINK_LWIP := $(KERNEL_ROOT)/resources/ethernet/LwIP/liblwip.a endif +ifeq ($(CONFIG_USE_MONGOOSE), y) +export LINK_MONGOOSE := $(KERNEL_ROOT)/../../APP_Framework/Applications/mongoose/mongoose.a +endif + export ARCH = arm diff --git a/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/ethernet/eth_driver.c b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/ethernet/eth_driver.c index 9ad1468d0..a1e94307c 100644 --- a/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/ethernet/eth_driver.c +++ b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/ethernet/eth_driver.c @@ -277,10 +277,7 @@ struct pbuf* low_level_input(struct netif* netif) return p; } -extern void LwipSetIPTest(int argc, char* argv[]); int HwEthInit(void) { - // lwip_config_tcp(0, lwip_ipaddr, lwip_netmask, lwip_gwaddr); - LwipSetIPTest(1, NULL); return EOK; } diff --git a/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/ethernet/eth_netdev.c b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/ethernet/eth_netdev.c index 862d80bd8..0f6a8df37 100644 --- a/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/ethernet/eth_netdev.c +++ b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/ethernet/eth_netdev.c @@ -76,6 +76,7 @@ static int lwip_netdev_set_addr_info(struct netdev* netdev, ip_addr_t* ip_addr, netif_set_gw((struct netif*)netdev->user_data, ip_2_ip4(gw)); } } + return 0; } #ifdef LWIP_DNS @@ -92,7 +93,7 @@ static int lwip_netdev_set_dns_server(struct netdev* netdev, uint8_t dns_num, ip } #endif -#ifdef LWIP_DHCP +#if LWIP_DHCP static int lwip_netdev_set_dhcp(struct netdev* netdev, bool is_enabled) { netdev_low_level_set_dhcp_status(netdev, is_enabled); @@ -120,7 +121,7 @@ static const struct netdev_ops lwip_netdev_ops = { #ifdef LWIP_DNS .set_dns_server = lwip_netdev_set_dns_server, #endif -#ifdef LWIP_DHCP +#if LWIP_DHCP .set_dhcp = lwip_netdev_set_dhcp, #endif .set_default = lwip_netdev_set_default, @@ -183,9 +184,9 @@ int lwip_netdev_add(struct netif* lwip_netif) netdev->ops = &lwip_netdev_ops; netdev->hwaddr_len = lwip_netif->hwaddr_len; memcpy(netdev->hwaddr, lwip_netif->hwaddr, lwip_netif->hwaddr_len); - netdev->ip_addr = lwip_netif->ip_addr; - netdev->gw = lwip_netif->gw; - netdev->netmask = lwip_netif->netmask; + netdev->ip_addr = &lwip_netif->ip_addr; + netdev->gw = &lwip_netif->gw; + netdev->netmask = &lwip_netif->netmask; return result; } diff --git a/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/ethernet/ethernetif.c b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/ethernet/ethernetif.c index 8347c4c50..15a14bcb7 100644 --- a/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/ethernet/ethernetif.c +++ b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/ethernet/ethernetif.c @@ -204,7 +204,6 @@ void ethernetif_input(void* netif_arg) /* Move received packet into a new pbuf */ while (1) { sys_arch_sem_wait(get_eth_recv_sem(), WAITING_FOREVER); - KPrintf("%s -->\n", netif->name); while (1) { p = low_level_input(netif); #ifndef ETHERNET_LOOPBACK_TEST diff --git a/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/ethernet_wiz/w5x00_lwip.c b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/ethernet_wiz/w5x00_lwip.c index 2494cdb32..357a9e404 100644 --- a/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/ethernet_wiz/w5x00_lwip.c +++ b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/ethernet_wiz/w5x00_lwip.c @@ -113,7 +113,6 @@ void ethernetif_input2(void* netif_arg) struct pbuf* p = NULL; for (;;) { sys_arch_sem_wait(get_eth_recv_sem2(), WAITING_FOREVER); - KPrintf("%s -->\n", netif->name); sys_mutex_lock(&wiz_trans_mtx); while (1) { diff --git a/Ubiquitous/XiZi_IIoT/board/xiwangtong-arm32/third_party_driver/ethernet/eth_netdev.c b/Ubiquitous/XiZi_IIoT/board/xiwangtong-arm32/third_party_driver/ethernet/eth_netdev.c index 03ca27594..09957b854 100644 --- a/Ubiquitous/XiZi_IIoT/board/xiwangtong-arm32/third_party_driver/ethernet/eth_netdev.c +++ b/Ubiquitous/XiZi_IIoT/board/xiwangtong-arm32/third_party_driver/ethernet/eth_netdev.c @@ -76,6 +76,7 @@ static int lwip_netdev_set_addr_info(struct netdev* netdev, ip_addr_t* ip_addr, netif_set_gw((struct netif*)netdev->user_data, ip_2_ip4(gw)); } } + return 0; } #ifdef LWIP_DNS @@ -92,7 +93,7 @@ static int lwip_netdev_set_dns_server(struct netdev* netdev, uint8_t dns_num, ip } #endif -#ifdef LWIP_DHCP +#if LWIP_DHCP static int lwip_netdev_set_dhcp(struct netdev* netdev, bool is_enabled) { netdev_low_level_set_dhcp_status(netdev, is_enabled); @@ -120,7 +121,7 @@ static const struct netdev_ops lwip_netdev_ops = { #ifdef LWIP_DNS .set_dns_server = lwip_netdev_set_dns_server, #endif -#ifdef LWIP_DHCP +#if LWIP_DHCP .set_dhcp = lwip_netdev_set_dhcp, #endif .set_default = lwip_netdev_set_default, @@ -180,9 +181,9 @@ int lwip_netdev_add(struct netif* lwip_netif) netdev->ops = &lwip_netdev_ops; netdev->hwaddr_len = lwip_netif->hwaddr_len; memcpy(netdev->hwaddr, lwip_netif->hwaddr, lwip_netif->hwaddr_len); - netdev->ip_addr = lwip_netif->ip_addr; - netdev->gw = lwip_netif->gw; - netdev->netmask = lwip_netif->netmask; + netdev->ip_addr = &lwip_netif->ip_addr; + netdev->gw = &lwip_netif->gw; + netdev->netmask = &lwip_netif->netmask; return result; } diff --git a/Ubiquitous/XiZi_IIoT/compiler.mk b/Ubiquitous/XiZi_IIoT/compiler.mk index 87aba0280..4a91b1ba0 100644 --- a/Ubiquitous/XiZi_IIoT/compiler.mk +++ b/Ubiquitous/XiZi_IIoT/compiler.mk @@ -2,6 +2,8 @@ ifeq ($(COMPILE_TYPE), COMPILE_MUSL) SRC_DIR_TEMP := $(MUSL_DIR) else ifeq ($(COMPILE_TYPE), COMPILE_LWIP) SRC_DIR_TEMP := $(LWIP_DIR) +else ifeq ($(COMPILE_TYPE), COMPILE_MONGOOSE) +SRC_DIR_TEMP := $(MONGOOSE_DIR) else SRC_DIR_TEMP := $(SRC_DIR) endif @@ -9,6 +11,7 @@ endif SRC_DIR := MUSL_DIR := LWIP_DIR := +MONGOOSE_DIR := ifeq ($(USE_APP_INCLUDEPATH), y) include $(KERNEL_ROOT)/path_app.mk diff --git a/Ubiquitous/XiZi_IIoT/kernel/include/xs_kdbg.h b/Ubiquitous/XiZi_IIoT/kernel/include/xs_kdbg.h index afd6dd617..c4cf2c162 100644 --- a/Ubiquitous/XiZi_IIoT/kernel/include/xs_kdbg.h +++ b/Ubiquitous/XiZi_IIoT/kernel/include/xs_kdbg.h @@ -44,15 +44,16 @@ extern "C" { #define MSGQUEUE_DEBUG 0 #define FILESYS_DEBUG 0 -#define NETDEV_DEBUG 0 +#define NETDEV_DEBUG 1 #define WEBNET_DEBUG 0 #define WIZNET_DEBUG 0 -#define SYS_KDEBUG_LOG(section, information) \ - do { \ - if (section) { \ - KPrintf information; \ - } \ +#define SYS_KDEBUG_LOG(section, information) \ + do { \ + if (section) { \ + KPrintf("[%s:%d] ", __func__, __LINE__); \ + KPrintf information; \ + } \ } while (0) #define KDYN_NONE 0 diff --git a/Ubiquitous/XiZi_IIoT/link.mk b/Ubiquitous/XiZi_IIoT/link.mk index a2bdd07d4..09e643226 100644 --- a/Ubiquitous/XiZi_IIoT/link.mk +++ b/Ubiquitous/XiZi_IIoT/link.mk @@ -3,7 +3,7 @@ OBJS := $(shell cat make.obj) $(TARGET): $(OBJS) @echo ------------------------------------------------ @echo link $(TARGET) - @$(CROSS_COMPILE)g++ -o $@ $($(LINK_FLAGS)) $(OBJS) $(LINK_LWIP) $(LINK_MUSLLIB) $(LIBCC) + @$(CROSS_COMPILE)g++ -o $@ $($(LINK_FLAGS)) $(OBJS) $(LINK_LWIP) $(LINK_MUSLLIB) $(LINK_MONGOOSE) $(LIBCC) @echo ------------------------------------------------ @$(CROSS_COMPILE)objcopy -O binary $@ XiZi-$(BOARD)$(COMPILE_TYPE).bin @$(CROSS_COMPILE)objdump -S $@ > XiZi-$(BOARD)$(COMPILE_TYPE).asm diff --git a/Ubiquitous/XiZi_IIoT/link_mongoose.mk b/Ubiquitous/XiZi_IIoT/link_mongoose.mk new file mode 100644 index 000000000..568c910b0 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/link_mongoose.mk @@ -0,0 +1,9 @@ +OBJS := $(shell cat make.obj) + +$(TARGET): $(OBJS) + @echo ------------------------------------------------ + @echo link $(TARGET) + @$(CROSS_COMPILE)ar -r $@ $(OBJS) + @echo ------------------------------------------------ + @$(CROSS_COMPILE)objcopy $@ $(TARGET) + @$(CROSS_COMPILE)size $@ \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/api/sockets.c b/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/api/sockets.c index 3ddd778f5..5f458d8f0 100644 --- a/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/api/sockets.c +++ b/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/api/sockets.c @@ -640,7 +640,8 @@ lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen) LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d)...\n", s)); sock = get_socket(s); if (!sock) { - return -1; + KPrintf("sock = get_socket(s);\n"); + return -1; } /* wait for a new connection */ @@ -655,6 +656,7 @@ lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen) sock_set_errno(sock, err_to_errno(err)); } done_socket(sock); + KPrintf("err = netconn_accept(sock->conn, &newconn);\n"); return -1; } LWIP_ASSERT("newconn != NULL", newconn != NULL); @@ -664,6 +666,7 @@ lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen) netconn_delete(newconn); sock_set_errno(sock, ENFILE); done_socket(sock); + KPrintf("newsock = alloc_socket(newconn, 1);\n"); return -1; } LWIP_ASSERT("invalid socket index", (newsock >= LWIP_SOCKET_OFFSET) && (newsock < NUM_SOCKETS + LWIP_SOCKET_OFFSET)); @@ -701,6 +704,7 @@ lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen) free_socket(nsock, 1); sock_set_errno(sock, err_to_errno(err)); done_socket(sock); + KPrintf("err = netconn_peer(newconn, &naddr, &port);\n"); return -1; } @@ -1242,6 +1246,8 @@ lwip_recvfrom(int s, void *mem, size_t len, int flags, if (err != ERR_OK) { LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom[UDP/RAW](%d): buf == NULL, error is \"%s\"!\n", s, lwip_strerr(err))); + KPrintf("lwip_recvfrom[UDP/RAW](%d): buf == NULL, error is \"%s\"!\n", + s, lwip_strerr(err)); sock_set_errno(sock, err_to_errno(err)); done_socket(sock); return -1; diff --git a/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/arch/lwipopts.h b/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/arch/lwipopts.h index feded6b5a..ffbb51d74 100644 --- a/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/arch/lwipopts.h +++ b/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/arch/lwipopts.h @@ -272,13 +272,16 @@ a lot of data that needs to be copied, this should be set high. */ #define MEMP_NUM_PBUF 32 /* MEMP_NUM_UDP_PCB: the number of UDP protocol control blocks. One per active UDP "connection". */ -#define MEMP_NUM_UDP_PCB 4 +#define MEMP_NUM_UDP_PCB 32 /* MEMP_NUM_TCP_PCB: the number of simulatenously active TCP connections. */ -#define MEMP_NUM_TCP_PCB 64 +#define MEMP_NUM_TCP_PCB 32 +#define MEMP_NUM_RAW_PCB 32 +#define MEMP_NUM_REASSDATA 32 +#define MEMP_NUM_NETCONN 32 /* MEMP_NUM_TCP_PCB_LISTEN: the number of listening TCP connections. */ -#define MEMP_NUM_TCP_PCB_LISTEN 2 +#define MEMP_NUM_TCP_PCB_LISTEN 32 /* MEMP_NUM_TCP_SEG: the number of simultaneously queued TCP segments. */ #define MEMP_NUM_TCP_SEG 256 @@ -384,12 +387,6 @@ a lot of data that needs to be copied, this should be set high. */ /* ---------- ICMP options ---------- */ #define LWIP_ICMP 1 -/* ---------- DHCP options ---------- */ -/* Define LWIP_DHCP to 1 if you want DHCP configuration of - interfaces. DHCP is not implemented in lwIP 0.5.1, however, so - turning this on does currently not work. */ -#define LWIP_DHCP 1 - /* ---------- UDP options ---------- */ #define LWIP_UDP 1 #define UDP_TTL 255 @@ -521,7 +518,7 @@ The STM32F4x7 allows computing and verifying the IP, UDP, TCP and ICMP checksums /* ---------- DHCP options ---------- */ /* Define LWIP_DHCP to 1 if you want DHCP configuration of interfaces. */ -#define LWIP_DHCP 1 +#define LWIP_DHCP 0 /* 1 if you want to do an ARP check on the offered address (recommended). */ diff --git a/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/arch/sys_arch.c b/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/arch/sys_arch.c index 68e3c0ff6..788e7e3e3 100644 --- a/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/arch/sys_arch.c +++ b/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/arch/sys_arch.c @@ -76,7 +76,7 @@ char lwip_eth0_ipaddr[20] = { 192, 168, 130, 77 }; char lwip_eth0_netmask[20] = { 255, 255, 254, 0 }; char lwip_eth0_gwaddr[20] = { 192, 168, 130, 1 }; -char lwip_eth1_ipaddr[20] = { 192, 168, 130, 88 }; +char lwip_eth1_ipaddr[20] = { 192, 168, 131, 88 }; char lwip_eth1_netmask[20] = { 255, 255, 254, 0 }; char lwip_eth1_gwaddr[20] = { 192, 168, 130, 1 }; @@ -346,7 +346,9 @@ void lwip_config_input(int eport, struct netif* net) if (eport == 0) { th_id = sys_thread_new("eth_input", ethernetif_input, net, LWIP_TASK_STACK_SIZE, 30); } else if (eport == 1) { +#ifdef NETIF_ENET1_INIT_FUNC th_id = sys_thread_new("eth_input2", ethernetif_input2, net, LWIP_TASK_STACK_SIZE, 30); +#endif } } @@ -360,7 +362,6 @@ void lwip_config_tcp(uint8_t enet_port, char* ip, char* mask, char* gw) if (chk_lwip_bit(LWIP_INIT_FLAG)) { lw_print("lw: [%s] already ...\n", __func__); - return; } set_lwip_bit(LWIP_INIT_FLAG); @@ -384,12 +385,13 @@ void lwip_config_tcp(uint8_t enet_port, char* ip, char* mask, char* gw) lw_print("Not Netif driver for Eport 0\n"); return; #endif +#ifdef NETIF_ENET0_INIT_FUNC lw_print("Add netif eport 0\n"); netif_add(&gnetif, &net_ipaddr, &net_netmask, &net_gw, eth_cfg, NETIF_ENET0_INIT_FUNC, tcpip_input); - // netif_set_default(&gnetif); - // netif_set_up(&gnetif); + netif_set_default(&gnetif); + netif_set_up(&gnetif); lw_print("\r\n************************************************\r\n"); lw_print(" Network Configuration\r\n"); @@ -404,6 +406,7 @@ void lwip_config_tcp(uint8_t enet_port, char* ip, char* mask, char* gw) lwip_config_input(enet_port, &gnetif); is_init_0 = 1; +#endif } else if (1 == enet_port) { if (is_init_1 == 1) { @@ -413,11 +416,12 @@ void lwip_config_tcp(uint8_t enet_port, char* ip, char* mask, char* gw) lw_print("Not Netif driver for Eport 1\n"); return; #endif +#ifdef NETIF_ENET1_INIT_FUNC lw_print("Add netif eport 1\n"); netif_add(&gnetif2, &net_ipaddr, &net_netmask, &net_gw, eth_cfg, NETIF_ENET1_INIT_FUNC, tcpip_input); - netif_set_default(&gnetif2); + // netif_set_default(&gnetif2); netif_set_up(&gnetif2); lw_print("\r\n************************************************\r\n"); @@ -433,5 +437,6 @@ void lwip_config_tcp(uint8_t enet_port, char* ip, char* mask, char* gw) lwip_config_input(enet_port, &gnetif2); is_init_1 = 1; +#endif } } \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/core/ipv4/ip4.c b/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/core/ipv4/ip4.c index 036457afe..3cb0ca16f 100644 --- a/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/core/ipv4/ip4.c +++ b/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/core/ipv4/ip4.c @@ -228,6 +228,95 @@ ip4_route(const ip4_addr_t *dest) return netif_default; } +/** + * Finds the appropriate network interface for a given IP address. It + * searches the list of network interfaces linearly. A match is found + * if the masked IP address of the network interface equals the masked + * IP address given to the function. + * + * @param dest the destination IP address for which to find the route + * @return the netif on which to send to reach dest + */ +struct netif* +ip4_route2(const ip4_addr_t* src, const ip4_addr_t* dest) +{ +#if !LWIP_SINGLE_NETIF + struct netif* netif; + LWIP_ASSERT_CORE_LOCKED(); + +#if LWIP_MULTICAST_TX_OPTIONS + /* Use administratively selected interface for multicast by default */ + if (ip4_addr_ismulticast(dest) && ip4_default_multicast_netif) { + return ip4_default_multicast_netif; + } +#endif /* LWIP_MULTICAST_TX_OPTIONS */ + + /* bug #54569: in case LWIP_SINGLE_NETIF=1 and LWIP_DEBUGF() disabled, the following loop is optimized away */ + LWIP_UNUSED_ARG(dest); + + /* iterate through netifs */ + NETIF_FOREACH(netif) + { + /* is the netif up, does it have a link and a valid address? */ + if (netif_is_up(netif) && netif_is_link_up(netif) && !ip4_addr_isany_val(*netif_ip4_addr(netif))) { + + /* network mask matches? */ + // if (ip4_addr_netcmp(dest, netif_ip4_addr(netif), netif_ip4_netmask(netif))) { + if (ip4_addr_cmp(src, netif_ip4_addr(netif))) { + /* return netif on which to forward IP packet */ + return netif; + } + /* gateway matches on a non broadcast interface? (i.e. peer in a point to point interface) */ + if (((netif->flags & NETIF_FLAG_BROADCAST) == 0) && ip4_addr_cmp(dest, netif_ip4_gw(netif))) { + /* return netif on which to forward IP packet */ + return netif; + } + } + } + +#if LWIP_NETIF_LOOPBACK && !LWIP_HAVE_LOOPIF + /* loopif is disabled, looopback traffic is passed through any netif */ + if (ip4_addr_isloopback(dest)) { + /* don't check for link on loopback traffic */ + if (netif_default != NULL && netif_is_up(netif_default)) { + return netif_default; + } + /* default netif is not up, just use any netif for loopback traffic */ + NETIF_FOREACH(netif) + { + if (netif_is_up(netif)) { + return netif; + } + } + return NULL; + } +#endif /* LWIP_NETIF_LOOPBACK && !LWIP_HAVE_LOOPIF */ + +#ifdef LWIP_HOOK_IP4_ROUTE_SRC + netif = LWIP_HOOK_IP4_ROUTE_SRC(NULL, dest); + if (netif != NULL) { + return netif; + } +#elif defined(LWIP_HOOK_IP4_ROUTE) + netif = LWIP_HOOK_IP4_ROUTE(dest); + if (netif != NULL) { + return netif; + } +#endif +#endif /* !LWIP_SINGLE_NETIF */ + + if ((netif_default == NULL) || !netif_is_up(netif_default) || !netif_is_link_up(netif_default) || ip4_addr_isany_val(*netif_ip4_addr(netif_default)) || ip4_addr_isloopback(dest)) { + /* No matching netif found and default netif is not usable. + If this is not good enough for you, use LWIP_HOOK_IP4_ROUTE() */ + LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip4_route: No route to %" U16_F ".%" U16_F ".%" U16_F ".%" U16_F "\n", ip4_addr1_16(dest), ip4_addr2_16(dest), ip4_addr3_16(dest), ip4_addr4_16(dest))); + IP_STATS_INC(ip.rterr); + MIB2_STATS_INC(mib2.ipoutnoroutes); + return NULL; + } + + return netif_default; +} + #if IP_FORWARD /** * Determine whether an IP address is in a reserved set of addresses diff --git a/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/include/lwip/ip4.h b/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/include/lwip/ip4.h index fd35a3369..d3789a9be 100644 --- a/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/include/lwip/ip4.h +++ b/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/include/lwip/ip4.h @@ -63,39 +63,41 @@ extern "C" { #define ip_init() /* Compatibility define, no init needed. */ struct netif *ip4_route(const ip4_addr_t *dest); +struct netif* ip4_route2(const ip4_addr_t* src, const ip4_addr_t* dest); #if LWIP_IPV4_SRC_ROUTING -struct netif *ip4_route_src(const ip4_addr_t *src, const ip4_addr_t *dest); +struct netif* ip4_route_src(const ip4_addr_t* src, const ip4_addr_t* dest); #else /* LWIP_IPV4_SRC_ROUTING */ -#define ip4_route_src(src, dest) ip4_route(dest) +// #define ip4_route_src(src, dest) ip4_route(dest) +#define ip4_route_src(src, dest) ip4_route2(src, dest) #endif /* LWIP_IPV4_SRC_ROUTING */ -err_t ip4_input(struct pbuf *p, struct netif *inp); -err_t ip4_output(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest, - u8_t ttl, u8_t tos, u8_t proto); -err_t ip4_output_if(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest, - u8_t ttl, u8_t tos, u8_t proto, struct netif *netif); -err_t ip4_output_if_src(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest, - u8_t ttl, u8_t tos, u8_t proto, struct netif *netif); +err_t ip4_input(struct pbuf* p, struct netif* inp); +err_t ip4_output(struct pbuf* p, const ip4_addr_t* src, const ip4_addr_t* dest, + u8_t ttl, u8_t tos, u8_t proto); +err_t ip4_output_if(struct pbuf* p, const ip4_addr_t* src, const ip4_addr_t* dest, + u8_t ttl, u8_t tos, u8_t proto, struct netif* netif); +err_t ip4_output_if_src(struct pbuf* p, const ip4_addr_t* src, const ip4_addr_t* dest, + u8_t ttl, u8_t tos, u8_t proto, struct netif* netif); #if LWIP_NETIF_USE_HINTS -err_t ip4_output_hinted(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest, - u8_t ttl, u8_t tos, u8_t proto, struct netif_hint *netif_hint); + err_t ip4_output_hinted(struct pbuf* p, const ip4_addr_t* src, const ip4_addr_t* dest, + u8_t ttl, u8_t tos, u8_t proto, struct netif_hint* netif_hint); #endif /* LWIP_NETIF_USE_HINTS */ #if IP_OPTIONS_SEND -err_t ip4_output_if_opt(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest, - u8_t ttl, u8_t tos, u8_t proto, struct netif *netif, void *ip_options, - u16_t optlen); -err_t ip4_output_if_opt_src(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest, - u8_t ttl, u8_t tos, u8_t proto, struct netif *netif, void *ip_options, - u16_t optlen); + err_t ip4_output_if_opt(struct pbuf* p, const ip4_addr_t* src, const ip4_addr_t* dest, + u8_t ttl, u8_t tos, u8_t proto, struct netif* netif, void* ip_options, + u16_t optlen); + err_t ip4_output_if_opt_src(struct pbuf* p, const ip4_addr_t* src, const ip4_addr_t* dest, + u8_t ttl, u8_t tos, u8_t proto, struct netif* netif, void* ip_options, + u16_t optlen); #endif /* IP_OPTIONS_SEND */ #if LWIP_MULTICAST_TX_OPTIONS -void ip4_set_default_multicast_netif(struct netif* default_multicast_netif); + void ip4_set_default_multicast_netif(struct netif* default_multicast_netif); #endif /* LWIP_MULTICAST_TX_OPTIONS */ #define ip4_netif_get_local_ip(netif) (((netif) != NULL) ? netif_ip_addr4(netif) : NULL) #if IP_DEBUG -void ip4_debug_print(struct pbuf *p); + void ip4_debug_print(struct pbuf* p); #else #define ip4_debug_print(p) #endif /* IP_DEBUG */ diff --git a/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/include/lwip/opt.h b/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/include/lwip/opt.h index a304c67c2..55c840233 100644 --- a/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/include/lwip/opt.h +++ b/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/include/lwip/opt.h @@ -521,7 +521,7 @@ * (only needed if you use the sequential API, like api_lib.c) */ #if !defined MEMP_NUM_NETBUF || defined __DOXYGEN__ -#define MEMP_NUM_NETBUF 2 +#define MEMP_NUM_NETBUF 8 #endif /** @@ -529,7 +529,7 @@ * (only needed if you use the sequential API, like api_lib.c) */ #if !defined MEMP_NUM_NETCONN || defined __DOXYGEN__ -#define MEMP_NUM_NETCONN 4 +#define MEMP_NUM_NETCONN 8 #endif /** @@ -538,7 +538,7 @@ * In that case, you need one per thread calling lwip_select.) */ #if !defined MEMP_NUM_SELECT_CB || defined __DOXYGEN__ -#define MEMP_NUM_SELECT_CB 4 +#define MEMP_NUM_SELECT_CB 4 #endif /** @@ -547,7 +547,7 @@ * (only needed if you use tcpip.c) */ #if !defined MEMP_NUM_TCPIP_MSG_API || defined __DOXYGEN__ -#define MEMP_NUM_TCPIP_MSG_API 8 +#define MEMP_NUM_TCPIP_MSG_API 8 #endif /** @@ -556,7 +556,7 @@ * (only needed if you use tcpip.c) */ #if !defined MEMP_NUM_TCPIP_MSG_INPKT || defined __DOXYGEN__ -#define MEMP_NUM_TCPIP_MSG_INPKT 8 +#define MEMP_NUM_TCPIP_MSG_INPKT 8 #endif /** @@ -564,7 +564,7 @@ * (before freeing the corresponding memory using lwip_freeaddrinfo()). */ #if !defined MEMP_NUM_NETDB || defined __DOXYGEN__ -#define MEMP_NUM_NETDB 1 +#define MEMP_NUM_NETDB 2 #endif /** @@ -572,7 +572,7 @@ * if DNS_LOCAL_HOSTLIST_IS_DYNAMIC==1. */ #if !defined MEMP_NUM_LOCALHOSTLIST || defined __DOXYGEN__ -#define MEMP_NUM_LOCALHOSTLIST 1 +#define MEMP_NUM_LOCALHOSTLIST 2 #endif /** diff --git a/Ubiquitous/XiZi_IIoT/resources/ethernet/cmd_lwip/lwip_config_demo.c b/Ubiquitous/XiZi_IIoT/resources/ethernet/cmd_lwip/lwip_config_demo.c index f6b6c6d01..1d6aa94e8 100755 --- a/Ubiquitous/XiZi_IIoT/resources/ethernet/cmd_lwip/lwip_config_demo.c +++ b/Ubiquitous/XiZi_IIoT/resources/ethernet/cmd_lwip/lwip_config_demo.c @@ -25,102 +25,145 @@ #include #include -#include +#include "argparse.h" + +#include "inet.h" +#include "netdev.h" /******************************************************************************/ -uint8_t enet_id = 0; -static void LwipSetIPTask(void* param) -{ - lwip_config_tcp(0, lwip_eth0_ipaddr, lwip_eth0_netmask, lwip_eth0_gwaddr); - lwip_config_tcp(1, lwip_eth1_ipaddr, lwip_eth1_netmask, lwip_eth1_gwaddr); -} +enum NETWORK_ACTIVE_E { + LWIP_ACTIVE = 'e', + LWIP_ACTIVE_ALL = 'a', +}; -void LwipSetIPTest(int argc, char* argv[]) +void LwipNetworkActive(int argc, char* argv[]) { - if (argc >= 4) { - printf("lw: [%s] ip %s mask %s gw %s netport %s\n", __func__, argv[1], argv[2], argv[3], argv[4]); - sscanf(argv[1], "%hhd.%hhd.%hhd.%hhd", &lwip_ipaddr[0], &lwip_ipaddr[1], &lwip_ipaddr[2], &lwip_ipaddr[3]); - sscanf(argv[2], "%hhd.%hhd.%hhd.%hhd", &lwip_netmask[0], &lwip_netmask[1], &lwip_netmask[2], &lwip_netmask[3]); - sscanf(argv[3], "%hhd.%hhd.%hhd.%hhd", &lwip_gwaddr[0], &lwip_gwaddr[1], &lwip_gwaddr[2], &lwip_gwaddr[3]); - sscanf(argv[4], "%hhd", &enet_id); + static char usage_info[] = "select a eport to start."; + static char program_info[] = "Active lwip network function."; + static const char* const net_active_usages[] = { + "LwipNetworkActive -e 0", + "LwipNetworkActive -e 1", + "LwipNetworkActive -a", + }; - if (0 == enet_id) { - printf("save eth0 info\n"); - memcpy(lwip_eth0_ipaddr, lwip_ipaddr, 20); - memcpy(lwip_eth0_netmask, lwip_netmask, 20); - memcpy(lwip_eth0_gwaddr, lwip_gwaddr, 20); - } else if (1 == enet_id) { - printf("save eth1 info\n"); - memcpy(lwip_eth1_ipaddr, lwip_ipaddr, 20); - memcpy(lwip_eth1_netmask, lwip_netmask, 20); - memcpy(lwip_eth1_gwaddr, lwip_gwaddr, 20); - } - } else if (argc == 2) { - printf("lw: [%s] set eth0 ipaddr %s \n", __func__, argv[1]); - sscanf(argv[1], "%hhd.%hhd.%hhd.%hhd", &lwip_ipaddr[0], &lwip_ipaddr[1], &lwip_ipaddr[2], &lwip_ipaddr[3]); - memcpy(lwip_eth0_ipaddr, lwip_ipaddr, strlen(lwip_ipaddr)); + int eport = -1; + bool all = false; + bool is_help = false; + struct argparse_option options[] = { + OPT_HELP(&is_help), + OPT_INTEGER(LWIP_ACTIVE, "eport", &eport, "eport to start network.", NULL, 0, 0), + OPT_BIT(LWIP_ACTIVE_ALL, "all", &all, "start network at both eport 0 and 1.", NULL, true, 0), + OPT_END(), + }; + + struct argparse argparse; + argparse_init(&argparse, options, net_active_usages, 0); + argparse_describe(&argparse, usage_info, program_info); + argc = argparse_parse(&argparse, argc, (const char**)argv); + if (is_help) { + return; } - // sys_thread_new("SET ip address", LwipSetIPTask, &enet_id, LWIP_TASK_STACK_SIZE, LWIP_DEMO_TASK_PRIO); - LwipSetIPTask(&enet_id); -} + if (all) { + lwip_config_tcp(0, lwip_eth0_ipaddr, lwip_eth0_netmask, lwip_eth0_gwaddr); + lwip_config_tcp(1, lwip_eth1_ipaddr, lwip_eth1_netmask, lwip_eth1_gwaddr); + return; + } + + if (eport != 0 && eport != 1) { + printf("[%s] Err: Support only eport 0 and eport 1.\n", __func__); + } + + if (eport == 0) { + lwip_config_tcp(0, lwip_eth0_ipaddr, lwip_eth0_netmask, lwip_eth0_gwaddr); + } else if (eport == 1) { + lwip_config_tcp(1, lwip_eth1_ipaddr, lwip_eth1_netmask, lwip_eth1_gwaddr); + } +} SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_PARAM_NUM(5), - setip, LwipSetIPTest, setip[IP][Netmask][Gateway][port]); + LwipNetworkActive, LwipNetworkActive, start lwip); -void LwipShowIPTask(int argc, char* argv[]) +enum NETWORK_CONFIG_E { + NETWORK_DEV = 'd', + NETWORK_IP = 'i', + NETWORK_NM = 'n', + NETWORK_GW = 'g', +}; + +void LwipSetNetwork(int argc, char* argv[]) { -#ifdef configMAC_ADDR - char mac_addr0[] = configMAC_ADDR; -#endif + static char usage_info[] = "config network information."; + static char program_info[] = "set network ip, netmask, gateway"; + static const char* const net_set_usages[] = { + "LwipSetNetwork -d [dev] -i [ip]", + "LwipSetNetwork -d [dev] -n [netmask]", + "LwipSetNetwork -d [dev] -g [gw]", + "LwipSetNetwork -d [dev] -i [ip] -n [netmask] -g [gw]", + }; - // find default netdev - struct netdev* netdev = netdev_get_by_name("en\0"); + char* dev_ptr = NULL; + char* ip_ptr = NULL; + char* nm_ptr = NULL; + char* gw_ptr = NULL; + bool is_help = false; + struct argparse_option options[] = { + OPT_HELP(&is_help), + OPT_GROUP("Param Options"), + OPT_STRING(NETWORK_DEV, "dev", &dev_ptr, "netdev", NULL, 0, 0), + OPT_STRING(NETWORK_IP, "ip", &ip_ptr, "change ip", NULL, 0, 0), + OPT_STRING(NETWORK_NM, "nm", &nm_ptr, "change netmask", NULL, 0, 0), + OPT_STRING(NETWORK_GW, "gw", &gw_ptr, "change gateway", NULL, 0, 0), + OPT_END(), + }; + + struct argparse argparse; + argparse_init(&argparse, options, net_set_usages, 0); + argparse_describe(&argparse, usage_info, program_info); + argc = argparse_parse(&argparse, argc, (const char**)argv); + /* help task */ + if (is_help) { + return; + } + + if (dev_ptr == NULL) { + printf("[%s] Err: must given a netdev name.\n", __func__); + return; + } + struct netdev* netdev = netdev_get_by_name(dev_ptr); if (netdev == NULL) { - lw_notice("[%s] Netdev not found by name en\n"); - struct netdev* default_netdev = NETDEV_DEFAULT; + printf("[%s] Err: Netdev not found by name: %s\n", __func__, dev_ptr); + return; } - lw_notice("\r\n************************************************\r\n"); - lw_notice(" Network Configuration\r\n"); - lw_notice("************************************************\r\n"); - // lw_notice(" ETH0 IPv4 Address : %u.%u.%u.%u\r\n", ((u8_t*)&lwip_eth0_ipaddr)[0], ((u8_t*)&lwip_eth0_ipaddr)[1], - // ((u8_t*)&lwip_eth0_ipaddr)[2], ((u8_t*)&lwip_eth0_ipaddr)[3]); - // lw_notice(" ETH0 IPv4 Subnet mask : %u.%u.%u.%u\r\n", ((u8_t*)&lwip_eth0_netmask)[0], ((u8_t*)&lwip_eth0_netmask)[1], - // ((u8_t*)&lwip_eth0_netmask)[2], ((u8_t*)&lwip_eth0_netmask)[3]); - // lw_notice(" ETH0 IPv4 Gateway : %u.%u.%u.%u\r\n", ((u8_t*)&lwip_gwaddr)[0], ((u8_t*)&lwip_eth0_gwaddr)[1], - // ((u8_t*)&lwip_eth0_gwaddr)[2], ((u8_t*)&lwip_eth0_gwaddr)[3]); - // #ifdef configMAC_ADDR - // lw_notice(" ETH0 MAC Address : %x:%x:%x:%x:%x:%x\r\n", mac_addr0[0], mac_addr0[1], mac_addr0[2], - // mac_addr0[3], mac_addr0[4], mac_addr0[5]); - // #endif - - lw_notice(" ETH0 IPv4 Address : %u.%u.%u.%u\r\n", ((u8_t*)&lwip_eth0_ipaddr)[0], ((u8_t*)&lwip_eth0_ipaddr)[1], - ((u8_t*)&lwip_eth0_ipaddr)[2], ((u8_t*)&lwip_eth0_ipaddr)[3]); - lw_notice(" ETH0 IPv4 Subnet mask : %u.%u.%u.%u\r\n", ((u8_t*)&lwip_eth0_netmask)[0], ((u8_t*)&lwip_eth0_netmask)[1], - ((u8_t*)&lwip_eth0_netmask)[2], ((u8_t*)&lwip_eth0_netmask)[3]); - lw_notice(" ETH0 IPv4 Gateway : %u.%u.%u.%u\r\n", ((u8_t*)&lwip_gwaddr)[0], ((u8_t*)&lwip_eth0_gwaddr)[1], - ((u8_t*)&lwip_eth0_gwaddr)[2], ((u8_t*)&lwip_eth0_gwaddr)[3]); -#ifdef configMAC_ADDR - lw_notice(" ETH0 MAC Address : %x:%x:%x:%x:%x:%x\r\n", mac_addr0[0], mac_addr0[1], mac_addr0[2], - mac_addr0[3], mac_addr0[4], mac_addr0[5]); -#endif - -#ifdef BOARD_NET_COUNT - if (BOARD_NET_COUNT > 1) { - char mac_addr1[] = configMAC_ADDR_ETH1; - lw_notice("\r\n"); - lw_notice(" ETH1 IPv4 Address : %u.%u.%u.%u\r\n", ((u8_t*)&lwip_eth1_ipaddr)[0], ((u8_t*)&lwip_eth1_ipaddr)[1], - ((u8_t*)&lwip_eth1_ipaddr)[2], ((u8_t*)&lwip_eth1_ipaddr)[3]); - lw_notice(" ETH1 IPv4 Subnet mask : %u.%u.%u.%u\r\n", ((u8_t*)&lwip_eth1_netmask)[0], ((u8_t*)&lwip_eth1_netmask)[1], - ((u8_t*)&lwip_eth1_netmask)[2], ((u8_t*)&lwip_eth1_netmask)[3]); - lw_notice(" ETH1 IPv4 Gateway : %u.%u.%u.%u\r\n", ((u8_t*)&lwip_eth1_gwaddr)[0], ((u8_t*)&lwip_eth1_gwaddr)[1], - ((u8_t*)&lwip_eth1_gwaddr)[2], ((u8_t*)&lwip_eth1_gwaddr)[3]); - lw_notice(" ETH1 MAC Address : %x:%x:%x:%x:%x:%x\r\n", mac_addr1[0], mac_addr1[1], mac_addr1[2], - mac_addr1[3], mac_addr1[4], mac_addr1[5]); + ip_addr_t ipaddr, maskaddr, gwaddr; + if (ip_ptr != NULL) { + inet_aton(ip_ptr, &ipaddr); + if (0 != netdev_set_ipaddr(netdev, &ipaddr)) { + printf("[%s] Err: set ip: %s failed.\n", __func__, ip_ptr); + } } -#endif - lw_notice("************************************************\r\n"); + if (nm_ptr != NULL) { + inet_aton(nm_ptr, &maskaddr); + if (0 != netdev_set_netmask(netdev, &maskaddr)) { + printf("[%s] Err: set netmask: %s failed.\n", __func__, nm_ptr); + } + } + if (gw_ptr != NULL) { + inet_aton(gw_ptr, &gwaddr); + if (0 != netdev_set_gw(netdev, &gwaddr)) { + printf("[%s] Err: set gateway: %s failed.\n", __func__, gw_ptr); + } + } +} + +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_PARAM_NUM(11), + LwipSetNetwork, LwipSetNetwork, config lwip); + +void LwipShowNetwork(int argc, char* argv[]) +{ + extern void netdev_list_dev(); + netdev_list_dev(); } SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_PARAM_NUM(0), - showip, LwipShowIPTask, GetIp[IP][Netmask][Gateway]); + LwipShowNetwork, LwipShowNetwork, show lwip network configuration); diff --git a/Ubiquitous/XiZi_IIoT/resources/ethernet/netdev/netdev_lowlevel.c b/Ubiquitous/XiZi_IIoT/resources/ethernet/netdev/netdev_lowlevel.c index c1d4e0fa4..8cd2b0fde 100644 --- a/Ubiquitous/XiZi_IIoT/resources/ethernet/netdev/netdev_lowlevel.c +++ b/Ubiquitous/XiZi_IIoT/resources/ethernet/netdev/netdev_lowlevel.c @@ -43,8 +43,8 @@ void netdev_low_level_set_ipaddr(struct netdev* netdev, const ip_addr_t* ip_addr { CHECK(ip_addr); - if (netdev && ip_addr_cmp(&(netdev->ip_addr), ip_addr) == 0) { - ip_addr_copy(netdev->ip_addr, *ip_addr); + if (netdev && ip_addr_cmp((netdev->ip_addr), ip_addr) == 0) { + ip_addr_copy(*netdev->ip_addr, *ip_addr); /* execute IP address change callback function */ if (netdev->addr_callback) { @@ -64,8 +64,8 @@ void netdev_low_level_set_netmask(struct netdev* netdev, const ip_addr_t* netmas { CHECK(netmask); - if (netdev && ip_addr_cmp(&(netdev->netmask), netmask) == 0) { - ip_addr_copy(netdev->netmask, *netmask); + if (netdev && ip_addr_cmp((netdev->netmask), netmask) == 0) { + ip_addr_copy(*netdev->netmask, *netmask); /* execute netmask address change callback function */ if (netdev->addr_callback) { @@ -85,8 +85,8 @@ void netdev_low_level_set_gw(struct netdev* netdev, const ip_addr_t* gw) { CHECK(gw); - if (netdev && ip_addr_cmp(&(netdev->gw), gw) == 0) { - ip_addr_copy(netdev->gw, *gw); + if (netdev && ip_addr_cmp((netdev->gw), gw) == 0) { + ip_addr_copy(*netdev->gw, *gw); /* execute gateway address change callback function */ if (netdev->addr_callback) { diff --git a/Ubiquitous/XiZi_IIoT/resources/ethernet/netdev/netdev_manipulate.c b/Ubiquitous/XiZi_IIoT/resources/ethernet/netdev/netdev_manipulate.c index fee6adeb2..283261a1b 100644 --- a/Ubiquitous/XiZi_IIoT/resources/ethernet/netdev/netdev_manipulate.c +++ b/Ubiquitous/XiZi_IIoT/resources/ethernet/netdev/netdev_manipulate.c @@ -277,7 +277,7 @@ struct netdev* netdev_get_by_ipaddr(ip_addr_t* ip_addr) struct netdev* current_dev = NETDEV_LISTHEAD; SINGLE_LINKLIST_FOR_EACH_ENTRY(current_dev, &(NETDEV_LISTHEAD->list), list) { - if (NULL != current_dev && ip_addr_cmp(&(current_dev->ip_addr), ip_addr)) { + if (NULL != current_dev && ip_addr_cmp((current_dev->ip_addr), ip_addr)) { ENABLE_INTERRUPT(lock); return current_dev; } @@ -325,10 +325,10 @@ struct netdev* netdev_get_by_name(const char* name) return NULL; } -struct netdev* netdev_list_dev() +void netdev_list_dev() { if (NETDEV_LISTHEAD == NULL) { - return NULL; + return; } char ip[IP4ADDR_STRLEN_MAX], netmask[IP4ADDR_STRLEN_MAX], gw[IP4ADDR_STRLEN_MAX], dns[IP4ADDR_STRLEN_MAX]; @@ -342,9 +342,9 @@ struct netdev* netdev_list_dev() continue; } - strncpy(ip, inet_ntoa(current_dev->ip_addr), IP4ADDR_STRLEN_MAX); - strncpy(netmask, inet_ntoa(current_dev->netmask), IP4ADDR_STRLEN_MAX); - strncpy(gw, inet_ntoa(current_dev->gw), IP4ADDR_STRLEN_MAX); + strncpy(ip, inet_ntoa(*current_dev->ip_addr), IP4ADDR_STRLEN_MAX); + strncpy(netmask, inet_ntoa(*current_dev->netmask), IP4ADDR_STRLEN_MAX); + strncpy(gw, inet_ntoa(*current_dev->gw), IP4ADDR_STRLEN_MAX); strncpy(dns, inet_ntoa(current_dev->dns_servers[0]), IP4ADDR_STRLEN_MAX); KPrintf("Netdev %s: ip: %s, mask: %s, gw: %s, dns: %s\n", current_dev->name, @@ -352,7 +352,7 @@ struct netdev* netdev_list_dev() } ENABLE_INTERRUPT(lock); - return NULL; + return; } SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_PARAM_NUM(5), netdev_list, netdev_list_dev, list sys netdev); \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/resources/ethernet/netdev/netdev_register.c b/Ubiquitous/XiZi_IIoT/resources/ethernet/netdev/netdev_register.c index 0fa3b1bb7..e6196feb6 100644 --- a/Ubiquitous/XiZi_IIoT/resources/ethernet/netdev/netdev_register.c +++ b/Ubiquitous/XiZi_IIoT/resources/ethernet/netdev/netdev_register.c @@ -65,17 +65,13 @@ int netdev_register(struct netdev* netdev, const char* name, void* user_data) // set flag mask, assert network is down uint16_t flag_mask = 0; - flag_mask = NETDEV_FLAG_UP | NETDEV_FLAG_LINK_UP | NETDEV_FLAG_INTERNET_UP | NETDEV_FLAG_DHCP; + flag_mask = NETDEV_FLAG_UP | NETDEV_FLAG_LINK_UP | NETDEV_FLAG_INTERNET_UP; netdev->flags &= ~flag_mask; // clear dev setting - ip_addr_set_zero(&(netdev->ip_addr)); - ip_addr_set_zero(&(netdev->netmask)); - ip_addr_set_zero(&(netdev->gw)); - - IP_SET_TYPE_VAL(netdev->ip_addr, IPADDR_TYPE_V4); - IP_SET_TYPE_VAL(netdev->netmask, IPADDR_TYPE_V4); - IP_SET_TYPE_VAL(netdev->gw, IPADDR_TYPE_V4); + netdev->ip_addr = NULL; + netdev->netmask = NULL; + netdev->gw = NULL; #if NETDEV_IPV6 for (index = 0; index < NETDEV_IPV6_NUM_ADDRESSES; index++) { @@ -87,7 +83,6 @@ int netdev_register(struct netdev* netdev, const char* name, void* user_data) // clear DNS servers for (uint16_t idx = 0; idx < NETDEV_DNS_SERVERS_NUM; idx++) { ip_addr_set_zero(&(netdev->dns_servers[idx])); - IP_SET_TYPE_VAL(netdev->ip_addr, IPADDR_TYPE_V4); } // clear callback fn netdev->addr_callback = NULL; diff --git a/Ubiquitous/XiZi_IIoT/resources/include/netdev/netdev.h b/Ubiquitous/XiZi_IIoT/resources/include/netdev/netdev.h index e3007fd9e..468a1a68e 100644 --- a/Ubiquitous/XiZi_IIoT/resources/include/netdev/netdev.h +++ b/Ubiquitous/XiZi_IIoT/resources/include/netdev/netdev.h @@ -93,9 +93,9 @@ struct netdev { SysSingleLinklistType list; char name[NAME_NUM_MAX]; /* network interface device name */ - ip_addr_t ip_addr; /* IP address */ - ip_addr_t netmask; /* subnet mask */ - ip_addr_t gw; /* gateway */ + ip_addr_t* ip_addr; /* IP address */ + ip_addr_t* netmask; /* subnet mask */ + ip_addr_t* gw; /* gateway */ #if NETDEV_IPV6 ip_addr_t ip6_addr[NETDEV_IPV6_NUM_ADDRESSES]; /* array of IPv6 addresses */ #endif /* NETDEV_IPV6 */