Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b1c2ffe1a0 | ||
|
|
9210a762de | ||
|
|
1620110f50 | ||
|
|
0d882f1b43 | ||
|
|
1bb85799ce | ||
|
|
12207edd55 | ||
|
|
bb37f72a63 | ||
|
|
b852e0f8c3 | ||
|
|
25dc078af7 | ||
|
|
06f525713f | ||
|
|
05ade0ba3c | ||
|
|
ec91eaf0f3 | ||
|
|
8392b9407a | ||
|
|
60fe567845 | ||
|
|
02e83c77a4 | ||
|
|
538a1a9bfa | ||
|
|
862fbd0abc | ||
|
|
2121be1abe | ||
|
|
0c794f19d2 | ||
|
|
44ef3b43d2 | ||
|
|
d27e7b3e7e | ||
|
|
f0d1800c6b | ||
|
|
81b61d335f | ||
|
|
70f14336f1 | ||
|
|
19ea5aba43 | ||
|
|
2a7fa4cb68 | ||
|
|
3d094ec921 | ||
|
|
abe19d2367 | ||
|
|
2b408e85e9 | ||
|
|
27897d5514 | ||
|
|
dfcfdfd0f7 | ||
|
|
ec032181c6 | ||
|
|
1cc6a48eea | ||
|
|
17b4054ea5 | ||
|
|
0ec11128f7 | ||
|
|
ed0423f79d | ||
|
|
ba69eb248c | ||
|
|
eefec28b50 | ||
|
|
564c352d0c | ||
|
|
d20eb8b280 | ||
|
|
cc617d537d | ||
|
|
205d4c6832 | ||
|
|
18cea946f1 | ||
|
|
0884338b2a | ||
|
|
ba768693ed | ||
|
|
3170261876 | ||
|
|
2d7e8aa712 | ||
|
|
c083f204fc | ||
|
|
e83e13d8c6 | ||
|
|
70d268d95f | ||
|
|
71f5556de7 | ||
|
|
8c64266f95 | ||
|
|
124b4e93c7 | ||
|
|
e01eeed303 | ||
|
|
4b3cfb4bc0 | ||
|
|
e5dfbec36d | ||
|
|
be1587a933 | ||
|
|
3e87f18a29 | ||
|
|
2214cf66a4 | ||
|
|
7b886ccbde | ||
|
|
b69b288d6c | ||
|
|
37fe251d31 | ||
|
|
5ec7ec141a | ||
|
|
e31079e107 | ||
|
|
1701fb0d03 | ||
|
|
f2ce01641e | ||
|
|
b5e4eef966 | ||
|
|
b93822fc50 | ||
|
|
715f98c546 | ||
|
|
b1878dc9d0 | ||
|
|
fe8cf7d9d6 | ||
|
|
5fa6b0a6ef | ||
|
|
d3ab638e5d | ||
|
|
44e773af54 | ||
|
|
ece3f43f34 | ||
|
|
edd1350864 | ||
|
|
8e0ef3ca5c | ||
|
|
b74913ded5 | ||
|
|
42abbb7e55 | ||
|
|
a4869febf6 | ||
|
|
b10355a536 | ||
|
|
e86d4da129 | ||
|
|
46ad050cea | ||
|
|
2a7cf8d5a7 | ||
|
|
07fd086230 | ||
|
|
f040d094ea | ||
|
|
f101d1422a | ||
|
|
6631c5db87 | ||
|
|
c429a0dc56 | ||
|
|
3f59974639 | ||
|
|
c10a88b64b | ||
|
|
d5e5b3397d | ||
|
|
ab83acf2d1 | ||
|
|
1db25117b0 | ||
|
|
bd1271dd41 | ||
|
|
5dddbb3fce | ||
|
|
a28decbef4 | ||
|
|
73d9c125c0 | ||
|
|
667abfb5e1 | ||
|
|
8c65c2f9af | ||
|
|
f36205e65f | ||
|
|
e2c0b2b477 | ||
|
|
29254ce84b | ||
|
|
1a0716ae4d | ||
|
|
e46ee68a95 | ||
|
|
db496fd7dd | ||
|
|
0a3e129527 | ||
|
|
12491777bb | ||
|
|
ad4b87e24a | ||
|
|
7ffc51d38e | ||
|
|
c9243c3f47 | ||
|
|
0d6c424e62 | ||
|
|
dc9395c904 | ||
|
|
2bb750070a | ||
|
|
17b0b65cab | ||
|
|
b5b63e731c | ||
|
|
7e376bb860 | ||
|
|
b313d697ff | ||
|
|
1cadd2b2aa | ||
|
|
f40b377fff | ||
|
|
43509c1781 | ||
|
|
209d1dd426 | ||
|
|
1f9e1a38b5 | ||
|
|
69936ac9f6 | ||
|
|
6de419d14c | ||
|
|
1200f50e2e | ||
|
|
73bec74380 | ||
|
|
f70647e28e | ||
|
|
effa61f9b2 | ||
|
|
b8bde63554 | ||
|
|
409d3d388a | ||
|
|
2c4bf4cea4 | ||
|
|
1b9c3a0fb0 | ||
|
|
71cc0cfd80 | ||
|
|
63da5aa403 | ||
|
|
cb13900c32 | ||
|
|
926a0e2cf2 | ||
|
|
2bfcfeb359 | ||
|
|
16d8e3b4f9 | ||
|
|
682fe2c9a0 | ||
|
|
bdd309b10b | ||
|
|
21fbf9cdc5 | ||
|
|
9ed98cecff | ||
|
|
ab4e229f57 | ||
|
|
7feab86700 | ||
|
|
6bc0af5dd0 | ||
|
|
6cb685b700 | ||
|
|
5c582c35d8 | ||
|
|
10ab9ae1ea | ||
|
|
756d127cab | ||
|
|
a49eb47a91 | ||
|
|
e15056a9e4 | ||
|
|
66d4069644 | ||
|
|
9aae863956 | ||
|
|
878ec8a86c | ||
|
|
8fccfca17b | ||
|
|
69925c774d | ||
|
|
c1298973e1 | ||
|
|
bedda34515 | ||
|
|
767b0ab90b | ||
|
|
b0109c3319 | ||
|
|
a42271a088 | ||
|
|
154e471256 | ||
|
|
bfc411acaf | ||
|
|
2acbb0ad62 | ||
|
|
60ce504489 | ||
|
|
22b8eda0df | ||
|
|
80ed81583e | ||
|
|
ce0c3a0fe7 | ||
|
|
492c6385da | ||
|
|
5b023cb85b | ||
|
|
4717a15c17 | ||
|
|
d6e7f8ee83 | ||
|
|
17ff656a7d | ||
|
|
4e8965cce5 | ||
|
|
b3d27a3c43 | ||
|
|
66dcca9392 | ||
|
|
0f1a3cf84b | ||
|
|
a4b7025396 | ||
|
|
9c148fd47e | ||
|
|
293d8c22e1 | ||
|
|
5f2ff680d5 | ||
|
|
8eaca9437e | ||
|
|
6e72bf4b5f | ||
|
|
710e7b2004 | ||
|
|
666a3b68e9 | ||
|
|
02e97adbef | ||
|
|
236724ea29 | ||
|
|
b503915ca5 | ||
|
|
156db0bc5e | ||
|
|
11b6bd7d9c | ||
|
|
7ca952faa6 | ||
|
|
4fc40f0ffb | ||
|
|
cac4b3e254 | ||
|
|
0d5cb5cbcc | ||
|
|
a35901121b | ||
|
|
e0740fc2ca | ||
|
|
7d22b5fe18 | ||
|
|
d2e66ac58d | ||
|
|
34cc8da87e | ||
|
|
1957ba8ffe | ||
|
|
72758812f5 | ||
|
|
ab5a0c43de | ||
|
|
c8291e4ae9 | ||
|
|
84e9ea76db | ||
|
|
b8994f8bc3 | ||
|
|
b53d8439e5 | ||
|
|
337e8abf2f | ||
|
|
f0bc1c031f | ||
|
|
19d2b93ec7 | ||
|
|
e0304f2b8f | ||
|
|
f7a86f8cf1 | ||
|
|
340f0dbf89 | ||
|
|
d90b62d911 | ||
|
|
d84aff6420 | ||
|
|
b3b73f4751 | ||
|
|
3c7b2dcd6d | ||
|
|
49470f9bd2 | ||
|
|
f7cf4f60ef | ||
|
|
7e0d06689e | ||
|
|
b843957bd2 | ||
|
|
1a0167eb6d | ||
|
|
6ea3b98941 | ||
|
|
4b0b93d4f3 | ||
|
|
64abf061bf | ||
|
|
05d5c68982 | ||
|
|
235dafe646 | ||
|
|
0cc40b0c70 | ||
|
|
07a0d1265b | ||
|
|
967d746574 | ||
|
|
bd12cb1b87 | ||
|
|
a21ca5d40b | ||
|
|
2d399107fb | ||
|
|
03bfa3806b | ||
|
|
6536ae9bcc | ||
|
|
e8fc817a0c | ||
|
|
e621ade392 | ||
|
|
3273c20ca9 | ||
|
|
a6b2124fd5 | ||
|
|
5a1ff125d7 | ||
|
|
ad58a48144 | ||
|
|
a205fd7877 | ||
|
|
776360ca93 | ||
|
|
af7602497d | ||
|
|
0f83c2a6e5 | ||
|
|
0d58748e63 | ||
|
|
01902bb8b9 | ||
|
|
e28e9aa1d7 | ||
|
|
587e79dc05 | ||
|
|
acd65f2340 | ||
|
|
d55fb80746 | ||
|
|
4536694f20 | ||
|
|
2c5a6d4df6 | ||
|
|
4c8e219643 | ||
|
|
daeca8128b | ||
|
|
fe6d357858 | ||
|
|
a99cc3dbaf | ||
|
|
3c4c04199a | ||
|
|
8ca692100f | ||
|
|
0b9f28b8e3 | ||
|
|
1dff394b63 | ||
|
|
f4c35d1036 | ||
|
|
81c166ad74 | ||
|
|
1f56776050 | ||
|
|
b3a0e7b884 | ||
|
|
8594507b5b | ||
|
|
fa811ce12b | ||
|
|
c1ef477ff3 | ||
|
|
4be3a96987 | ||
|
|
387f875aa1 | ||
|
|
cc069e7e5d | ||
|
|
df994df611 | ||
|
|
8f77fd3940 | ||
|
|
7530062e4b | ||
|
|
0e63510708 | ||
|
|
26260a1d88 | ||
|
|
9e82844f10 | ||
|
|
0568b5a75b | ||
|
|
3baabebb34 | ||
|
|
bf4dd15317 | ||
|
|
b0f2f9621a | ||
|
|
04d6d05e9e | ||
|
|
7339c7dfe7 | ||
|
|
c1152f5eeb | ||
|
|
024922d566 | ||
|
|
6f64c8c0de | ||
|
|
2a5ac3c2e5 | ||
|
|
7b0120f0c2 | ||
|
|
7ee1f14a6d | ||
|
|
3aaf7d0da7 | ||
|
|
434f3f8415 | ||
|
|
739d78a45a | ||
|
|
8a62633b2f | ||
|
|
aae1a687a9 | ||
|
|
61285ec418 | ||
|
|
a00b3f1c6c | ||
|
|
2c813f3e72 | ||
|
|
ea68d7a705 | ||
|
|
654f401038 | ||
|
|
ad89122a06 | ||
|
|
73ed158e76 | ||
|
|
548c3dc77f | ||
|
|
c1fa067a1f | ||
|
|
9fd87060f9 | ||
|
|
de0a3b035a | ||
|
|
9f76ea8030 | ||
|
|
76b7356873 | ||
|
|
c24d5aabd8 | ||
|
|
0df6645b90 | ||
|
|
b19cf8654f | ||
|
|
19933a4673 | ||
|
|
76963f7d01 | ||
|
|
e670ea3d61 | ||
|
|
fa33b57e4f | ||
|
|
77e369bc79 | ||
|
|
94ad9767d3 | ||
|
|
aa76f5673b | ||
|
|
81a699c801 | ||
|
|
bd15c456b2 | ||
|
|
10d9e1e9ae | ||
|
|
6a3813f633 | ||
|
|
51fe22a95f | ||
|
|
105762416f | ||
|
|
db7087f455 | ||
|
|
c5693503cb | ||
|
|
b74590a4a5 | ||
|
|
d5eeed48eb | ||
|
|
fc5c0d0964 | ||
|
|
aa2647c0bc | ||
|
|
cef0acdb40 | ||
|
|
2140656acc | ||
|
|
fd0c969f16 | ||
|
|
dfeb929e0e | ||
|
|
d3e67733a6 | ||
|
|
eff74fdc9d | ||
|
|
5e4c40ad09 | ||
|
|
087e6d3142 | ||
|
|
587b074822 | ||
|
|
6aa8c01ac7 | ||
|
|
3bbcd5df3e | ||
|
|
af512c57ef | ||
|
|
58297a7871 | ||
|
|
18a530048c | ||
|
|
f9ed75d6b3 | ||
|
|
3c1f41e575 | ||
|
|
c772936dd1 | ||
|
|
253696be45 | ||
|
|
79b7accc55 | ||
|
|
7a1e846c73 | ||
|
|
ce59ff89c3 | ||
|
|
d31d064d5e | ||
|
|
467fbf4bb4 | ||
|
|
6769223ce1 | ||
|
|
294e483885 | ||
|
|
43513e2d56 | ||
|
|
d1b7687e98 | ||
|
|
9ac09da1d2 | ||
|
|
24a330c750 | ||
|
|
13a9c773f2 | ||
|
|
3cd166d065 | ||
|
|
490066fd17 | ||
|
|
94fce72ade | ||
|
|
eacc64bdd1 | ||
|
|
7b037f4957 | ||
|
|
fa841916c1 | ||
|
|
75c11436ff | ||
|
|
e07a8283ec | ||
|
|
2a174b0d3b | ||
|
|
013993abae | ||
|
|
dccc153c68 | ||
|
|
db0867f435 | ||
|
|
7234121835 | ||
|
|
3aafc073d8 | ||
|
|
b527ed313c | ||
|
|
cd86559685 | ||
|
|
f67e843be6 | ||
|
|
4f9ebd8092 | ||
|
|
6c044d6aeb | ||
|
|
c6ee909aa4 | ||
|
|
393063428e | ||
|
|
1494f5e831 | ||
|
|
8bfd0c2ca3 | ||
|
|
e9de2f3eb1 | ||
|
|
8bf9d09d96 | ||
|
|
67255ce8f5 | ||
|
|
5db89aa264 | ||
|
|
8a9b1d9873 | ||
|
|
c08c1afb1e | ||
|
|
2c7f58aed2 | ||
|
|
b3ee71acbe | ||
|
|
52ab6bc499 | ||
|
|
bf059ad42f | ||
|
|
85df6a6131 | ||
|
|
d840b4a4ee | ||
|
|
a8c2ce544e | ||
|
|
b95022a3b3 | ||
|
|
8c45a9d2c9 | ||
|
|
0fe64fbff9 | ||
|
|
64e806628b | ||
|
|
ccd2b2699f | ||
|
|
0b5c0c9889 | ||
|
|
6293e7dbec | ||
|
|
87325ece82 | ||
|
|
6cbd9b3067 | ||
|
|
aa27fde9d0 | ||
|
|
e854585802 | ||
|
|
2c5aba24cc | ||
|
|
806ee0f2cb | ||
|
|
e72b95fb1c | ||
|
|
471e7ff61a | ||
|
|
3d2de154d1 | ||
|
|
fc551ec2e9 | ||
|
|
f5e2c68c8b | ||
|
|
074ef5197b | ||
|
|
5f1f4a0df8 | ||
|
|
86334e9040 | ||
|
|
f71cc3ebc3 | ||
|
|
00910462e7 | ||
|
|
2fc56dd1d0 | ||
|
|
a5ebe71394 | ||
|
|
0eb8bf6b51 | ||
|
|
3a0fe5288c | ||
|
|
bfca233160 | ||
|
|
acf217601b | ||
|
|
b0d0fbfd9f | ||
|
|
9411f1c7b6 | ||
|
|
d7d7ebf99a | ||
|
|
8072ae2057 | ||
|
|
e529e644ab | ||
|
|
d6fdfe5b1b | ||
|
|
50e15e574f | ||
|
|
58f1533779 | ||
|
|
f4a49829ea | ||
|
|
3efe6641eb | ||
|
|
0459d9e106 | ||
|
|
305d69ee36 | ||
|
|
98e744a9ad | ||
|
|
1d97f2e2b5 | ||
|
|
c92bc4b4ac | ||
|
|
6a3e1e41c4 | ||
|
|
650caface3 | ||
|
|
8b6e02e985 | ||
|
|
3ee6fe45f9 | ||
|
|
e811afd397 | ||
|
|
b197a674e1 | ||
|
|
08f6b99b13 | ||
|
|
b18d0301f3 | ||
|
|
5596621420 | ||
|
|
bd8a66eee7 | ||
|
|
b62ebb3c10 | ||
|
|
45d796fe5b | ||
|
|
d8a3b90cad | ||
|
|
5be9e55425 | ||
|
|
6b6acd3967 | ||
|
|
1b06403a19 | ||
|
|
b740c80855 | ||
|
|
29594283c1 | ||
|
|
51f54f9b7e | ||
|
|
1f48b1ca65 | ||
|
|
fd2d7cccf3 | ||
|
|
5726e680ec | ||
|
|
fadf28adb4 | ||
|
|
a321c2d096 | ||
|
|
bbb07bf6f7 | ||
|
|
a801160bc0 | ||
|
|
662cc27f4f | ||
|
|
ccfe7e0724 | ||
|
|
8061a41b38 | ||
|
|
d01aa01a51 | ||
|
|
39392b3690 | ||
|
|
54d4611eb6 | ||
|
|
34cdce750d | ||
|
|
f3fafb6759 | ||
|
|
0372c97ff5 | ||
|
|
b46136a0af | ||
|
|
ac3d41fb79 | ||
|
|
14be42c868 | ||
|
|
f0ec14543a | ||
|
|
f46c5b7214 | ||
|
|
ccd6bcd95f | ||
|
|
a3b63f3b0d | ||
|
|
f2905a5e10 | ||
|
|
1ef6c6aeb5 | ||
|
|
bd53529b45 | ||
|
|
cc8ecc5a42 | ||
|
|
5a816a1d41 | ||
|
|
9922286c67 | ||
|
|
cdc439bc38 | ||
|
|
ae8422e304 | ||
|
|
539d080346 | ||
|
|
041ec6e1f8 | ||
|
|
f618fe125c | ||
|
|
8ab514fabc | ||
|
|
08ad2c3145 | ||
|
|
c64fd404d4 | ||
|
|
143b0ac126 | ||
|
|
c2e2432010 | ||
|
|
1d2a768184 | ||
|
|
fb099641bc | ||
|
|
6da9afbf29 | ||
|
|
dceb4beb09 | ||
|
|
6f697db49d | ||
|
|
b44193780e | ||
|
|
8e0212c3db | ||
|
|
3861e2e1e7 | ||
|
|
21eefa4b55 | ||
|
|
fb6c6aafeb | ||
|
|
df07426e78 | ||
|
|
5cf1523a13 | ||
|
|
f2fe47e9f7 | ||
|
|
2557ab2e60 | ||
|
|
fbc1708000 | ||
|
|
0539cf1023 | ||
|
|
07b410447b | ||
|
|
fb69016196 | ||
|
|
169cbc044f | ||
|
|
08091d02e5 | ||
|
|
6f2dcf92a7 | ||
|
|
578e52618d | ||
|
|
ec0fe66a17 | ||
|
|
8fee24291a | ||
|
|
05bba2958d | ||
|
|
e656b1c792 | ||
|
|
e0ccbadd25 | ||
|
|
40a2a8822f | ||
|
|
e2ee356a87 | ||
|
|
189bef61d3 | ||
|
|
7d94f9f61b | ||
|
|
e37a0b9056 | ||
|
|
0b57b23951 | ||
|
|
c84826e84e | ||
|
|
064fc6ff7b | ||
|
|
042ea53478 | ||
|
|
900b0acf7a | ||
|
|
dc5f2e295a | ||
|
|
c1849c2b19 | ||
|
|
4eadf3699f | ||
|
|
b30cf6587c | ||
|
|
fbc231f33e | ||
|
|
bc8c839342 | ||
|
|
90a23fe230 | ||
|
|
065027843e | ||
|
|
8906b1ac0f | ||
|
|
05f9e61a41 | ||
|
|
782896b5d3 | ||
|
|
4258f62560 | ||
|
|
537ba64a54 | ||
|
|
25d20b7354 | ||
|
|
04d8362905 | ||
|
|
21266e9a45 | ||
|
|
7304e2171d | ||
|
|
61fc480850 | ||
|
|
562e82f5ac | ||
|
|
d7ff85bb48 | ||
|
|
55bc6105e1 | ||
|
|
306c0b6096 | ||
|
|
024078ae33 | ||
|
|
b5a9ba8390 | ||
|
|
93f36927ca | ||
|
|
1db90cafd1 | ||
|
|
bf23a0def7 | ||
|
|
ea1cbeea9d | ||
|
|
aeda7e5520 | ||
|
|
a7899af8b8 | ||
|
|
b0385f47af | ||
|
|
86c384657c | ||
|
|
6e569110d2 | ||
|
|
3b1024b13c | ||
|
|
b3f5d11275 | ||
|
|
1078ba0a92 | ||
|
|
005c8170d4 | ||
|
|
b8d1d7a10b | ||
|
|
76769fb4d5 | ||
|
|
6ff6f0a4c6 | ||
|
|
72a45d2f6a | ||
|
|
2fe7c8a410 | ||
|
|
5269eb9c39 | ||
|
|
0a86bc0af2 | ||
|
|
bc9f6ba0b0 | ||
|
|
9e16a0ae42 | ||
|
|
9ccbb49aef | ||
|
|
d59f84fbbc | ||
|
|
4bbb5008b1 | ||
|
|
49ce25511e | ||
|
|
985276665d | ||
|
|
91f553c45f | ||
|
|
38ede8ec58 | ||
|
|
997f6543ce | ||
|
|
b50081a83b | ||
|
|
34f512d244 | ||
|
|
eb5752f41b | ||
|
|
ef8e7419fa | ||
|
|
cfcdd15b89 | ||
|
|
b26debaebc | ||
|
|
6deb061b12 | ||
|
|
4c6745670c | ||
|
|
01c662b7de | ||
|
|
179fe652c2 | ||
|
|
394bc3260d | ||
|
|
ce1a70e2dc | ||
|
|
99022896f6 | ||
|
|
446b400667 | ||
|
|
a0d9b6a7e0 | ||
|
|
7d53c21efe | ||
|
|
b78efbac36 | ||
|
|
9be9dcec46 | ||
|
|
3766ab802b | ||
|
|
b9141925a3 | ||
|
|
ed79fe86aa | ||
|
|
2f0b0955a9 | ||
|
|
2f8e15a900 | ||
|
|
b8b3a5c305 | ||
|
|
e7ea421c54 | ||
|
|
8de9699390 | ||
|
|
bf592a22ae | ||
|
|
8d4a619a15 | ||
|
|
1a3588624d | ||
|
|
74b3fd2efc | ||
|
|
091356ed59 | ||
|
|
fc0e1ee311 | ||
|
|
8dbfcbff58 | ||
|
|
317591bc8a | ||
|
|
f71b3b91c0 | ||
|
|
9e255bcbce | ||
|
|
8af319b953 | ||
|
|
f90fd9cec4 | ||
|
|
d386b1c12d | ||
|
|
81551ec50d | ||
|
|
8fafcf6eaa | ||
|
|
f0df6c61c9 | ||
|
|
6cf36b5771 | ||
|
|
54799187e9 | ||
|
|
6d0320be06 | ||
|
|
317a1527ad | ||
|
|
490eb0f57f | ||
|
|
f95283e341 | ||
|
|
837da0e458 | ||
|
|
8ce82a100e | ||
|
|
9ece98c101 | ||
|
|
6a83147b33 | ||
|
|
90e4228e1d | ||
|
|
553aeeef77 | ||
|
|
6147e865f8 | ||
|
|
7b296fabb0 | ||
|
|
00c8f8acd0 | ||
|
|
1e1efa2c5e | ||
|
|
b0b0dd9f0b | ||
|
|
30bb1c52d0 | ||
|
|
7fc96a61ad | ||
|
|
4a164c39b4 | ||
|
|
b0e4069bb7 | ||
|
|
19cbb27b4c | ||
|
|
d44c864387 | ||
|
|
36e21e53e0 | ||
|
|
b7598cc354 | ||
|
|
0a4f322d49 | ||
|
|
bf013fcdae | ||
|
|
fd52fccc15 | ||
|
|
c493d3a4ce | ||
|
|
aeceb2b9e7 | ||
|
|
cb5f833dd2 | ||
|
|
0740ccd9f7 | ||
|
|
716c84c896 | ||
|
|
c5fda07d1e | ||
|
|
7fffe0abaa | ||
|
|
8a42325c23 | ||
|
|
78900304bf | ||
|
|
fb6dfbcd3c | ||
|
|
3dd4c7da2a | ||
|
|
03c955410c | ||
|
|
74f77c9ded | ||
|
|
3caca03e8a | ||
|
|
49469840ab | ||
|
|
85613ab02d | ||
|
|
6e4ce85c87 | ||
|
|
2a093dc183 | ||
|
|
01eeadbaf4 | ||
|
|
851b3a7cfb | ||
|
|
b6dc830bcb | ||
|
|
8ef02aae41 | ||
|
|
423dbd58a1 | ||
|
|
5582db615a | ||
|
|
1479ebfb5d | ||
|
|
4389ef1e77 | ||
|
|
5c305e7fa8 | ||
|
|
0427908eae | ||
|
|
2df53c3d27 | ||
|
|
53ec9adb1b | ||
|
|
8b95a22e75 | ||
|
|
665298a04b | ||
|
|
7e668df1fe | ||
|
|
85414cfec2 | ||
|
|
b973187960 | ||
|
|
991080e613 | ||
|
|
72bf199577 | ||
|
|
7bda43a6ec | ||
|
|
2b8b0ebe95 | ||
|
|
0aa61ce58f | ||
|
|
51a5dc78d7 | ||
|
|
232bd9a22b | ||
|
|
58327a1753 | ||
|
|
7844d84798 | ||
|
|
7a30a42797 | ||
|
|
094202ff16 | ||
|
|
9c4523f4fa | ||
|
|
69859c61e0 | ||
|
|
9878518e29 | ||
|
|
cde270728f | ||
|
|
5559d0fa68 | ||
|
|
8feff78526 | ||
|
|
226a3de55d | ||
|
|
67d0f5f4ae | ||
|
|
192f5e563c | ||
|
|
b6296e7a67 | ||
|
|
67e17d3bc3 | ||
|
|
64a6fef823 | ||
|
|
e0c64cc4ff | ||
|
|
3e55478b3b | ||
|
|
9aef821862 | ||
|
|
f394df840e | ||
|
|
7d33699173 | ||
|
|
d3ffe8c647 | ||
|
|
9b99f62311 | ||
|
|
3319ce78d3 | ||
|
|
8eabf43525 | ||
|
|
adb12bb7be | ||
|
|
3c10b36651 | ||
|
|
d37c300d87 | ||
|
|
9fc92e901e | ||
|
|
5b52529295 | ||
|
|
f77a7ad623 | ||
|
|
504ef9422e | ||
|
|
cbbcec0895 | ||
|
|
32d90c38db | ||
|
|
e1f7f3d7bb | ||
|
|
244536ea72 | ||
|
|
fa24a3e09e | ||
|
|
5ec26a5015 | ||
|
|
8a8ff2aef0 | ||
|
|
069254be6a | ||
|
|
f3cd74cb46 | ||
|
|
4be8aa0f91 | ||
|
|
93dd7a85f6 | ||
|
|
062596e3fb | ||
|
|
5af2de635e | ||
|
|
a16df91fbb | ||
|
|
44178b9103 | ||
|
|
b767f930ad | ||
|
|
ba61a6545a | ||
|
|
23ada5c7a5 | ||
|
|
97c37efffe | ||
|
|
5db95be4fc | ||
|
|
5897422c70 | ||
|
|
a7db0d3cc5 | ||
|
|
c49036a713 | ||
|
|
03246997fa | ||
|
|
f4eac6e4fc | ||
|
|
48f695f3e6 | ||
|
|
3525f044f5 | ||
|
|
b58f8b9d7c | ||
|
|
c00962e881 | ||
|
|
9bcf1d662b | ||
|
|
586e0721d8 | ||
|
|
882dd1f3a7 | ||
|
|
399291d783 | ||
|
|
46ac2e5252 | ||
|
|
a81818b2db | ||
|
|
9b0d112176 | ||
|
|
ac17df0c65 | ||
|
|
c4be4e7928 | ||
|
|
877cbbd11d | ||
|
|
b2bb03310e | ||
|
|
5c8885ee5f | ||
|
|
40ec6b263d | ||
|
|
3742da8770 | ||
|
|
19b06418c5 | ||
|
|
b7b8b9219d | ||
|
|
949966964f | ||
|
|
c0a0f9c1df | ||
|
|
7cff2fa8f1 | ||
|
|
c1b703a039 | ||
|
|
e0eff1d2bb | ||
|
|
037ef76ad8 | ||
|
|
ae8025cd5c | ||
|
|
1804cc3a09 | ||
|
|
2d8e6b45ec | ||
|
|
3fa52d0d7d | ||
|
|
6a7129d7af | ||
|
|
f0e113a532 | ||
|
|
8b3e415201 | ||
|
|
eb6a8afe8d | ||
|
|
a705a89e4a | ||
|
|
ea509c0a36 | ||
|
|
269600d875 | ||
|
|
95e3a8f3cc | ||
|
|
ffeff3ab69 | ||
|
|
bdc009eb65 | ||
|
|
683f65f8ac | ||
|
|
a737698372 | ||
|
|
eeecbbcff9 | ||
|
|
44b3d60692 | ||
|
|
641c7d1967 | ||
|
|
7923d1e930 | ||
|
|
42e072a868 | ||
|
|
97296934ab | ||
|
|
83dbe5fa3e | ||
|
|
b566b8b45a | ||
|
|
ecdfda56c2 | ||
|
|
166c4a244a | ||
|
|
be7bfbac39 | ||
|
|
3c8953672d | ||
|
|
045b196eeb | ||
|
|
d763fce8ed | ||
|
|
15c8ba5d3f | ||
|
|
1b75017c3c | ||
|
|
3ffe5e958f | ||
|
|
4f6a78cde8 | ||
|
|
3081d0766b | ||
|
|
c1e34cb9b5 | ||
|
|
dedf67fb52 | ||
|
|
a74fb940aa | ||
|
|
09275ae4ca | ||
|
|
657717d0fb | ||
|
|
4493d35d26 | ||
|
|
0d26ce9bcc | ||
|
|
fe77075996 | ||
|
|
4d6b126b9d | ||
|
|
7b1900d547 | ||
|
|
5a8c56e784 | ||
|
|
8c4cfc8101 | ||
|
|
5f1f5ffffd | ||
|
|
603c4b7672 | ||
|
|
4b49c63344 | ||
|
|
9bdc910327 | ||
|
|
730f50f770 | ||
|
|
91606a9e3f | ||
|
|
22b52f831b | ||
|
|
071b3f558f | ||
|
|
59cd4004ac | ||
|
|
7f7c1ff6c2 | ||
|
|
ad3acf355e | ||
|
|
4dcc4e3308 | ||
|
|
a9902b55d8 | ||
|
|
d46798c2a7 | ||
|
|
90623492b7 | ||
|
|
ddf3ba8a15 | ||
|
|
0c4d33d558 | ||
|
|
1c3b6ad59b | ||
|
|
473a12d700 | ||
|
|
774cfc4bdc | ||
|
|
509fbcc4f8 | ||
|
|
00862344f7 | ||
|
|
5ad2b0531a | ||
|
|
be8dbb0dc7 | ||
|
|
bdfa0b302b | ||
|
|
7541304a9a | ||
|
|
395a51eeca | ||
|
|
17e2d49c43 | ||
|
|
ac71c320cd | ||
|
|
0356bf6092 | ||
|
|
8bc1edd027 | ||
|
|
403f0dc8a5 | ||
|
|
dffa198ebd | ||
|
|
7028417d88 | ||
|
|
2d4ebba3ed | ||
|
|
aa3fda9c33 | ||
|
|
0f9f0b545e | ||
|
|
9fcc398540 | ||
|
|
61f4ab61cb | ||
|
|
1f481cbe54 | ||
|
|
f4ee10a96a | ||
|
|
9974be3fdc | ||
|
|
793171e9e0 | ||
|
|
cee7087d54 | ||
|
|
f9bcffcbd5 | ||
|
|
8fd7e87333 | ||
|
|
c436194d43 | ||
|
|
fcd160cc8c | ||
|
|
5adbadc901 | ||
|
|
5084279d81 | ||
|
|
bd21d0d0cf | ||
|
|
a3fd81540a | ||
|
|
ba3f6a5e76 | ||
|
|
25c56e86c9 | ||
|
|
0897b0969d | ||
|
|
6cb1c3c0e9 | ||
|
|
df257a8e8a | ||
|
|
71abdc1bda | ||
|
|
22de1dc0f2 | ||
|
|
6357b30712 | ||
|
|
b0e18d5e8a | ||
|
|
be58d73a0a | ||
|
|
c1f630f5ed | ||
|
|
ab75bfa6e7 | ||
|
|
a4e0225c69 | ||
|
|
6d3d6c3601 | ||
|
|
2872de75a0 | ||
|
|
70936e3738 | ||
|
|
c272883ec1 | ||
|
|
d9619a8fa4 | ||
|
|
9ec2022447 | ||
|
|
10f56c55e6 | ||
|
|
69682d6d97 | ||
|
|
b61575eb2b | ||
|
|
6942de4f57 | ||
|
|
8085e21a05 | ||
|
|
0061fe02e6 | ||
|
|
6bb40e6ec9 | ||
|
|
94efcc83a1 | ||
|
|
03402cf359 | ||
|
|
a473cf99b5 | ||
|
|
c26bd2ffe8 | ||
|
|
9dc3d09981 | ||
|
|
76b4c9a6ff | ||
|
|
41add69294 | ||
|
|
c911c9ad19 | ||
|
|
dd883c0563 | ||
|
|
16a0c89d5f | ||
|
|
ac0e6f3377 | ||
|
|
68f7be7a1a | ||
|
|
b796e33ede | ||
|
|
1051ba77c0 | ||
|
|
cb5b6b972a | ||
|
|
925f21aca4 | ||
|
|
dc09851ac8 | ||
|
|
323ba9d90c | ||
|
|
c6ff8ab6dc | ||
|
|
b5443f10c5 | ||
|
|
3ae1a0f82a | ||
|
|
81f0f8a7c2 | ||
|
|
50963df42f | ||
|
|
b316989378 | ||
|
|
23c68e2677 | ||
|
|
b46bee0540 | ||
|
|
4c6c27d8f6 | ||
|
|
3c531897b6 | ||
|
|
6c7672f4af | ||
|
|
2def6e867d | ||
|
|
573f13c1ed | ||
|
|
b7f9e5c947 | ||
|
|
da85affe5c | ||
|
|
3168a2aca0 | ||
|
|
1f5feaa103 | ||
|
|
4be3dfd52b | ||
|
|
1e26983263 | ||
|
|
a620419b59 | ||
|
|
ffdc9b0d3a | ||
|
|
379e047289 | ||
|
|
8e420406b9 | ||
|
|
fc0364b321 | ||
|
|
ea4986dec5 | ||
|
|
2be30a3193 | ||
|
|
81f90c7b51 | ||
|
|
205a564482 | ||
|
|
497df68de1 | ||
|
|
eaf8e24d4c | ||
|
|
1721fb0484 | ||
|
|
fe0b144b84 | ||
|
|
d391bca2d3 | ||
|
|
a0b6e70ff8 | ||
|
|
4f15392440 | ||
|
|
959fcfdf1d | ||
|
|
57f90d200d | ||
|
|
663c645cf1 | ||
|
|
972b255a48 | ||
|
|
8c5dfa4227 | ||
|
|
290d48e1aa | ||
|
|
4eb3a1c978 | ||
|
|
b4a36a8303 | ||
|
|
d08ee4e63a | ||
|
|
42f5802e47 | ||
|
|
120ffb0b1f | ||
|
|
d3a3ba0a32 | ||
|
|
79eebc14bb | ||
|
|
6fc41e2a3c | ||
|
|
4843323f87 | ||
|
|
04c6f3e6ef | ||
|
|
5345c7260e | ||
|
|
71a48ccde0 | ||
|
|
41e24d7733 | ||
|
|
f888b30863 | ||
|
|
10029d6a8d | ||
|
|
6697a2cfaa | ||
|
|
59020e0d5d | ||
|
|
70abd1f98d | ||
|
|
312ca8e978 | ||
|
|
e1ccdc0570 | ||
|
|
c7f9fe4a03 | ||
|
|
89aaf1c30c | ||
|
|
601af780c9 | ||
|
|
93477c8db4 | ||
|
|
ec5531dbf4 | ||
|
|
157f87f01a | ||
|
|
0f4ca8d010 | ||
|
|
0a168b6791 | ||
|
|
a025577b30 | ||
|
|
ef61d6ea48 | ||
|
|
e6bf658271 | ||
|
|
9cccb9839b | ||
|
|
2bd188f3d6 | ||
|
|
9fa840c1c7 | ||
|
|
e0e599ffa1 | ||
|
|
e93d18d200 | ||
|
|
34150f3f71 | ||
|
|
db6730c8a3 | ||
|
|
08cac802a4 | ||
|
|
af6a52e060 | ||
|
|
1c63645254 | ||
|
|
be5d8b1d4f | ||
|
|
2ac3552e6e | ||
|
|
3c3c775213 | ||
|
|
a24b7043ed | ||
|
|
7b621d7b5b | ||
|
|
8a335a8cea | ||
|
|
355c292dbf | ||
|
|
2511d747ae | ||
|
|
03c326a04e | ||
|
|
b3312f3761 | ||
|
|
2e250ee7aa | ||
|
|
924984dde1 | ||
|
|
33b7bb91d9 | ||
|
|
f68fe0fb5c | ||
|
|
e6663ec186 | ||
|
|
6ff0f9ccd8 | ||
|
|
48830aa9a9 | ||
|
|
9276f764e0 | ||
|
|
7876d464f2 | ||
|
|
5d0d01c2c1 | ||
|
|
393418d50d | ||
|
|
23bb912eb5 | ||
|
|
1d5b5296da | ||
|
|
655f5db996 | ||
|
|
c20cc4ae09 | ||
|
|
7581229bbf | ||
|
|
d094e090ff | ||
|
|
c7a13025e4 | ||
|
|
e4cd6bd824 | ||
|
|
f3ad0572e2 | ||
|
|
406d6cc305 | ||
|
|
d042697b10 | ||
|
|
ba678b9ad1 | ||
|
|
7a5cf118e9 | ||
|
|
e9a2da61ef | ||
|
|
d3fe1ef681 | ||
|
|
9725bca966 | ||
|
|
1f627e4263 | ||
|
|
7ac0c5fc2a | ||
|
|
091ebd8a98 | ||
|
|
d9a6e85b65 | ||
|
|
7cc3d89980 | ||
|
|
f58b90f7ea | ||
|
|
fd84109c1d | ||
|
|
626f605835 | ||
|
|
943a8a2708 | ||
|
|
d7b2b3f42e | ||
|
|
fafc5c8348 | ||
|
|
15bd8b4fe9 | ||
|
|
928aed4342 | ||
|
|
98782e44c2 | ||
|
|
65b23777b2 | ||
|
|
c8fd3d6d25 | ||
|
|
01e7cd5f13 | ||
|
|
3ac9bd0468 | ||
|
|
9f498d2eea | ||
|
|
2d2d9ad277 | ||
|
|
2cc18a8ea3 | ||
|
|
25036d5f48 | ||
|
|
defee39ef9 | ||
|
|
c78afb12a3 | ||
|
|
f72b0b5056 | ||
|
|
d46e505a80 | ||
|
|
4027bcf7ea | ||
|
|
2905392665 | ||
|
|
98db3360df | ||
|
|
f26c713482 | ||
|
|
05e55334fc | ||
|
|
01fe61276e | ||
|
|
219253ad71 | ||
|
|
7b125558cb | ||
|
|
02120e24b6 | ||
|
|
91bc79c14c | ||
|
|
5ca552cf1c | ||
|
|
2066304b14 | ||
|
|
1c6f8b95eb | ||
|
|
5384591f5b | ||
|
|
309668ccbc | ||
|
|
06a9fb3f53 | ||
|
|
00db56f7d7 | ||
|
|
cec06eb25c | ||
|
|
73a3897e1b | ||
|
|
100c4c15ce | ||
|
|
c59bf6613a | ||
|
|
ac435bcb91 | ||
|
|
5d0bfccbc7 | ||
|
|
813489dc2f | ||
|
|
828f31d5e6 | ||
|
|
8130f7f25f | ||
|
|
943e1c5f77 | ||
|
|
ecb3301bcb | ||
|
|
a0f33aebf7 | ||
|
|
6862981640 | ||
|
|
f61f2d2e9f | ||
|
|
1743e175cd | ||
|
|
a027f58744 | ||
|
|
c98886402b | ||
|
|
112a1e908a | ||
|
|
01ae80ecd1 | ||
|
|
52997c6c51 | ||
|
|
1c114a279e | ||
|
|
93148e3223 | ||
|
|
f01807ef17 | ||
|
|
a4ed740518 | ||
|
|
0e2f3de154 | ||
|
|
d128d2146a | ||
|
|
c683e1e988 | ||
|
|
0b7038d44d | ||
|
|
55698b91c0 | ||
|
|
eff54827b2 | ||
|
|
2c2c7f6894 | ||
|
|
5baa4d969e | ||
|
|
d745c41d5b | ||
|
|
a86bde7b3f | ||
|
|
4ab2309a5d | ||
|
|
9172f62970 | ||
|
|
daa47e8272 | ||
|
|
2419f02766 | ||
|
|
c8d45c9ff1 | ||
|
|
0b667ca869 | ||
|
|
1a5ea930ab | ||
|
|
e4bfb2b5b0 | ||
|
|
936e7bbc88 | ||
|
|
93b5063251 | ||
|
|
e0668bc1c0 | ||
|
|
fa5aa308bc | ||
|
|
cbfa57a955 | ||
|
|
f8898b016e | ||
|
|
8a9630485f | ||
|
|
066e4ac332 | ||
|
|
f231760395 | ||
|
|
ebfa5f0ba7 | ||
|
|
d7754516f0 | ||
|
|
00fd1884ff | ||
|
|
b828be4873 | ||
|
|
4045a541ef | ||
|
|
f7557c9e48 | ||
|
|
7c62b5005e | ||
|
|
b804217501 | ||
|
|
c6128094b6 | ||
|
|
0fc0230364 | ||
|
|
dd6458262d | ||
|
|
eb68bb2ce1 | ||
|
|
8dc62c25ed | ||
|
|
d8fec13d2c | ||
|
|
922d148ab5 | ||
|
|
08f05d6f8c | ||
|
|
7bec3b4954 | ||
|
|
4d3fba57d4 | ||
|
|
1a8a144726 | ||
|
|
00ea3830a7 | ||
|
|
3880300cd9 | ||
|
|
6b0e4a425d | ||
|
|
f883504d2d | ||
|
|
a1c5995967 | ||
|
|
8500afbbd4 | ||
|
|
13cb94cf2b | ||
|
|
f26a79d75c | ||
|
|
68e2cd9b29 | ||
|
|
6e44bab3d5 | ||
|
|
677fea7bfa | ||
|
|
0d2ae10bd9 | ||
|
|
faa582040b | ||
|
|
0ad4002569 | ||
|
|
dfc2e97d5e | ||
|
|
57159dc5c0 | ||
|
|
77ff1511ff | ||
|
|
124ab99995 | ||
|
|
8ea08306b8 | ||
|
|
3e0d20a335 | ||
|
|
727b3d4f19 | ||
|
|
80782b289f | ||
|
|
72127a4bed | ||
|
|
d4a49e00e7 | ||
|
|
5826d0e41c | ||
|
|
68cb7ce8d9 | ||
|
|
514699fc41 | ||
|
|
deca1aaf46 | ||
|
|
b8bfa5565b | ||
|
|
50c7844031 | ||
|
|
cba0d1b2f9 | ||
|
|
5735ee3269 | ||
|
|
ee3593b887 | ||
|
|
9bebe7cf68 | ||
|
|
bd5e4dba26 | ||
|
|
2427c40a4c | ||
|
|
744df7b244 | ||
|
|
3965aecfd4 | ||
|
|
93bcde0176 | ||
|
|
4b3884a49d | ||
|
|
768908ae4a | ||
|
|
1a965d5c43 | ||
|
|
01b612cff5 | ||
|
|
176db1aedb | ||
|
|
06f8238107 | ||
|
|
97127a57da | ||
|
|
61825b2390 | ||
|
|
669ffe2c74 | ||
|
|
a50b8ff5d7 | ||
|
|
aae2954c14 | ||
|
|
abab569778 | ||
|
|
365a731574 | ||
|
|
285dc63c5c | ||
|
|
24d9fbffae | ||
|
|
04178ad0f7 | ||
|
|
a0e66fb9e6 | ||
|
|
df3c216315 | ||
|
|
e9a6bad751 | ||
|
|
4b7d871048 | ||
|
|
2528dd6425 | ||
|
|
b3fcd9c420 | ||
|
|
9270fc0b15 | ||
|
|
33aa021e96 | ||
|
|
1c78ed1fed | ||
|
|
562c318648 | ||
|
|
65cb894f0d | ||
|
|
bbd27a0a9c | ||
|
|
79e138ef28 | ||
|
|
387334c8c2 | ||
|
|
cd021daf79 | ||
|
|
536aa1fb62 | ||
|
|
a14a838dab | ||
|
|
ad57731ae1 | ||
|
|
ad90b0b7b1 | ||
|
|
18325cb216 | ||
|
|
8df70ba58b | ||
|
|
ee43a5389f | ||
|
|
6192573eb8 | ||
|
|
92ecef7bd3 | ||
|
|
45d7f4ca7e | ||
|
|
144c2f443e | ||
|
|
98d877c5f0 | ||
|
|
9de31ba816 | ||
|
|
560561c5b7 | ||
|
|
ed2d4c1c2b | ||
|
|
e70628cbdc | ||
|
|
161edec195 | ||
|
|
2ba4a74762 | ||
|
|
693316de44 | ||
|
|
6e68124405 | ||
|
|
c8105cffba | ||
|
|
21f6944fc7 | ||
|
|
5adcba7ba1 | ||
|
|
fc8ba744dc | ||
|
|
4fc43cfbf7 | ||
|
|
22837f93c8 | ||
|
|
b03ececbbb | ||
|
|
708908dce5 | ||
|
|
f33302acc9 | ||
|
|
7f8cdf1e79 | ||
|
|
dbc7b5e70b | ||
|
|
4c445453d3 | ||
|
|
4b8fb23def | ||
|
|
253bc64c9e | ||
|
|
32d3fc6803 | ||
|
|
920875ecc9 | ||
|
|
85d3e7f375 | ||
|
|
4ceb50d485 | ||
|
|
7d2fca9574 | ||
|
|
d88e60a525 | ||
|
|
4b4dcb20ca | ||
|
|
d4ab0aa7fd | ||
|
|
c02c1130ed | ||
|
|
f9bbb37721 | ||
|
|
57837f285f | ||
|
|
3379f11b23 | ||
|
|
c74534cf5e | ||
|
|
64ca1ad787 | ||
|
|
8022635c04 | ||
|
|
1f37595200 | ||
|
|
30738f6638 | ||
|
|
bd53e46873 | ||
|
|
122115dbea | ||
|
|
28162f8034 | ||
|
|
9cfd3124ef | ||
|
|
36748ee406 | ||
|
|
2a25e449a2 | ||
|
|
f2f60a7b3b | ||
|
|
82916a1cef | ||
|
|
f86c14abb3 | ||
|
|
fa76312313 | ||
|
|
46687f6fe3 | ||
|
|
6386cdff50 | ||
|
|
7c25c0d6f3 | ||
|
|
8ed57f57cb | ||
|
|
c8f207c277 | ||
|
|
d70d9aff11 | ||
|
|
1118c997b5 | ||
|
|
b999275550 | ||
|
|
f549646ddd | ||
|
|
5ee8552e6c | ||
|
|
b0eb7b6dec | ||
|
|
a546d360d0 | ||
|
|
3cc8a98b9d | ||
|
|
1032f0ade7 | ||
|
|
eb65d269eb | ||
|
|
b379f81004 | ||
|
|
d1b0342a18 | ||
|
|
b815e6bc04 | ||
|
|
81bf65954c | ||
|
|
9cfe72af4a | ||
|
|
7c2e1e1339 | ||
|
|
817115cb6c | ||
|
|
7a3734e54d | ||
|
|
79c3341f74 | ||
|
|
abdd14b0a1 | ||
|
|
1f77e53b23 | ||
|
|
a619de0508 | ||
|
|
8faa11585c | ||
|
|
13259f8902 | ||
|
|
bb5aba2e19 | ||
|
|
22fc01d5f2 | ||
|
|
3b4672c109 | ||
|
|
351bd42bc4 | ||
|
|
e418da4bd8 | ||
|
|
18d13f9848 | ||
|
|
ee792db6a3 | ||
|
|
129bf93b30 | ||
|
|
1dda8b9e60 | ||
|
|
107e303282 | ||
|
|
22f76091a2 | ||
|
|
376e5ccaae | ||
|
|
b792304cf8 | ||
|
|
b357485523 | ||
|
|
07936343c8 | ||
|
|
1b93ca0fb2 | ||
|
|
18cd18d1e5 | ||
|
|
deab6772e8 | ||
|
|
d6d2d7575a | ||
|
|
d63ec65663 | ||
|
|
f0a927831e | ||
|
|
ef16a733d2 | ||
|
|
9044c02edc | ||
|
|
2fa98b00f2 | ||
|
|
15b4d566e7 | ||
|
|
6dabbe237d | ||
|
|
2caff93f83 | ||
|
|
2903937cba | ||
|
|
c33fd6a7fb | ||
|
|
64180e8fe8 | ||
|
|
001134af89 | ||
|
|
b91044dea7 | ||
|
|
34639f86b0 | ||
|
|
32559f15ea | ||
|
|
b10eef1e32 | ||
|
|
7c4911598c | ||
|
|
efacb20bdc | ||
|
|
2e6188205f | ||
|
|
83fec2cf45 | ||
|
|
9be36eb9cb | ||
|
|
a51802ecaf | ||
|
|
b1c220e610 | ||
|
|
36f6b805e3 | ||
|
|
64efad9e46 | ||
|
|
8a8d5ce151 | ||
|
|
907417f9ec | ||
|
|
0965177e72 | ||
|
|
7d07ca8427 | ||
|
|
d18b2b390a | ||
|
|
fefe8b1c15 | ||
|
|
ea2ff010a9 | ||
|
|
e357cb3185 | ||
|
|
293ee2162c | ||
|
|
c29ee769bc | ||
|
|
82399f1561 | ||
|
|
9255ceaf8a | ||
|
|
bb9c7c0eb3 | ||
|
|
8ec327f9c7 | ||
|
|
c9b982eaff | ||
|
|
248e7b6e29 | ||
|
|
cb1ae312a1 | ||
|
|
aec25cf547 | ||
|
|
4db3fc2515 | ||
|
|
79d6017c56 | ||
|
|
d4c122b17a | ||
|
|
57fd93eeda | ||
|
|
19cac05747 | ||
|
|
5ebede5096 | ||
|
|
46ecb07fc8 | ||
|
|
a628a05efb | ||
|
|
fc626bb57f | ||
|
|
1291839182 | ||
|
|
736e7a2cf9 | ||
|
|
7884a2f3c7 | ||
|
|
dde699ffda | ||
|
|
fa54a22aed | ||
|
|
822b0c011a | ||
|
|
a0f8a197c9 | ||
|
|
7e75e51332 | ||
|
|
b37efbe891 | ||
|
|
6e648c90b0 | ||
|
|
377d6acc74 | ||
|
|
f552d15fe4 | ||
|
|
d1204e8a66 | ||
|
|
9ec48e41f7 | ||
|
|
9055a83b4f | ||
|
|
dd047b2613 | ||
|
|
b7a32069b1 | ||
|
|
00d475bc7e | ||
|
|
33ab44430c | ||
|
|
b355da32b9 | ||
|
|
3f0366a514 | ||
|
|
7ecbbc517d | ||
|
|
a04c94444e | ||
|
|
42b9ac1145 | ||
|
|
7be4925c70 | ||
|
|
7b19568683 | ||
|
|
8f56779855 | ||
|
|
fdfad8462c | ||
|
|
3773ef45e7 | ||
|
|
c0ca3cacb4 | ||
|
|
bed0630698 | ||
|
|
53baa18836 | ||
|
|
32a2144426 | ||
|
|
264026acde | ||
|
|
43503ef73a | ||
|
|
7f52717e9d | ||
|
|
bd59185ef1 | ||
|
|
310ffcd4eb | ||
|
|
d23664a457 | ||
|
|
a1e316ddcf | ||
|
|
e328758fc7 | ||
|
|
dbf49255a3 | ||
|
|
1391bdcf8b | ||
|
|
d8106a8ffe | ||
|
|
ae55789c4b | ||
|
|
ec02ccf5b2 | ||
|
|
f970cd78d7 | ||
|
|
8140ea16a7 | ||
|
|
2883709756 | ||
|
|
ca4c2c6c41 | ||
|
|
fbc56f4adf | ||
|
|
2f014237b2 | ||
|
|
f33e3a7752 | ||
|
|
d5b5cec797 | ||
|
|
f8e1f17651 | ||
|
|
be58bfe22b | ||
|
|
995a63dc39 | ||
|
|
e8d57ac4e1 | ||
|
|
eab3a83548 | ||
|
|
3fb9e5fd56 | ||
|
|
41448278cf | ||
|
|
48516b43c5 | ||
|
|
80b7be0568 | ||
|
|
4183552aee | ||
|
|
527e89754e | ||
|
|
30e0f42c97 | ||
|
|
39b40daf5d | ||
|
|
94636f4d30 | ||
|
|
fd53548c5e | ||
|
|
354ea30797 | ||
|
|
11303e0dc1 | ||
|
|
b4c645f703 | ||
|
|
3256218fd2 | ||
|
|
a4f14b0ddf | ||
|
|
e7459d91f9 | ||
|
|
b32d1c15f0 | ||
|
|
1e0d57a832 | ||
|
|
f3617a1cf3 | ||
|
|
89a9a50b96 | ||
|
|
69d2ba7316 | ||
|
|
3ea5f8dbde | ||
|
|
d56152875d | ||
|
|
7459d30a28 | ||
|
|
16bf9101aa | ||
|
|
2b20af36a7 | ||
|
|
f5e87cceec | ||
|
|
36fcb7ed21 | ||
|
|
9fe7807b02 | ||
|
|
88e3017ee5 | ||
|
|
17f3738192 | ||
|
|
6cfdc39005 | ||
|
|
58886a9693 | ||
|
|
66e022c454 | ||
|
|
ea3968601e | ||
|
|
54be13d1d8 | ||
|
|
22ea825d46 | ||
|
|
8c03aa2801 | ||
|
|
5bb952260a | ||
|
|
face6c44c6 | ||
|
|
66c2bfe822 | ||
|
|
3721bcc790 | ||
|
|
cacab6fe4c | ||
|
|
6ad8674cd4 | ||
|
|
847990ce49 | ||
|
|
1bfdc1f138 | ||
|
|
58367fe23e | ||
|
|
a8712e2307 | ||
|
|
8acfae1111 | ||
|
|
70fc71c6f7 | ||
|
|
dd5118cab0 | ||
|
|
2d75a6ccd4 | ||
|
|
e004ab1693 | ||
|
|
acddfc3bf4 | ||
|
|
519d4b0286 | ||
|
|
8005a5e687 | ||
|
|
f5943fe591 | ||
|
|
cea7fcdb37 | ||
|
|
b5213c13dd | ||
|
|
3a06b4833c | ||
|
|
5cdf6c1d05 | ||
|
|
5754e5dd59 | ||
|
|
e5ab1c454b | ||
|
|
697576b63c | ||
|
|
2db41aef09 | ||
|
|
7f4ad3cade | ||
|
|
74c4c32082 | ||
|
|
30d545443c | ||
|
|
dedba52315 | ||
|
|
481f7b5cff | ||
|
|
6ce4f4930c | ||
|
|
e33a10db75 | ||
|
|
ef17055145 | ||
|
|
6a2fa10a4e | ||
|
|
6b81a5846d | ||
|
|
b54d086fde | ||
|
|
5ee9d22263 | ||
|
|
7dcb097a5d | ||
|
|
29a30239ab | ||
|
|
ed54b60ea3 | ||
|
|
199af33b30 | ||
|
|
adfa1d0e20 | ||
|
|
ef25c42e86 | ||
|
|
91a638156c | ||
|
|
26ce666938 | ||
|
|
7548af895b | ||
|
|
9548437a9e | ||
|
|
5e50b7104c | ||
|
|
d824cf7dbd | ||
|
|
0613cc62f4 | ||
|
|
d9cbcb5fa8 | ||
|
|
a4f5355161 | ||
|
|
a24b6c1909 | ||
|
|
fd7dc72410 | ||
|
|
e4f4dfab3b | ||
|
|
66010be5a6 | ||
|
|
852c42a8f3 | ||
|
|
132725de7b | ||
|
|
0a761c09e3 | ||
|
|
09ce6ae1c5 | ||
|
|
85e60ed858 | ||
|
|
86fd18324b | ||
|
|
fdf82e5d6c | ||
|
|
eb0b1580d1 | ||
|
|
2d33c545b8 | ||
|
|
cdaf523aa8 | ||
|
|
3195f2cec2 | ||
|
|
ea89a4afab | ||
|
|
3415b62d2d | ||
|
|
ee80822564 | ||
|
|
3c9e218d07 | ||
|
|
387a602885 | ||
|
|
ef0ff43975 | ||
|
|
ae37407369 | ||
|
|
e1c91b5763 | ||
|
|
c49b472f92 | ||
|
|
0a6b1b9418 | ||
|
|
ac40673a9e | ||
|
|
818f99b286 | ||
|
|
320da5e84c | ||
|
|
6957c379d5 | ||
|
|
88e880f107 | ||
|
|
bf8c4dfc83 | ||
|
|
5dff282132 | ||
|
|
1148ac0ae4 | ||
|
|
59c46fc594 | ||
|
|
03a94e3a6a | ||
|
|
5c8e05a4fc | ||
|
|
d791ce393b | ||
|
|
a452231086 | ||
|
|
a392a19c9c | ||
|
|
a864c04702 | ||
|
|
8d2f7296a1 | ||
|
|
040936eb47 | ||
|
|
101beec3ae | ||
|
|
2f1a836bf0 | ||
|
|
62f5e0a1a9 | ||
|
|
cca771e70e | ||
|
|
0c7e6b548f | ||
|
|
8b87e8aa92 | ||
|
|
415bbf2932 | ||
|
|
48df4f18cd | ||
|
|
dc0f9aca4a | ||
|
|
1b9b8e3f6c | ||
|
|
5d10e9dbee | ||
|
|
0adc858c85 | ||
|
|
eda1e8a402 | ||
|
|
4b0e34cdf4 | ||
|
|
c688687ff8 | ||
|
|
d56e5bea62 | ||
|
|
aed7b6b37a | ||
|
|
8114443e97 | ||
|
|
8ba0a33f84 | ||
|
|
661ed61779 | ||
|
|
427f95337f | ||
|
|
fa8490fb4e | ||
|
|
5be1c6381b | ||
|
|
6794a89f79 | ||
|
|
8f19ee7b97 | ||
|
|
c63135ec7f | ||
|
|
5c87f2f22c | ||
|
|
6e6e34c423 | ||
|
|
bb983fb4b2 | ||
|
|
285bbf50e9 | ||
|
|
c2ad2e1151 | ||
|
|
46e796ffaa | ||
|
|
3bf25d86f2 | ||
|
|
2dca4805b0 | ||
|
|
54aa4678d1 | ||
|
|
3ab0e6cade | ||
|
|
41e3b23253 | ||
|
|
b00d780a50 | ||
|
|
71b3e26232 | ||
|
|
40f28c02b9 | ||
|
|
362b22a673 | ||
|
|
d6be9a2bba | ||
|
|
6bfd113a87 | ||
|
|
b7f86ba743 | ||
|
|
2bab274056 | ||
|
|
dd6bffdd0d | ||
|
|
bcc044eb92 | ||
|
|
a7f1982d03 | ||
|
|
d013e0fc78 | ||
|
|
6f69ad93c1 | ||
|
|
7ea2093a91 | ||
|
|
dd32deb2ad | ||
|
|
ad71fb321c | ||
|
|
cc6c28a7ff | ||
|
|
c763087462 | ||
|
|
63ff4ddea0 | ||
|
|
4178fc125d | ||
|
|
dcfa7ad657 | ||
|
|
c061e60664 | ||
|
|
a0dd3ecd68 | ||
|
|
0168a312f2 | ||
|
|
92fe5a5b58 | ||
|
|
7f3d450b32 | ||
|
|
8166339920 | ||
|
|
57424d4a26 | ||
|
|
6511b6dd5d | ||
|
|
0625b97246 | ||
|
|
9f8ce82825 | ||
|
|
c3c925dc84 | ||
|
|
36f3703499 | ||
|
|
6ae59c3711 | ||
|
|
c8f5f85635 | ||
|
|
4e5e186784 | ||
|
|
828f7a513c | ||
|
|
6085998d57 | ||
|
|
71e44d5b65 | ||
|
|
e762bbdbf8 | ||
|
|
fe0d2272f6 | ||
|
|
e017b88adf | ||
|
|
5f76d9cf33 | ||
|
|
85a5bdf4dc | ||
|
|
4abc34ffd1 | ||
|
|
250b1d511b | ||
|
|
59e3b0285a | ||
|
|
f961f993c8 | ||
|
|
adf124c00c | ||
|
|
f8579131e8 | ||
|
|
1dde754724 | ||
|
|
771696fda8 | ||
|
|
dd5f469c83 | ||
|
|
6d3fda12cd | ||
|
|
dc32480563 | ||
|
|
06ac9e18cb | ||
|
|
0648943220 | ||
|
|
7a4a82e872 | ||
|
|
6c0c05cf7f | ||
|
|
efd2db129f | ||
|
|
f4f276f370 | ||
|
|
bff1462e9e | ||
|
|
4d06f33089 | ||
|
|
a433d9ef03 | ||
|
|
58606e1702 | ||
|
|
1ccc9aa72e | ||
|
|
49a9bb5a8b | ||
|
|
380d6ac5c2 | ||
|
|
7d9f76df05 | ||
|
|
96707acb4e | ||
|
|
4e504823c0 | ||
|
|
82faa2e9c9 | ||
|
|
1df9cd8071 | ||
|
|
a8d5e4dd28 | ||
|
|
e59ea39a33 | ||
|
|
62d1dc1eea | ||
|
|
379af7dec2 | ||
|
|
68a45adac7 | ||
|
|
9ea8e29cb0 | ||
|
|
90092c0762 | ||
|
|
b379816178 | ||
|
|
e4353255ca | ||
|
|
923f2c7635 | ||
|
|
a8309ef705 | ||
|
|
bad05485d0 | ||
|
|
38d7799ffa | ||
|
|
6e6696ccd4 | ||
|
|
feb546920e | ||
|
|
81b05b9de4 | ||
|
|
ab10b042be | ||
|
|
26699914cc | ||
|
|
45e4b3c423 | ||
|
|
6a5a139e33 | ||
|
|
1908d3200e | ||
|
|
f4cf40d38f | ||
|
|
514de84b97 | ||
|
|
7e7d0bb354 | ||
|
|
e468b90442 | ||
|
|
926959ab47 | ||
|
|
4663090a8f | ||
|
|
b0868a4d0b | ||
|
|
9088b00006 | ||
|
|
9c0fe8999d | ||
|
|
901aa5f7c1 | ||
|
|
3ee28c035b | ||
|
|
1e31b90905 | ||
|
|
48333041f4 | ||
|
|
717c9dbe89 | ||
|
|
fd86eb7aa7 | ||
|
|
9b4b35eff5 | ||
|
|
ac528caf2b | ||
|
|
fbe626e791 | ||
|
|
9ca37d30d8 | ||
|
|
84986898c8 | ||
|
|
5cebce3f4b | ||
|
|
bb344b14a8 | ||
|
|
20e613b444 | ||
|
|
a0952e0012 | ||
|
|
49e66f809e | ||
|
|
5152ed8731 | ||
|
|
33811a826f | ||
|
|
d33aebfd31 | ||
|
|
7d53c52a6b | ||
|
|
f015a8686e | ||
|
|
ab791d2a2d | ||
|
|
a303858da7 | ||
|
|
4c58c62cfe | ||
|
|
4593332204 | ||
|
|
9f5d8c4280 | ||
|
|
b0d44bf0ba | ||
|
|
59b8434e36 | ||
|
|
e6f27cbaf3 | ||
|
|
6c13df1aff | ||
|
|
44bf059b2f | ||
|
|
9ade464c2e | ||
|
|
aed5d4e05b | ||
|
|
b57648df14 | ||
|
|
7bce887077 | ||
|
|
cacd9c7f95 | ||
|
|
cd64bfe84b | ||
|
|
52ed68ed24 | ||
|
|
20577021a6 | ||
|
|
838a2236a1 | ||
|
|
d03941b792 | ||
|
|
92299c3079 | ||
|
|
d9f05532cd | ||
|
|
2fd2dff126 | ||
|
|
8e14ad0536 | ||
|
|
2b325102f3 | ||
|
|
1f2be606fa | ||
|
|
6b29a2a724 | ||
|
|
f79edeb053 | ||
|
|
84b92096d4 | ||
|
|
70f4814cb1 | ||
|
|
49579eb2b4 | ||
|
|
cc6caeeca9 | ||
|
|
90af22eba1 | ||
|
|
f4b4b41264 | ||
|
|
9918b03c11 | ||
|
|
95f44246bf | ||
|
|
b098723f78 | ||
|
|
a819513a92 | ||
|
|
7531b28b4c | ||
|
|
2b8586d1b7 | ||
|
|
8167291ffc | ||
|
|
0dfcf9607a | ||
|
|
4827831107 | ||
|
|
0ebb6d5d30 | ||
|
|
f4ed5062f6 | ||
|
|
434b129746 | ||
|
|
2f5041ac7d | ||
|
|
24f9766b39 | ||
|
|
ba872217d7 | ||
|
|
b2ae517dac | ||
|
|
32b52dc0c8 | ||
|
|
33a3fe9bbd | ||
|
|
245dc76503 | ||
|
|
21dbfd79d8 | ||
|
|
b9f2250278 | ||
|
|
a0601f1891 | ||
|
|
70403ee433 | ||
|
|
f3cde58c8f | ||
|
|
71c267776a | ||
|
|
359ff94a8c | ||
|
|
efe1c1492f | ||
|
|
2aaaf7c358 | ||
|
|
cefaffa0f0 | ||
|
|
a22d56dc41 | ||
|
|
51eca94504 | ||
|
|
2b6d24d328 | ||
|
|
4932025423 | ||
|
|
c466abf4d0 | ||
|
|
2ece3a8b4c | ||
|
|
3f760e1875 | ||
|
|
1da134c38c | ||
|
|
0bf96e9864 | ||
|
|
1f5c19306e | ||
|
|
db10b3821c | ||
|
|
4245a6d04d | ||
|
|
6920c1159b | ||
|
|
3801e1eade | ||
|
|
3e419303a7 | ||
|
|
0de1e6a3af | ||
|
|
99c415f898 | ||
|
|
f68d83dbf0 | ||
|
|
6e97905bce | ||
|
|
572a10d5a0 | ||
|
|
eaa6199de0 | ||
|
|
70799101e4 | ||
|
|
9cc70d0323 | ||
|
|
20c5da6e55 | ||
|
|
4c356bc368 | ||
|
|
aeb04deae4 | ||
|
|
873e4d6547 | ||
|
|
9ba20304c2 | ||
|
|
252619b1a0 | ||
|
|
38b129de66 | ||
|
|
da028d1af9 | ||
|
|
bba361016d | ||
|
|
c362af1f81 | ||
|
|
520507afd9 | ||
|
|
4e7584167b | ||
|
|
112bd61a25 | ||
|
|
1df8bc0dfe | ||
|
|
f2076fe309 | ||
|
|
67dea15bf2 | ||
|
|
910f19fe55 | ||
|
|
290bf0b6d2 | ||
|
|
4c87a776e6 | ||
|
|
4436093816 | ||
|
|
b85aa7b084 | ||
|
|
99e28b639d | ||
|
|
9b94b4da26 | ||
|
|
5b46986628 | ||
|
|
d0e5690bfd | ||
|
|
ddbfa06bcc | ||
|
|
2c6fc99c68 | ||
|
|
d8ad0ac72c | ||
|
|
9de50d7981 | ||
|
|
2c5c46dc48 | ||
|
|
6423b4cbb9 | ||
|
|
2566aa725a | ||
|
|
eb463bbb2b | ||
|
|
1a8a559d84 | ||
|
|
57c1d787e3 | ||
|
|
999a32424f | ||
|
|
c2ed20ba23 | ||
|
|
01cbb37359 | ||
|
|
3e205e9536 | ||
|
|
b29d6b4478 | ||
|
|
b9424e4c21 | ||
|
|
87fe912d8d | ||
|
|
59343c2f82 | ||
|
|
700fc64383 | ||
|
|
ca256b9949 | ||
|
|
68750f3455 | ||
|
|
906fc417c8 | ||
|
|
ac203c56df | ||
|
|
734ad45f1c | ||
|
|
4a1f2e0dd3 | ||
|
|
24e3514640 | ||
|
|
dadb05e022 | ||
|
|
ca3dfb3c07 | ||
|
|
cf452942fa | ||
|
|
28ee40bebe | ||
|
|
6267752a2a | ||
|
|
2ece24e077 | ||
|
|
59013e62d3 | ||
|
|
824763aae9 | ||
|
|
a8c5b04feb | ||
|
|
64f069ec24 | ||
|
|
515e438d4f | ||
|
|
9ec064f9d9 | ||
|
|
60c6b04a01 | ||
|
|
9deaa81a72 | ||
|
|
ae703db6ee | ||
|
|
267f54bc0e | ||
|
|
8aa26fb2cd | ||
|
|
e7667f2537 | ||
|
|
bac15d2ecf | ||
|
|
ae27e07903 | ||
|
|
605dfa7366 | ||
|
|
85db19e33f | ||
|
|
052bc6b356 | ||
|
|
24985e2bca | ||
|
|
8e3eb8b3d2 | ||
|
|
2be44dbd94 | ||
|
|
7c6b26faa2 | ||
|
|
cfc42512ed | ||
|
|
50f5834296 | ||
|
|
07e91bb73a | ||
|
|
3c547eeed8 | ||
|
|
6f011fce3b | ||
|
|
5aebed95a4 | ||
|
|
8321f9f6e9 | ||
|
|
bf9d69ab56 | ||
|
|
faaff57d2b | ||
|
|
40667ef1c1 | ||
|
|
04b4e3298b | ||
|
|
43cbd3a61e | ||
|
|
bfb091f2f4 | ||
|
|
4974303e6b | ||
|
|
664bb0a663 | ||
|
|
491596d03d | ||
|
|
75538be235 | ||
|
|
1cb99ea2fc | ||
|
|
c0f4bde5fc | ||
|
|
a4430dd49d | ||
|
|
b513d40bd6 | ||
|
|
fbaaf89a21 | ||
|
|
7625a0154e | ||
|
|
396ee803b2 | ||
|
|
5a42319a07 | ||
|
|
61b9820f78 | ||
|
|
a383a45269 | ||
|
|
7bd4869ae6 | ||
|
|
49a6559453 | ||
|
|
2e16a10720 | ||
|
|
cd973b50ff | ||
|
|
b6fc67fff2 | ||
|
|
12f00d785d | ||
|
|
de1ff6ed49 | ||
|
|
d0a6cbe5dd | ||
|
|
35924ce550 | ||
|
|
ad1d8cbedd | ||
|
|
6294ce59f7 | ||
|
|
d445ff40c2 | ||
|
|
c6010c3ab4 | ||
|
|
9da80d7b7d | ||
|
|
2c62e58dbd | ||
|
|
efc54375dd | ||
|
|
0c3946033b | ||
|
|
9dc86aa77d | ||
|
|
0cbe320a5f | ||
|
|
1c749a5310 | ||
|
|
a647a69791 | ||
|
|
12db089c73 | ||
|
|
f5ff7cfcf1 | ||
|
|
2ddf71ec46 | ||
|
|
9017374292 | ||
|
|
633f50cf5b | ||
|
|
1993e9c65b | ||
|
|
8edc8610dc | ||
|
|
6700b373cd | ||
|
|
8d824799a0 | ||
|
|
dc86c62d8b | ||
|
|
4ae4ff72e3 | ||
|
|
958eebb16c | ||
|
|
43e48d2ba6 | ||
|
|
b6d8099c74 | ||
|
|
25bac7c5ce | ||
|
|
5d7a080e39 | ||
|
|
b2a76dba98 | ||
|
|
15ad69c8cb | ||
|
|
e3ca006265 | ||
|
|
961cc13948 | ||
|
|
50da233258 | ||
|
|
15ad58b5cc | ||
|
|
61a27ff430 | ||
|
|
befdb0a708 | ||
|
|
06b79600ac | ||
|
|
b9e633ad06 | ||
|
|
736a78faed | ||
|
|
d76e69f9a7 | ||
|
|
1612e1d142 | ||
|
|
56a33fd4c5 | ||
|
|
1ca3244868 | ||
|
|
8f358f09b8 | ||
|
|
d903de6526 | ||
|
|
c41ade2983 | ||
|
|
99dbbc7f39 | ||
|
|
4dd51cc889 | ||
|
|
54c651f7e2 | ||
|
|
d1c9d7ffdc | ||
|
|
052b40680d | ||
|
|
b0d2519192 | ||
|
|
997da11cc5 | ||
|
|
476232ea22 | ||
|
|
4c83f4e2de | ||
|
|
4bf39e18d9 | ||
|
|
edfa533a4d | ||
|
|
28262145ab | ||
|
|
51136ce982 | ||
|
|
84893ec582 | ||
|
|
382362668e |
No files matched your search
@@ -0,0 +1 @@
|
|||||||
|
blank_issues_enabled: false
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
---
|
||||||
|
name: Issue template
|
||||||
|
about: Please fill this issue template for reporting Mongoose issues
|
||||||
|
#title:
|
||||||
|
#labels:
|
||||||
|
#assignees:
|
||||||
|
---
|
||||||
|
|
||||||
|
- My goal is: _describe_
|
||||||
|
- My actions were: _describe_
|
||||||
|
- My expectation was: _describe_
|
||||||
|
- The result I saw: _provide logs or description_
|
||||||
|
- My question is: _your question_
|
||||||
|
|
||||||
|
# Environment
|
||||||
|
|
||||||
|
- mongoose version: _X.Y_
|
||||||
|
- Compiler/IDE and SDK: ZZZ version _X.Y_
|
||||||
|
- Target hardware/board: _?_
|
||||||
|
- Connectivity chip/module: _?_
|
||||||
|
- Target RTOS/OS (if applicable): _?_
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
- My goal is: _describe_
|
|
||||||
- My actions were: _describe_
|
|
||||||
- My expectation was: _describe_
|
|
||||||
- The result I saw: _provide logs or description_
|
|
||||||
- My question is: _your question_
|
|
||||||
|
|
||||||
# Environment
|
|
||||||
|
|
||||||
- mongoose version: _X.Y_
|
|
||||||
- Compiler/IDE and SDK: ZZZ version _X.Y_
|
|
||||||
- Target hardware/board: _?_
|
|
||||||
- Connectivity chip/module: _?_
|
|
||||||
- Target RTOS/OS (if applicable): _?_
|
|
||||||
@@ -1,9 +1,16 @@
|
|||||||
name: CIFuzz
|
name: CIFuzz
|
||||||
on: [pull_request]
|
on:
|
||||||
|
schedule:
|
||||||
|
- cron: '0 2 * * *' # run at 2 AM UTC
|
||||||
|
# Allow manual runs
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
Fuzzing:
|
Fuzzing:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with: { fetch-depth: 2 }
|
||||||
- name: Build Fuzzers
|
- name: Build Fuzzers
|
||||||
id: build
|
id: build
|
||||||
uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master
|
uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master
|
||||||
@@ -19,7 +26,7 @@ jobs:
|
|||||||
dry-run: false
|
dry-run: false
|
||||||
language: c++
|
language: c++
|
||||||
- name: Upload Crash
|
- name: Upload Crash
|
||||||
uses: actions/upload-artifact@v1
|
uses: actions/upload-artifact@v4
|
||||||
if: failure() && steps.build.outcome == 'success'
|
if: failure() && steps.build.outcome == 'success'
|
||||||
with:
|
with:
|
||||||
name: artifacts
|
name: artifacts
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
name: "CodeQL Scanning"
|
||||||
|
# https://github.com/github/codeql-action
|
||||||
|
|
||||||
|
on:
|
||||||
|
#schedule:
|
||||||
|
# - cron: '30 23 * * *' # run at 11:30 PM UTC
|
||||||
|
# Allow manual runs
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
env:
|
||||||
|
IPV6: 0
|
||||||
|
jobs:
|
||||||
|
CodeQL-Build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
permissions:
|
||||||
|
security-events: write
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with: { fetch-depth: 2 }
|
||||||
|
|
||||||
|
- name: Initialize CodeQL
|
||||||
|
uses: github/codeql-action/init@v3
|
||||||
|
with:
|
||||||
|
languages: cpp
|
||||||
|
- run: |
|
||||||
|
make -C test test CC=gcc ASAN= ASAN_OPTIONS=
|
||||||
|
./test/setup_ga_network.sh && make -C test mip_test CC=gcc ASAN= ASAN_OPTIONS=
|
||||||
|
|
||||||
|
- name: Perform CodeQL Analysis
|
||||||
|
uses: github/codeql-action/analyze@v3
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
name: Fuzz
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
- cron: '0 21 * * *' # run at 9 PM UTC
|
||||||
|
# Allow manual runs
|
||||||
|
workflow_dispatch:
|
||||||
|
env:
|
||||||
|
CC: clang
|
||||||
|
jobs:
|
||||||
|
fuzz:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
target: [fuzz, fuzz_tls]
|
||||||
|
name: ${{ matrix.target }}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with: { fetch-depth: 2 }
|
||||||
|
- run: make -C test ${{ matrix.target }} ARGS="-max_total_time=14400"
|
||||||
|
|
||||||
|
# as we're not getting access to test units causing a problem, convert from the log:
|
||||||
|
# base64 -d > dataofdeath
|
||||||
|
# then paste the base64 data, enter, Ctrl-D; maybe check with hexdump -C dataofdeath
|
||||||
@@ -0,0 +1,509 @@
|
|||||||
|
name: Full build
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
- cron: '0 22 * * *' # run at 10 PM UTC
|
||||||
|
# Allow manual runs
|
||||||
|
workflow_dispatch:
|
||||||
|
env:
|
||||||
|
IPV6: 0
|
||||||
|
jobs:
|
||||||
|
linux:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
cc: [gcc, clang, g++, clang++]
|
||||||
|
target: [test]
|
||||||
|
ssl: ["", BUILTIN, MBEDTLS, OPENSSL, WOLFSSL]
|
||||||
|
select: ["-DMG_ENABLE_POLL=0 -DMG_ENABLE_EPOLL=0", "-DMG_ENABLE_POLL=1 -DMG_ENABLE_EPOLL=0", "-DMG_ENABLE_POLL=0 -DMG_ENABLE_EPOLL=1"]
|
||||||
|
exclude:
|
||||||
|
- ssl: MBEDTLS
|
||||||
|
select: "-DMG_ENABLE_POLL=0 -DMG_ENABLE_EPOLL=0"
|
||||||
|
- ssl: MBEDTLS
|
||||||
|
select: "-DMG_ENABLE_POLL=1 -DMG_ENABLE_EPOLL=0"
|
||||||
|
- ssl: OPENSSL
|
||||||
|
select: "-DMG_ENABLE_POLL=0 -DMG_ENABLE_EPOLL=0"
|
||||||
|
- ssl: OPENSSL
|
||||||
|
select: "-DMG_ENABLE_POLL=1 -DMG_ENABLE_EPOLL=0"
|
||||||
|
- ssl: WOLFSSL
|
||||||
|
select: "-DMG_ENABLE_POLL=0 -DMG_ENABLE_EPOLL=0"
|
||||||
|
- ssl: WOLFSSL
|
||||||
|
select: "-DMG_ENABLE_POLL=1 -DMG_ENABLE_EPOLL=0"
|
||||||
|
include:
|
||||||
|
- ssl: BUILTIN
|
||||||
|
cc: gcc
|
||||||
|
target: test
|
||||||
|
select: "-DMG_ENABLE_POLL=0 -DMG_ENABLE_EPOLL=1 -DMG_ENABLE_CHACHA20=0"
|
||||||
|
name: linux ${{ matrix.target }} CC=${{ matrix.cc }} SSL=${{ matrix.ssl }} TFLAGS=${{ matrix.select }}
|
||||||
|
env:
|
||||||
|
CC: ${{ matrix.cc }}
|
||||||
|
SSL: ${{ matrix.ssl }}
|
||||||
|
TFLAGS: ${{ matrix.select }} -DMQTT_LOCALHOST -DNO_ABORT
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with: { fetch-depth: 2 }
|
||||||
|
- uses: webfactory/ssh-agent@v0.9.1
|
||||||
|
with:
|
||||||
|
ssh-private-key: ${{ secrets.HEALTH_TESTS_SSH_KEY }}
|
||||||
|
- run: sudo apt -y update ; sudo apt -y install libmbedtls-dev libwolfssl-dev && test/setup_mqtt_server.sh && make -C test ${{ matrix.target }} > log
|
||||||
|
- if: success() || failure()
|
||||||
|
run: |
|
||||||
|
cat log
|
||||||
|
test/health.awk < log > json
|
||||||
|
scp -o "StrictHostKeyChecking=no" json "root@176.9.217.245:/data/downloads/health/linux_${{ matrix.target }}_${{ matrix.cc }}_${{ matrix.ssl }}_${{ matrix.select }}_$(date +"%Y%m%d").json"
|
||||||
|
mip:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
cc: [gcc, clang, g++, clang++]
|
||||||
|
target: [mip_test, mip_tap_test]
|
||||||
|
ssl: ["", BUILTIN, MBEDTLS, OPENSSL, WOLFSSL]
|
||||||
|
# #3226: built-in TCP is currently not working with WolfSSL (builds fine)
|
||||||
|
exclude:
|
||||||
|
- ssl: WOLFSSL
|
||||||
|
target: mip_tap_test
|
||||||
|
name: ${{ matrix.target }} CC=${{ matrix.cc }} SSL=${{ matrix.ssl }}
|
||||||
|
env:
|
||||||
|
CC: ${{ matrix.cc }}
|
||||||
|
SSL: ${{ matrix.ssl }}
|
||||||
|
TFLAGS: -DMQTT_LOCALHOST -DNO_ABORT
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with: { fetch-depth: 2 }
|
||||||
|
- uses: webfactory/ssh-agent@v0.9.1
|
||||||
|
with:
|
||||||
|
ssh-private-key: ${{ secrets.HEALTH_TESTS_SSH_KEY }}
|
||||||
|
- run: if [ "${{ matrix.target }}" == "mip_tap_test" ]; then ./test/setup_ga_network.sh ; export IPV6=0; else export IPV6=1 ; fi && sudo apt -y update ; sudo apt -y install libmbedtls-dev libwolfssl-dev && make -C test ${{ matrix.target }} > log
|
||||||
|
- if: success() || failure()
|
||||||
|
run: |
|
||||||
|
cat log
|
||||||
|
test/health.awk < log > json
|
||||||
|
scp -o "StrictHostKeyChecking=no" json "root@176.9.217.245:/data/downloads/health/${{ matrix.target }}_${{ matrix.cc }}_${{ matrix.ssl }}_$(date +"%Y%m%d").json"
|
||||||
|
|
||||||
|
mip89:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
max-parallel: 1 # no parallel runs, to minimize MQTT errors
|
||||||
|
matrix:
|
||||||
|
target: [mip_vc98]
|
||||||
|
name: mip89 ${{ matrix.target }}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with: { fetch-depth: 2 }
|
||||||
|
- run: make -C test ${{ matrix.target }} IPV6=1
|
||||||
|
s390:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
ssl: ["", BUILTIN]
|
||||||
|
name: S390 SSL=${{ matrix.ssl }}
|
||||||
|
env:
|
||||||
|
TFLAGS: -DMQTT_LOCALHOST
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with: { fetch-depth: 2 }
|
||||||
|
- run: sudo apt -y update ; sudo apt -y install binfmt-support qemu-user-static && ./test/setup_mqtt_server.sh && docker run --rm --privileged multiarch/qemu-user-static --reset -p yes && make -C test s390 SSL=${{ matrix.ssl }} MULTIREC=NO
|
||||||
|
armhf:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
ssl: ["", BUILTIN]
|
||||||
|
name: ArmHF SSL=${{ matrix.ssl }}
|
||||||
|
env:
|
||||||
|
TFLAGS: -DMQTT_LOCALHOST
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with: { fetch-depth: 2 }
|
||||||
|
- run: sudo apt -y update ; sudo apt -y install binfmt-support qemu-user-static && ./test/setup_mqtt_server.sh && docker run --rm --privileged multiarch/qemu-user-static --reset -p yes && make -C test armhf SSL=${{ matrix.ssl }} MULTIREC=NO
|
||||||
|
unamalgamated-mg_prefix:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
ssl: ["", BUILTIN, MBEDTLS, OPENSSL, WOLFSSL]
|
||||||
|
name: unamalgamated-mg_prefix SSL=${{ matrix.ssl }}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with: { fetch-depth: 2 }
|
||||||
|
- run: sudo apt -y update ; sudo apt -y install libmbedtls-dev libwolfssl-dev
|
||||||
|
- run: make -C test unamalgamated SSL=${{ matrix.ssl }} && make -C test mg_prefix
|
||||||
|
valgrind:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
ssl: ["", BUILTIN, MBEDTLS, OPENSSL, WOLFSSL]
|
||||||
|
name: Valgrind SSL=${{ matrix.ssl }}
|
||||||
|
env:
|
||||||
|
TFLAGS: -DMQTT_LOCALHOST
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with: { fetch-depth: 2 }
|
||||||
|
- run: sudo apt -y update ; sudo apt -y install libmbedtls-dev libwolfssl-dev valgrind
|
||||||
|
- run: ./test/setup_mqtt_server.sh && make -C test valgrind SSL=${{ matrix.ssl }}
|
||||||
|
macos:
|
||||||
|
runs-on: macos-latest
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
ssl: ["", BUILTIN, MBEDTLS, OPENSSL, WOLFSSL]
|
||||||
|
select: [-DMG_ENABLE_POLL=0, -DMG_ENABLE_POLL=1]
|
||||||
|
exclude:
|
||||||
|
- ssl: MBEDTLS
|
||||||
|
select: -DMG_ENABLE_POLL=0
|
||||||
|
- ssl: MBEDTLS # see issue#2694
|
||||||
|
select: -DMG_ENABLE_POLL=1
|
||||||
|
- ssl: OPENSSL
|
||||||
|
select: -DMG_ENABLE_POLL=0
|
||||||
|
- ssl: WOLFSSL
|
||||||
|
select: -DMG_ENABLE_POLL=0
|
||||||
|
name: macos SSL=${{ matrix.ssl }} TFLAGS=${{ matrix.select }}
|
||||||
|
env:
|
||||||
|
SSL: ${{ matrix.ssl }}
|
||||||
|
TFLAGS: ${{ matrix.select }} -DMQTT_LOCALHOST ${{ matrix.env.tflags }} -DNO_ABORT -Wno-sign-conversion -Wno-undef # Workarounds for MbedTLS
|
||||||
|
HOMEBREW_NO_AUTO_UPDATE: 1
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with: { fetch-depth: 2 }
|
||||||
|
- uses: webfactory/ssh-agent@v0.9.1
|
||||||
|
with:
|
||||||
|
ssh-private-key: ${{ secrets.HEALTH_TESTS_SSH_KEY }}
|
||||||
|
- run: brew install mbedtls wolfssl mosquitto gawk # jq openssl already pre-installed
|
||||||
|
- run: /opt/homebrew/opt/mosquitto/sbin/mosquitto -c /Users/runner/work/mongoose/mongoose/test/mosquitto.conf.macos &
|
||||||
|
- run: make -C test test ASAN_OPTIONS= MBEDTLS=$(echo $(brew --cellar)/mbedtls*/*) OPENSSL=$(echo $(brew --cellar)/openssl*/*) WOLFSSL=$(echo $(brew --cellar)/wolfssl*/*) > log
|
||||||
|
- if: success() || failure()
|
||||||
|
run: |
|
||||||
|
cat log
|
||||||
|
test/health.awk < log > json
|
||||||
|
scp -o "StrictHostKeyChecking=no" json "root@176.9.217.245:/data/downloads/health/macos_test_cc_${{ matrix.ssl }}_${{ matrix.select }}_$(date +"%Y%m%d").json"
|
||||||
|
|
||||||
|
windows:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
max-parallel: 1 # no parallel runs, to minimize MQTT errors
|
||||||
|
matrix:
|
||||||
|
target: [vc98, vc17, vc22, mingw, mingw++]
|
||||||
|
ssl: ["", BUILTIN]
|
||||||
|
select: [-DMG_ENABLE_POLL=0, -DMG_ENABLE_POLL=1]
|
||||||
|
exclude:
|
||||||
|
- target: vc98
|
||||||
|
select: -DMG_ENABLE_POLL=1
|
||||||
|
name: windows ${{ matrix.target }} SSL=${{ matrix.ssl }} TFLAGS=${{ matrix.select }}
|
||||||
|
env:
|
||||||
|
SSL: ${{ matrix.ssl }}
|
||||||
|
TFLAGS: ${{ matrix.select }} -DMQTT_LOCALHOST -DNO_ABORT
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with: { fetch-depth: 2 }
|
||||||
|
- uses: webfactory/ssh-agent@v0.9.1
|
||||||
|
with:
|
||||||
|
ssh-private-key: ${{ secrets.HEALTH_TESTS_SSH_KEY }}
|
||||||
|
- run: ./test/setup_mqtt_server.sh && make -C test ${{ matrix.target }} > log
|
||||||
|
- if: success() || failure()
|
||||||
|
run: |
|
||||||
|
cat log
|
||||||
|
test/health.awk < log > json
|
||||||
|
scp -o "StrictHostKeyChecking=no" json "root@176.9.217.245:/data/downloads/health/windows_${{ matrix.target }}_${{ matrix.cc }}_${{ matrix.ssl }}_${{ matrix.select }}_$(date +"%Y%m%d").json"
|
||||||
|
|
||||||
|
arm:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
ssl: ["", BUILTIN]
|
||||||
|
name: Arm SSL=${{ matrix.ssl }}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- run: make -C test arm SSL=${{ matrix.ssl }}
|
||||||
|
riscv:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
ssl: ["", BUILTIN]
|
||||||
|
name: RISC-V SSL=${{ matrix.ssl }}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- run: make -C test riscv SSL=${{ matrix.ssl }}
|
||||||
|
|
||||||
|
tutorials:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
ssl: [-DMG_TLS=MG_TLS_NONE, -DMG_TLS=MG_TLS_BUILTIN]
|
||||||
|
name: tutorials ${{ matrix.ssl }}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: webfactory/ssh-agent@v0.9.1
|
||||||
|
with:
|
||||||
|
ssh-private-key: ${{ secrets.HEALTH_TESTS_SSH_KEY }}
|
||||||
|
- run: sudo apt -y install libpcap-dev
|
||||||
|
- run: make -C test tutorials CFLAGS_EXTRA="${{ matrix.ssl }}" > log
|
||||||
|
- if: success() || failure()
|
||||||
|
run: |
|
||||||
|
cat log
|
||||||
|
test/health.awk < log > json
|
||||||
|
scp -o "StrictHostKeyChecking=no" json "root@176.9.217.245:/data/downloads/health/tutorials_${{ matrix.ssl }}_$(date +"%Y%m%d").json"
|
||||||
|
- run: make -C test clean_tutorials
|
||||||
|
|
||||||
|
tutorials_win:
|
||||||
|
runs-on: windows-latest
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
ssl: [-DMG_TLS=MG_TLS_NONE, -DMG_TLS=MG_TLS_BUILTIN]
|
||||||
|
name: tutorials_win ${{ matrix.ssl }}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
# - uses: egor-tensin/setup-mingw@v2
|
||||||
|
# with:
|
||||||
|
# platform: x64
|
||||||
|
- name: test they build
|
||||||
|
run: make -C test tutorials_win CFLAGS_EXTRA="${{ matrix.ssl }}"
|
||||||
|
shell: cmd
|
||||||
|
- name: test they clean
|
||||||
|
run: make -C test clean_tutorials_win
|
||||||
|
shell: cmd
|
||||||
|
tutorials_mac:
|
||||||
|
runs-on: macos-latest
|
||||||
|
env: { HOMEBREW_NO_AUTO_UPDATE: 1 }
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
ssl: [-DMG_TLS=MG_TLS_NONE, -DMG_TLS=MG_TLS_BUILTIN]
|
||||||
|
name: tutorials_mac ${{ matrix.ssl }}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- run: make -C test tutorials_mac CFLAGS_EXTRA="${{ matrix.ssl }}"
|
||||||
|
- run: make -C test clean_tutorials_mac
|
||||||
|
|
||||||
|
|
||||||
|
arduino:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with: { fetch-depth: 2 }
|
||||||
|
- run: echo # nothing specific to install or do
|
||||||
|
- run: make -C test/arduino
|
||||||
|
- run: make -C test/arduino cleanall
|
||||||
|
|
||||||
|
|
||||||
|
# wizard_examples:
|
||||||
|
# runs-on: ubuntu-latest
|
||||||
|
# strategy:
|
||||||
|
# fail-fast: false
|
||||||
|
# matrix:
|
||||||
|
# example:
|
||||||
|
# - path: esp32/esp32-idf
|
||||||
|
# name: ${{ matrix.example.path }}
|
||||||
|
# env:
|
||||||
|
# GO: 0
|
||||||
|
# steps:
|
||||||
|
# - uses: actions/checkout@v4
|
||||||
|
# with: { fetch-depth: 2 }
|
||||||
|
# - run: echo # nothing specific to install or do
|
||||||
|
# fi
|
||||||
|
# - run: make -C tutorials/${{ matrix.example.path }} build
|
||||||
|
|
||||||
|
wizard_examples_arm:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
example:
|
||||||
|
- path: infineon/xmc47_relax-make-baremetal-builtin
|
||||||
|
- path: infineon/xmc_plt2go_4400-make-baremetal-builtin
|
||||||
|
- path: infineon/xmc72_evk-make-baremetal-builtin
|
||||||
|
- path: nxp/frdm-mcxn947-make-baremetal-builtin
|
||||||
|
- path: nxp/frdm-mcxn947-make-freertos-builtin
|
||||||
|
- path: nxp/rt1020-evk-make-baremetal-builtin
|
||||||
|
- path: nxp/rt1060-evk-make-baremetal-builtin
|
||||||
|
- path: nxp/rt1170-evk-make-baremetal-builtin
|
||||||
|
- path: pico-sdk/pico-w-picosdk-baremetal-builtin
|
||||||
|
- path: pico-sdk/pico-2-w-picosdk-baremetal-builtin
|
||||||
|
- path: pico-sdk/w5500-evb-pico-picosdk-baremetal-builtin
|
||||||
|
- path: pico-sdk/w5500-evb-pico2-picosdk-baremetal-builtin
|
||||||
|
- path: pico-sdk/w55rp20-evb-pico-picosdk-baremetal-builtin
|
||||||
|
- path: stm32/nucleo-f429zi-make-baremetal-builtin
|
||||||
|
- path: stm32/nucleo-f429zi-make-freertos-builtin
|
||||||
|
- path: stm32/nucleo-f746zg-make-baremetal-builtin
|
||||||
|
- path: stm32/nucleo-f746zg-make-freertos-builtin
|
||||||
|
- path: stm32/nucleo-h563zi-make-baremetal-builtin
|
||||||
|
- path: stm32/nucleo-h563zi-make-freertos-builtin
|
||||||
|
- path: stm32/nucleo-h723zg-make-baremetal-builtin
|
||||||
|
- path: stm32/nucleo-h723zg-make-freertos-builtin
|
||||||
|
- path: stm32/nucleo-h743zi-make-baremetal-builtin
|
||||||
|
- path: stm32/nucleo-h743zi-make-freertos-builtin
|
||||||
|
- path: stm32/stm32h573i-dk-make-baremetal-builtin
|
||||||
|
- path: stm32/stm32h573i-dk-make-freertos-builtin
|
||||||
|
- path: ti/ek-tm4c1294xl-make-baremetal-builtin
|
||||||
|
- path: ti/ek-tm4c1294xl-make-freertos-builtin
|
||||||
|
name: ${{ matrix.example.path }}
|
||||||
|
env:
|
||||||
|
GO: 0
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with: { fetch-depth: 2 }
|
||||||
|
- run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
||||||
|
- run: make -C tutorials/${{ matrix.example.path }} build
|
||||||
|
|
||||||
|
|
||||||
|
generic_examples:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
example:
|
||||||
|
- path: micropython/esp32
|
||||||
|
- path: http/uart-bridge/esp32
|
||||||
|
- path: http/http-client/esp8266/http-client-server
|
||||||
|
name: ${{ matrix.example.path }}
|
||||||
|
env:
|
||||||
|
GO: 0
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with: { fetch-depth: 2 }
|
||||||
|
- run: echo # nothing specific to install or do
|
||||||
|
- run: make -C tutorials/${{ matrix.example.path }} build
|
||||||
|
|
||||||
|
generic_examples_arm:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
example:
|
||||||
|
- path: mqtt/mqtt-client/microchip/same54-xpro
|
||||||
|
- path: nxp/nxp-frdmk66f-freertos
|
||||||
|
- path: nxp/nxp-lpcxpresso54s018m-freertos
|
||||||
|
- path: nxp/nxp-mimxrt1020-freertos
|
||||||
|
- path: nxp/nxp-evkbimxrt1050-lwip-freertos
|
||||||
|
- path: nxp/nxp-evkmimxrt1020-lwip-freertos
|
||||||
|
- path: nxp/nxp-evkmimxrt1024-lwip-freertos
|
||||||
|
- path: nxp/nxp-evkmimxrt1060-lwip-freertos
|
||||||
|
- path: nxp/nxp-evkmimxrt1064-lwip-freertos
|
||||||
|
- path: nxp/nxp-evkmimxrt1160-cm7-lwip-freertos
|
||||||
|
- path: nxp/nxp-evkmimxrt1170-cm7-lwip-freertos
|
||||||
|
- path: nxp/nxp-frdmk64f-lwip-freertos
|
||||||
|
- path: nxp/nxp-frdmk66f-lwip-freertos
|
||||||
|
- path: nxp/nxp-lpcxpresso54018-lwip-freertos
|
||||||
|
- path: nxp/nxp-lpcxpresso54608-lwip-freertos
|
||||||
|
- path: nxp/nxp-lpcxpresso54618-lwip-freertos
|
||||||
|
- path: nxp/nxp-lpcxpresso54628-lwip-freertos
|
||||||
|
- path: nxp/nxp-twrk65f180m-lwip-freertos
|
||||||
|
- path: nxp/nxp-twrkv58f220m-lwip-freertos
|
||||||
|
- path: pico-sdk/pico-rmii
|
||||||
|
- path: stm32/nucleo-f429zi-make-baremetal-builtin-rndis
|
||||||
|
- path: stm32/nucleo-f746zg-make-baremetal-builtin-rndis
|
||||||
|
- path: stm32/nucleo-g031-make-baremetal-builtin
|
||||||
|
- path: ti/ti-ek-tm4c1294xl-http-server
|
||||||
|
- path: ti/ek-tm4c1294xl-make-baremetal-builtin-rndis
|
||||||
|
name: ${{ matrix.example.path }}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with: { fetch-depth: 2 }
|
||||||
|
- run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
||||||
|
- run: make -C tutorials/${{ matrix.example.path }} build
|
||||||
|
|
||||||
|
device_dashboard_examples:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
example:
|
||||||
|
- path: esp32
|
||||||
|
name: ${{ matrix.example.path }}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with: { fetch-depth: 2 }
|
||||||
|
- run: echo # nothing specific to install or do
|
||||||
|
- run: make -C tutorials/http/device-dashboard/${{ matrix.example.path }} build
|
||||||
|
|
||||||
|
|
||||||
|
device_dashboard_examples_arm:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
ssl: ["", -DMG_TLS=MG_TLS_BUILTIN]
|
||||||
|
example:
|
||||||
|
- path: http/device-dashboard/microchip/same54-xpro
|
||||||
|
- path: nxp/rt1020-evk-make-freertos-builtin
|
||||||
|
- path: nxp/rt1060-evk-make-freertos-builtin
|
||||||
|
- path: nxp/rt1170-evk-make-freertos-builtin
|
||||||
|
- path: renesas/ek-ra6m4-make-baremetal-builtin
|
||||||
|
- path: pico-sdk/pico-rndis-dashboard
|
||||||
|
- path: pico-sdk/pico-w-picosdk-freertos-lwip
|
||||||
|
- path: pico-sdk/pico-2-w-picosdk-freertos-lwip
|
||||||
|
- path: stm32/nucleo-f746zg-make-freertos-tcp
|
||||||
|
- path: stm32/nucleo-f746zg-make-baremetal-builtin-cmsis_driver
|
||||||
|
name: ${{ matrix.example.path }} ${{ matrix.ssl }}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with: { fetch-depth: 2 }
|
||||||
|
- run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
||||||
|
- run: make -C tutorials/${{ matrix.example.path }} build CFLAGS_EXTRA="${{ matrix.ssl }}"
|
||||||
|
|
||||||
|
# mqtt_dashboard_examples:
|
||||||
|
# runs-on: ubuntu-latest
|
||||||
|
# strategy:
|
||||||
|
# fail-fast: false
|
||||||
|
# matrix:
|
||||||
|
# example:
|
||||||
|
# - path:
|
||||||
|
# name: ${{ matrix.example.path }}
|
||||||
|
# steps:
|
||||||
|
# - uses: actions/checkout@v4
|
||||||
|
# with: { fetch-depth: 2 }
|
||||||
|
# - run: echo # nothing specific to install or do
|
||||||
|
# - run: make -C tutorials/${{ matrix.example.path }} build
|
||||||
|
|
||||||
|
mqtt_dashboard_examples_arm:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
example:
|
||||||
|
- path: pico-sdk/pico-rndis-device
|
||||||
|
name: ${{ matrix.example.path }}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with: { fetch-depth: 2 }
|
||||||
|
- run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
||||||
|
- run: make -C tutorials/${{ matrix.example.path }} build
|
||||||
|
|
||||||
|
# dual_examples:
|
||||||
|
# runs-on: ubuntu-latest
|
||||||
|
# strategy:
|
||||||
|
# fail-fast: false
|
||||||
|
# matrix:
|
||||||
|
# example:
|
||||||
|
# - path:
|
||||||
|
# name: ${{ matrix.example.path }}
|
||||||
|
# steps:
|
||||||
|
# - uses: actions/checkout@v4
|
||||||
|
# with: { fetch-depth: 2 }
|
||||||
|
# - run: echo # nothing specific to install or do
|
||||||
|
# - run: make -C tutorials/${{ matrix.example.path }} device_dashboard
|
||||||
|
# - run: make -C tutorials/${{ matrix.example.path }} mqtt_dashboard
|
||||||
|
|
||||||
|
cube_examples:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with: { fetch-depth: 2 }
|
||||||
|
- run: sudo pip install yq
|
||||||
|
- run: cd test/cube && make
|
||||||
|
|
||||||
|
# xpresso_examples:
|
||||||
|
# runs-on: ubuntu-latest
|
||||||
|
# steps:
|
||||||
|
# - uses: actions/checkout@v4
|
||||||
|
# with: { fetch-depth: 2 }
|
||||||
|
# - run: sudo pip install yq
|
||||||
|
# - run: cd test/xpresso && make
|
||||||
@@ -0,0 +1,143 @@
|
|||||||
|
name: Full test
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
- cron: '0 23 * * *' # run at 11 PM UTC
|
||||||
|
# Allow manual runs
|
||||||
|
workflow_dispatch:
|
||||||
|
env:
|
||||||
|
IPV6: 0
|
||||||
|
jobs:
|
||||||
|
|
||||||
|
test_f7:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with: { fetch-depth: 2 }
|
||||||
|
- name: baremetal
|
||||||
|
run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
||||||
|
- run: make -C tutorials/stm32/nucleo-f746zg-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
|
- run: make -C tutorials/stm32/nucleo-f746zg-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
|
- run: make -C tutorials/stm32/nucleo-f746zg-make-freertos-tcp test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
|
- name: Cube
|
||||||
|
run: sudo pip install yq
|
||||||
|
# - run: make -C test/cube PROJECTS=../../tutorials/stm32/nucleo-f746zg-cube-baremetal-builtin VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=5
|
||||||
|
# - run: make -C test/cube PROJECTS=../../tutorials/stm32/nucleo-f746zg-cube-freertos-builtin VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=5
|
||||||
|
- run: make -C test/cube PROJECTS=../../tutorials/stm32/nucleo-f746zg-cube-freertos-lwip VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=5
|
||||||
|
|
||||||
|
test_f4:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with: { fetch-depth: 2 }
|
||||||
|
- name: baremetal
|
||||||
|
run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
||||||
|
- run: make -C tutorials/stm32/nucleo-f429zi-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
|
- run: make -C tutorials/stm32/nucleo-f429zi-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
|
- name: Cube
|
||||||
|
run: sudo pip install yq
|
||||||
|
# - run: make -C test/cube PROJECTS=../../tutorials/stm32/nucleo-f429zi-cube-baremetal-builtin VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=2
|
||||||
|
# - run: make -C test/cube PROJECTS=../../tutorials/stm32/nucleo-f429zi-cube-freertos-builtin VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=2
|
||||||
|
- run: make -C test/cube PROJECTS=../../tutorials/stm32/nucleo-f429zi-cube-freertos-lwip VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=2
|
||||||
|
|
||||||
|
test_h743:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with: { fetch-depth: 3 }
|
||||||
|
- name: baremetal
|
||||||
|
run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
||||||
|
- run: make -C tutorials/stm32/nucleo-h743zi-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
|
- run: make -C tutorials/stm32/nucleo-h743zi-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
|
# - name: Cube
|
||||||
|
# run: echo # nothing specific to install or do
|
||||||
|
# - run: make -C test/cube PROJECTS=../../tutorials/stm32/nucleo-h743zi-cube-baremetal-builtin VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=6
|
||||||
|
# - run: make -C test/cube PROJECTS=../../tutorials/stm32/nucleo-h743zi-cube-freertos-builtin VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=6
|
||||||
|
|
||||||
|
test_h723:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with: { fetch-depth: 3 }
|
||||||
|
- name: baremetal
|
||||||
|
run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
||||||
|
- run: make -C tutorials/stm32/nucleo-h723zg-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
|
- run: make -C tutorials/stm32/nucleo-h723zg-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
|
|
||||||
|
test_h5:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with: { fetch-depth: 3 }
|
||||||
|
- name: baremetal
|
||||||
|
run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
||||||
|
- run: make -C tutorials/stm32/nucleo-h563zi-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
|
- run: make -C tutorials/stm32/nucleo-h563zi-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
|
|
||||||
|
test_rt1020:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with: { fetch-depth: 3 }
|
||||||
|
- name: baremetal
|
||||||
|
run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
||||||
|
- run: make -C tutorials/nxp/rt1020-evk-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
|
- run: make -C tutorials/nxp/rt1020-evk-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
|
|
||||||
|
test_rt1060:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with: { fetch-depth: 3 }
|
||||||
|
- name: baremetal
|
||||||
|
run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
||||||
|
- run: make -C tutorials/nxp/rt1060-evk-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
|
- run: make -C tutorials/nxp/rt1060-evk-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
|
|
||||||
|
test_rt1170:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with: { fetch-depth: 3 }
|
||||||
|
- name: baremetal
|
||||||
|
run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
||||||
|
- run: make -C tutorials/nxp/rt1170-evk-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
|
- run: make -C tutorials/nxp/rt1170-evk-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
|
|
||||||
|
test_ra6m4:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with: { fetch-depth: 3 }
|
||||||
|
- name: baremetal
|
||||||
|
run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
||||||
|
- run: make -C tutorials/renesas/ek-ra6m4-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
|
# - run: make -C tutorials/renesas/ek-ra6m4-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
|
|
||||||
|
test_tm4c:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with: { fetch-depth: 2 }
|
||||||
|
- name: baremetal
|
||||||
|
run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
||||||
|
- run: make -C tutorials/ti/ek-tm4c1294xl-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
|
- run: make -C tutorials/ti/ek-tm4c1294xl-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
|
|
||||||
|
test_same54:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with: { fetch-depth: 2 }
|
||||||
|
- name: baremetal
|
||||||
|
run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
||||||
|
- run: make -C tutorials/http/device-dashboard/microchip/same54-xpro test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
|
- run: make -C tutorials/mqtt/mqtt-client/microchip/same54-xpro test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
|
|
||||||
|
test_pico_w5500:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with: { fetch-depth: 2 }
|
||||||
|
- name: SDK
|
||||||
|
run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
||||||
|
- run: make -C tutorials/pico-sdk/w5500-evb-pico-picosdk-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
name: On demand ad hoc test
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
env:
|
||||||
|
IPV6: 0
|
||||||
|
jobs:
|
||||||
|
macos:
|
||||||
|
runs-on: macos-latest
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
ssl: [MBEDTLS, WOLFSSL]
|
||||||
|
select: [-DMG_ENABLE_POLL=1]
|
||||||
|
name: macos SSL=${{ matrix.ssl }} TFLAGS=${{ matrix.select }}
|
||||||
|
env:
|
||||||
|
SSL: ${{ matrix.ssl }}
|
||||||
|
TFLAGS: ${{ matrix.select }} -DMQTT_LOCALHOST -DNO_ABORT -Wno-sign-conversion -Wno-undef # Workarounds for MbedTLS
|
||||||
|
HOMEBREW_NO_AUTO_UPDATE: 1
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with: { fetch-depth: 2 }
|
||||||
|
- uses: webfactory/ssh-agent@v0.9.1
|
||||||
|
with:
|
||||||
|
ssh-private-key: ${{ secrets.HEALTH_TESTS_SSH_KEY }}
|
||||||
|
- run: brew install mbedtls wolfssl mosquitto gawk # jq openssl already pre-installed
|
||||||
|
- run: /opt/homebrew/opt/mosquitto/sbin/mosquitto -c /Users/runner/work/mongoose/mongoose/test/mosquitto.conf.macos &
|
||||||
|
- run: make -C test test ASAN_OPTIONS= MBEDTLS=$(echo $(brew --cellar)/mbedtls*/*) OPENSSL=$(echo $(brew --cellar)/openssl*/*) WOLFSSL=$(echo $(brew --cellar)/wolfssl*/*) > log
|
||||||
|
- if: success() || failure()
|
||||||
|
run: |
|
||||||
|
cat log
|
||||||
|
test/health.awk < log > json
|
||||||
|
scp -o "StrictHostKeyChecking=no" json "root@176.9.217.245:/data/downloads/health/macos_test_cc_${{ matrix.ssl }}_${{ matrix.select }}_$(date +"%Y%m%d").json"
|
||||||
@@ -0,0 +1,723 @@
|
|||||||
|
name: Build and test - essentials
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
paths:
|
||||||
|
- "**Makefile"
|
||||||
|
- "**.c"
|
||||||
|
- "**.h"
|
||||||
|
# Allow manual runs
|
||||||
|
workflow_dispatch:
|
||||||
|
env:
|
||||||
|
IPV6: 0
|
||||||
|
jobs:
|
||||||
|
linux:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
cc: [gcc, clang++]
|
||||||
|
target: [test, mip_test]
|
||||||
|
ssl: ["", BUILTIN]
|
||||||
|
name: linux ${{ matrix.target }} CC=${{ matrix.cc }} SSL=${{ matrix.ssl }}
|
||||||
|
env:
|
||||||
|
CC: ${{ matrix.cc }}
|
||||||
|
SSL: ${{ matrix.ssl }}
|
||||||
|
TFLAGS: -DMQTT_LOCALHOST
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with: { fetch-depth: 2 }
|
||||||
|
- run: if ./test/match_changed_files.sh '^test|^src/.*.[ch]' ; then echo GO=1 >> $GITHUB_ENV ; fi
|
||||||
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: if [ "${{ matrix.target }}" == "test" ]; then ./test/setup_mqtt_server.sh ; fi && make -C test ${{ matrix.target }}
|
||||||
|
s390:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
env:
|
||||||
|
TFLAGS: -DMQTT_LOCALHOST
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with: { fetch-depth: 2 }
|
||||||
|
- run: if ./test/match_changed_files.sh '^test|^src/.*.[ch]' ; then echo GO=1 >> $GITHUB_ENV ; fi
|
||||||
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: sudo apt -y update ; sudo apt -y install binfmt-support qemu-user-static && ./test/setup_mqtt_server.sh && docker run --rm --privileged multiarch/qemu-user-static --reset -p yes && make -C test s390
|
||||||
|
armhf:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
env:
|
||||||
|
TFLAGS: -DMQTT_LOCALHOST
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with: { fetch-depth: 2 }
|
||||||
|
- run: if ./test/match_changed_files.sh '^test|^src/.*.[ch]' ; then echo GO=1 >> $GITHUB_ENV ; fi
|
||||||
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: sudo apt -y update ; sudo apt -y install binfmt-support qemu-user-static && ./test/setup_mqtt_server.sh && docker run --rm --privileged multiarch/qemu-user-static --reset -p yes && make -C test armhf
|
||||||
|
unamalgamated-mg_prefix:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with: { fetch-depth: 2 }
|
||||||
|
- run: if ./test/match_changed_files.sh '^test|^src/.*.[ch]' ; then echo GO=1 >> $GITHUB_ENV ; fi
|
||||||
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: make -C test unamalgamated && make -C test mg_prefix
|
||||||
|
macos:
|
||||||
|
runs-on: macos-latest
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
ssl: ["", BUILTIN]
|
||||||
|
name: macos SSL=${{ matrix.ssl }}
|
||||||
|
env:
|
||||||
|
SSL: ${{ matrix.ssl }}
|
||||||
|
TFLAGS: -DMQTT_LOCALHOST # -DNO_SNTP_CHECK
|
||||||
|
HOMEBREW_NO_AUTO_UPDATE: 1
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with: { fetch-depth: 2 }
|
||||||
|
- run: if ./test/match_changed_files.sh '^test|^src/.*.[ch]' ; then echo GO=1 >> $GITHUB_ENV ; fi
|
||||||
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: |
|
||||||
|
brew install mosquitto
|
||||||
|
/opt/homebrew/opt/mosquitto/sbin/mosquitto -c /Users/runner/work/mongoose/mongoose/test/mosquitto.conf.macos &
|
||||||
|
make -C test test ASAN_OPTIONS=
|
||||||
|
windows:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
target: [vc98, vc22, mingw++]
|
||||||
|
name: windows ${{ matrix.target }}
|
||||||
|
env:
|
||||||
|
TFLAGS: -DMQTT_LOCALHOST
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with: { fetch-depth: 2 }
|
||||||
|
- run: if ./test/match_changed_files.sh '^test|^src/.*.[ch]' ; then echo GO=1 >> $GITHUB_ENV ; fi
|
||||||
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: ./test/setup_mqtt_server.sh && make -C test ${{ matrix.target }}
|
||||||
|
arm:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- run: make -C test arm
|
||||||
|
riscv:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- run: make -C test riscv
|
||||||
|
|
||||||
|
tutorials:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- run: make -C test tutorials_essential
|
||||||
|
- run: make -C test clean_tutorials_essential
|
||||||
|
tutorials_win:
|
||||||
|
runs-on: windows-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
# - uses: egor-tensin/setup-mingw@v2
|
||||||
|
# with:
|
||||||
|
# platform: x64
|
||||||
|
- name: test they build
|
||||||
|
run: make -C test tutorials_win
|
||||||
|
shell: cmd
|
||||||
|
- name: test they clean
|
||||||
|
run: make -C test clean_tutorials_win
|
||||||
|
shell: cmd
|
||||||
|
tutorials_mac:
|
||||||
|
runs-on: macos-latest
|
||||||
|
env: { HOMEBREW_NO_AUTO_UPDATE: 1 }
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- run: make -C test tutorials_mac
|
||||||
|
- run: make -C test clean_tutorials_mac
|
||||||
|
|
||||||
|
|
||||||
|
# wizard_examples:
|
||||||
|
# runs-on: ubuntu-latest
|
||||||
|
# strategy:
|
||||||
|
# fail-fast: false
|
||||||
|
# matrix:
|
||||||
|
# example:
|
||||||
|
# - path: esp32/esp32-idf
|
||||||
|
# name: ${{ matrix.example.path }}
|
||||||
|
# env:
|
||||||
|
# GO: 0
|
||||||
|
# steps:
|
||||||
|
# - uses: actions/checkout@v4
|
||||||
|
# with: { fetch-depth: 2 }
|
||||||
|
# - run: |
|
||||||
|
# if ./test/match_changed_files.sh '^src'; then
|
||||||
|
# echo GO=1 >> $GITHUB_ENV
|
||||||
|
# # nothing specific to install or do
|
||||||
|
# fi
|
||||||
|
# - if: ${{ env.GO == 1 }}
|
||||||
|
# run: make -C tutorials/${{ matrix.example.path }} build
|
||||||
|
|
||||||
|
wizard_examples_arm:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
example:
|
||||||
|
- path: infineon/xmc47_relax-make-baremetal-builtin
|
||||||
|
- path: infineon/xmc_plt2go_4400-make-baremetal-builtin
|
||||||
|
- path: infineon/xmc72_evk-make-baremetal-builtin
|
||||||
|
- path: nxp/frdm-mcxn947-make-baremetal-builtin
|
||||||
|
- path: nxp/frdm-mcxn947-make-freertos-builtin
|
||||||
|
- path: nxp/rt1020-evk-make-baremetal-builtin
|
||||||
|
- path: nxp/rt1060-evk-make-baremetal-builtin
|
||||||
|
- path: nxp/rt1170-evk-make-baremetal-builtin
|
||||||
|
- path: pico-sdk/pico-w-picosdk-baremetal-builtin
|
||||||
|
- path: pico-sdk/pico-2-w-picosdk-baremetal-builtin
|
||||||
|
- path: pico-sdk/w5500-evb-pico-picosdk-baremetal-builtin
|
||||||
|
- path: pico-sdk/w5500-evb-pico2-picosdk-baremetal-builtin
|
||||||
|
- path: pico-sdk/w55rp20-evb-pico-picosdk-baremetal-builtin
|
||||||
|
- path: stm32/nucleo-f429zi-make-baremetal-builtin
|
||||||
|
- path: stm32/nucleo-f429zi-make-freertos-builtin
|
||||||
|
- path: stm32/nucleo-f746zg-make-baremetal-builtin
|
||||||
|
- path: stm32/nucleo-f746zg-make-freertos-builtin
|
||||||
|
- path: stm32/nucleo-h563zi-make-baremetal-builtin
|
||||||
|
- path: stm32/nucleo-h563zi-make-freertos-builtin
|
||||||
|
- path: stm32/nucleo-h723zg-make-baremetal-builtin
|
||||||
|
- path: stm32/nucleo-h723zg-make-freertos-builtin
|
||||||
|
- path: stm32/nucleo-h743zi-make-baremetal-builtin
|
||||||
|
- path: stm32/nucleo-h743zi-make-freertos-builtin
|
||||||
|
- path: stm32/stm32h573i-dk-make-baremetal-builtin
|
||||||
|
- path: stm32/stm32h573i-dk-make-freertos-builtin
|
||||||
|
- path: ti/ek-tm4c1294xl-make-baremetal-builtin
|
||||||
|
- path: ti/ek-tm4c1294xl-make-freertos-builtin
|
||||||
|
name: ${{ matrix.example.path }}
|
||||||
|
env:
|
||||||
|
GO: 0
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with: { fetch-depth: 2 }
|
||||||
|
- run: |
|
||||||
|
if ./test/match_changed_files.sh '^src'; then
|
||||||
|
echo GO=1 >> $GITHUB_ENV
|
||||||
|
sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
||||||
|
fi
|
||||||
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: make -C tutorials/${{ matrix.example.path }} build
|
||||||
|
|
||||||
|
|
||||||
|
generic_examples:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
example:
|
||||||
|
- path: http/uart-bridge/esp32
|
||||||
|
- path: http/http-client/esp8266/http-client-server
|
||||||
|
name: ${{ matrix.example.path }}
|
||||||
|
env:
|
||||||
|
GO: 0
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with: { fetch-depth: 2 }
|
||||||
|
- run: if ./test/match_changed_files.sh '^src|^tutorials/http/uart-bridge|^tutorials/${{ matrix.example.path }}'; then echo GO=1 >> $GITHUB_ENV ; fi
|
||||||
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: |
|
||||||
|
# nothing specific to install or do
|
||||||
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: make -C tutorials/${{ matrix.example.path }} build
|
||||||
|
|
||||||
|
generic_examples_arm:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
example:
|
||||||
|
- path: stm32/nucleo-g031-make-baremetal-builtin
|
||||||
|
name: ${{ matrix.example.path }}
|
||||||
|
env:
|
||||||
|
GO: 0
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with: { fetch-depth: 2 }
|
||||||
|
- run: if ./test/match_changed_files.sh '^src|^tutorials/${{ matrix.example.path }}'; then echo GO=1 >> $GITHUB_ENV ; fi
|
||||||
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
||||||
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: make -C tutorials/${{ matrix.example.path }} build
|
||||||
|
|
||||||
|
device_dashboard_examples:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
example:
|
||||||
|
- path: esp32
|
||||||
|
name: ${{ matrix.example.path }}
|
||||||
|
env:
|
||||||
|
GO: 0
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with: { fetch-depth: 2 }
|
||||||
|
- run: |
|
||||||
|
if ./test/match_changed_files.sh '^src|tutorials/http/device-dashboard'; then
|
||||||
|
echo GO=1 >> $GITHUB_ENV
|
||||||
|
# nothing specific to install or do
|
||||||
|
fi
|
||||||
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: make -C tutorials/http/device-dashboard/${{ matrix.example.path }} build
|
||||||
|
|
||||||
|
device_dashboard_examples_arm:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
example:
|
||||||
|
- path: http/device-dashboard/microchip/same54-xpro
|
||||||
|
- path: nxp/rt1020-evk-make-freertos-builtin
|
||||||
|
- path: nxp/rt1060-evk-make-freertos-builtin
|
||||||
|
- path: nxp/rt1170-evk-make-freertos-builtin
|
||||||
|
- path: renesas/ek-ra6m4-make-baremetal-builtin
|
||||||
|
- path: pico-sdk/pico-rndis-dashboard
|
||||||
|
- path: pico-sdk/pico-w-picosdk-freertos-lwip
|
||||||
|
- path: pico-sdk/pico-2-w-picosdk-freertos-lwip
|
||||||
|
- path: stm32/nucleo-f746zg-make-freertos-tcp
|
||||||
|
- path: stm32/nucleo-f746zg-make-baremetal-builtin-cmsis_driver
|
||||||
|
name: ${{ matrix.example.path }}
|
||||||
|
env:
|
||||||
|
GO: 0
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with: { fetch-depth: 2 }
|
||||||
|
- run: |
|
||||||
|
if ./test/match_changed_files.sh '^src|tutorials/http/device-dashboard|^tutorials/${{ matrix.example.path }}'; then
|
||||||
|
echo GO=1 >> $GITHUB_ENV
|
||||||
|
sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
||||||
|
fi
|
||||||
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: make -C tutorials/${{ matrix.example.path }} build
|
||||||
|
|
||||||
|
# mqtt_dashboard_examples:
|
||||||
|
# runs-on: ubuntu-latest
|
||||||
|
# strategy:
|
||||||
|
# fail-fast: false
|
||||||
|
# matrix:
|
||||||
|
# example:
|
||||||
|
# - path:
|
||||||
|
# name: ${{ matrix.example.path }}
|
||||||
|
# env:
|
||||||
|
# GO: 0
|
||||||
|
# steps:
|
||||||
|
# - uses: actions/checkout@v4
|
||||||
|
# with: { fetch-depth: 2 }
|
||||||
|
# - run: |
|
||||||
|
# if ./test/match_changed_files.sh '^src|tutorials/mqtt/mqtt-dashboard/device|^tutorials/${{ matrix.example.path }}'; then
|
||||||
|
# echo GO=1 >> $GITHUB_ENV
|
||||||
|
# # nothing specific to install or do
|
||||||
|
# fi
|
||||||
|
# - if: ${{ env.GO == 1 }}
|
||||||
|
# run: make -C tutorials/${{ matrix.example.path }} build
|
||||||
|
|
||||||
|
mqtt_dashboard_examples_arm:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
example:
|
||||||
|
- path: pico-sdk/pico-rndis-device
|
||||||
|
name: ${{ matrix.example.path }}
|
||||||
|
env:
|
||||||
|
GO: 0
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with: { fetch-depth: 2 }
|
||||||
|
- run: |
|
||||||
|
if ./test/match_changed_files.sh '^src|tutorials/mqtt/mqtt-dashboard/device|^tutorials/${{ matrix.example.path }}'; then
|
||||||
|
echo GO=1 >> $GITHUB_ENV
|
||||||
|
sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
||||||
|
fi
|
||||||
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: make -C tutorials/${{ matrix.example.path }} build
|
||||||
|
|
||||||
|
cube_examples:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
env:
|
||||||
|
GO: 0
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with: { fetch-depth: 2 }
|
||||||
|
- run: |
|
||||||
|
if ./test/match_changed_files.sh '^src|tutorials/stm32/nucleo-*-cube-*'; then
|
||||||
|
echo GO=1 >> $GITHUB_ENV
|
||||||
|
sudo pip install yq
|
||||||
|
fi
|
||||||
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: cd test/cube && make
|
||||||
|
|
||||||
|
# xpresso_examples:
|
||||||
|
# runs-on: ubuntu-latest
|
||||||
|
# env:
|
||||||
|
# GO: 0
|
||||||
|
# steps:
|
||||||
|
# - uses: actions/checkout@v4
|
||||||
|
# with: { fetch-depth: 2 }
|
||||||
|
# - run: |
|
||||||
|
# if ./test/match_changed_files.sh '^src|tutorials/stm32/nucleo-*-cube-*'; then
|
||||||
|
# echo GO=1 >> $GITHUB_ENV
|
||||||
|
# sudo pip install yq
|
||||||
|
# fi
|
||||||
|
# - if: ${{ env.GO == 1 }}
|
||||||
|
# run: cd test/xpresso && make
|
||||||
|
|
||||||
|
|
||||||
|
# test_f7:
|
||||||
|
# runs-on: ubuntu-latest
|
||||||
|
# env:
|
||||||
|
# GO: 0
|
||||||
|
# steps:
|
||||||
|
# - uses: actions/checkout@v4
|
||||||
|
# with: { fetch-depth: 2 }
|
||||||
|
# - name: baremetal
|
||||||
|
# run: |
|
||||||
|
# if ./test/match_changed_files.sh "^src|tutorials/http/device-dashboard|tutorials/stm32/nucleo-f7.*-make-" ; then
|
||||||
|
# echo GO=1 >> $GITHUB_ENV
|
||||||
|
# sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
||||||
|
# fi
|
||||||
|
# # always run baremetal on core or dashboard or specific example changes; other examples only on specific example changes
|
||||||
|
# - if: ${{ env.GO == 1 }}
|
||||||
|
# continue-on-error: true # continue so next test has a chance to re-flash and exit from collisions and flash failures
|
||||||
|
# run: |
|
||||||
|
# if ./test/match_changed_files.sh '^src|tutorials/http/device-dashboard|tutorials/stm32/nucleo-f746zg-make-baremetal-builtin'; then
|
||||||
|
# make -C tutorials/stm32/nucleo-f746zg-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
|
# fi
|
||||||
|
# - if: ${{ env.GO == 1 }}
|
||||||
|
# run: |
|
||||||
|
# if ./test/match_changed_files.sh 'tutorials/stm32/nucleo-f746zg-make-freertos-builtin'; then
|
||||||
|
# make -C tutorials/stm32/nucleo-f746zg-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
|
# fi
|
||||||
|
# - if: ${{ env.GO == 1 }}
|
||||||
|
# run: |
|
||||||
|
# if ./test/match_changed_files.sh 'tutorials/stm32/nucleo-f746zg-make-freertos-tcp'; then
|
||||||
|
# make -C tutorials/stm32/nucleo-f746zg-make-freertos-tcp test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
|
# fi
|
||||||
|
# - name: Cube
|
||||||
|
# run: |
|
||||||
|
# echo GO=0 >> $GITHUB_ENV
|
||||||
|
# if ./test/match_changed_files.sh 'tutorials/stm32/nucleo-f7.*-cube-'; then
|
||||||
|
# echo GO=1 >> $GITHUB_ENV
|
||||||
|
# # nothing specific to install or do
|
||||||
|
# fi
|
||||||
|
## - if: ${{ env.GO == 1 }}
|
||||||
|
## run: |
|
||||||
|
## if ./test/match_changed_files.sh 'tutorials/stm32/nucleo-f746zg-cube-baremetal-builtin'; then
|
||||||
|
## make -C test/cube test PROJECTS=../../tutorials/stm32/nucleo-f746zg-cube-baremetal-builtin VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=5
|
||||||
|
## fi
|
||||||
|
## - if: ${{ env.GO == 1 }}
|
||||||
|
## run: |
|
||||||
|
## if ./test/match_changed_files.sh 'tutorials/stm32/nucleo-f746zg-cube-freertos-builtin'; then
|
||||||
|
## make -C test/cube test PROJECTS=../../tutorials/stm32/nucleo-f746zg-cube-freertos-builtin VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=5
|
||||||
|
## fi
|
||||||
|
# - if: ${{ env.GO == 1 }}
|
||||||
|
# run: |
|
||||||
|
# if ./test/match_changed_files.sh 'tutorials/stm32/nucleo-f746zg-cube-freertos-lwip'; then
|
||||||
|
# make -C test/cube test PROJECTS=../../tutorials/stm32/nucleo-f746zg-cube-freertos-lwip VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=5
|
||||||
|
# fi
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# test_f4:
|
||||||
|
# runs-on: ubuntu-latest
|
||||||
|
# env:
|
||||||
|
# GO: 0
|
||||||
|
# steps:
|
||||||
|
# - uses: actions/checkout@v4
|
||||||
|
# with: { fetch-depth: 2 }
|
||||||
|
# - name: baremetal
|
||||||
|
# run: |
|
||||||
|
# if ./test/match_changed_files.sh "^src|tutorials/http/device-dashboard|tutorials/stm32/nucleo-f4.*-make-" ; then
|
||||||
|
# echo GO=1 >> $GITHUB_ENV
|
||||||
|
# sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
||||||
|
# fi
|
||||||
|
# - if: ${{ env.GO == 1 }}
|
||||||
|
# continue-on-error: true
|
||||||
|
# run: |
|
||||||
|
# if ./test/match_changed_files.sh '^src|tutorials/http/device-dashboard|tutorials/stm32/nucleo-f429zi-make-baremetal-builtin'; then
|
||||||
|
# make -C tutorials/stm32/nucleo-f429zi-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
|
# fi
|
||||||
|
# - if: ${{ env.GO == 1 }}
|
||||||
|
# run: |
|
||||||
|
# if ./test/match_changed_files.sh 'tutorials/stm32/nucleo-f429zi-make-freertos-builtin'; then
|
||||||
|
# make -C tutorials/stm32/nucleo-f429zi-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
|
# fi
|
||||||
|
# - name: Cube
|
||||||
|
# run: |
|
||||||
|
# echo GO=0 >> $GITHUB_ENV
|
||||||
|
# if ./test/match_changed_files.sh 'tutorials/stm32/nucleo-f4.*-cube-'; then
|
||||||
|
# echo GO=1 >> $GITHUB_ENV
|
||||||
|
# # nothing specific to install or do
|
||||||
|
# fi
|
||||||
|
## - if: ${{ env.GO == 1 }}
|
||||||
|
## run: |
|
||||||
|
## if ./test/match_changed_files.sh 'tutorials/stm32/nucleo-f429zi-cube-baremetal-builtin'; then
|
||||||
|
## make -C test/cube test PROJECTS=../../tutorials/stm32/nucleo-f429zi-cube-baremetal-builtin VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=2
|
||||||
|
## fi
|
||||||
|
## - if: ${{ env.GO == 1 }}
|
||||||
|
## run: |
|
||||||
|
## if ./test/match_changed_files.sh 'tutorials/stm32/nucleo-f429zi-cube-freertos-builtin'; then
|
||||||
|
## make -C test/cube test PROJECTS=../../tutorials/stm32/nucleo-f429zi-cube-freertos-builtin VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=2
|
||||||
|
## fi
|
||||||
|
# - if: ${{ env.GO == 1 }}
|
||||||
|
# run: |
|
||||||
|
# if ./test/match_changed_files.sh 'tutorials/stm32/nucleo-f429zi-cube-freertos-lwip'; then
|
||||||
|
# make -C test/cube test PROJECTS=../../tutorials/stm32/nucleo-f429zi-cube-freertos-lwip VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=2
|
||||||
|
# fi
|
||||||
|
#
|
||||||
|
# test_h743:
|
||||||
|
# runs-on: ubuntu-latest
|
||||||
|
# env:
|
||||||
|
# GO: 0
|
||||||
|
# steps:
|
||||||
|
# - uses: actions/checkout@v4
|
||||||
|
# with: { fetch-depth: 3 }
|
||||||
|
# - name: baremetal
|
||||||
|
# run: |
|
||||||
|
# if ./test/match_changed_files.sh "^src|tutorials/http/device-dashboard|tutorials/stm32/nucleo-h74.*-make-" ; then
|
||||||
|
# echo GO=1 >> $GITHUB_ENV
|
||||||
|
# sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
||||||
|
# fi
|
||||||
|
# - if: ${{ env.GO == 1 }}
|
||||||
|
# continue-on-error: true
|
||||||
|
# run: |
|
||||||
|
# if ./test/match_changed_files.sh '^src|tutorials/http/device-dashboard|tutorials/stm32/nucleo-h743zi-make-baremetal-builtin'; then
|
||||||
|
# make -C tutorials/stm32/nucleo-h743zi-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
|
# fi
|
||||||
|
# - if: ${{ env.GO == 1 }}
|
||||||
|
# run: |
|
||||||
|
# if ./test/match_changed_files.sh 'tutorials/stm32/nucleo-h743zi-make-freertos-builtin'; then
|
||||||
|
# make -C tutorials/stm32/nucleo-h743zi-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
|
# fi
|
||||||
|
## - name: Cube
|
||||||
|
## run: |
|
||||||
|
## echo GO=0 >> $GITHUB_ENV
|
||||||
|
## if ./test/match_changed_files.sh 'tutorials/stm32/nucleo-h74.*-cube-'; then
|
||||||
|
## echo GO=1 >> $GITHUB_ENV
|
||||||
|
## # nothing specific to install or do
|
||||||
|
## fi
|
||||||
|
## - if: ${{ env.GO == 1 }}
|
||||||
|
## run: |
|
||||||
|
## if ./test/match_changed_files.sh 'tutorials/stm32/nucleo-h743zi-cube-baremetal-builtin'; then
|
||||||
|
## make -C test/cube test PROJECTS=../../tutorials/stm32/nucleo-h743zi-cube-baremetal-builtin VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=6
|
||||||
|
## fi
|
||||||
|
## - if: ${{ env.GO == 1 }}
|
||||||
|
## run: |
|
||||||
|
## if ./test/match_changed_files.sh 'tutorials/stm32/nucleo-h743zi-cube-freertos-builtin'; then
|
||||||
|
## make -C test/cube test PROJECTS=../../tutorials/stm32/nucleo-h743zi-cube-freertos-builtin VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=6
|
||||||
|
## fi
|
||||||
|
#
|
||||||
|
# test_h723:
|
||||||
|
# runs-on: ubuntu-latest
|
||||||
|
# env:
|
||||||
|
# GO: 0
|
||||||
|
# steps:
|
||||||
|
# - uses: actions/checkout@v4
|
||||||
|
# with: { fetch-depth: 3 }
|
||||||
|
# - name: baremetal
|
||||||
|
# run: |
|
||||||
|
# if ./test/match_changed_files.sh "^src|tutorials/http/device-dashboard|tutorials/stm32/nucleo-h72.*-make-" ; then
|
||||||
|
# echo GO=1 >> $GITHUB_ENV
|
||||||
|
# sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
||||||
|
# fi
|
||||||
|
# - if: ${{ env.GO == 1 }}
|
||||||
|
# continue-on-error: true
|
||||||
|
# run: |
|
||||||
|
# if ./test/match_changed_files.sh '^src|tutorials/http/device-dashboard|tutorials/stm32/nucleo-h723zg-make-baremetal-builtin'; then
|
||||||
|
# make -C tutorials/stm32/nucleo-h723zg-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
|
# fi
|
||||||
|
# - if: ${{ env.GO == 1 }}
|
||||||
|
# run: |
|
||||||
|
# if ./test/match_changed_files.sh 'tutorials/stm32/nucleo-h723zg-make-freertos-builtin'; then
|
||||||
|
# make -C tutorials/stm32/nucleo-h723zg-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
|
# fi
|
||||||
|
#
|
||||||
|
# test_h5:
|
||||||
|
# runs-on: ubuntu-latest
|
||||||
|
# env:
|
||||||
|
# GO: 0
|
||||||
|
# steps:
|
||||||
|
# - uses: actions/checkout@v4
|
||||||
|
# with: { fetch-depth: 3 }
|
||||||
|
# - name: baremetal
|
||||||
|
# run: |
|
||||||
|
# if ./test/match_changed_files.sh "^src|tutorials/http/device-dashboard|tutorials/stm32/nucleo-h5.*-make-" ; then
|
||||||
|
# echo GO=1 >> $GITHUB_ENV
|
||||||
|
# sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
||||||
|
# fi
|
||||||
|
# - if: ${{ env.GO == 1 }}
|
||||||
|
# continue-on-error: true
|
||||||
|
# run: |
|
||||||
|
# if ./test/match_changed_files.sh '^src|tutorials/http/device-dashboard|tutorials/stm32/nucleo-h563zi-make-baremetal-builtin'; then
|
||||||
|
# make -C tutorials/stm32/nucleo-h563zi-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
|
# fi
|
||||||
|
# - if: ${{ env.GO == 1 }}
|
||||||
|
# run: |
|
||||||
|
# if ./test/match_changed_files.sh 'tutorials/stm32/nucleo-h563zi-make-freertos-builtin'; then
|
||||||
|
# make -C tutorials/stm32/nucleo-h563zi-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
|
# fi
|
||||||
|
#
|
||||||
|
# test_rt1020:
|
||||||
|
# runs-on: ubuntu-latest
|
||||||
|
# env:
|
||||||
|
# GO: 0
|
||||||
|
# steps:
|
||||||
|
# - uses: actions/checkout@v4
|
||||||
|
# with: { fetch-depth: 3 }
|
||||||
|
# - name: baremetal
|
||||||
|
# run: |
|
||||||
|
# if ./test/match_changed_files.sh "^src|tutorials/http/device-dashboard|tutorials/nxp/rt1020.*-make-" ; then
|
||||||
|
# echo GO=1 >> $GITHUB_ENV
|
||||||
|
# sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
||||||
|
# fi
|
||||||
|
# - if: ${{ env.GO == 1 }}
|
||||||
|
# continue-on-error: true
|
||||||
|
# run: |
|
||||||
|
# if ./test/match_changed_files.sh '^src|tutorials/http/device-dashboard|tutorials/nxp/rt1020-evk-make-baremetal-builtin'; then
|
||||||
|
# make -C tutorials/nxp/rt1020-evk-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
|
# fi
|
||||||
|
# - if: ${{ env.GO == 1 }}
|
||||||
|
# run: |
|
||||||
|
# if ./test/match_changed_files.sh 'tutorials/nxp/rt1020-evk-make-freertos-builtin'; then
|
||||||
|
# make -C tutorials/nxp/rt1020-evk-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
|
# fi
|
||||||
|
#
|
||||||
|
# test_rt1060:
|
||||||
|
# runs-on: ubuntu-latest
|
||||||
|
# env:
|
||||||
|
# GO: 0
|
||||||
|
# steps:
|
||||||
|
# - uses: actions/checkout@v4
|
||||||
|
# with: { fetch-depth: 3 }
|
||||||
|
# - name: baremetal
|
||||||
|
# run: |
|
||||||
|
# if ./test/match_changed_files.sh "^src|tutorials/http/device-dashboard|tutorials/nxp/rt1060.*-make-" ; then
|
||||||
|
# echo GO=1 >> $GITHUB_ENV
|
||||||
|
# sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
||||||
|
# fi
|
||||||
|
# - if: ${{ env.GO == 1 }}
|
||||||
|
# continue-on-error: true
|
||||||
|
# run: |
|
||||||
|
# if ./test/match_changed_files.sh '^src|tutorials/http/device-dashboard|tutorials/nxp/rt1060-evk-make-baremetal-builtin'; then
|
||||||
|
# make -C tutorials/nxp/rt1060-evk-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
|
# fi
|
||||||
|
# - if: ${{ env.GO == 1 }}
|
||||||
|
# run: |
|
||||||
|
# if ./test/match_changed_files.sh 'tutorials/nxp/rt1060-evk-make-freertos-builtin'; then
|
||||||
|
# make -C tutorials/nxp/rt1060-evk-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
|
# fi
|
||||||
|
#
|
||||||
|
# test_rt1170:
|
||||||
|
# runs-on: ubuntu-latest
|
||||||
|
# env:
|
||||||
|
# GO: 0
|
||||||
|
# steps:
|
||||||
|
# - uses: actions/checkout@v4
|
||||||
|
# with: { fetch-depth: 3 }
|
||||||
|
# - name: baremetal
|
||||||
|
# run: |
|
||||||
|
# if ./test/match_changed_files.sh "^src|tutorials/http/device-dashboard|tutorials/nxp/rt1170.*-make-" ; then
|
||||||
|
# echo GO=1 >> $GITHUB_ENV
|
||||||
|
# sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
||||||
|
# fi
|
||||||
|
# - if: ${{ env.GO == 1 }}
|
||||||
|
# continue-on-error: true
|
||||||
|
# run: |
|
||||||
|
# if ./test/match_changed_files.sh '^src|tutorials/http/device-dashboard|tutorials/nxp/rt1170-evk-make-baremetal-builtin'; then
|
||||||
|
# make -C tutorials/nxp/rt1170-evk-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
|
# fi
|
||||||
|
# - if: ${{ env.GO == 1 }}
|
||||||
|
# run: |
|
||||||
|
# if ./test/match_changed_files.sh 'tutorials/nxp/rt1170-evk-make-freertos-builtin'; then
|
||||||
|
# make -C tutorials/nxp/rt1170-evk-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
|
# fi
|
||||||
|
#
|
||||||
|
# test_ra6m4:
|
||||||
|
# runs-on: ubuntu-latest
|
||||||
|
# env:
|
||||||
|
# GO: 0
|
||||||
|
# steps:
|
||||||
|
# - uses: actions/checkout@v4
|
||||||
|
# with: { fetch-depth: 3 }
|
||||||
|
# - name: baremetal
|
||||||
|
# run: |
|
||||||
|
# if ./test/match_changed_files.sh "^src|tutorials/http/device-dashboard|tutorials/renesas/ek-ra6m4.*-make-" ; then
|
||||||
|
# echo GO=1 >> $GITHUB_ENV
|
||||||
|
# sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
||||||
|
# fi
|
||||||
|
# - if: ${{ env.GO == 1 }}
|
||||||
|
# continue-on-error: true
|
||||||
|
# run: |
|
||||||
|
# if ./test/match_changed_files.sh '^src|tutorials/http/device-dashboard|tutorials/renesas/ek-ra6m4-make-baremetal-builtin'; then
|
||||||
|
# make -C tutorials/renesas/ek-ra6m4-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
|
# fi
|
||||||
|
## - if: ${{ env.GO == 1 }}
|
||||||
|
## run: |
|
||||||
|
## if ./test/match_changed_files.sh 'tutorials/renesas/ek-ra6m4-make-freertos-builtin'; then
|
||||||
|
## make -C tutorials/renesas/ek-ra6m4-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
|
## fi
|
||||||
|
#
|
||||||
|
# test_tm4c:
|
||||||
|
# runs-on: ubuntu-latest
|
||||||
|
# env:
|
||||||
|
# GO: 0
|
||||||
|
# steps:
|
||||||
|
# - uses: actions/checkout@v4
|
||||||
|
# with: { fetch-depth: 2 }
|
||||||
|
# - name: baremetal
|
||||||
|
# run: |
|
||||||
|
# if ./test/match_changed_files.sh "^src|tutorials/http/device-dashboard|tutorials/ti/ek-tm4c.*-make-" ; then
|
||||||
|
# echo GO=1 >> $GITHUB_ENV
|
||||||
|
# sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
||||||
|
# fi
|
||||||
|
# - if: ${{ env.GO == 1 }}
|
||||||
|
# run: |
|
||||||
|
# if ./test/match_changed_files.sh '^src|tutorials/http/device-dashboard|tutorials/ti/ek-tm4c1294xl-make-baremetal-builtin'; then
|
||||||
|
# make -C tutorials/ti/ek-tm4c1294xl-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
|
# fi
|
||||||
|
# - if: ${{ env.GO == 1 }}
|
||||||
|
# run: |
|
||||||
|
# if ./test/match_changed_files.sh 'tutorials/ti/ek-tm4c1294xl-make-freertos-builtin'; then
|
||||||
|
# make -C tutorials/ti/ek-tm4c1294xl-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
|
# fi
|
||||||
|
#
|
||||||
|
# test_same54:
|
||||||
|
# runs-on: ubuntu-latest
|
||||||
|
# env:
|
||||||
|
# GO: 0
|
||||||
|
# steps:
|
||||||
|
# - uses: actions/checkout@v4
|
||||||
|
# with: { fetch-depth: 2 }
|
||||||
|
# - name: baremetal
|
||||||
|
# run: |
|
||||||
|
# if ./test/match_changed_files.sh "^src|tutorials/http/device-dashboard|tutorials/mqtt/mqtt-client" ; then
|
||||||
|
# echo GO=1 >> $GITHUB_ENV
|
||||||
|
# sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
||||||
|
# fi
|
||||||
|
# - if: ${{ env.GO == 1 }}
|
||||||
|
# run: |
|
||||||
|
# if ./test/match_changed_files.sh '^src|tutorials/http/device-dashboard'; then
|
||||||
|
# make -C tutorials/http/device-dashboard/microchip/same54-xpro test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
|
# fi
|
||||||
|
# - if: ${{ env.GO == 1 }}
|
||||||
|
# run: |
|
||||||
|
# if ./test/match_changed_files.sh '^src|tutorials/mqtt/mqtt-client'; then
|
||||||
|
# make -C tutorials/mqtt/mqtt-client/microchip/same54-xpro test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
|
# fi
|
||||||
|
#
|
||||||
|
# test_pico_w5500:
|
||||||
|
# runs-on: ubuntu-latest
|
||||||
|
# env:
|
||||||
|
# GO: 0
|
||||||
|
# steps:
|
||||||
|
# - uses: actions/checkout@v4
|
||||||
|
# with: { fetch-depth: 2 }
|
||||||
|
# - name: SDK
|
||||||
|
# run: |
|
||||||
|
# if ./test/match_changed_files.sh "^src" ; then
|
||||||
|
# echo GO=1 >> $GITHUB_ENV
|
||||||
|
# sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
||||||
|
# fi
|
||||||
|
# - if: ${{ env.GO == 1 }}
|
||||||
|
# run: make -C tutorials/pico-sdk/w5500-evb-pico-picosdk-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
|
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
name: build
|
name: original workflow, outdated # *** YES, OUTDATED *** kept for hystorical/reference purposes, attachment, etc.
|
||||||
on: [push, pull_request]
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
env:
|
env:
|
||||||
IPV6: 0
|
IPV6: 0
|
||||||
jobs:
|
jobs:
|
||||||
@@ -10,69 +11,100 @@ jobs:
|
|||||||
matrix:
|
matrix:
|
||||||
cc: [gcc, clang, g++, clang++]
|
cc: [gcc, clang, g++, clang++]
|
||||||
target: [test, mip_test]
|
target: [test, mip_test]
|
||||||
# target: [test]
|
ssl: ["", MBEDTLS, OPENSSL]
|
||||||
ssl: [MBEDTLS, OPENSSL]
|
select: ["-DMG_ENABLE_POLL=0 -DMG_ENABLE_EPOLL=0", "-DMG_ENABLE_POLL=1 -DMG_ENABLE_EPOLL=0", "-DMG_ENABLE_POLL=0 -DMG_ENABLE_EPOLL=1"]
|
||||||
name: linux ${{ matrix.target }} CC=${{ matrix.cc }} SSL=${{ matrix.ssl }}
|
exclude:
|
||||||
|
- ssl: MBEDTLS
|
||||||
|
select: "-DMG_ENABLE_POLL=0 -DMG_ENABLE_EPOLL=0"
|
||||||
|
- ssl: MBEDTLS
|
||||||
|
select: "-DMG_ENABLE_POLL=1 -DMG_ENABLE_EPOLL=0"
|
||||||
|
- ssl: OPENSSL
|
||||||
|
select: "-DMG_ENABLE_POLL=0 -DMG_ENABLE_EPOLL=0"
|
||||||
|
- ssl: OPENSSL
|
||||||
|
select: "-DMG_ENABLE_POLL=1 -DMG_ENABLE_EPOLL=0"
|
||||||
|
name: linux ${{ matrix.target }} CC=${{ matrix.cc }} SSL=${{ matrix.ssl }} TFLAGS=${{ matrix.select }}
|
||||||
env:
|
env:
|
||||||
CC: ${{ matrix.cc }}
|
CC: ${{ matrix.cc }}
|
||||||
SSL: ${{ matrix.ssl }}
|
SSL: ${{ matrix.ssl }}
|
||||||
|
TFLAGS: ${{ matrix.select }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- run: ./test/setup_ga_network.sh
|
with: { fetch-depth: 2 }
|
||||||
- run: sudo apt-get update ; sudo apt-get install libmbedtls-dev
|
- run: if ./test/match_changed_files.sh '^test|^src/.*.[ch]' ; then echo GO=1 >> $GITHUB_ENV ; fi
|
||||||
- run: make ${{ matrix.target }}
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: ./test/setup_ga_network.sh && sudo apt -y update ; sudo apt -y install libmbedtls-dev && make ${{ matrix.target }}
|
||||||
s390:
|
s390:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- run: sudo apt-get update && sudo apt-get install qemu binfmt-support qemu-user-static
|
with: { fetch-depth: 2 }
|
||||||
- run: docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
|
- run: if ./test/match_changed_files.sh '^test|^src/.*.[ch]' ; then echo GO=1 >> $GITHUB_ENV ; fi
|
||||||
- run: make s390
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: sudo apt -y update ; sudo apt -y install qemu binfmt-support qemu-user-static && docker run --rm --privileged multiarch/qemu-user-static --reset -p yes && make s390
|
||||||
armhf:
|
armhf:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- run: sudo apt-get update && sudo apt-get install qemu binfmt-support qemu-user-static
|
with: { fetch-depth: 2 }
|
||||||
- run: docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
|
- run: if ./test/match_changed_files.sh '^test|^src/.*.[ch]' ; then echo GO=1 >> $GITHUB_ENV ; fi
|
||||||
- run: make armhf
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: sudo apt -y update ; sudo apt -y install qemu binfmt-support qemu-user-static && docker run --rm --privileged multiarch/qemu-user-static --reset -p yes && make armhf
|
||||||
linux2:
|
linux2:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- run: sudo apt-get update ; sudo apt-get install libmbedtls-dev valgrind
|
with: { fetch-depth: 2 }
|
||||||
- run: make unamalgamated
|
- run: if ./test/match_changed_files.sh '^test|^src/.*.[ch]' ; then echo GO=1 >> $GITHUB_ENV ; fi
|
||||||
- run: make valgrind
|
- if: ${{ env.GO == 1 }}
|
||||||
- run: make mg_prefix
|
run: sudo apt -y update ; sudo apt -y install libmbedtls-dev valgrind
|
||||||
examples:
|
- if: ${{ env.GO == 1 }}
|
||||||
runs-on: ubuntu-latest
|
run: make unamalgamated && make valgrind && make mg_prefix
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
- run: sudo apt -y install libmbedtls-dev libpcap-dev
|
|
||||||
- run: make clean examples
|
|
||||||
- run: make clean test MG_ENABLE_POLL=1
|
|
||||||
macos:
|
macos:
|
||||||
runs-on: macos-latest
|
runs-on: macos-latest
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
ssl: ["", MBEDTLS, OPENSSL]
|
||||||
|
select: [-DMG_ENABLE_POLL=0, -DMG_ENABLE_POLL=1]
|
||||||
|
exclude:
|
||||||
|
- ssl: MBEDTLS
|
||||||
|
select: -DMG_ENABLE_POLL=0
|
||||||
|
- ssl: OPENSSL
|
||||||
|
select: -DMG_ENABLE_POLL=0
|
||||||
|
name: macos SSL=${{ matrix.ssl }} TFLAGS=${{ matrix.select }}
|
||||||
|
env:
|
||||||
|
SSL: ${{ matrix.ssl }}
|
||||||
|
TFLAGS: ${{ matrix.select }} -DNO_SNTP_CHECK -Wno-sign-conversion # Workaround for MbedTLS 3.5.0
|
||||||
|
HOMEBREW_NO_AUTO_UPDATE: 1
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- run: HOMEBREW_NO_AUTO_UPDATE=1 brew install jq mbedtls openssl
|
with: { fetch-depth: 2 }
|
||||||
- run: make test upload-coverage SSL=OPENSSL ASAN_OPTIONS= OPENSSL=`echo /usr/local/Cellar/openssl*/*`
|
- run: if ./test/match_changed_files.sh '^test|^src/.*.[ch]' ; then echo GO=1 >> $GITHUB_ENV ; fi
|
||||||
- run: make test SSL=MBEDTLS ASAN_OPTIONS= MBEDTLS=`echo /usr/local/Cellar/mbedtls*/*`
|
- if: ${{ env.GO == 1 }}
|
||||||
#- run: make mip_test ASAN_OPTIONS=
|
run: brew install jq mbedtls openssl
|
||||||
- run: make mg_prefix
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: make test ASAN_OPTIONS= MBEDTLS=`echo /usr/local/Cellar/mbedtls*/*` OPENSSL=`echo /usr/local/Cellar/openssl*/*`
|
||||||
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: make mg_prefix
|
||||||
windows:
|
windows:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
target: [vc98, vc17, vc22, mingw, mingw++]
|
||||||
|
select: [-DMG_ENABLE_POLL=0, -DMG_ENABLE_POLL=1]
|
||||||
|
exclude:
|
||||||
|
- target: vc98
|
||||||
|
select: -DMG_ENABLE_POLL=1
|
||||||
|
name: windows ${{ matrix.target }} TFLAGS=${{ matrix.select }}
|
||||||
|
env:
|
||||||
|
TFLAGS: ${{ matrix.select }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- run: make vc98
|
with: { fetch-depth: 2 }
|
||||||
- run: make vc17
|
- run: if ./test/match_changed_files.sh '^test|^src/.*.[ch]' ; then echo GO=1 >> $GITHUB_ENV ; fi
|
||||||
- run: make vc22
|
- if: ${{ env.GO == 1 }}
|
||||||
- run: make mingw
|
run: make ${{ matrix.target }}
|
||||||
- run: make mingw++
|
|
||||||
arduino-xiao:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
- run: make arduino-xiao
|
|
||||||
arm:
|
arm:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
@@ -83,29 +115,92 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- run: make riscv
|
- run: make riscv
|
||||||
matrix_examples:
|
|
||||||
|
examples:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- run: sudo apt -y install libmbedtls-dev libpcap-dev
|
||||||
|
- run: make examples
|
||||||
|
- run: make clean
|
||||||
|
examples_win:
|
||||||
|
runs-on: windows-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
# - uses: egor-tensin/setup-mingw@v2
|
||||||
|
# with:
|
||||||
|
# platform: x64
|
||||||
|
- name: test they build
|
||||||
|
run: make examples_win
|
||||||
|
shell: cmd
|
||||||
|
- name: test they clean
|
||||||
|
run: make clean_examples_win
|
||||||
|
shell: cmd
|
||||||
|
examples_mac:
|
||||||
|
runs-on: macos-latest
|
||||||
|
env: { HOMEBREW_NO_AUTO_UPDATE: 1 }
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- run: make examples_mac
|
||||||
|
- run: make clean_examples_mac
|
||||||
|
|
||||||
|
|
||||||
|
arduino:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
env:
|
||||||
|
GO: 0
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
with: { fetch-depth: 2 }
|
||||||
|
- run: |
|
||||||
|
if ./test/match_changed_files.sh "^src|examples/device-dashboard|examples/arduino" ; then
|
||||||
|
echo GO=1 >> $GITHUB_ENV
|
||||||
|
# nothing specific to install or do
|
||||||
|
fi
|
||||||
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: |
|
||||||
|
if ./test/match_changed_files.sh '^src|examples/arduino'; then
|
||||||
|
make -C examples/arduino arduino-xiao
|
||||||
|
fi
|
||||||
|
# - if: ${{ env.GO == 1 }}
|
||||||
|
# run: |
|
||||||
|
# if ./test/match_changed_files.sh '^src|examples/arduino'; then
|
||||||
|
# make -C examples/arduino arduino-nano
|
||||||
|
# fi
|
||||||
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: make -C examples/arduino clean
|
||||||
|
|
||||||
|
|
||||||
|
generic_examples:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
example:
|
example:
|
||||||
- path: esp32/device-dashboard
|
|
||||||
- path: esp32/uart-bridge
|
- path: esp32/uart-bridge
|
||||||
|
- path: esp32/micropython
|
||||||
- path: esp8266/http-client-server
|
- path: esp8266/http-client-server
|
||||||
- path: stm32/nucleo-h743zi-baremetal
|
name: ${{ matrix.example.path }}
|
||||||
target: test
|
env:
|
||||||
- path: stm32/stm32-freertos-tcp
|
GO: 0
|
||||||
- path: stm32/stm32-nucleo-f746z
|
steps:
|
||||||
- path: stm32/stm32-nucleo-f746zg
|
- uses: actions/checkout@v3
|
||||||
- path: stm32/stm32-nucleo-f429z
|
with: { fetch-depth: 2 }
|
||||||
- path: stm32/stm32-nucleo-h743z
|
- run: if ./test/match_changed_files.sh '^src|^examples/${{ matrix.example.path }}'; then echo GO=1 >> $GITHUB_ENV ; fi
|
||||||
- path: stm32/nucleo-f429zi-baremetal
|
- if: ${{ env.GO == 1 }}
|
||||||
target: test
|
run: |
|
||||||
- path: stm32/nucleo-f429zi-freertos-mip
|
# nothing specific to install or do
|
||||||
- path: stm32/nucleo-f429zi-usb-rndis
|
- if: ${{ env.GO == 1 }}
|
||||||
- path: stm32/nucleo-f746zg-baremetal
|
run: make -C examples/${{ matrix.example.path }} build
|
||||||
- path: stm32/nucleo-f746zg-freertos-mip
|
|
||||||
- path: stm32/nucleo-f746zg-usb-rndis
|
generic_examples_arm:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
example:
|
||||||
|
- path: microchip/same54-xpro/mqtt-client
|
||||||
|
- path: infineon/infineon-xmc4700_4800-lwip-rtx-rtos
|
||||||
- path: nxp/nxp-mimxrt1020-azurertos
|
- path: nxp/nxp-mimxrt1020-azurertos
|
||||||
- path: nxp/nxp-frdmk66f-freertos
|
- path: nxp/nxp-frdmk66f-freertos
|
||||||
- path: nxp/nxp-lpcxpresso54s018m-freertos
|
- path: nxp/nxp-lpcxpresso54s018m-freertos
|
||||||
@@ -125,33 +220,521 @@ jobs:
|
|||||||
- path: nxp/nxp-lpcxpresso54628-lwip-freertos
|
- path: nxp/nxp-lpcxpresso54628-lwip-freertos
|
||||||
- path: nxp/nxp-twrk65f180m-lwip-freertos
|
- path: nxp/nxp-twrk65f180m-lwip-freertos
|
||||||
- path: nxp/nxp-twrkv58f220m-lwip-freertos
|
- path: nxp/nxp-twrkv58f220m-lwip-freertos
|
||||||
- path: infineon/infineon-xmc4700_4800-lwip-rtx-rtos
|
|
||||||
- path: ti/ti-ek-tm4c1294xl-http-server
|
|
||||||
- path: ti/ek-tm4c1294xl-baremetal
|
|
||||||
- path: ti/ek-tm4c1294xl-freertos-mip
|
|
||||||
- path: rp2040/pico-rmii
|
- path: rp2040/pico-rmii
|
||||||
|
- path: stm32/nucleo-f429zi-make-baremetal-builtin-rndis
|
||||||
|
- path: stm32/nucleo-f746zg-make-baremetal-builtin-rndis
|
||||||
|
- path: stm32/nucleo-g031-make-baremetal-builtin
|
||||||
|
- path: ti/ti-ek-tm4c1294xl-http-server
|
||||||
|
- path: ti/ek-tm4c1294xl-make-baremetal-builtin-rndis
|
||||||
|
name: ${{ matrix.example.path }}
|
||||||
|
env:
|
||||||
|
GO: 0
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
with: { fetch-depth: 2 }
|
||||||
|
- run: if ./test/match_changed_files.sh '^src|^examples/${{ matrix.example.path }}'; then echo GO=1 >> $GITHUB_ENV ; fi
|
||||||
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
||||||
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: make -C examples/${{ matrix.example.path }} build
|
||||||
|
|
||||||
|
device_dashboard_examples:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
example:
|
||||||
|
- path: esp32/device-dashboard
|
||||||
|
name: ${{ matrix.example.path }}
|
||||||
|
env:
|
||||||
|
GO: 0
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
with: { fetch-depth: 2 }
|
||||||
|
- run: |
|
||||||
|
if ./test/match_changed_files.sh '^src|examples/device-dashboard|^examples/${{ matrix.example.path }}'; then
|
||||||
|
echo GO=1 >> $GITHUB_ENV
|
||||||
|
# nothing specific to install or do
|
||||||
|
fi
|
||||||
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: make -C examples/${{ matrix.example.path }} build
|
||||||
|
|
||||||
|
device_dashboard_examples_arm:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
example:
|
||||||
|
- path: microchip/same54-xpro/device-dashboard
|
||||||
|
- path: nxp/rt1020-evk-make-baremetal-builtin
|
||||||
|
- path: nxp/rt1020-evk-make-freertos-builtin
|
||||||
|
- path: nxp/rt1060-evk-make-baremetal-builtin
|
||||||
|
- path: nxp/rt1060-evk-make-freertos-builtin
|
||||||
- path: rp2040/pico-rndis-dashboard
|
- path: rp2040/pico-rndis-dashboard
|
||||||
- path: rp2040/pico-w
|
- path: rp2040/pico-w
|
||||||
- path: rp2040/pico-w5500
|
- path: rp2040/pico-w5500
|
||||||
target: test
|
- path: stm32/nucleo-f429zi-make-baremetal-builtin
|
||||||
|
- path: stm32/nucleo-f429zi-make-freertos-builtin
|
||||||
|
- path: stm32/nucleo-f746zg-make-baremetal-builtin
|
||||||
|
- path: stm32/nucleo-f746zg-make-freertos-builtin
|
||||||
|
- path: stm32/nucleo-f746zg-make-freertos-tcp
|
||||||
|
- path: stm32/nucleo-f746zg-make-baremetal-builtin-cmsis_driver
|
||||||
|
- path: stm32/nucleo-h563zi-make-baremetal-builtin
|
||||||
|
- path: stm32/nucleo-h563zi-make-freertos-builtin
|
||||||
|
- path: stm32/nucleo-h723zg-make-freertos-builtin
|
||||||
|
- path: stm32/nucleo-h743zi-make-baremetal-builtin
|
||||||
|
- path: stm32/nucleo-h743zi-make-freertos-builtin
|
||||||
|
- path: stm32/stm32h573i-dk-make-baremetal-builtin
|
||||||
|
- path: stm32/stm32h573i-dk-make-freertos-builtin
|
||||||
|
- path: ti/ek-tm4c1294xl-make-baremetal-builtin
|
||||||
|
- path: ti/ek-tm4c1294xl-make-freertos-builtin
|
||||||
name: ${{ matrix.example.path }}
|
name: ${{ matrix.example.path }}
|
||||||
|
env:
|
||||||
|
GO: 0
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- run: sudo apt -y install gcc-arm-none-eabi
|
with: { fetch-depth: 2 }
|
||||||
- name: ${{ matrix.example.path }}
|
- run: |
|
||||||
run: make -C examples/${{ matrix.example.path }} ${{ matrix.example.target || 'build' }} VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
if ./test/match_changed_files.sh '^src|examples/device-dashboard|^examples/${{ matrix.example.path }}'; then
|
||||||
|
echo GO=1 >> $GITHUB_ENV
|
||||||
|
sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
||||||
|
fi
|
||||||
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: make -C examples/${{ matrix.example.path }} build
|
||||||
|
|
||||||
|
# mqtt_dashboard_examples:
|
||||||
|
# runs-on: ubuntu-latest
|
||||||
|
# strategy:
|
||||||
|
# fail-fast: false
|
||||||
|
# matrix:
|
||||||
|
# example:
|
||||||
|
# - path:
|
||||||
|
# name: ${{ matrix.example.path }}
|
||||||
|
# env:
|
||||||
|
# GO: 0
|
||||||
|
# steps:
|
||||||
|
# - uses: actions/checkout@v3
|
||||||
|
# with: { fetch-depth: 2 }
|
||||||
|
# - run: |
|
||||||
|
# if ./test/match_changed_files.sh '^src|examples/mqtt-dashboard/device|^examples/${{ matrix.example.path }}'; then
|
||||||
|
# echo GO=1 >> $GITHUB_ENV
|
||||||
|
# # nothing specific to install or do
|
||||||
|
# fi
|
||||||
|
# - if: ${{ env.GO == 1 }}
|
||||||
|
# run: make -C examples/${{ matrix.example.path }} build
|
||||||
|
|
||||||
|
mqtt_dashboard_examples_arm:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
example:
|
||||||
|
- path: rp2040/pico-rndis-device
|
||||||
|
name: ${{ matrix.example.path }}
|
||||||
|
env:
|
||||||
|
GO: 0
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
with: { fetch-depth: 2 }
|
||||||
|
- run: |
|
||||||
|
if ./test/match_changed_files.sh '^src|examples/mqtt-dashboard/device|^examples/${{ matrix.example.path }}'; then
|
||||||
|
echo GO=1 >> $GITHUB_ENV
|
||||||
|
sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
||||||
|
fi
|
||||||
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: make -C examples/${{ matrix.example.path }} build
|
||||||
|
|
||||||
|
# dual_examples:
|
||||||
|
# runs-on: ubuntu-latest
|
||||||
|
# strategy:
|
||||||
|
# fail-fast: false
|
||||||
|
# matrix:
|
||||||
|
# example:
|
||||||
|
# - path:
|
||||||
|
# name: ${{ matrix.example.path }}
|
||||||
|
# env:
|
||||||
|
# GO: 0
|
||||||
|
# steps:
|
||||||
|
# - uses: actions/checkout@v3
|
||||||
|
# with: { fetch-depth: 2 }
|
||||||
|
# - run: |
|
||||||
|
# if ./test/match_changed_files.sh '^src|examples/device-dashboard|examples/mqtt-dashboard/device|^examples/${{ matrix.example.path }}'; then
|
||||||
|
# echo GO=1 >> $GITHUB_ENV
|
||||||
|
# # nothing specific to install or do
|
||||||
|
# fi
|
||||||
|
# - if: ${{ env.GO == 1 }}
|
||||||
|
# run: |
|
||||||
|
# if ./test/match_changed_files.sh '^src|examples/device-dashboard|^examples/${{ matrix.example.path }}'; then
|
||||||
|
# make -C examples/${{ matrix.example.path }} device_dashboard
|
||||||
|
# fi
|
||||||
|
# - if: ${{ env.GO == 1 }}
|
||||||
|
# run: |
|
||||||
|
# if ./test/match_changed_files.sh '^src|examples/mqtt-dashboard/device|^examples/${{ matrix.example.path }}'; then
|
||||||
|
# make -C examples/${{ matrix.example.path }} mqtt_dashboard
|
||||||
|
# fi
|
||||||
|
|
||||||
|
dual_examples_arm:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
example:
|
||||||
|
- path: stm32/nucleo-h723zg-make-baremetal-builtin
|
||||||
|
name: ${{ matrix.example.path }}
|
||||||
|
env:
|
||||||
|
GO: 0
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
with: { fetch-depth: 2 }
|
||||||
|
- run: |
|
||||||
|
if ./test/match_changed_files.sh '^src|examples/device-dashboard|examples/mqtt-dashboard/device|^examples/${{ matrix.example.path }}'; then
|
||||||
|
echo GO=1 >> $GITHUB_ENV
|
||||||
|
sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
||||||
|
fi
|
||||||
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: |
|
||||||
|
if ./test/match_changed_files.sh '^src|examples/device-dashboard|^examples/${{ matrix.example.path }}'; then
|
||||||
|
make -C examples/${{ matrix.example.path }} device_dashboard
|
||||||
|
fi
|
||||||
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: |
|
||||||
|
if ./test/match_changed_files.sh '^src|examples/mqtt-dashboard/device|^examples/${{ matrix.example.path }}'; then
|
||||||
|
make -C examples/${{ matrix.example.path }} mqtt_dashboard
|
||||||
|
fi
|
||||||
|
|
||||||
|
cube_examples:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
env:
|
||||||
|
GO: 0
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
with: { fetch-depth: 2 }
|
||||||
|
- run: |
|
||||||
|
if ./test/match_changed_files.sh '^src|examples/stm32/nucleo-*-cube-*'; then
|
||||||
|
echo GO=1 >> $GITHUB_ENV
|
||||||
|
# nothing specific to install or do
|
||||||
|
fi
|
||||||
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: cd test/cube && make
|
||||||
|
|
||||||
zephyr_examples:
|
zephyr_examples:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
env:
|
||||||
|
GO: 0
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- run: make -C examples/zephyr init
|
with: { fetch-depth: 2 }
|
||||||
|
- run: |
|
||||||
|
if ./test/match_changed_files.sh '^src/.*.[ch]|^examples/zephyr'; then
|
||||||
|
echo GO=1 >> $GITHUB_ENV
|
||||||
|
sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
||||||
|
fi
|
||||||
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: make -C examples/zephyr init
|
||||||
- name: minify manifest
|
- name: minify manifest
|
||||||
|
if: ${{ env.GO == 1 }}
|
||||||
uses: mikefarah/yq@master
|
uses: mikefarah/yq@master
|
||||||
with:
|
with:
|
||||||
cmd: yq -i eval '(.manifest.defaults, .manifest.remotes, .manifest.projects[] | select(.name == "cmsis" or .name == "hal_stm32" or .name == "mbedtls" or .name == "mcuboot" or .name == "picolibc" | del(.null) ), .manifest.self) as $i ireduce({};setpath($i | path; $i)) | del(.manifest.projects.[].null) | del(..|select(length==0))' examples/zephyr/zephyrproject/zephyr/west.yml
|
cmd: yq -i eval '(.manifest.defaults, .manifest.remotes, .manifest.projects[] | select(.name == "cmsis" or .name == "hal_stm32" or .name == "mbedtls" or .name == "mcuboot" or .name == "picolibc" | del(.null) ), .manifest.self) as $i ireduce({};setpath($i | path; $i)) | del(.manifest.projects.[].null) | del(..|select(length==0))' examples/zephyr/zephyrproject/zephyr/west.yml
|
||||||
- run: make -C examples/zephyr update
|
- if: ${{ env.GO == 1 }}
|
||||||
- run: make -C examples/zephyr/device-dashboard build
|
run: make -C examples/zephyr update
|
||||||
- run: make -C examples/zephyr/http-client build
|
- if: ${{ env.GO == 1 }}
|
||||||
- run: make -C examples/zephyr/http-server build
|
run: make -C examples/zephyr/device-dashboard build
|
||||||
- run: make -C examples/zephyr/mqtt-aws-client build
|
- if: ${{ env.GO == 1 }}
|
||||||
- run: make -C examples/zephyr/websocket-server build
|
run: make -C examples/zephyr/http-client build
|
||||||
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: make -C examples/zephyr/http-server build
|
||||||
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: make -C examples/zephyr/mqtt-aws-client build
|
||||||
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: make -C examples/zephyr/websocket-server build
|
||||||
|
|
||||||
|
test_f7:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
env:
|
||||||
|
GO: 0
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
with: { fetch-depth: 2 }
|
||||||
|
- name: baremetal
|
||||||
|
run: |
|
||||||
|
if ./test/match_changed_files.sh "^src|examples/device-dashboard|examples/stm32/nucleo-f7.*-make-" ; then
|
||||||
|
echo GO=1 >> $GITHUB_ENV
|
||||||
|
sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
||||||
|
fi
|
||||||
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: |
|
||||||
|
if ./test/match_changed_files.sh '^src|examples/device-dashboard|examples/stm32/nucleo-f746zg-make-baremetal-builtin'; then
|
||||||
|
make -C examples/stm32/nucleo-f746zg-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
|
fi
|
||||||
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: |
|
||||||
|
if ./test/match_changed_files.sh '^src|examples/device-dashboard|examples/stm32/nucleo-f746zg-make-freertos-builtin'; then
|
||||||
|
make -C examples/stm32/nucleo-f746zg-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
|
fi
|
||||||
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: |
|
||||||
|
if ./test/match_changed_files.sh '^src|examples/device-dashboard|examples/stm32/nucleo-f746zg-make-freertos-tcp'; then
|
||||||
|
make -C examples/stm32/nucleo-f746zg-make-freertos-tcp test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
|
fi
|
||||||
|
- name: Cube
|
||||||
|
run: |
|
||||||
|
echo GO=0 >> $GITHUB_ENV
|
||||||
|
if ./test/match_changed_files.sh '^src|examples/device-dashboard|examples/stm32/nucleo-f7.*-cube-'; then
|
||||||
|
echo GO=1 >> $GITHUB_ENV
|
||||||
|
# nothing specific to install or do
|
||||||
|
fi
|
||||||
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: |
|
||||||
|
if ./test/match_changed_files.sh '^src|examples/device-dashboard|examples/stm32/nucleo-f746zg-cube-baremetal-builtin'; then
|
||||||
|
make -C test/cube test PROJECTS=../../examples/stm32/nucleo-f746zg-cube-baremetal-builtin VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=5
|
||||||
|
fi
|
||||||
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: |
|
||||||
|
if ./test/match_changed_files.sh '^src|examples/device-dashboard|examples/stm32/nucleo-f746zg-cube-freertos-builtin'; then
|
||||||
|
make -C test/cube test PROJECTS=../../examples/stm32/nucleo-f746zg-cube-freertos-builtin VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=5
|
||||||
|
fi
|
||||||
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: |
|
||||||
|
if ./test/match_changed_files.sh '^src|examples/device-dashboard|examples/stm32/nucleo-f746zg-cube-freertos-lwip'; then
|
||||||
|
make -C test/cube test PROJECTS=../../examples/stm32/nucleo-f746zg-cube-freertos-lwip VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=5
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
test_f4:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
env:
|
||||||
|
GO: 0
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
with: { fetch-depth: 2 }
|
||||||
|
- name: baremetal
|
||||||
|
run: |
|
||||||
|
if ./test/match_changed_files.sh "^src|examples/device-dashboard|examples/stm32/nucleo-f4.*-make-" ; then
|
||||||
|
echo GO=1 >> $GITHUB_ENV
|
||||||
|
sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
||||||
|
fi
|
||||||
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: |
|
||||||
|
if ./test/match_changed_files.sh '^src|examples/device-dashboard|examples/stm32/nucleo-f429zi-make-baremetal-builtin'; then
|
||||||
|
make -C examples/stm32/nucleo-f429zi-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
|
fi
|
||||||
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: |
|
||||||
|
if ./test/match_changed_files.sh '^src|examples/device-dashboard|examples/stm32/nucleo-f429zi-make-freertos-builtin'; then
|
||||||
|
make -C examples/stm32/nucleo-f429zi-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
|
fi
|
||||||
|
- name: Cube
|
||||||
|
run: |
|
||||||
|
echo GO=0 >> $GITHUB_ENV
|
||||||
|
if ./test/match_changed_files.sh '^src|examples/device-dashboard|examples/stm32/nucleo-f4.*-cube-'; then
|
||||||
|
echo GO=1 >> $GITHUB_ENV
|
||||||
|
# nothing specific to install or do
|
||||||
|
fi
|
||||||
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: |
|
||||||
|
if ./test/match_changed_files.sh '^src|examples/device-dashboard|examples/stm32/nucleo-f429zi-cube-baremetal-builtin'; then
|
||||||
|
make -C test/cube test PROJECTS=../../examples/stm32/nucleo-f429zi-cube-baremetal-builtin VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=2
|
||||||
|
fi
|
||||||
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: |
|
||||||
|
if ./test/match_changed_files.sh '^src|examples/device-dashboard|examples/stm32/nucleo-f429zi-cube-freertos-builtin'; then
|
||||||
|
make -C test/cube test PROJECTS=../../examples/stm32/nucleo-f429zi-cube-freertos-builtin VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=2
|
||||||
|
fi
|
||||||
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: |
|
||||||
|
if ./test/match_changed_files.sh '^src|examples/device-dashboard|examples/stm32/nucleo-f429zi-cube-freertos-lwip'; then
|
||||||
|
make -C test/cube test PROJECTS=../../examples/stm32/nucleo-f429zi-cube-freertos-lwip VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=2
|
||||||
|
fi
|
||||||
|
|
||||||
|
test_h743:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
env:
|
||||||
|
GO: 0
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
with: { fetch-depth: 3 }
|
||||||
|
- name: baremetal
|
||||||
|
run: |
|
||||||
|
if ./test/match_changed_files.sh "^src|examples/device-dashboard|examples/stm32/nucleo-h74.*-make-" ; then
|
||||||
|
echo GO=1 >> $GITHUB_ENV
|
||||||
|
sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
||||||
|
fi
|
||||||
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: |
|
||||||
|
if ./test/match_changed_files.sh '^src|examples/device-dashboard|examples/stm32/nucleo-h743zi-make-baremetal-builtin'; then
|
||||||
|
make -C examples/stm32/nucleo-h743zi-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
|
fi
|
||||||
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: |
|
||||||
|
if ./test/match_changed_files.sh '^src|examples/device-dashboard|examples/stm32/nucleo-h743zi-make-freertos-builtin'; then
|
||||||
|
make -C examples/stm32/nucleo-h743zi-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
|
fi
|
||||||
|
- name: Cube
|
||||||
|
run: |
|
||||||
|
echo GO=0 >> $GITHUB_ENV
|
||||||
|
if ./test/match_changed_files.sh '^src|examples/device-dashboard|examples/stm32/nucleo-h74.*-cube-'; then
|
||||||
|
echo GO=1 >> $GITHUB_ENV
|
||||||
|
# nothing specific to install or do
|
||||||
|
fi
|
||||||
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: |
|
||||||
|
if ./test/match_changed_files.sh '^src|examples/device-dashboard|examples/stm32/nucleo-h743zi-cube-baremetal-builtin'; then
|
||||||
|
make -C test/cube test PROJECTS=../../examples/stm32/nucleo-h743zi-cube-baremetal-builtin VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=6
|
||||||
|
fi
|
||||||
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: |
|
||||||
|
if ./test/match_changed_files.sh '^src|examples/device-dashboard|examples/stm32/nucleo-h743zi-cube-freertos-builtin'; then
|
||||||
|
make -C test/cube test PROJECTS=../../examples/stm32/nucleo-h743zi-cube-freertos-builtin VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=6
|
||||||
|
fi
|
||||||
|
|
||||||
|
test_h723:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
env:
|
||||||
|
GO: 0
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
with: { fetch-depth: 3 }
|
||||||
|
- name: baremetal
|
||||||
|
run: |
|
||||||
|
if ./test/match_changed_files.sh "^src|examples/device-dashboard|examples/stm32/nucleo-h72.*-make-" ; then
|
||||||
|
echo GO=1 >> $GITHUB_ENV
|
||||||
|
sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
||||||
|
fi
|
||||||
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: |
|
||||||
|
if ./test/match_changed_files.sh '^src|examples/device-dashboard|examples/stm32/nucleo-h723zg-make-baremetal-builtin'; then
|
||||||
|
make -C examples/stm32/nucleo-h723zg-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
|
fi
|
||||||
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: |
|
||||||
|
if ./test/match_changed_files.sh '^src|examples/device-dashboard|examples/stm32/nucleo-h723zg-make-freertos-builtin'; then
|
||||||
|
make -C examples/stm32/nucleo-h723zg-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
|
fi
|
||||||
|
|
||||||
|
test_h5:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
env:
|
||||||
|
GO: 0
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
with: { fetch-depth: 3 }
|
||||||
|
- name: baremetal
|
||||||
|
run: |
|
||||||
|
if ./test/match_changed_files.sh "^src|examples/device-dashboard|examples/stm32/nucleo-h5.*-make-" ; then
|
||||||
|
echo GO=1 >> $GITHUB_ENV
|
||||||
|
sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
||||||
|
fi
|
||||||
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: |
|
||||||
|
if ./test/match_changed_files.sh '^src|examples/device-dashboard|examples/stm32/nucleo-h563zi-make-baremetal-builtin'; then
|
||||||
|
make -C examples/stm32/nucleo-h563zi-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
|
fi
|
||||||
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: |
|
||||||
|
if ./test/match_changed_files.sh '^src|examples/device-dashboard|examples/stm32/nucleo-h563zi-make-freertos-builtin'; then
|
||||||
|
make -C examples/stm32/nucleo-h563zi-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
|
fi
|
||||||
|
|
||||||
|
test_rt1020:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
env:
|
||||||
|
GO: 0
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
with: { fetch-depth: 3 }
|
||||||
|
- name: baremetal
|
||||||
|
run: |
|
||||||
|
if ./test/match_changed_files.sh "^src|examples/device-dashboard|examples/nxp/rt1020.*-make-" ; then
|
||||||
|
echo GO=1 >> $GITHUB_ENV
|
||||||
|
sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
||||||
|
fi
|
||||||
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: |
|
||||||
|
#if ./test/match_changed_files.sh '^src|examples/device-dashboard|examples/nxp/rt1020-evk-make-baremetal-builtin'; then
|
||||||
|
if ./test/match_changed_files.sh '^src|examples/nxp/rt1020-evk-make-baremetal-builtin'; then
|
||||||
|
make -C examples/nxp/rt1020-evk-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
|
fi
|
||||||
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: |
|
||||||
|
#if ./test/match_changed_files.sh '^src|examples/device-dashboard|examples/nxp/rt1020-evk-make-freertos-builtin'; then
|
||||||
|
if ./test/match_changed_files.sh '^src|examples/nxp/rt1020-evk-make-freertos-builtin'; then
|
||||||
|
make -C examples/nxp/rt1020-evk-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
|
fi
|
||||||
|
|
||||||
|
test_rt1060:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
env:
|
||||||
|
GO: 0
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
with: { fetch-depth: 3 }
|
||||||
|
- name: baremetal
|
||||||
|
run: |
|
||||||
|
if ./test/match_changed_files.sh "^src|examples/device-dashboard|examples/nxp/rt1060.*-make-" ; then
|
||||||
|
echo GO=1 >> $GITHUB_ENV
|
||||||
|
sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
||||||
|
fi
|
||||||
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: |
|
||||||
|
if ./test/match_changed_files.sh '^src|examples/device-dashboard|examples/nxp/rt1060-evk-make-baremetal-builtin'; then
|
||||||
|
make -C examples/nxp/rt1060-evk-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
|
fi
|
||||||
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: |
|
||||||
|
if ./test/match_changed_files.sh '^src|examples/device-dashboard|examples/nxp/rt1060-evk-make-freertos-builtin'; then
|
||||||
|
make -C examples/nxp/rt1060-evk-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
|
fi
|
||||||
|
|
||||||
|
test_tm4c:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
env:
|
||||||
|
GO: 0
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
with: { fetch-depth: 2 }
|
||||||
|
- name: baremetal
|
||||||
|
run: |
|
||||||
|
if ./test/match_changed_files.sh "^src|examples/device-dashboard|examples/ti/ek-tm4c.*-make-" ; then
|
||||||
|
echo GO=1 >> $GITHUB_ENV
|
||||||
|
sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
||||||
|
fi
|
||||||
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: make -C examples/ti/ek-tm4c1294xl-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: make -C examples/ti/ek-tm4c1294xl-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
|
|
||||||
|
test_same54:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
env:
|
||||||
|
GO: 0
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
with: { fetch-depth: 2 }
|
||||||
|
- name: baremetal
|
||||||
|
run: |
|
||||||
|
if ./test/match_changed_files.sh "^src|examples/device-dashboard|examples/microchip/same54-xpro" ; then
|
||||||
|
echo GO=1 >> $GITHUB_ENV
|
||||||
|
sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
||||||
|
fi
|
||||||
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: make -C examples/microchip/same54-xpro/device-dashboard test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: make -C examples/microchip/same54-xpro/mqtt-client test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
|
|
||||||
|
test_pico_w5500:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
env:
|
||||||
|
GO: 0
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
with: { fetch-depth: 2 }
|
||||||
|
- name: SDK
|
||||||
|
run: |
|
||||||
|
if ./test/match_changed_files.sh "^src|examples/device-dashboard|examples/rp2040/pico-w5500" ; then
|
||||||
|
echo GO=1 >> $GITHUB_ENV
|
||||||
|
sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
||||||
|
fi
|
||||||
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: make -C examples/rp2040/pico-w5500 test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
|
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
name: Zephyr
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
- cron: '0 0 * * *' # run at 12 AM UTC
|
||||||
|
# Allow manual runs
|
||||||
|
workflow_dispatch:
|
||||||
|
jobs:
|
||||||
|
zephyr_examples:
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
revno: ["--mr v3.7-branch", "--mr v4.2.0", "--mr v4.3.0"] # LTS, latest stable
|
||||||
|
name: Zephyr ${{ matrix.revno }}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with: { fetch-depth: 2 }
|
||||||
|
- run: test/setup_ga_docker_filesystem.sh
|
||||||
|
- run: make -C tutorials/zephyr init REPO=zephyrprojectrtos/ci:v0.28.8 REVNO="${{ matrix.revno }}"
|
||||||
|
- run: make -C tutorials/zephyr minify REVNO="${{ matrix.revno }}"
|
||||||
|
- run: make -C tutorials/zephyr update
|
||||||
|
- run: make -C tutorials/zephyr/device-dashboard build REPO=zephyrprojectrtos/ci:v0.28.8
|
||||||
|
- run: make -C tutorials/zephyr/http-client build REPO=zephyrprojectrtos/ci:v0.28.8
|
||||||
|
- run: make -C tutorials/zephyr/http-server build REPO=zephyrprojectrtos/ci:v0.28.8
|
||||||
|
- run: make -C tutorials/zephyr/mqtt-aws-client build REPO=zephyrprojectrtos/ci:v0.28.8
|
||||||
|
- run: make -C tutorials/zephyr/websocket-server build REPO=zephyrprojectrtos/ci:v0.28.8
|
||||||
|
# Latest CI image does not work with pre 4.4, they changed some SDK paths
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
Copyright (c) 2004-2013 Sergey Lyubka
|
Copyright (c) 2004-2013 Sergey Lyubka
|
||||||
Copyright (c) 2013-2023 Cesanta Software Limited
|
Copyright (c) 2013-2026 Cesanta Software Limited
|
||||||
All rights reserved
|
All rights reserved
|
||||||
|
|
||||||
This software is dual-licensed: you can redistribute it and/or modify
|
This software is dual-licensed: you can redistribute it and/or modify
|
||||||
|
|||||||
@@ -1,186 +0,0 @@
|
|||||||
SRCS = mongoose.c test/unit_test.c test/packed_fs.c
|
|
||||||
HDRS = $(wildcard src/*.h) $(wildcard mip/*.h)
|
|
||||||
DEFS ?= -DMG_MAX_HTTP_HEADERS=7 -DMG_ENABLE_LINES -DMG_ENABLE_PACKED_FS=1 -DMG_ENABLE_SSI=1
|
|
||||||
WARN ?= -pedantic -W -Wall -Werror -Wshadow -Wdouble-promotion -fno-common -Wconversion -Wundef
|
|
||||||
OPTS ?= -O3 -g3
|
|
||||||
INCS ?= -Isrc -I.
|
|
||||||
SSL ?=
|
|
||||||
CWD ?= $(realpath $(CURDIR))
|
|
||||||
ENV ?= -e Tmp=. -e WINEDEBUG=-all
|
|
||||||
DOCKER ?= docker run --platform linux/amd64 --rm $(ENV) -v $(CWD):$(CWD) -w $(CWD)
|
|
||||||
VCFLAGS = /nologo /W3 /O2 /MD /I. $(DEFS) $(TFLAGS)
|
|
||||||
IPV6 ?= 1
|
|
||||||
ASAN ?= -fsanitize=address,undefined,alignment -fno-sanitize-recover=all -fno-omit-frame-pointer -fno-common
|
|
||||||
ASAN_OPTIONS ?= detect_leaks=1
|
|
||||||
EXAMPLES := $(dir $(wildcard examples/*/Makefile))
|
|
||||||
PREFIX ?= /usr/local
|
|
||||||
VERSION ?= $(shell cut -d'"' -f2 src/version.h)
|
|
||||||
COMMON_CFLAGS ?= $(C_WARN) $(WARN) $(INCS) $(DEFS) -DMG_ENABLE_IPV6=$(IPV6) $(TFLAGS)
|
|
||||||
CFLAGS ?= $(OPTS) $(ASAN) $(COMMON_CFLAGS)
|
|
||||||
VALGRIND_CFLAGS ?= $(OPTS) $(COMMON_CFLAGS)
|
|
||||||
VALGRIND_RUN ?= valgrind --tool=memcheck --gen-suppressions=all --leak-check=full --show-leak-kinds=all --leak-resolution=high --track-origins=yes --error-exitcode=1 --exit-on-first-error=yes
|
|
||||||
.PHONY: examples test valgrind mip_test
|
|
||||||
|
|
||||||
ifeq "$(findstring ++,$(CC))" ""
|
|
||||||
# $(CC) does not end with ++, i.e. we're using C. Apply C flags
|
|
||||||
C_WARN ?= -Wmissing-prototypes -Wstrict-prototypes
|
|
||||||
else
|
|
||||||
# $(CC) ends with ++, i.e. we're using C++. Apply C++ flags
|
|
||||||
C_WARN ?= -Wno-deprecated
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq "$(SSL)" "MBEDTLS"
|
|
||||||
MBEDTLS ?= /usr/local
|
|
||||||
CFLAGS += -DMG_ENABLE_MBEDTLS=1 -I$(MBEDTLS)/include -I/usr/include
|
|
||||||
LDFLAGS ?= -L$(MBEDTLS)/lib -lmbedtls -lmbedcrypto -lmbedx509
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq "$(SSL)" "OPENSSL"
|
|
||||||
OPENSSL ?= /usr/local
|
|
||||||
CFLAGS += -DMG_ENABLE_OPENSSL=1 -I$(OPENSSL)/include
|
|
||||||
LDFLAGS ?= -L$(OPENSSL)/lib -lssl -lcrypto
|
|
||||||
endif
|
|
||||||
|
|
||||||
all:
|
|
||||||
$(MAKE) -C examples/http-server
|
|
||||||
|
|
||||||
tall: mg_prefix unamalgamated test mip_test arm examples vc98 vc17 vc22 mingw mingw++ fuzz
|
|
||||||
|
|
||||||
mip_test: test/mip_test.c mongoose.c mongoose.h Makefile mip_tap_test
|
|
||||||
$(CC) test/mip_test.c $(INCS) $(WARN) $(OPTS) $(C_WARN) $(ASAN) -o $@
|
|
||||||
ASAN_OPTIONS=$(ASAN_OPTIONS) $(RUN) ./$@
|
|
||||||
|
|
||||||
mip_tap_test: test/mip_tap_test.c mongoose.c mongoose.h Makefile
|
|
||||||
$(CC) test/mip_tap_test.c $(INCS) $(WARN) $(OPTS) $(C_WARN) $(ASAN) -o $@
|
|
||||||
ASAN_OPTIONS=$(ASAN_OPTIONS) $(RUN) ./$@
|
|
||||||
|
|
||||||
examples:
|
|
||||||
@for X in $(EXAMPLES); do test -f $$X/Makefile || continue; $(MAKE) -C $$X example || exit 1; done
|
|
||||||
|
|
||||||
test/packed_fs.c: Makefile src/ssi.h test/fuzz.c test/data/a.txt
|
|
||||||
$(CC) $(CFLAGS) test/pack.c -o pack
|
|
||||||
$(RUN) ./pack Makefile src/ssi.h test/fuzz.c test/data/a.txt test/data/range.txt > $@
|
|
||||||
|
|
||||||
DIR ?= test/data
|
|
||||||
OUT ?= packed_fs.c
|
|
||||||
mkfs:
|
|
||||||
$(CC) $(CFLAGS) test/pack.c -o pack
|
|
||||||
$(RUN) ./pack -s $(DIR) `find $(DIR) -type f` > $(OUT)
|
|
||||||
# find $(DIR) -type f | sed -e s,^$(DIR),,g -e s,^/,,g
|
|
||||||
|
|
||||||
# Check that all external (exported) symbols have "mg_" prefix
|
|
||||||
mg_prefix: mongoose.c mongoose.h
|
|
||||||
$(CC) mongoose.c $(CFLAGS) -c -o /tmp/x.o && nm /tmp/x.o | grep ' T ' | grep -v 'mg_' ; test $$? = 1
|
|
||||||
|
|
||||||
musl: test
|
|
||||||
musl: ASAN =
|
|
||||||
musl: WARN += -Wno-sign-conversion
|
|
||||||
musl: CC = $(DOCKER) mdashnet/cc1 gcc
|
|
||||||
musl: RUN = $(DOCKER) mdashnet/cc1
|
|
||||||
|
|
||||||
# Make sure we can build from an unamalgamated sources
|
|
||||||
unamalgamated: $(HDRS) Makefile test/packed_fs.c
|
|
||||||
$(CC) src/*.c test/packed_fs.c test/unit_test.c $(CFLAGS) $(LDFLAGS) -g -o unit_test
|
|
||||||
|
|
||||||
fuzz: ASAN = -fsanitize=fuzzer,signed-integer-overflow,address,undefined
|
|
||||||
fuzz: mongoose.c mongoose.h Makefile test/fuzz.c
|
|
||||||
$(CC) test/fuzz.c $(OPTS) $(WARN) $(INCS) $(TFLAGS) $(ASAN) -o fuzzer
|
|
||||||
$(RUN) ./fuzzer
|
|
||||||
|
|
||||||
FUZZDATA ?= /tmp/fuzzdata
|
|
||||||
fuzz2: mongoose.c mongoose.h Makefile test/fuzz.c
|
|
||||||
$(CC) test/fuzz.c -DMAIN $(OPTS) $(WARN) $(ASAN) $(INCS) -o fuzzer
|
|
||||||
$(RUN) ./fuzzer $(FUZZDATA)
|
|
||||||
|
|
||||||
test: Makefile mongoose.h $(SRCS)
|
|
||||||
$(CC) $(SRCS) $(CFLAGS) $(LDFLAGS) -o unit_test
|
|
||||||
ASAN_OPTIONS=$(ASAN_OPTIONS) $(RUN) ./unit_test
|
|
||||||
|
|
||||||
coverage: CFLAGS += -coverage
|
|
||||||
coverage: test
|
|
||||||
gcov -l -n *.gcno | sed '/^$$/d' | sed 'N;s/\n/ /'
|
|
||||||
gcov -t mongoose.c > mongoose.gcov
|
|
||||||
|
|
||||||
upload-coverage: coverage
|
|
||||||
curl -s https://codecov.io/bash | /bin/bash
|
|
||||||
|
|
||||||
valgrind: Makefile mongoose.h mongoose.c
|
|
||||||
$(CC) $(SRCS) $(VALGRIND_CFLAGS) $(LDFLAGS) -g -o unit_test
|
|
||||||
$(VALGRIND_RUN) ./unit_test
|
|
||||||
|
|
||||||
armhf: ASAN=
|
|
||||||
armhf: IPV6=0
|
|
||||||
armhf: CC = $(DOCKER) mdashnet/armhf cc
|
|
||||||
armhf: RUN = $(DOCKER) mdashnet/armhf
|
|
||||||
armhf: test
|
|
||||||
|
|
||||||
s390: ASAN=
|
|
||||||
s390: IPV6=0
|
|
||||||
s390: CC = $(DOCKER) mdashnet/s390 cc
|
|
||||||
s390: RUN = $(DOCKER) mdashnet/s390
|
|
||||||
s390: test
|
|
||||||
|
|
||||||
arm: DEFS += -DMG_ENABLE_FILE=0 -DMG_ENABLE_MIP=1 -DMG_ARCH=MG_ARCH_NEWLIB
|
|
||||||
arm: mongoose.h $(SRCS)
|
|
||||||
$(DOCKER) mdashnet/armgcc arm-none-eabi-gcc -mcpu=cortex-m3 -mthumb $(SRCS) $(OPTS) $(WARN) $(INCS) $(DEFS) $(TFLAGS) -o unit_test -nostartfiles --specs nosys.specs -e 0
|
|
||||||
|
|
||||||
riscv: DEFS += -DMG_ENABLE_FILE=0 -DMG_ENABLE_MIP=1 -DMG_ARCH=MG_ARCH_NEWLIB
|
|
||||||
riscv: mongoose.h $(SRCS)
|
|
||||||
$(DOCKER) mdashnet/riscv riscv-none-elf-gcc -march=rv32imc -mabi=ilp32 $(SRCS) $(OPTS) $(WARN) $(INCS) $(DEFS) $(TFLAGS) -o unit_test
|
|
||||||
|
|
||||||
vc98: Makefile mongoose.h $(SRCS)
|
|
||||||
$(DOCKER) mdashnet/vc98 wine cl $(SRCS) $(VCFLAGS) ws2_32.lib /Fe$@.exe
|
|
||||||
$(DOCKER) mdashnet/vc98 wine $@.exe
|
|
||||||
|
|
||||||
vc17: Makefile mongoose.h $(SRCS)
|
|
||||||
$(DOCKER) mdashnet/vc17 wine64 cl $(SRCS) $(VCFLAGS) ws2_32.lib /Fe$@.exe
|
|
||||||
$(DOCKER) mdashnet/vc17 wine64 $@.exe
|
|
||||||
|
|
||||||
vc22: Makefile mongoose.h $(SRCS)
|
|
||||||
$(DOCKER) mdashnet/vc22 wine64 cl $(SRCS) $(VCFLAGS) ws2_32.lib /Fe$@.exe
|
|
||||||
$(DOCKER) mdashnet/vc22 wine64 $@.exe
|
|
||||||
|
|
||||||
mingw: Makefile mongoose.h $(SRCS)
|
|
||||||
$(DOCKER) mdashnet/mingw x86_64-w64-mingw32-gcc $(SRCS) -W -Wall -Werror -I. $(DEFS) -lwsock32 -o $@.exe
|
|
||||||
$(DOCKER) mdashnet/mingw wine64 $@.exe
|
|
||||||
|
|
||||||
arduino: ENV = -v $(CWD)/arduino:/root
|
|
||||||
arduino:
|
|
||||||
curl -sL http://downloads.arduino.cc/arduino-1.8.19-linux64.tar.xz | unxz | tar -xf -
|
|
||||||
mv arduino-* $@
|
|
||||||
$(DOCKER) mdashnet/cc2 ./arduino/arduino --pref "boardsmanager.additional.urls=https://files.seeedstudio.com/arduino/package_seeeduino_boards_index.json" --save-prefs
|
|
||||||
$(DOCKER) mdashnet/cc2 ./arduino/arduino --pref "compiler.warning_level=all" --save-prefs
|
|
||||||
$(DOCKER) mdashnet/cc2 ./arduino/arduino --install-boards Seeeduino:samd
|
|
||||||
|
|
||||||
arduino-xiao: ENV = -v $(CWD)/arduino:/root
|
|
||||||
arduino-xiao: arduino
|
|
||||||
rm -rf tmp; mkdir tmp
|
|
||||||
cp examples/arduino/w5500/w5500.ino tmp/tmp.ino
|
|
||||||
cp mongoose.c mongoose.h examples/arduino/w5500/mongoose_custom.h tmp/
|
|
||||||
$(DOCKER) mdashnet/cc2 ./arduino/arduino --verbose --verify --board Seeeduino:samd:seeed_XIAO_m0 tmp/tmp.ino
|
|
||||||
|
|
||||||
mingw++: Makefile mongoose.h $(SRCS)
|
|
||||||
$(DOCKER) mdashnet/mingw x86_64-w64-mingw32-g++ $(SRCS) -W -Wall -Werror -I. $(DEFS) -lwsock32 -o $@.exe
|
|
||||||
|
|
||||||
linux-libs: CFLAGS += -fPIC
|
|
||||||
linux-libs: mongoose.o
|
|
||||||
$(CC) mongoose.o $(LDFLAGS) -shared -o libmongoose.so.$(VERSION)
|
|
||||||
$(AR) rcs libmongoose.a mongoose.o
|
|
||||||
|
|
||||||
install: linux-libs
|
|
||||||
install -Dm644 libmongoose.a libmongoose.so.$(VERSION) $(DESTDIR)$(PREFIX)/lib
|
|
||||||
ln -s libmongoose.so.$(VERSION) $(DESTDIR)$(PREFIX)/lib/libmongoose.so
|
|
||||||
install -Dm644 mongoose.h $(DESTDIR)$(PREFIX)/include/mongoose.h
|
|
||||||
|
|
||||||
uninstall:
|
|
||||||
rm -rf $(DESTDIR)$(PREFIX)/lib/libmongoose.a $(DESTDIR)$(PREFIX)/lib/libmongoose.so.$(VERSION) $(DESTDIR)$(PREFIX)/include/mongoose.h $(DESTDIR)$(PREFIX)/lib/libmongoose.so
|
|
||||||
|
|
||||||
mongoose.c: Makefile $(wildcard src/*) $(wildcard mip/*.c)
|
|
||||||
(cat src/license.h; echo; echo '#include "mongoose.h"' ; (for F in src/*.c mip/*.c ; do echo; echo '#ifdef MG_ENABLE_LINES'; echo "#line 1 \"$$F\""; echo '#endif'; cat $$F | sed -e 's,#include ".*,,'; done))> $@
|
|
||||||
|
|
||||||
mongoose.h: $(HDRS) Makefile
|
|
||||||
(cat src/license.h; echo; echo '#ifndef MONGOOSE_H'; echo '#define MONGOOSE_H'; echo; cat src/version.h ; echo; echo '#ifdef __cplusplus'; echo 'extern "C" {'; echo '#endif'; cat src/arch.h src/arch_*.h src/net_*.h src/config.h src/str.h src/fmt.h src/log.h src/timer.h src/fs.h src/util.h src/url.h src/iobuf.h src/base64.h src/md5.h src/sha1.h src/event.h src/net.h src/http.h src/ssi.h src/tls.h src/tls_mbed.h src/tls_openssl.h src/ws.h src/sntp.h src/mqtt.h src/dns.h src/json.h src/rpc.h mip/mip.h mip/driver_*.h | sed -e '/keep/! s,#include ".*,,' -e 's,^#pragma once,,'; echo; echo '#ifdef __cplusplus'; echo '}'; echo '#endif'; echo '#endif // MONGOOSE_H')> $@
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -rf $(PROG) *.exe *.o *.dSYM *_test* ut fuzzer *.gcov *.gcno *.gcda *.obj *.exe *.ilk *.pdb slow-unit* _CL_* infer-out data.txt crash-* test/packed_fs.c pack arduino tmp
|
|
||||||
find examples -maxdepth 3 -name zephyr -prune -o -name Makefile -print | xargs dirname | xargs -n1 make clean -C
|
|
||||||
@@ -1,36 +1,165 @@
|
|||||||
# Mongoose - Embedded Web Server / Embedded Networking Library
|
# Mongoose - Embedded Web Server / Embedded Network Library
|
||||||
|
|
||||||
[](https://opensource.org/licenses/gpl-2.0.php)
|
[](https://opensource.org/licenses/gpl-2.0.php)
|
||||||
[](https://github.com/cesanta/mongoose/actions)
|
[](https://github.com/cesanta/mongoose/actions)
|
||||||
[](https://codecov.io/gh/cesanta/mongoose)
|
[](https://codecov.io/gh/cesanta/mongoose)
|
||||||
[](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:mongoose)
|
[](https://issues.oss-fuzz.com/issues?sort=-opened&can=1&q=proj:mongoose)
|
||||||
|
|
||||||
Mongoose is a networking library for C/C++. It implements event-driven
|
<img src="https://mongoose.ws/images/logo.svg" width="48" height="48" align="left" style="float:left;" /> Mongoose is a network library for C/C++. It provides event-driven non-blocking
|
||||||
non-blocking APIs for TCP, UDP, HTTP, WebSocket, MQTT. It is designed for
|
APIs for TCP, UDP, HTTP, WebSocket, MQTT, and other protocols. It is designed
|
||||||
connecting devices and bringing them online. On the market since 2004, used by
|
for connecting devices and bringing them online. On the market since 2004, used
|
||||||
vast number of open source and commercial products - it even runs on the
|
by vast number of open source and commercial products - it even runs on the
|
||||||
International Space Station! Mongoose makes embedded network programming fast,
|
International Space Station! Mongoose makes embedded network programming fast,
|
||||||
robust, and easy. Features include:
|
robust, and easy. Features include:
|
||||||
|
|
||||||
- Cross-platform: works on Linux/UNIX, MacOS, Windows, Android, FreeRTOS, etc.
|
- Cross-platform:
|
||||||
- Supported embedded architectures: ESP32, NRF52, STM32, NXP, and more
|
- works on Linux/UNIX, MacOS, Windows, Android
|
||||||
- Built-in protocols: plain TCP/UDP, HTTP, MQTT, Websocket
|
- works on ST, NXP, ESP32, Nordic, TI, Microchip, Infineon, Renesas and other chips
|
||||||
- SSL/TLS support: mbedTLS, OpenSSL or custom (via API)
|
- write code once - and it'll work everywhere
|
||||||
|
- ideal for the unification of the network infrastructure code across company
|
||||||
|
- Built-in protocols: plain TCP/UDP, SNTP, HTTP, MQTT, Websocket, and other
|
||||||
- Asynchronous DNS resolver
|
- Asynchronous DNS resolver
|
||||||
- Tiny static and run-time footprint
|
- Tiny static and run-time footprint
|
||||||
- Source code is both ISO C and ISO C++ compliant
|
- Source code is both ISO C and ISO C++ compliant
|
||||||
- Works with any network stack with socket API, like LwIP or FreeRTOS-Plus-TCP
|
- Easy to integrate: just copy [mongoose.c](https://raw.githubusercontent.com/cesanta/mongoose/master/mongoose.c)
|
||||||
- Very easy to integrate: just copy `mongoose.c` and `mongoose.h` files to your build tree
|
and [mongoose.h](https://raw.githubusercontent.com/cesanta/mongoose/master/mongoose.h) files to your source tree
|
||||||
- Optional built-in TCP/IP stack with drivers for bare metal or RTOS firmwares
|
- Built-in TCP/IP stack with drivers for bare metal or RTOS systems
|
||||||
- A full device dashboard
|
- Available drivers: STM32F, STM32H; NXP RT1xxx; TI TM4C; Microchip SAME54; Wiznet W5500
|
||||||
[bare metal example on Nucleo-F429ZI](examples/stm32/nucleo-f429zi-baremetal)
|
- A complete Web device dashboard on bare metal ST Nucleo boards is only 6 files
|
||||||
is only 6 files
|
|
||||||
- For comparison, a CubeIDE generated HTTP example is 400+ files
|
- For comparison, a CubeIDE generated HTTP example is 400+ files
|
||||||
- Detailed [documentation](https://mongoose.ws/documentation/) and
|
- Can run on top of an existing TCP/IP stack with BSD API, e.g. lwIP, Zephyr, Azure, etc
|
||||||
[tutorials](https://mongoose.ws/tutorials/)
|
- Built-in TLS 1.3 ECC stack. Also can use external TLS libraries - mbedTLS, OpenSSL, or other
|
||||||
|
- Does not depend on any other software to implement networking
|
||||||
|
- Built-in firmware updates for STM32 H5, STM32 H7
|
||||||
|
|
||||||
|
See https://mongoose.ws/ for complete documentation, videos, case studies, etc.
|
||||||
|
|
||||||
# Commercial use
|
## Supported platforms
|
||||||
|
|
||||||
|
Mongoose can work on top of any TCP/IP stack that supports BSD sockets API.
|
||||||
|
Platforms supported by the 3rd party TCP/IP stacks:
|
||||||
|
|
||||||
|
| TCP/IP stack | Notes |
|
||||||
|
| :-------------- | :------- |
|
||||||
|
| **lwIP** | All devices running lwIP, for example ESP32, ESP32S3, ESP32C3, ESP32C6, etc |
|
||||||
|
| **Zephyr** | All devices supported by Zephyr |
|
||||||
|
| **Other** | Any other TCP/IP stack that supports BSD socket API, for example Amazon FreeRTOS-TCP |
|
||||||
|
| **Linux, Mac, Windows** | Workstations, server, single board computers, embedded Linux devices running on MPUs or FPGAs |
|
||||||
|
|
||||||
|
Optionally, Mongoose provides its own built-in TCP/IP stack, eliminating the
|
||||||
|
need for additional software to implement networking functionality. The
|
||||||
|
built-in stack supports operation in both bare-metal and RTOS environments.
|
||||||
|
Platforms supported by the Mongoose built-in TCP/IP stack:
|
||||||
|
|
||||||
|
| Hardware | Notes |
|
||||||
|
| :------------- | :------- |
|
||||||
|
| **STM32** | All STM32 MCUs with built-in Ethernet: STM32Fxx, STM32H5xx, STM32H7xx |
|
||||||
|
| **NXP** | All NXP MCUs with built-in Ethernet: IMXRT102x, IMXRT104x, IMXRT105x, IMXRT106x, IMXRT117x, RW612, MCXN94x |
|
||||||
|
| **Microchip** | ATSAME54 MCUs with built-int Ethernet |
|
||||||
|
| **Renesas** | RA5M, RA6M, RA8M MCUs with built-in Ethernet |
|
||||||
|
| **Infineon** | XMC4, XMC7 MCUs with built-in Ethernet |
|
||||||
|
| **Texas Instruments** | TM4C, TMS570 MCUs with built-in Ethernet |
|
||||||
|
| **Cypress WiFi** | Any MCU with CY43xx WiFi chips, like RP2040 Pico-W, RP2350 Pico2-W, Arduino Portenta |
|
||||||
|
| **Wiznet Ethernet** | Any MCU that use Wiznet W5500 or Wiznet 5100 MAC+PHY chips |
|
||||||
|
| **Cellular** | NRF9160, SIM800 |
|
||||||
|
|
||||||
|
## Usage Examples
|
||||||
|
|
||||||
|
Below are quick snippets that should give an idea how simple the API is and
|
||||||
|
how easy it is to create applications with it.
|
||||||
|
|
||||||
|
Create a simple web server that serves a directory. The behavior of the
|
||||||
|
HTTP server is specified by its event handler function:
|
||||||
|
|
||||||
|
```c
|
||||||
|
#include "mongoose.h" // To build, run: cc main.c mongoose.c
|
||||||
|
|
||||||
|
// HTTP server event handler function
|
||||||
|
void ev_handler(struct mg_connection *c, int ev, void *ev_data) {
|
||||||
|
if (ev == MG_EV_HTTP_MSG) {
|
||||||
|
struct mg_http_message *hm = (struct mg_http_message *) ev_data;
|
||||||
|
struct mg_http_serve_opts opts = { .root_dir = "./web_root/" };
|
||||||
|
mg_http_serve_dir(c, hm, &opts);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
struct mg_mgr mgr; // Declare event manager
|
||||||
|
mg_mgr_init(&mgr); // Initialise event manager
|
||||||
|
mg_http_listen(&mgr, "http://0.0.0.0:8000", ev_handler, NULL); // Setup listener
|
||||||
|
for (;;) { // Run an infinite event loop
|
||||||
|
mg_mgr_poll(&mgr, 1000);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
HTTP server implements a REST API that returns current time. JSON formatting:
|
||||||
|
```c
|
||||||
|
static void ev_handler(struct mg_connection *c, int ev, void *ev_data) {
|
||||||
|
if (ev == MG_EV_HTTP_MSG) {
|
||||||
|
struct mg_http_message *hm = (struct mg_http_message *) ev_data;
|
||||||
|
if (mg_match(hm->uri, mg_str("/api/time/get"), NULL)) {
|
||||||
|
mg_http_reply(c, 200, "", "{%m:%lu}\n", MG_ESC("time"), time(NULL));
|
||||||
|
} else {
|
||||||
|
mg_http_reply(c, 500, "", "{%m:%m}\n", MG_ESC("error"), MG_ESC("Unsupported URI"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
MQTT client that subscribes to a topic `device1/rx` and
|
||||||
|
echoes incoming messages to `device1/tx`:
|
||||||
|
|
||||||
|
```c
|
||||||
|
#include "mongoose.h"
|
||||||
|
|
||||||
|
static const char *s_mqtt_url = "mqtt://broker.hivemq.com:1883";
|
||||||
|
static struct mg_connection *s_mqtt_conn = NULL;
|
||||||
|
|
||||||
|
// MQTT connection event handler function
|
||||||
|
static void ev_handler(struct mg_connection *c, int ev, void *ev_data) {
|
||||||
|
if (ev == MG_EV_OPEN) {
|
||||||
|
MG_INFO(("%lu created, connecting to %s ...", c->id, s_mqtt_url));
|
||||||
|
} else if (ev == MG_EV_MQTT_OPEN) {
|
||||||
|
struct mg_mqtt_opts opts = {.qos = 1, .topic = mg_str("device1/rx")};
|
||||||
|
mg_mqtt_sub(c, &opts);
|
||||||
|
MG_INFO(("%lu connected, subscribing to %s", c->id, opts.topic.buf));
|
||||||
|
} else if (ev == MG_EV_MQTT_MSG) {
|
||||||
|
char response[100];
|
||||||
|
struct mg_mqtt_message *mm = (struct mg_mqtt_message *) ev_data;
|
||||||
|
struct mg_mqtt_opts opts = {.qos = 1, .topic = mg_str("device1/tx")};
|
||||||
|
mg_snprintf(response, sizeof(response), "Received [%.*s] / [%.*s]",
|
||||||
|
mm->topic.len, mm->topic.buf, mm->data.len, mm->data.buf);
|
||||||
|
opts.message = mg_str(response);
|
||||||
|
mg_mqtt_pub(c, &opts);
|
||||||
|
} else if (ev == MG_EV_CLOSE) {
|
||||||
|
MG_INFO(("%u closing", c->id));
|
||||||
|
s_mqtt_conn = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reconnection timer function. If we get disconnected, reconnect again
|
||||||
|
static void timer_fn(void *arg) {
|
||||||
|
struct mg_mgr *mgr = (struct mg_mgr *) arg;
|
||||||
|
if (s_mqtt_conn == NULL) {
|
||||||
|
struct mg_mqtt_opts opts = {.clean = true};
|
||||||
|
s_mqtt_conn = mg_mqtt_connect(mgr, s_mqtt_url, &opts, ev_handler, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
struct mg_mgr mgr; // Mongoose event manager. Holds all connections
|
||||||
|
mg_mgr_init(&mgr); // Initialise event manager
|
||||||
|
mg_timer_add(&mgr, 3000, MG_TIMER_REPEAT | MG_TIMER_RUN_NOW, timer_fn, &mgr);
|
||||||
|
for (;;) {
|
||||||
|
mg_mgr_poll(&mgr, 1000); // Infinite event loop
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Commercial use
|
||||||
- Mongoose is used by hundreds of businesses, from Fortune500 giants like
|
- Mongoose is used by hundreds of businesses, from Fortune500 giants like
|
||||||
Siemens, Schneider Electric, Broadcom, Bosch, Google, Samsung, Qualcomm, Caterpillar to the small businesses
|
Siemens, Schneider Electric, Broadcom, Bosch, Google, Samsung, Qualcomm, Caterpillar to the small businesses
|
||||||
- Used to solve a wide range of business needs, like implementing Web UI
|
- Used to solve a wide range of business needs, like implementing Web UI
|
||||||
@@ -40,11 +169,11 @@ robust, and easy. Features include:
|
|||||||
- See [Case Studies](https://mongoose.ws/case-studies/) from our respected
|
- See [Case Studies](https://mongoose.ws/case-studies/) from our respected
|
||||||
customers like [Schneider Electric](https://mongoose.ws/case-studies/schneider-electric/) (industrial automation), [Broadcom](https://mongoose.ws/case-studies/broadcom/) (semiconductors), [Pilz](https://mongoose.ws/case-studies/pilz/) (industrial automation), and others
|
customers like [Schneider Electric](https://mongoose.ws/case-studies/schneider-electric/) (industrial automation), [Broadcom](https://mongoose.ws/case-studies/broadcom/) (semiconductors), [Pilz](https://mongoose.ws/case-studies/pilz/) (industrial automation), and others
|
||||||
- See [Testimonials](https://mongoose.ws/testimonials/) from engineers that integrated Mongoose in their commercial products
|
- See [Testimonials](https://mongoose.ws/testimonials/) from engineers that integrated Mongoose in their commercial products
|
||||||
- We provide [Evaluation and Commercial licensing](https://mongoose.ws/licensing/), [support](https://mongoose.ws/support/), consultancy and integration
|
- We provide [Evaluation and Commercial licensing](https://mongoose.ws/licensing/), [support](https://mongoose.ws/support/), consultancy and [integration
|
||||||
assistance - don't hesitate to [contact us](https://mongoose.ws/contact/)
|
services](https://mongoose.ws/integration/) - don't hesitate to [contact us](https://mongoose.ws/contact/)
|
||||||
|
|
||||||
|
|
||||||
# Security
|
## Security
|
||||||
|
|
||||||
We take security seriously:
|
We take security seriously:
|
||||||
1. Mongoose repository runs a
|
1. Mongoose repository runs a
|
||||||
@@ -69,8 +198,32 @@ We take security seriously:
|
|||||||
have specific security requirements and run independent security audits,
|
have specific security requirements and run independent security audits,
|
||||||
of which we get notified and in case of any issue, act similar to (3).
|
of which we get notified and in case of any issue, act similar to (3).
|
||||||
|
|
||||||
|
## How to report security vulnerabilities
|
||||||
|
|
||||||
# Contributions
|
Please send an email to support@cesanta.com, with the full information.
|
||||||
|
Do NOT create a github issue.
|
||||||
|
|
||||||
|
## Articles
|
||||||
|
|
||||||
|
Technical guides and deep dives into embedded web servers, WebUI integration and embedded networking technologies:
|
||||||
|
- [Embedded Web Server: A Comprehensive Guide for Modern Connected Devices](https://mongoose.ws/articles/embedded-web-server-a-comprehensive-guide-for-modern-connected-devices/)
|
||||||
|
- [Building Embedded Web Device Dashboards](https://mongoose.ws/articles/building-embedded-web-device-dashboard/)
|
||||||
|
- [ESP32 Device Dashboard: A Step-by-Step Guide for Developers](https://mongoose.ws/articles/esp32-device-dashboard/)
|
||||||
|
- [How to build an STM32 Web Dashboard](https://mongoose.ws/articles/stm32-device-dashboard/)
|
||||||
|
- [STM32 WebSocket Guide](https://mongoose.ws/articles/stm32-websocket-guide/)
|
||||||
|
- [Web File Manager on STM32, ESP32 and Embedded Linux](https://mongoose.ws/articles/building-a-web-file-manager-on-stm32-esp32-embedded-linux/)
|
||||||
|
- [Web dashboard on Zephyr RTOS](https://mongoose.ws/articles/web-dashboard-on-zephyr-rtos/)
|
||||||
|
- [Limiting TCP/IP RAM usage on STM32](https://mongoose.ws/articles/limiting-tcpip-ram-usage-on-stm32/)
|
||||||
|
- [STM32 Ethernet explained](https://mongoose.ws/articles/stm32-ethernet-explained/)
|
||||||
|
- [MQTT on a Microcontroller](https://mongoose.ws/articles/mqtt-on-a-microcontroller/)
|
||||||
|
- [STM32 OTA Firmware Update](https://mongoose.ws/articles/stm32-ota-firmware-update/)
|
||||||
|
- [RP2350 OTA Firmware Update](https://mongoose.ws/articles/rp2350-ota-firmware-update/)
|
||||||
|
- [STM32 Ethernet and caches](https://mongoose.ws/articles/stm32-ethernet-and-cache/)
|
||||||
|
- [NXP RW612 OTA Firmware Update](https://mongoose.ws/articles/rw612-ota-firmware-update/)
|
||||||
|
- [lwIP vs Mongoose - TCP/IP Stack Integration Benchmark](https://mongoose.ws/articles/lwip-vs-mongoose-tcpip-stack-integration/)
|
||||||
|
|
||||||
|
|
||||||
|
## Contributions
|
||||||
|
|
||||||
Contributions are welcome! Please follow the guidelines below:
|
Contributions are welcome! Please follow the guidelines below:
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<svg viewBox="-5.229 8.358 512.162 263.062" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
||||||
<image width="512.162" height="263.062" x="-5.229" y="8.358" style="" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAArkAAAFmCAYAAABp3oLTAAAAAXNSR0IArs4c6QAAIABJREFUeF7sXQdYFUcXva9TBQEr9t4ARewFNVbsGhG7wRI1UeyixhLRoGLsXZNYYu8NxQJ2FMGKBcWCSAdp0l79v7PPMe8nqEhRILvfh+B7u7MzZ2Z3ztw5914B8QePAI8AjwCPAI8AjwCPAI8Aj0ARQ0BQxNrDN4dHgEeAR4BHgEeAR4BHgEeAR4B4kssPAh4BHgEeAR4BHgEeAR4BHoEihwBPcotcl/IN4hHgEeAR4BHgEeAR4BHgEeBJLj8GeAR4BHgEeAR4BHgEeAR4BIocAjzJLUJdOmnSpIFxcTGW27fv/F0gEKiLUNP4pvAI8AjwCPAI8AjwCPAIfBECPMn9IrgK9snW1tYX79+/39rYxPh1N4duG4cMGbLewcEhqWDXmq8djwCPAI8AjwCPAI8Aj0DeI8CT3LzH9JuVWL9+/YfPX72s06qVPb18+UoTFR4RbN+23YlxY0Yu6NChQ+I3qxh/Yx4BHgEeAR4BHgEeAR6Br4wAT3K/MuD5eTsrG+ug9Ax1jV/d3EgpV9DVq9fp6pUrFBMVGdisRbMj/fsN2DZoUN8X+VkHvmweAR4BHgEeAR4BHgEegYKAAE9yC0Iv5FEdrKxsglIz1DXmL3AjIgHJpHqUnJREd+/cIW/v8xQVFfHStr6198iRwxY4Ojq+zqPb8sXwCPAI8AjwCPAI8AjwCBQ4BHiSW+C6JOcVsrJu8FiuEtea7jqLRAIRqVVqkojFJJNJSalUkN/Na3ThwlmKjAx7ZtfE7tTg4cPXDOrLW3Zzjjh/JY8AjwCPAI8AjwCPQEFFgCe5BbVnclAvKyubh2lKYZ3ZcxaQQEOkUROJxSKSy+WED4oZG5I8PZXu3r9HFy6cp5BXL17XqV372kjnkfOHDXN6moNb8pfwCPAI8AjwCPAI8AjwCBRIBHiSWyC7JWeVqmdl/SBDLao3a/Y8juASCUmtIRIKhKTRqEmjUZKABGRsbEzv3qXQ06eP6OqVi/Tgwf2whg3rew4Z4Lj8hx9+eJKzu/NX8QjwCPAI8AjwCPAI8AgUHAR4kltw+iLXNalnZX0/Qy2y0iW5GpBcoYg0GhVHdAUCAalUahKLxaQnk1BGeiqFvnlN3hfO0f17dyOq16zuPbj/9+4///zzw1xXiC+AR4BHgEeAR4BHgEeAR+AbIcCT3G8EfH7c9lMkl0hNarWKky/AwqtQKEggIJKIRSQSCUmjVtHz4Gd07rwXBT64H1q5UgUv5+FDfh8/fjxv2c2PzuLL5BHgEeAR4BHgEeARyFcEeJKbr/B+3cKzkitoLblauQKIrlKpJJFI8t6iC9Ir5qy8GAgymYwU8gwKCwuliz4X6Kafb2T5cqWv9e7b181t7tx7X7c1/N14BHgEeAR4BHgEeAR4BHKOAE9yc45dgbvSyso6MF0tqptZriAQCEmtVpJYLOTqrNEISKPRcORXrdaQSoXvxCQSibR/i0QkEhKFhLygS5cvUkDArQjz4qbnBjkNWjxnzozHBa7hfIV4BHgEeAR4BHgEeAR4BDIhwJPcIjQk6llZPZRrJHVmzZrLEVnO8UxNnNUWVlytJldLcrWHhvsO5BbyBcTWhX5XpVJxMgapVEwqlZzevHlDvtev0PWrlyNLlyxxxdGxr9vcuXMfFCHo+KbwCPAI8AjwCPAI8AgUMQR4kluEOrSelfUjhUZce+ZHSC5IrfZHa9EF8dXGGsMwYD9CsGIu/hhHijVEBoZ6XJzdmOgIunzxAt28cSNcX1//yvd9+6xesmTR9SIEId8UHgEeAR4BHgEeAR6BIoIAT3KLSEeiGfWsrB8rNOJaOSO5DAghZ92FBVir19WQQiHXOqgJ1Zx1Nzo6mi6cP093bgfEaTQq/8EDB3j89tuCC0UISr4pPAI8AjwCPAI8AjwChRwBnuQW8g7UrX49K+snCo24ZvZJLq6GZZcd+Fur14XDGrS8IpH4PelVEWmUpNaoSCKRklQsotDQ13TnTgD5eJ9P0NfT83Xo6rBq7arfvYoQpHxTvjICPj4+eqmpqabp6elikUgk0NPTSylfvvy7unXryr9yVfjb8QjwCPAI8AgUcgR4klvIO1C3+nWtrIOUGnGNLyG5SA6hpbpMyqAhlRqaXDERibhoDNDpqtVqEomFJBQKSKlQkFBAJJVKQYkpOSmBrl27QhcvXkxSKxT+ffr0XLt69YojRQhavin5gIC/v7/k8uXLTZ88edLh2bNnjRISEsySkpKMU1JS9BQKhVAgEKgNDQ3lUqk0w8TEJMXS0jKsevXqV6pVq3ZrzJgxvvlQJb5IHgEeAR4BHoEihABPcotQZ9arZ/1UQeLq2SW5ILiC905oILkagYYEpCYVtLhQ7Ko1nFMaky9oBAIuexq9TywhEuJ6LT02MJBR/Ns4juz6+fklJycnXOndo9uWtWvXHi1CEPNNyQME1q5da3vu3LnxT548qR8eHl4xOTm5uE6xiHWHIcXl7HsvFoeInBOSS6VSTbFixaIrVKjwxNra2qdz5857nJz4lNR50C3frIi7d+/WDQ0NbfjmzZsaISEhFeLi4iwSExMN09PTEQEmUU9PL8TY2DiqdOnSTytUqPDa0tLyjYODw5tvVmH+xjwCPAKFBgGe5Baarvp8RRnJRQgxaGoRRQG/ESpMyxkyO55lXSYXjIEjuYjGwJzUtFEa1NAxvA8/pj1H9U+UBqGQZFIJxcW9pUePHpDXmZPvMlKT73Xp1m3L5g3rtn++BfwZRRkBd3f3NidPnpwWGBhok5iYaPm+rSpjY+NQc3PzpyVKlHhXunTpRGNjY5WBgYEIx9u3bw0SEhKMo6KiikdGRprEx8eXUSgUxiC/GI9ly5aNsLa2vjlo0KC5gwcP5iN+FIIBpNFoBK9fvx7i4+Mz/PLlyy38/f2l0PmnpKQQiC3eO5BMoX/x7kK0FxxisViur6+fUKxYsYQqVaqE29raXm7WrNkRR0fHu4Wg2XwVc4jAw4cPpS9evCiRnJxsnJaWJhMIBCI9Pb1UExOTBAcHhyiBAO7R/MEj8BE+wwNTdBAAyVUKJJwlNzck90sRYRMSF3pMIuEc1lQqBSkyUunevTt07uzZjKioiBs9uzls3rbtj91fWj5/fuFGYOfOndW2b9++zM/Pr2lycnIpjUajNjMze1KtWrUXzZo1S6pXr16V+vXrNzQxMZEUK1aMS0qCMYRDLpdzP/Hx8fT8+XO6f/8+PXv27K2fn1/GmzdvDJOSkophzJUtWzasffv224YPH/57q1at4gs3YkWz9iC39+/fn3X27Nlpnp6eJkFBQVy/pqWlcWQW/a6vr096enrcb/Qr3ikIb5iRkcERYJyLv1mcbzMzs0g7Ozu/Ll26bHBxcTlTNJH7b7XqxIkTlrdu3er86NGjjmFhYSVjY2PNEhMTTdLS0vQVCoUEq1uZTKbU09NLNjIyijM3N48uV67cyyZNmpysUaPGw169eoX+txDjW/spBHhLbhEaH9Y29Z8qSVJ9husvpFKxUGFwJIPZ6x/N7T8hxPKm8bC44AcTEou7q4EVmNSkpyejlHfJdOeOP13wvpARGx15r327trsmT3bZYGdnh+C8/FGEEZg2bdqAw4cPz3n+/HltmPwtLCzu29vbB3Tr1q2Kra1tm/Lly5OhoSFHchixhSUPPxhPID7swP9BdGDxA0Hy9fUlLy+v9Js3b2pSUlL0oRG3tbW9MWzYMJexY8f6FWFYC13THj161Mvb23v1vn37yqPv4uLiOKJqampKlpaWVLVqVapSpQr3u0yZMoTFDsguDvR3QkIChYWF0evXr+np06cUHBycERYWpkpJSTHAOSYmJolNmjS57uzs/IuTk9PtQgcQX2Fyd3fv5+PjM/bx48e1oqOjS2ZkZIgwn2Cc4N0hEok0EokEc4ZGoVBIVSoVi3vJoWdgYJBYsmTJ6Dp16jy1t7f/c8aMGYd5WHkEeJJbhMZA/QYNgxQkrjF9+ixSKrHdB6lB/pNcQAjtLiMnDFKRSEhKhZJEYhEZ6EkpJeUdPX70kC6c96LwyDDfFi2bHRg6YMDWnj17JhehbuCbQkQ+Pj7iLVu2/H706NFBqamp5sWKFXtlZ2d3w9nZuXybNm1agNiwA5Y5zomR6WSyQJCNLbagYtvYgYGBdOTIETpw4IAa5EmlUglh1Rk6dKjrb7/9tp/vjG+PwNmzZ5ft3LlzyokTJzjCisWKubk5NWjQgNq0aUOtWrWimjVrcp9ppVUfP7DISUpKoocPH9KFCxfo2rVrbwIDAxWxsbGVcVX58uVfd+3adevgwYNXtmzZkn+vfPvu/2wNXF1dB3l7e4978uSJbVJSkh6ecbFYrDI0NBSUKlVKiHdFiRIlyNjYmIyMjLh5hi18sFiKiIhAWMuMd+/eCZVKpQSk2MTEJLVmzZq3O3fuvPHXX3/dzUsaPtsNRfYEnuQWoa5taNcoSEGSGlOmupJSoX5PPDkJbb5acrXaXW3mNLxg8H8cAkxYXDgyDYmFQhLAUY3wvYIeBj6gs+fO0Juw0KB2rdp4OjkNX9SnT/u4ItQd/9mm+Pj4mC5atGjb1atXu6Snp0urVKlyrWfPnqEDBgxwql27NkdoMVYYoXlvqeHGEJO+ALwP4+j9TgEjwex8kCWUk5iYCFJNhw8fpvPnz8sjIyOlJUqUiHV0dFy0bt26lf/ZjigADd+2bdu+rVu3Ovr7+3N9W7x4cWrRogV1796dmjdvTuXKlfuwwGH9qjsGuPfI+/7XhjbU/qDfU1NTKSQkhLy9veXHjx9/fPPmzdJJSUmlIHNo2rTppfHjx493dHTkddoFYBxkVYWNGzfa7NixY+n9+/ebvHv3zLine truncated
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 163 KiB |
@@ -1,4 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<svg viewBox="-11.551 4.783 524.391 265.184" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
||||||
<image width="524.391" height="265.184" style="" x="-11.551" y="4.783" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAr4AAAFjCAYAAADbzwgZAAAAAXNSR0IArs4c6QAAIABJREFUeF7sXQdYVEcXvVvYpQqiYsUWuyJgb7E3sJcQo7Fgxd4FrFhjrLF3FHuLDewFRMUGCip2QRQRFaV3dvf/zuDohh8EpAjyJh8fxH1v3syZ2Tdn7px7r4iEIiAgICAgICAgICAgICAgICAgUAAQEBWAPgpdFBAQEBAQEBAQEBAQEBAQEBAQIIH4CpNAQEBAQEBAQEBAQEBAQEBAoEAgIBDfAjHMQicFBAQEBAQEBAQEBAQEBAQEBOIrzAEBAQEBAQEBAQEBAQEBAQGBAoGAQHwLxDALnRQQEBAQEBAQEBAQEBAQEBAQiK8wBwQEBAQEBAQEBAQEBAQEBAQKBAIC8S0Qwyx0UkBAQEBAQEBAQEBAQEBAQEAgvgVgDhw/flxv5syZ66tWrRrcr1+/hT169AgrAN0WuiggICAgICAgICAgICAg8B8EBOJbACaEk5NT6YEDB/pLpVJp0aJFnjRp0vR4nz59lltZWX0oAN0XuiggICAgICAgICAgICAgwBAQiG8BmAhbt24tZ2Nj49utW3ed4sWLk4eHB717F/yscePG5/v06fO3lZXVqwIAg9BFAQEBAQEBAQEBAQGBAo6AQHwLwATYsmVLhWHDhj+bPM1e0qJFGwoJCSHf+z50yfUiBb4JfF7XzPzw4MED1lpZWb0pAHAIXRQQEBAQEBAQEBAQECigCAjEtwAM/I4dO34ZNGjIk/GT7ST1GzalxIRE0tHWpMjISHr69BGdPXuGAl48e1K3bh3n4cMHQwIRXABgEbooICAgICAgICAgICBQwBAQiG8BGPCtW7dWGjp0xGNGfBs1o4T4BFIpFSQRi0lbW5tiYiLp2dPHdOH8OfLze36/Vo0axwYPttnQv3+vtwUAHqGLAgICAgICAgICAgICBQQBgfgWgIF2cnKqMnDg4EfjJ9uJGzRsRgkJiUzdDeKbkJhAEpGItOQyUqiU9ND3AV29cpke+D54WrNmjTOD+vdZMHjwYMEJrgDME6GLAgICAgICAgICAj87AgLx/dlHmIi2b99ezdp66MPxk+1EjPgmJVFSkoJEIhFpSCWkVCpIpVQxJDQ1ZSRSqejJ06d0xf0yPX784H7FCsb7f/+t16YxY8Z8LABwCV0UEBAQEBAQEBAQEBD4SREQiO9POrDq3XJ0dKwxePAw3/GT7ahBo2YUG5dAYomYFAoFScUSUqmSSS+KWESkTEokbR0dUiqV5Of3jK5dcaW7d7weGhuXdu77x++LJ06cKMQBLgDzRuiigICAgICAgICAwM+GgEB8f7YRTaU/27dvN7G2HnZv4lR7qtegKcXGxzNrr3rB/6sUSpJIQISVjPRKxBKSSsQklRAFBLykixfPk7f3XS+jYkWODhrQd9OUKVNCCgB8QhcFBAQEBAQEBAQEBAR+EgQE4vuTDOS3urFli1PtYcOG+HDiG5eQkOrlmAww/v5nUqhUzAoMSYREIqagt0F0/twZuuN167Gevt7FP/v8NtPBwUGwABeAeSR0UUBAQEBAQEBAQCC/IyAQ3/w+ghlo//bt282srYfdTY/48qpEX5UPzDKMH8giJCIiOZzgFEkUHPyGPDyukdvlSz6G+voH/+xr9Y+Dg0NMBpojXCIgICAgICAgICAgICAg8EMQEIjvD4E9dx+6dauT+dChQ+5w4hsfn7rFV71Vqi8zAxIIIpUIxFdMKkggpGKSSsWkIZFQ8LtguuzmRrdv3nygrS073qVT+7+WLVsWnbs9FJ4mICAgICAgICAgICAgIJA+AgLxTR+jfH+Fo6NjncGDh3t9Jb6J6fTpq8lXxbTAKlKSiml+SakkpUr52SlOycivXC6noDdv6NatG3TZ9aynplxy2MLCYsOaNWsi8j14QgcEBAQEBAQEBAQEBAR+GgQE4vvTDGXaHeHEd9JUe6rboCnFx4P4pjX0IL1qxJdUJBKLSCSWkFKhYHcplEoSi0SMCCuTFMwRTltbi90XFRFCV69eVrlfdnuWpEhy69Wj2+xVq1a9KwAwC13MQQRUKpVIJFIX4eTgw4SqBQQEBAQEBAR+WgQE4vvTDu3XjjHiO8TGa8o0ezKv1+gz8c3+jmMySSUiksmkLB3y1SvuSIbxKDY25kgfq+7/LF++XIgCkf2w/zQ1qlQqDQ8Pj5qvXr2q8erVq9oBAQHmERERhWJjY2WJiYkiqVSqKFKkSHThwoUDy5Qpc7dSpUoPS5cufd/U1DTwpwFB6IiAgICAgICAQI4iIBDfHIU3b1SeW8QXvU1WRihZQgwdHS0KDw+lO163ydX10ovYmMgr7dq0W75t28YHeQMZoRV5AYFz587V8/Dw+NPT07P1y5cvSwUGBupHRkZKcZLAC481zcPwyWQyhaGhYXS5cuXCTE1NnzVo0GBno0aNXGrWrPkpL/RJaMP3IfDhwwe9z3OgelRUVOHo6OhCRKTU0dGJ0tPTCylcuPDLEiVKvK1ataqwif4+iIW7BAQKPAIC8S0AUyA3iS9EEkiBDCkEMsKBCMtlUoqOjmIE+NKliwEfQz6e69DJYvMux02eBQB+oYtpIODs7Nz4yJEjM93c3OoHBAQUA7kFsUUsaW1tbdLS0mI/0JBLpVJKSkqi6Ohoio2Npfj4ePaTmJisV9fX14+qXr36406dOu3r1q3bHhMTE0Fekw9mnq+vr+zt27fV7t+/3/7evXttnz17Vubt27eGMTExenFxcZpxcXESSFzkcnmSTCaL19TUjDI0NAyrUKHCm7p167qbmpperV69+p1ffvklPB90V2jidyDg7++vqVQq5UqlUpaUlKSUyWSYCwnGxsax31GdcIuAQJpCTwGanwiBXCW+KjGRCBZfJYnEYpKKYQBWMgKspanJJBDe3nfIze3yu48hwbfbtGq6YdeuXad+IriFrqSDwKVLl6oeOnRoyqlTpzq/fv26BAivjo4OFS5cmKpWrcp+qlevTuXKlQOhJU1NTRKLxZSQkEARERFsDj148ICeP39Ojx8/Jn9/fwoPT+Y9mpqaCSYmJj4DBw78a+TIkUeFwcibCLx48ULf3d29vbOz87gHDx5UDgoKMoqKivqPIQabIJlMxjqAsVfPMIl/09HRURYuXPhjrVq1nrVo0eJI69atjzRs2NA/b/ZYaFVGEbh8+XIFf3//On5+fi3evn1rFhQUZBgVFSWPj4+XiMVilba2dlKhQoXiSpQo8bp06dKe5cuXv161atVH9erVe5XRZwjXFWwEBItvARj/3CS+iUlKFutXJCZSJCYxCx4sdWI4yKmgARaTXFNGUVHR9OD+Xbrkejbs/bt3l5s1buJ46ND+EwVgOApsF2G5OXLkSJ9t27ZNffr0aTWFQiE2MDAgExMTRnR79OjB/jYyMmJW35TZBdWBAwmC9Rfk9/r16+Tu7k5XrlxhpDgqKooKFSoU2rFjxzODBg2a3bFjx+cFFvQ81vHg4GCdf//99zdnZ+fR169frx4eHq6DJsKiX6xYsYjixYtHFStWLL5s2bKKQoUKgdzCq5FiYmKkYWFh0qCgIMnHjx813r17p/n27VvdhIQEtobp6OhEmpmZPWnXrt2+Xr16CRb/PDbu6TXn2rVr5c6fP9//7t27HR8+fFguMDCwWGxsrDy9+zBvihQpEleuXLm31apVu9+oUaNDTZs2dRN0/+khV7A/F4hvARh/xPEdYWNzZ9IUWzKt04ASEpJyrNdiiZSSFElM5sDJC/S+mGhikZhFgED0B2SBQyxgRVIc+T54QBcvXIh+GeB/u3XrlhsO7tt9MMcaKFT8QxDw9fUtsWTJkvXHjx9vFR4ebgD5Qu3atal79+7UsWNHqlatGmloaHxOmZ0cVYQnT0mtwZA4YH7BEoyN1du3b+nJkye0a9cucnV1pTdv3rDPzM3NPW1sbCYOGTLk6g/puPDQLwicOXOmwbZt2xZfunSpwcePHxnhLVSoUJSJiUlE06ZNk8zNzUtWqlRJo2TJkkzqAmsv5gQKxhg/kLl8+PCB/Pz8YPVP8vDwiHzw4IE4ICBAH9dpa2tHt2jR4vaff/65uF+/fmcF+PM2Aq6urpWcnZ0nnTp1ysLf37885Eu86OnpJRQqVChGX18/XldXN0lHR0eB9SMqKkocFhYmiYiIkOFdkpCQIOHvC2yWqlWr9qRbt26OHTt23F2nTp2gvI2A0LofgYBAfH8E6rn8TGRuG24z5u6kybZkYlYvR4kvidkr6P97qFRLB/f502QyrCKxBPGBFfTk8SM6f/Fs7KuX/lcbNai7Z/DgQYe6dOkiZIPL5fmS3Y+7fft2xSVLlmw7ceJESxxZ6+npUf/+/alfv35kZmbGpAwgNbDepCxpWX1TOrtxYgQpxMmTJ2nnzp3MEoznVapU6fmQIUMm2dnZOWd334T6MobAypUrh+/bt2/q7du3K2HsDAwMEhs3bvxx9OjRhapVq6ZtbGzMSC7Gm2u906oZWST5vAgJCaE7d+7QoUOHkk6ePJn47t07xFWkihUr+ltZWW3p37//JsHhMWNjlJtX4fRn/fr105ydnQc+fvy4IieuhoaGH83NzRPMzMxkNWvWLAK5U6lSpdg7Aj8oOOnBqQ42u8+fPw++f/9+hI+Pj9zX19cgMjKSbYAgnTI1NfXp37//Ihsbm8Mikeirp2xudlR4Vp5EQCC+eXJYsrdR27btMrUZZeMNi29ts/o5Fs6MtVr8/wQX/8wWs/98BOuvilnlxBIRiZQq0pRrUFxCHPn7PafzZ08rnj9/+qBuXXPnoYMH/dOzZ8+P2YuKUFtuIHDt2rVf5syZs+fSpUsNMdY1atSg4cOHU6dOnahs2bKfZTBiZr1NrXxL7qB+PSxBLine truncated
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 158 KiB |
@@ -1,97 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!-- Generator: Adobe Illustrator 26.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
|
||||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
|
||||||
viewBox="0 0 1034 239" style="enable-background:new 0 0 1034 239;" xml:space="preserve">
|
|
||||||
<style type="text/css">
|
|
||||||
.st0{fill:#576174;}
|
|
||||||
.st1{fill:#FFFFFF;}
|
|
||||||
.st2{font-family:'Courier-Bold';}
|
|
||||||
.st3{font-size:16.7604px;}
|
|
||||||
.st4{fill:#00983A;}
|
|
||||||
.st5{fill:none;stroke:#45CFFF;stroke-width:2.7934;stroke-linecap:round;stroke-linejoin:round;}
|
|
||||||
.st6{fill:#45CFFF;}
|
|
||||||
.st7{fill:none;stroke:#A000FF;stroke-width:2.7934;stroke-linecap:round;stroke-linejoin:round;}
|
|
||||||
.st8{fill:#A000FF;}
|
|
||||||
.st9{fill:none;stroke:#FFDE00;stroke-width:2.793;stroke-linecap:round;stroke-linejoin:round;}
|
|
||||||
.st10{fill:#FFDE00;}
|
|
||||||
.st11{fill:none;stroke:#EA5B0C;stroke-width:2.793;stroke-linecap:round;stroke-linejoin:round;}
|
|
||||||
.st12{fill:#EA5B0C;}
|
|
||||||
</style>
|
|
||||||
<g>
|
|
||||||
<path class="st0" d="M485.3,224.22H8.5c-4.7,0-8.5-3.8-8.5-8.5V27.22c0-4.7,3.8-8.5,8.5-8.5h476.8c4.7,0,8.5,3.8,8.5,8.5v188.5
|
|
||||||
C493.8,220.32,490,224.22,485.3,224.22z"/>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 21.294 60.1267)" class="st1 st2 st3">struct mg_str k,v,s = mg_str(”a=333, b=777”);</text>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 21.294 136.2499)" class="st1 st2 st3">mg_commalist(&s, &k, &v); </text>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 21.294 197.1485)" class="st1 st2 st3">mg_commalist(&s, &k, &v); </text>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 291.5096 140.18)" class="st4 st2 st3">// 1st call</text>
|
|
||||||
<text transform="matrix(1 0 0 1 291.5096 199.8101)" class="st4 st2 st3">// 2nd call</text>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<polyline class="st5" points="336.4,64.52 336.4,68.52 317.8,68.52 317.8,64.52 "/>
|
|
||||||
<g>
|
|
||||||
<path class="st5" d="M122.3,59.62"/>
|
|
||||||
<g>
|
|
||||||
<polyline class="st5" points="327.5,76.82 327.6,94.02 203.3,94.02 203.3,116.12 "/>
|
|
||||||
<path class="st6" d="M331,77.62c0,1.8-1.4,3.2-3.2,3.3c-1.8,0.1-3.2-1.4-3.3-3.2c0-1.8,1.4-3.2,3.2-3.3l0,0
|
|
||||||
C329.5,74.42,331,75.92,331,77.62z"/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<path class="st6" d="M203.2,114.92c-1.8,0-3.2,1.3-3.3,3s1.4,3,3.2,3s3.2-1.3,3.3-3l0,0C206.5,116.32,205,114.92,203.2,114.92z"/>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<polyline class="st7" points="407.4,64.52 407.4,68.52 388.8,68.52 388.8,64.52 "/>
|
|
||||||
<g>
|
|
||||||
<path class="st5" d="M193.4,59.62"/>
|
|
||||||
<g>
|
|
||||||
<polyline class="st7" points="398.6,76.82 398.6,149.02 203.4,149.02 203.4,177.12 "/>
|
|
||||||
<path class="st8" d="M402,77.62c0,1.8-1.4,3.2-3.2,3.3c-1.8,0.1-3.2-1.4-3.3-3.2c0-1.8,1.4-3.2,3.2-3.3l0,0
|
|
||||||
C400.6,74.42,402,75.92,402,77.62z"/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<path class="st8" d="M203.2,175.42c-1.8,0-3.2,1.3-3.3,3s1.4,3,3.2,3s3.2-1.3,3.3-3l0,0C206.5,176.82,205,175.42,203.2,175.42z"/>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<polyline class="st9" points="440.8,64.52 440.8,68.52 414.2,68.52 414.2,64.52 "/>
|
|
||||||
<g>
|
|
||||||
<path class="st5" d="M218.8,59.62"/>
|
|
||||||
<g>
|
|
||||||
<polyline class="st9" points="428,76.82 428,163.02 245.7,163.02 245.7,176.12 "/>
|
|
||||||
<path class="st10" d="M431.4,77.62c0,1.8-1.4,3.2-3.2,3.3c-1.8,0.1-3.2-1.4-3.3-3.2c0-1.8,1.4-3.2,3.2-3.3l0,0
|
|
||||||
C430,74.42,431.4,75.92,431.4,77.62z"/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<path class="st10" d="M245.4,175.42c-1.8,0-3.2,1.3-3.3,3s1.4,3,3.2,3s3.2-1.3,3.3-3l0,0C248.7,176.82,247.2,175.42,245.4,175.42z
|
|
||||||
"/>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<polyline class="st11" points="372.8,64.52 372.8,68.52 343.2,68.52 343.2,64.52 "/>
|
|
||||||
<g>
|
|
||||||
<path class="st5" d="M164.7,59.62"/>
|
|
||||||
<g>
|
|
||||||
<polyline class="st11" points="358.3,76.62 358.3,104.82 245.7,105.02 245.7,116.12 "/>
|
|
||||||
<path class="st12" d="M361.4,77.62c0,1.8-1.4,3.2-3.2,3.3c-1.8,0.1-3.2-1.4-3.3-3.2c0-1.8,1.4-3.2,3.2-3.3l0,0
|
|
||||||
C359.9,74.42,361.4,75.92,361.4,77.62z"/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<path class="st12" d="M245.7,114.92c-1.8,0-3.2,1.3-3.3,3s1.4,3,3.2,3s3.2-1.3,3.3-3l0,0C248.9,116.32,247.4,114.92,245.7,114.92z
|
|
||||||
"/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 3.9 KiB |
@@ -1,48 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!-- Generator: Adobe Illustrator 26.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
|
||||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
|
||||||
viewBox="0 0 1034 158.07" style="enable-background:new 0 0 1034 158.07;" xml:space="preserve">
|
|
||||||
<style type="text/css">
|
|
||||||
.st0{fill:#67748A;}
|
|
||||||
.st1{fill:#FFFFFF;}
|
|
||||||
.st2{font-family:'Courier-Bold';}
|
|
||||||
.st3{font-size:16.7604px;}
|
|
||||||
.st4{fill:none;stroke:#45CFFF;stroke-width:2.793;stroke-linecap:round;stroke-linejoin:round;}
|
|
||||||
.st5{fill:#45CFFF;}
|
|
||||||
.st6{font-family:'Arial-BoldMT';}
|
|
||||||
</style>
|
|
||||||
<g>
|
|
||||||
<path class="st0" d="M516.7,39.8v56.33c0,4.17-3.8,7.54-8.5,7.54H14.6H8.5c-4.7,0-8.5-3.37-8.5-7.54V39.8c0-4.17,3.8-7.54,8.5-7.54
|
|
||||||
h499.7C512.9,32.26,516.7,35.63,516.7,39.8z"/>
|
|
||||||
<text transform="matrix(1 0 0 1 51.0379 69.3318)" class="st1 st2 st3">GET /test \n\nGET /test \n\nGET test \n\n</text>
|
|
||||||
<g>
|
|
||||||
<polyline class="st4" points="189.5,76.47 189.5,80.47 51.8,80.47 51.8,76.47 "/>
|
|
||||||
<polyline class="st4" points="331.3,76.47 331.3,80.47 195.6,80.47 195.6,76.47 "/>
|
|
||||||
<polyline class="st4" points="462.7,76.47 462.7,80.47 336.9,80.47 336.9,76.47 "/>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 78.8909 148.8896)" class="st5 st6 st3">1st request</text>
|
|
||||||
<g>
|
|
||||||
<line class="st4" x1="120.2" y1="93.57" x2="120.3" y2="129.57"/>
|
|
||||||
<path class="st5" d="M117.1,92.57c0-1.8,1.4-3.2,3.2-3.3c1.8,0,3.2,1.4,3.3,3.2c0,1.8-1.4,3.2-3.2,3.3l0,0
|
|
||||||
C118.5,95.77,117.1,94.37,117.1,92.57z"/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 217.3594 148.8891)" class="st5 st6 st3">2nd request </text>
|
|
||||||
<g>
|
|
||||||
<line class="st4" x1="263.8" y1="93.57" x2="263.9" y2="129.57"/>
|
|
||||||
<path class="st5" d="M260.7,92.57c0-1.8,1.4-3.2,3.2-3.3c1.8,0,3.2,1.4,3.3,3.2c0,1.8-1.4,3.2-3.2,3.3l0,0
|
|
||||||
C262.1,95.77,260.7,94.37,260.7,92.57z"/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 354.7297 148.8896)" class="st5 st6 st3">3rd request </text>
|
|
||||||
<g>
|
|
||||||
<line class="st4" x1="399.4" y1="93.57" x2="399.4" y2="129.57"/>
|
|
||||||
<path class="st5" d="M396.2,92.57c0-1.8,1.4-3.2,3.2-3.3c1.8,0,3.2,1.4,3.3,3.2c0,1.8-1.4,3.2-3.2,3.3l0,0
|
|
||||||
C397.7,95.77,396.2,94.37,396.2,92.57z"/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 2.2 KiB |
@@ -1,113 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!-- Generator: Adobe Illustrator 26.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
|
||||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
|
||||||
viewBox="0 0 1035.4 429.9" style="enable-background:new 0 0 1035.4 429.9;" xml:space="preserve">
|
|
||||||
<style type="text/css">
|
|
||||||
.st0{fill:#576174;}
|
|
||||||
.st1{fill:#67748A;}
|
|
||||||
.st2{fill:none;stroke:#87005B;stroke-width:2.7934;stroke-linecap:round;stroke-linejoin:round;}
|
|
||||||
.st3{fill:#87005B;}
|
|
||||||
.st4{fill:#FFFFFF;}
|
|
||||||
.st5{font-family:'Courier-Bold';}
|
|
||||||
.st6{font-size:16.7604px;}
|
|
||||||
.st7{fill:none;stroke:#EA5B0C;stroke-width:2.793;stroke-linecap:round;stroke-linejoin:round;}
|
|
||||||
.st8{fill:#EA5B0C;}
|
|
||||||
.st9{fill:none;stroke:#CA70FF;stroke-width:2.7934;stroke-linecap:round;stroke-linejoin:round;}
|
|
||||||
.st10{fill:#CA70FF;}
|
|
||||||
.st11{fill:none;stroke:#FFDE00;stroke-width:2.793;stroke-linecap:round;stroke-linejoin:round;}
|
|
||||||
.st12{fill:#FFDE00;}
|
|
||||||
.st13{fill:none;stroke:#00CF4F;stroke-width:2.7934;stroke-linecap:round;stroke-linejoin:round;}
|
|
||||||
.st14{fill:#00CF4F;}
|
|
||||||
.st15{fill:none;stroke:#45CFFF;stroke-width:2.7934;stroke-linecap:round;stroke-linejoin:round;}
|
|
||||||
.st16{fill:none;stroke:#EA5B0C;stroke-width:2.7934;stroke-linecap:round;stroke-linejoin:round;}
|
|
||||||
.st17{font-family:'Arial-BoldMT';}
|
|
||||||
.st18{font-size:24px;}
|
|
||||||
.st19{fill:#45CFFF;}
|
|
||||||
</style>
|
|
||||||
<g>
|
|
||||||
<path class="st0" d="M755.8,391.8H8.5c-4.7,0-8.5-3.8-8.5-8.5v-153c0-4.7,3.8-8.5,8.5-8.5h747.3c4.7,0,8.5,3.8,8.5,8.5v153
|
|
||||||
C764.3,388,760.5,391.8,755.8,391.8z"/>
|
|
||||||
<path class="st1" d="M996.9,261.5h-427c-4.7,0-8.5-3.8-8.5-8.5V81.2c0-4.7,3.8-8.5,8.5-8.5h427c4.7,0,8.5,3.8,8.5,8.5V253
|
|
||||||
C1005.4,257.7,1001.5,261.5,996.9,261.5z"/>
|
|
||||||
<g>
|
|
||||||
<polyline class="st2" points="598.1,238.2 598.1,242.3 787.7,242.3 787.7,238.2 "/>
|
|
||||||
<g>
|
|
||||||
<line class="st2" x1="689.3" y1="342.2" x2="276.4" y2="343.3"/>
|
|
||||||
<g>
|
|
||||||
<line class="st2" x1="689.4" y1="253.3" x2="689.4" y2="342.1"/>
|
|
||||||
<path class="st3" d="M689.4,249.3c1.8,0,3.2,1.4,3.3,3.2c0,1.8-1.4,3.2-3.2,3.3c-1.8,0-3.2-1.4-3.3-3.2l0,0
|
|
||||||
C686.1,250.7,687.6,249.3,689.4,249.3z"/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<path class="st3" d="M274.2,340.4c1.8,0,3.2,1.4,3.3,3.2s-1.4,3.2-3.2,3.3c-1.8,0-3.2-1.4-3.3-3.2l0,0
|
|
||||||
C270.9,341.8,272.4,340.4,274.2,340.4z"/>
|
|
||||||
</g>
|
|
||||||
<text transform="matrix(1 0 0 1 26.0923 262.5192)" class="st4 st5 st6">struct mg_http_message {</text>
|
|
||||||
<text transform="matrix(1 0 0 1 45.542 286.2874)" class="st4 st5 st6">struct mg_str method; uri, query, proto; </text>
|
|
||||||
<text transform="matrix(1 0 0 1 45.542 306.3874)" class="st4 st5 st6">struct mg_http_header headers[MG_MAX_HTTP_HEADERS];</text>
|
|
||||||
<text transform="matrix(1 0 0 1 45.542 326.4874)" class="st4 st5 st6">struct mg_str body;</text>
|
|
||||||
<text transform="matrix(1 0 0 1 45.542 346.5874)" class="st4 st5 st6">struct mg_str message; </text>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<polyline class="st7" points="621.1,89.6 621.1,78.6 215.4,79.7 215.3,269.4 "/>
|
|
||||||
<path class="st8" d="M624.3,90.6c0,1.8-1.4,3.2-3.2,3.3c-1.8,0-3.2-1.4-3.3-3.2c0-1.8,1.4-3.2,3.2-3.3l0,0
|
|
||||||
C622.8,87.4,624.3,88.8,624.3,90.6z"/>
|
|
||||||
</g>
|
|
||||||
<path class="st8" d="M212.3,269.4c0-1.8,1.4-3.2,3.2-3.3c1.8,0,3.2,1.4,3.3,3.2c0,1.8-1.4,3.2-3.2,3.3l0,0
|
|
||||||
C213.7,272.6,212.3,271.2,212.3,269.4z"/>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<polyline class="st9" points="597.2,183.6 593.1,183.6 593.1,127.8 597.2,127.8 "/>
|
|
||||||
<g>
|
|
||||||
<polyline class="st9" points="582.4,156.2 575.2,156.2 575,302.8 563.4,302.8 "/>
|
|
||||||
<path class="st10" d="M586.1,156.2c0-1.8-1.4-3.2-3.2-3.3c-1.8,0-3.2,1.4-3.3,3.2c0,1.8,1.4,3.2,3.2,3.3l0,0
|
|
||||||
C584.7,159.4,586.1,158,586.1,156.2z"/>
|
|
||||||
<path class="st10" d="M564.2,303c0-1.8-1.4-3.2-3.2-3.3c-1.8,0-3.2,1.4-3.3,3.2s1.4,3.2,3.2,3.3l0,0
|
|
||||||
C562.7,306.2,564.2,304.7,564.2,303z"/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<text transform="matrix(1 0 0 1 601.1215 118.1291)" class="st4 st5 st6">POST /foo/bar/baz?aa=b&cc=ddd HTTP/1.1</text>
|
|
||||||
<text transform="matrix(1 0 0 1 601.1215 138.2291)" class="st4 st5 st6">Content-Type: application/json</text>
|
|
||||||
<text transform="matrix(1 0 0 1 601.1215 158.3291)" class="st4 st5 st6">Content-Length: 19</text>
|
|
||||||
<text transform="matrix(1 0 0 1 601.1215 178.4291)" class="st4 st5 st6">Host: reqbin.com</text>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<polyline class="st11" points="712.3,90.6 712.4,67.6 277.8,67.6 279.7,269.3 "/>
|
|
||||||
<path class="st12" d="M715.6,90.8c0,1.8-1.4,3.2-3.2,3.3c-1.8,0-3.2-1.4-3.3-3.2c0-1.8,1.4-3.2,3.2-3.3l0,0
|
|
||||||
C714.1,87.6,715.6,89.1,715.6,90.8z"/>
|
|
||||||
</g>
|
|
||||||
<path class="st12" d="M276.5,269.4c0-1.8,1.4-3.2,3.2-3.3s3.2,1.4,3.3,3.2s-1.4,3.2-3.2,3.3l0,0
|
|
||||||
C278,272.6,276.5,271.2,276.5,269.4z"/>
|
|
||||||
</g>
|
|
||||||
<polyline class="st11" points="771.5,104.3 771.5,100.3 652.7,100.3 652.7,104.3 "/>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<polyline class="st13" points="836.3,90.6 836.3,56.6 342.8,56.6 344.7,268.3 "/>
|
|
||||||
<path class="st14" d="M839.5,90.6c0,1.8-1.4,3.2-3.2,3.3c-1.8,0-3.2-1.4-3.3-3.2c0-1.8,1.4-3.2,3.2-3.3l0,0
|
|
||||||
C838,87.4,839.5,88.9,839.5,90.6z"/>
|
|
||||||
</g>
|
|
||||||
<path class="st14" d="M341.4,269.3c0-1.8,1.4-3.2,3.2-3.3c1.8,0,3.2,1.4,3.3,3.2c0,1.8-1.4,3.2-3.2,3.3l0,0
|
|
||||||
C342.9,272.5,341.4,271.1,341.4,269.3z"/>
|
|
||||||
</g>
|
|
||||||
<polyline class="st15" points="981.4,104.2 981.4,100.2 902.6,100.2 902.6,104.2 "/>
|
|
||||||
</g>
|
|
||||||
<text transform="matrix(1 0 0 1 596.891 232.3658)" class="st4 st5 st6">{"success": "true"}</text>
|
|
||||||
<polyline class="st16" points="643.1,104.4 643.1,100.4 599.3,100.4 599.3,104.4 "/>
|
|
||||||
<text transform="matrix(1 0 0 1 9.5506 207.5157)" class="st17 st18">Source Code</text>
|
|
||||||
<text transform="matrix(1 0 0 1 797.0799 32.3923)" class="st17 st18">HTTP message</text>
|
|
||||||
<text transform="matrix(1 0 0 1 26.0924 359.209)" class="st4 st5 st6">};</text>
|
|
||||||
<polyline class="st13" points="894.2,104.2 894.2,100.2 774.4,100.2 774.4,104.2 "/>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<polyline class="st15" points="941.3,90.6 941.3,45.6 412.8,45.6 414.7,268.3 "/>
|
|
||||||
<path class="st19" d="M944.5,90.6c0,1.8-1.4,3.2-3.2,3.3c-1.8,0-3.2-1.4-3.3-3.2c0-1.8,1.4-3.2,3.2-3.3l0,0
|
|
||||||
C943,87.4,944.5,88.9,944.5,90.6z"/>
|
|
||||||
</g>
|
|
||||||
<path class="st19" d="M411.4,269.3c0-1.8,1.4-3.2,3.2-3.3c1.8,0,3.2,1.4,3.3,3.2c0,1.8-1.4,3.2-3.2,3.3l0,0
|
|
||||||
C412.9,272.5,411.4,271.1,411.4,269.3z"/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 6.0 KiB |
@@ -1,109 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!-- Generator: Adobe Illustrator 26.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
|
||||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
|
||||||
viewBox="0 0 1034 663.54" style="enable-background:new 0 0 1034 663.54;" xml:space="preserve">
|
|
||||||
<style type="text/css">
|
|
||||||
.st0{fill:none;stroke:#45CFFF;stroke-width:2.7934;stroke-linecap:round;stroke-linejoin:round;}
|
|
||||||
.st1{fill:#45CFFF;}
|
|
||||||
.st2{fill:#576174;}
|
|
||||||
.st3{fill:#FFFFFF;}
|
|
||||||
.st4{font-family:'Courier-Bold';}
|
|
||||||
.st5{font-size:16.7604px;}
|
|
||||||
.st6{font-family:'Arial-BoldMT';}
|
|
||||||
.st7{font-size:24px;}
|
|
||||||
.st8{fill:#67748A;}
|
|
||||||
.st9{fill:#8B9CBA;}
|
|
||||||
.st10{fill:none;stroke:#00CF4F;stroke-width:2.7934;stroke-linecap:round;stroke-linejoin:round;}
|
|
||||||
.st11{fill:#00CF4F;}
|
|
||||||
.st12{fill:none;stroke:#EA5B0C;stroke-width:2.793;stroke-linecap:round;stroke-linejoin:round;}
|
|
||||||
.st13{fill:#EA5B0C;}
|
|
||||||
.st14{fill:#414857;}
|
|
||||||
</style>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<polyline class="st0" points="498.5,624.21 498.5,628.21 447.9,628.21 447.9,624.21 "/>
|
|
||||||
<g>
|
|
||||||
<path class="st0" d="M491.8,844.81"/>
|
|
||||||
<g>
|
|
||||||
<path class="st1" d="M473.8,636.11c-1.8,0-3.2,1.4-3.3,3.2c0,1.8,1.4,3.2,3.2,3.3c1.8,0,3.2-1.4,3.3-3.2l0,0
|
|
||||||
C477.1,637.61,475.6,636.11,473.8,636.11z"/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<path class="st1" d="M296.7,852.71c-1.8,0-3.2,1.3-3.3,3c0,1.7,1.4,3,3.2,3c1.8,0,3.2-1.3,3.3-3l0,0
|
|
||||||
C299.9,854.01,298.5,852.71,296.7,852.71z"/>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<path class="st2" d="M584.6,199.01H8.5c-4.7,0-8.5-3.8-8.5-8.5V60.71c0-4.7,3.8-8.5,8.5-8.5h576.1c4.7,0,8.5,3.8,8.5,8.5v129.8
|
|
||||||
C593.1,195.21,589.3,199.01,584.6,199.01z"/>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 28.7 90.8107)" class="st3 st4 st5">struct mg_http_part part;</text>
|
|
||||||
<text transform="matrix(1 0 0 1 28.7 110.9108)" class="st3 st4 st5">size_t pos = 0;</text>
|
|
||||||
<text transform="matrix(1 0 0 1 28.7 151.1107)" class="st3 st4 st5">pos = mg_http_next_multipart(&hm->body, pos, &part);</text>
|
|
||||||
<text transform="matrix(1 0 0 1 28.7 171.3107)" class="st3 st4 st5">pos = mg_http_next_multipart(&hm->body, pos, &part);</text>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<text transform="matrix(1 0 0 1 1.3738 40.559)" class="st6 st7">Source Code</text>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<path class="st8" d="M685.5,646.41H8.5c-4.7,0-8.5-3.8-8.5-8.5v-362.9c0-4.7,3.8-8.5,8.5-8.5h677c4.7,0,8.5,3.8,8.5,8.5v362.9
|
|
||||||
C694,642.61,690.2,646.41,685.5,646.41z"/>
|
|
||||||
</g>
|
|
||||||
<path class="st9" d="M640.2,629.41H26.3c-4.7,0-8.5-3.8-8.5-8.5v-106.5c0-4.7,3.8-8.5,8.5-8.5h613.9c4.7,0,8.5,3.8,8.5,8.5v106.5
|
|
||||||
C648.7,625.61,644.8,629.41,640.2,629.41z"/>
|
|
||||||
<path class="st9" d="M644,490.91H30.1c-4.7,0-8.5-3.8-8.5-8.5v-106.5c0-4.7,3.8-8.5,8.5-8.5H644c4.7,0,8.5,3.8,8.5,8.5v106.5
|
|
||||||
C652.5,487.11,648.7,490.91,644,490.91z"/>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 0.0299 253.0343)" class="st6 st7">HTTP message</text>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 28.7 302.8107)" class="st3 st4 st5">POST /upload HTTP/1.1 </text>
|
|
||||||
<text transform="matrix(1 0 0 1 28.7 322.9107)" class="st3 st4 st5">Content-Type: multipart/form-data; boundary="--xyz"</text>
|
|
||||||
<text transform="matrix(1 0 0 1 28.7 363.1107)" class="st3 st4 st5">--xyz</text>
|
|
||||||
<text transform="matrix(1 0 0 1 28.7 383.3107)" class="st3 st4 st5">Content-Disposition: form-data; name="foo"; filename="a.txt"</text>
|
|
||||||
<text transform="matrix(1 0 0 1 28.7 403.4107)" class="st3 st4 st5">Content-Type: text/plain</text>
|
|
||||||
<text transform="matrix(1 0 0 1 28.7 443.6107)" class="st3 st4 st5">hello world</text>
|
|
||||||
<text transform="matrix(1 0 0 1 28.7 483.8107)" class="st3 st4 st5">--xyz---</text>
|
|
||||||
<text transform="matrix(1 0 0 1 28.7 524.0107)" class="st3 st4 st5">Content-Disposition: form-data; name="bar"; filename="b.txt"</text>
|
|
||||||
<text transform="matrix(1 0 0 1 28.7 544.2108)" class="st3 st4 st5">Content-Type: text/plain</text>
|
|
||||||
<text transform="matrix(1 0 0 1 28.7 584.4108)" class="st3 st4 st5">hello world again</text>
|
|
||||||
<text transform="matrix(1 0 0 1 28.7 624.6107)" class="st3 st4 st5">--xyz--</text>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<polyline class="st10" points="569.5,162.51 574.5,162.51 574.5,176.11 569.5,176.11 "/>
|
|
||||||
<g>
|
|
||||||
<path class="st0" d="M726.8,392.91"/>
|
|
||||||
<g>
|
|
||||||
<polyline class="st10" points="587.3,169.71 726.7,169.71 726.6,569.31 684.3,569.31 "/>
|
|
||||||
<path class="st11" d="M585,166.41c-1.8,0-3.2,1.4-3.3,3.2c0,1.8,1.4,3.2,3.2,3.3c1.8,0,3.2-1.4,3.3-3.2l0,0
|
|
||||||
C588.2,167.91,586.8,166.41,585,166.41z"/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<path class="st11" d="M685,566.31c-1.7,0-3,1.3-3,3s1.3,3,3,3s3-1.3,3-3l0,0C688,567.61,686.6,566.31,685,566.31z"/>
|
|
||||||
</g>
|
|
||||||
<polyline class="st10" points="657.9,501.61 673.9,501.61 673.9,634.21 657.9,634.21 "/>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<polyline class="st12" points="569.5,143.21 574.5,143.21 574.5,156.81 569.5,156.81 "/>
|
|
||||||
<g>
|
|
||||||
<path class="st0" d="M726.8,254.61"/>
|
|
||||||
<g>
|
|
||||||
<polyline class="st12" points="587.3,150.41 710.7,150.41 710.6,431.01 684.3,431.01 "/>
|
|
||||||
<path class="st13" d="M585,147.11c-1.8,0-3.2,1.4-3.3,3.2s1.4,3.2,3.2,3.3c1.8,0,3.2-1.4,3.3-3.2l0,0
|
|
||||||
C588.2,148.61,586.8,147.11,585,147.11z"/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<path class="st13" d="M685,428.01c-1.7,0-3,1.3-3,3s1.3,3,3,3s3-1.3,3-3l0,0C688,429.31,686.6,428.01,685,428.01z"/>
|
|
||||||
</g>
|
|
||||||
<polyline class="st12" points="657.9,363.31 673.9,363.31 673.9,495.91 657.9,495.91 "/>
|
|
||||||
</g>
|
|
||||||
<text transform="matrix(1 0 0 1 537.9671 462.1467)" class="st14 st6 st7">Part 1</text>
|
|
||||||
<text transform="matrix(1 0 0 1 537.9671 600.4373)" class="st14 st6 st7">Part 2</text>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 5.5 KiB |
@@ -1,94 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!-- Generator: Adobe Illustrator 26.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
|
||||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
|
||||||
viewBox="0 0 1034 480.6" style="enable-background:new 0 0 1034 480.6;" xml:space="preserve">
|
|
||||||
<style type="text/css">
|
|
||||||
.st0{fill:#67748A;}
|
|
||||||
.st1{fill:#8B9CBA;}
|
|
||||||
.st2{fill:#FFFFFF;}
|
|
||||||
.st3{font-family:'Courier-Bold';}
|
|
||||||
.st4{font-size:16.7604px;}
|
|
||||||
.st5{fill:#414857;}
|
|
||||||
.st6{font-family:'Arial-BoldMT';}
|
|
||||||
.st7{font-size:30px;}
|
|
||||||
.st8{font-size:24px;}
|
|
||||||
.st9{fill:#576174;}
|
|
||||||
.st10{fill:none;stroke:#45CFFF;stroke-width:2.7934;stroke-linecap:round;stroke-linejoin:round;}
|
|
||||||
.st11{fill:#45CFFF;}
|
|
||||||
.st12{fill:none;stroke:#EA5B0C;stroke-width:2.793;stroke-linecap:round;stroke-linejoin:round;}
|
|
||||||
.st13{fill:#EA5B0C;}
|
|
||||||
.st14{fill:none;stroke:#EA5B0C;stroke-width:2.7934;stroke-linecap:round;stroke-linejoin:round;}
|
|
||||||
.st15{fill:none;stroke:#FFDE00;stroke-width:2.793;stroke-linecap:round;stroke-linejoin:round;}
|
|
||||||
.st16{fill:#FFDE00;}
|
|
||||||
</style>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<path class="st0" d="M908.4,454.9H272c-4.7,0-8.5-3.8-8.5-8.5V216c0-4.7,3.8-8.5,8.5-8.5h636.4c4.7,0,8.5,3.8,8.5,8.5v230.4
|
|
||||||
C916.9,451.1,913.1,454.9,908.4,454.9z"/>
|
|
||||||
<g>
|
|
||||||
<path class="st1" d="M898.6,430.8H284.7c-4.7,0-8.5-3.8-8.5-8.5V315.9c0-4.7,3.8-8.5,8.5-8.5h613.9c4.7,0,8.5,3.8,8.5,8.5v106.5
|
|
||||||
C907.1,427,903.3,430.8,898.6,430.8z"/>
|
|
||||||
<text transform="matrix(1 0 0 1 295.3688 243.086)" class="st2 st3 st4">POST /upload HTTP/1.1 </text>
|
|
||||||
<text transform="matrix(1 0 0 1 295.3688 263.186)" class="st2 st3 st4">Content-Type: multipart/form-data: boundary="--xyz"</text>
|
|
||||||
<text transform="matrix(1 0 0 1 295.3688 303.386)" class="st2 st3 st4">--xyz</text>
|
|
||||||
<text transform="matrix(1 0 0 1 295.3688 323.586)" class="st2 st3 st4">Content-Disposition: form-data; name="foo"; filename="a.txt"</text>
|
|
||||||
<text transform="matrix(1 0 0 1 295.3688 343.686)" class="st2 st3 st4">Content-Type: text/plain</text>
|
|
||||||
<text transform="matrix(1 0 0 1 295.3688 383.886)" class="st2 st3 st4">hello world</text>
|
|
||||||
<text transform="matrix(1 0 0 1 295.3688 424.086)" class="st2 st3 st4">--xyz---</text>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<text transform="matrix(1 0 0 1 739.2766 414.2906)" class="st5 st6 st7">HTTP part</text>
|
|
||||||
<text transform="matrix(1 0 0 1 739.2764 193.4305)" class="st6 st8">HTTP message</text>
|
|
||||||
<path class="st9" d="M304.9,198H8.5c-4.7,0-8.5-3.8-8.5-8.5V64.8c0-4.7,3.8-8.5,8.5-8.5H305c4.7,0,8.5,3.8,8.5,8.5v124.7
|
|
||||||
C313.4,194.2,309.6,198,304.9,198z"/>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 25.2409 91.1617)" class="st2 st3 st4">struct mg_http_part {</text>
|
|
||||||
<text transform="matrix(1 0 0 1 47.0734 113.7079)" class="st2 st3 st4">struct mg_str name;</text>
|
|
||||||
<text transform="matrix(1 0 0 1 47.0734 133.8079)" class="st2 st3 st4">strucy mg_str filename;</text>
|
|
||||||
<text transform="matrix(1 0 0 1 47.0734 153.9079)" class="st2 st3 st4">struct mg_str body;</text>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<polyline class="st10" points="237.4,159 237.4,163 185.8,163 185.8,159 "/>
|
|
||||||
<g>
|
|
||||||
<polyline class="st10" points="211.7,348.3 349.5,348.4 349.5,355.6 "/>
|
|
||||||
<g>
|
|
||||||
<line class="st10" x1="211.6" y1="174.4" x2="211.6" y2="348.1"/>
|
|
||||||
<path class="st11" d="M211.6,170.3c-1.8,0-3.2,1.4-3.3,3.2c0,1.8,1.4,3.2,3.2,3.3c1.8,0,3.2-1.4,3.3-3.2l0,0
|
|
||||||
C214.8,171.8,213.4,170.3,211.6,170.3z"/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<path class="st11" d="M349.6,353.6c-1.8,0-3.2,1.4-3.3,3.2s1.4,3.2,3.2,3.3c1.8,0,3.2-1.4,3.3-3.2l0,0
|
|
||||||
C352.8,355.1,351.4,353.6,349.6,353.6z"/>
|
|
||||||
<polyline class="st10" points="237.4,159 237.4,163 185.8,163 185.8,159 "/>
|
|
||||||
<polyline class="st10" points="407.3,371.1 407.3,367.1 293.3,367.1 293.3,371.1 "/>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<polyline class="st12" points="693.7,291.6 693.7,277.7 280.7,278.8 280.5,109.4 248.3,109.4 "/>
|
|
||||||
<path class="st13" d="M696.9,293.6c0,1.8-1.4,3.2-3.2,3.3c-1.8,0-3.2-1.4-3.3-3.2c0-1.8,1.4-3.2,3.2-3.3l0,0
|
|
||||||
C695.4,290.4,696.9,291.9,696.9,293.6z"/>
|
|
||||||
</g>
|
|
||||||
<path class="st13" d="M243.9,109.5c0-1.8,1.4-3.2,3.2-3.3c1.8,0,3.2,1.4,3.3,3.2c0,1.8-1.4,3.2-3.2,3.3l0,0
|
|
||||||
C245.3,112.7,243.9,111.3,243.9,109.5z"/>
|
|
||||||
</g>
|
|
||||||
<polyline class="st14" points="707.6,309.2 707.6,305.2 679.9,305.2 679.9,309.2 "/>
|
|
||||||
</g>
|
|
||||||
<text transform="matrix(1 0 0 1 0.8627 37.8099)" class="st6 st8">Source Code</text>
|
|
||||||
<text transform="matrix(1 0 0 1 25.2408 177.7241)" class="st2 st3 st4">};</text>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<polyline class="st15" points="863.8,291.5 863.7,218.6 329.7,218.7 329.6,130.3 298.4,130.3 "/>
|
|
||||||
<path class="st16" d="M867.1,293.6c0,1.8-1.4,3.2-3.2,3.3c-1.8,0-3.2-1.4-3.3-3.2c0-1.8,1.4-3.2,3.2-3.3l0,0
|
|
||||||
C865.6,290.3,867.1,291.8,867.1,293.6z"/>
|
|
||||||
</g>
|
|
||||||
<path class="st16" d="M293,130.1c0-1.8,1.4-3.2,3.2-3.3c1.8,0,3.2,1.4,3.3,3.2c0,1.8-1.4,3.2-3.2,3.3l0,0
|
|
||||||
C294.4,133.3,293,131.9,293,130.1z"/>
|
|
||||||
</g>
|
|
||||||
<polyline class="st15" points="888.7,309.1 888.7,305.1 838.9,305.1 838.9,309.1 "/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 4.9 KiB |
@@ -1,84 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!-- Generator: Adobe Illustrator 26.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
|
||||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
|
||||||
viewBox="0 0 1034 331.2" style="enable-background:new 0 0 1034 331.2;" xml:space="preserve">
|
|
||||||
<style type="text/css">
|
|
||||||
.st0{fill:#576174;}
|
|
||||||
.st1{fill:#67748A;}
|
|
||||||
.st2{fill:#FFFFFF;}
|
|
||||||
.st3{font-family:'Courier-Bold';}
|
|
||||||
.st4{font-size:16.7604px;}
|
|
||||||
.st5{font-family:'Arial-BoldMT';}
|
|
||||||
.st6{font-size:24px;}
|
|
||||||
.st7{fill:none;stroke:#45CFFF;stroke-width:2.7934;stroke-linecap:round;stroke-linejoin:round;}
|
|
||||||
.st8{fill:#45CFFF;}
|
|
||||||
.st9{fill:none;stroke:#EA5B0C;stroke-width:2.793;stroke-linecap:round;stroke-linejoin:round;}
|
|
||||||
.st10{fill:#EA5B0C;}
|
|
||||||
.st11{fill:none;stroke:#EA5B0C;stroke-width:2.7934;stroke-linecap:round;stroke-linejoin:round;}
|
|
||||||
.st12{fill:none;stroke:#00CF4F;stroke-width:2.7934;stroke-linecap:round;stroke-linejoin:round;}
|
|
||||||
.st13{fill:#00CF4F;}
|
|
||||||
</style>
|
|
||||||
<g>
|
|
||||||
<path class="st0" d="M541.43,184.2H8.53c-4.7,0-8.5-3.8-8.5-8.5V54.8c0-4.7,3.8-8.5,8.5-8.5h532.9c4.7,0,8.5,3.8,8.5,8.5v120.9
|
|
||||||
C549.93,180.4,546.13,184.2,541.43,184.2z"/>
|
|
||||||
<g>
|
|
||||||
<path class="st1" d="M829.23,315.5h-370c-4.7,0-8.5-3.8-8.5-8.5V157c0-4.7,3.8-8.5,8.5-8.5h370c4.7,0,8.5,3.8,8.5,8.5v150
|
|
||||||
C837.83,311.7,833.93,315.5,829.23,315.5z"/>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 490.6096 184.0905)" class="st2 st3 st4">HTTP/1.1 200 OK</text>
|
|
||||||
<text transform="matrix(1 0 0 1 490.6096 204.1905)" class="st2 st3 st4">Content-Length; 13</text>
|
|
||||||
<text transform="matrix(1 0 0 1 490.6096 224.2905)" class="st2 st3 st4">X-Header-1: additional value 1</text>
|
|
||||||
<text transform="matrix(1 0 0 1 490.6096 244.3905)" class="st2 st3 st4">X-Header-2: additional value 2</text>
|
|
||||||
<text transform="matrix(1 0 0 1 490.8657 293.1559)" class="st2 st3 st4">Hello, world!</text>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<text transform="matrix(1 0 0 1 660.5036 137.3383)" class="st5 st6">HTTP message</text>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 20.7331 85.1617)" class="st2 st3 st4">mg_http_reply(c, 200</text>
|
|
||||||
<text transform="matrix(1 0 0 1 159.5657 113.7079)" class="st2 st3 st4">"X-Header-1: additional value 1\r\n"</text>
|
|
||||||
<text transform="matrix(1 0 0 1 159.5657 133.8079)" class="st2 st3 st4">"X-Header-2: additional value 2\r\n",</text>
|
|
||||||
<text transform="matrix(1 0 0 1 159.5657 153.9079)" class="st2 st3 st4">"Hello, %s!", "world");</text>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<polyline class="st7" points="362.93,159 362.93,163 167.33,163 167.33,159 "/>
|
|
||||||
<g>
|
|
||||||
<polyline class="st7" points="265.93,256.6 552.13,256.7 552.13,264.4 "/>
|
|
||||||
<g>
|
|
||||||
<line class="st7" x1="265.83" y1="174.4" x2="265.83" y2="256.6"/>
|
|
||||||
<path class="st8" d="M265.83,170.3c-1.8,0-3.2,1.4-3.3,3.2c0,1.8,1.4,3.2,3.2,3.3c1.8,0,3.2-1.4,3.3-3.2l0,0
|
|
||||||
C269.03,171.8,267.53,170.3,265.83,170.3z"/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<path class="st8" d="M552.23,261.6c-1.8,0-3.2,1.4-3.3,3.2c0,1.8,1.4,3.2,3.2,3.3c1.8,0,3.2-1.4,3.3-3.2l0,0
|
|
||||||
C555.43,263.1,554.03,261.6,552.23,261.6z"/>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<polyline class="st9" points="206.33,53.6 206.43,37.6 596.43,38.7 596.53,161.3 "/>
|
|
||||||
<path class="st10" d="M203.23,54.6c0,1.8,1.4,3.2,3.2,3.3c1.8,0,3.2-1.4,3.3-3.2c0-1.8-1.4-3.2-3.2-3.3l0,0
|
|
||||||
C204.63,51.4,203.23,52.8,203.23,54.6z"/>
|
|
||||||
</g>
|
|
||||||
<path class="st10" d="M599.83,164c0-1.8-1.4-3.2-3.2-3.3c-1.8,0-3.2,1.4-3.3,3.2c0,1.8,1.4,3.2,3.2,3.3l0,0
|
|
||||||
C598.33,167.2,599.83,165.8,599.83,164z"/>
|
|
||||||
</g>
|
|
||||||
<polyline class="st11" points="192.43,69.2 192.43,65.2 220.23,65.2 220.23,69.2 "/>
|
|
||||||
</g>
|
|
||||||
<text transform="matrix(1 0 0 1 -1.917133e-04 35.0037)" class="st5 st6">Source Code</text>
|
|
||||||
<g>
|
|
||||||
<polyline class="st12" points="160.13,135.9 156.03,135.9 156.03,100.1 160.13,100.1 "/>
|
|
||||||
<g>
|
|
||||||
<line class="st12" x1="123.93" y1="231" x2="469.73" y2="231"/>
|
|
||||||
<polyline class="st12" points="144.73,117.2 123.83,117.2 123.73,230.8 "/>
|
|
||||||
<path class="st13" d="M147.83,117.2c0-1.8-1.4-3.2-3.2-3.3c-1.8,0-3.2,1.4-3.3,3.2c0,1.8,1.4,3.2,3.2,3.3l0,0
|
|
||||||
C146.33,120.4,147.83,119,147.83,117.2z"/>
|
|
||||||
<path class="st13" d="M474.83,230.8c0-1.8-1.4-3.2-3.2-3.3c-1.8,0-3.2,1.4-3.3,3.2c0,1.8,1.4,3.2,3.2,3.3l0,0
|
|
||||||
C473.43,234,474.83,232.5,474.83,230.8z"/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<polyline class="st7" points="489.03,279.6 489.03,275.6 620.63,275.6 620.63,279.6 "/>
|
|
||||||
<polyline class="st12" points="487.63,248.3 483.63,248.3 483.63,211.5 487.63,211.5 "/>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 4.4 KiB |
@@ -1,124 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!-- Generator: Adobe Illustrator 26.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
|
||||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
|
||||||
viewBox="0 0 869.6 185.67" style="enable-background:new 0 0 869.6 185.67;" xml:space="preserve">
|
|
||||||
<style type="text/css">
|
|
||||||
.st0{font-family:'Arial-BoldMT';}
|
|
||||||
.st1{font-size:24px;}
|
|
||||||
.st2{opacity:0.2;fill:#00983A;enable-background:new ;}
|
|
||||||
.st3{fill:none;stroke:#7A8387;stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round;}
|
|
||||||
.st4{fill:#00983A;}
|
|
||||||
.st5{fill:none;stroke:#576174;stroke-miterlimit:10;}
|
|
||||||
.st6{fill:#F2F3F3;stroke:#7A8387;stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round;}
|
|
||||||
.st7{fill:none;stroke:#576174;stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round;}
|
|
||||||
.st8{font-family:'Courier-Bold';}
|
|
||||||
.st9{font-size:16.7604px;}
|
|
||||||
.st10{fill:none;stroke:#00983A;stroke-linecap:round;stroke-linejoin:round;}
|
|
||||||
.st11{fill:#576174;}
|
|
||||||
.st12{font-family:'Courier';}
|
|
||||||
.st13{fill:none;}
|
|
||||||
.st14{fill:#7A8387;}
|
|
||||||
</style>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 1.0956 32.4549)" class="st0 st1">Memory</text>
|
|
||||||
<polyline class="st2" points="424.58,115.4 219.88,115.4 219.88,90.7 424.58,90.7 "/>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<polyline class="st3" points="458.98,115.4 218.98,115.4 218.98,90.7 458.98,90.7 "/>
|
|
||||||
<polyline class="st4" points="219.18,115.1 2.98,115.1 2.98,91.3 219.18,91.3 "/>
|
|
||||||
<line class="st3" x1="2.98" y1="69.2" x2="2.98" y2="130.4"/>
|
|
||||||
<line class="st5" x1="219.78" y1="69.2" x2="219.78" y2="130.4"/>
|
|
||||||
<line class="st5" x1="425.28" y1="69.2" x2="425.28" y2="130.4"/>
|
|
||||||
<path class="st6" d="M458.98,115.4"/>
|
|
||||||
<path class="st7" d="M33.98,114.6"/>
|
|
||||||
<path class="st7" d="M33.98,90.9"/>
|
|
||||||
<path class="st7" d="M2.98,90.7h216.8v24.9l-216.8-0.2C2.98,115.4,3.18,90.7,2.98,90.7z"/>
|
|
||||||
<line class="st3" x1="425.18" y1="90.8" x2="425.18" y2="115.3"/>
|
|
||||||
<path class="st6" d="M251.98,115.6"/>
|
|
||||||
<path class="st6" d="M251.98,91.9"/>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 -2.290726e-04 175.3858)" class="st4 st8 st9">buf</text>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<line class="st10" x1="2.68" y1="158.2" x2="2.68" y2="137.2"/>
|
|
||||||
<g>
|
|
||||||
<polygon class="st4" points="0.28,137.6 5.08,137.6 2.68,135.1 "/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 214.6515 175.3858)" class="st4 st8 st9">len</text>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<line class="st10" x1="219.78" y1="158.2" x2="219.78" y2="137.2"/>
|
|
||||||
<g>
|
|
||||||
<polygon class="st4" points="217.38,137.6 222.18,137.6 219.78,135.1 "/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 421.6186 175.3858)" class="st4 st8 st9">size</text>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<line class="st10" x1="425.38" y1="158.2" x2="425.38" y2="137.2"/>
|
|
||||||
<g>
|
|
||||||
<polygon class="st4" points="422.98,137.6 427.78,137.6 425.38,135.1 "/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 93.1143 69.4458)" class="st11 st12 st9">data</text>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 273.8231 69.4458)" class="st11 st12 st9">free space</text>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<line class="st5" x1="132.98" y1="76.3" x2="13.98" y2="76.3"/>
|
|
||||||
<g>
|
|
||||||
<polygon class="st11" points="14.28,78.7 14.28,73.8 11.88,76.3 "/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<line class="st13" x1="123.88" y1="76.3" x2="210.88" y2="76.3"/>
|
|
||||||
<g>
|
|
||||||
<line class="st5" x1="123.88" y1="76.3" x2="208.78" y2="76.3"/>
|
|
||||||
<g>
|
|
||||||
<polygon class="st11" points="208.48,73.8 208.48,78.7 210.88,76.3 "/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<line class="st5" x1="320.38" y1="76.3" x2="414.28" y2="76.3"/>
|
|
||||||
<g>
|
|
||||||
<polygon class="st14" points="413.98,73.8 413.98,78.7 416.38,76.3 "/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<line class="st5" x1="322.28" y1="76.3" x2="233.28" y2="76.3"/>
|
|
||||||
<g>
|
|
||||||
<polygon class="st14" points="233.68,78.7 233.68,73.8 231.18,76.3 "/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 4.1 KiB |
@@ -1,52 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!-- Generator: Adobe Illustrator 26.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
|
||||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
|
||||||
viewBox="0 0 869 124.66" style="enable-background:new 0 0 869 124.66;" xml:space="preserve">
|
|
||||||
<style type="text/css">
|
|
||||||
.st0{fill:#F2F3F3;stroke:#7A8387;stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round;}
|
|
||||||
.st1{fill:none;stroke:#7A8387;stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round;}
|
|
||||||
.st2{fill:#00983A;}
|
|
||||||
.st3{font-family:'Courier-Bold';}
|
|
||||||
.st4{font-size:16.7604px;}
|
|
||||||
.st5{fill:none;stroke:#00983A;stroke-linecap:round;stroke-linejoin:round;}
|
|
||||||
.st6{fill:#7A8387;}
|
|
||||||
</style>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<polyline class="st0" points="830.92,78.4 5.52,78.4 5.52,53.7 830.92,53.6 "/>
|
|
||||||
<line class="st1" x1="5.52" y1="32.2" x2="5.52" y2="93.4"/>
|
|
||||||
<path class="st0" d="M830.92,78.4"/>
|
|
||||||
<line class="st1" x1="36.52" y1="53.9" x2="36.52" y2="77.6"/>
|
|
||||||
<line class="st1" x1="68.92" y1="53.9" x2="68.92" y2="77.6"/>
|
|
||||||
<line class="st1" x1="101.42" y1="53.9" x2="101.42" y2="77.6"/>
|
|
||||||
<line class="st1" x1="133.72" y1="53.9" x2="133.72" y2="77.6"/>
|
|
||||||
<line class="st1" x1="166.22" y1="53.9" x2="166.22" y2="77.6"/>
|
|
||||||
<line class="st1" x1="198.52" y1="54.6" x2="198.52" y2="78.3"/>
|
|
||||||
<line class="st1" x1="230.92" y1="54.6" x2="230.92" y2="78.3"/>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 59.1908 40.8585)" class="st2 st3 st4">buf=NULL, len=0, size=0 </text>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 -1.811981e-04 109.9024)" class="st2 st3 st4">0</text>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<line class="st5" x1="46.72" y1="37.7" x2="17.72" y2="37.7"/>
|
|
||||||
<g>
|
|
||||||
<polygon class="st2" points="18.12,40.1 18.12,35.2 15.62,37.7 "/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<path class="st6" d="M511.52,66.4c0,0.9-0.7,1.6-1.6,1.6s-1.6-0.7-1.6-1.6s0.7-1.6,1.6-1.6S511.52,65.5,511.52,66.4z"/>
|
|
||||||
<path class="st6" d="M525.32,66.4c0,0.9-0.7,1.6-1.6,1.6s-1.6-0.7-1.6-1.6s0.7-1.6,1.6-1.6S525.32,65.5,525.32,66.4z"/>
|
|
||||||
<path class="st6" d="M539.02,66.4c0,0.9-0.7,1.6-1.6,1.6c-0.9,0-1.6-0.7-1.6-1.6s0.7-1.6,1.6-1.6S539.02,65.5,539.02,66.4z"/>
|
|
||||||
<path class="st6" d="M552.82,66.4c0,0.9-0.7,1.6-1.6,1.6s-1.6-0.7-1.6-1.6s0.7-1.6,1.6-1.6S552.82,65.5,552.82,66.4z"/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 2.3 KiB |
@@ -1,185 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!-- Generator: Adobe Illustrator 26.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
|
||||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
|
||||||
viewBox="0 0 869.6 127.5" style="enable-background:new 0 0 869.6 127.5;" xml:space="preserve">
|
|
||||||
<style type="text/css">
|
|
||||||
.st0{opacity:0.2;fill:#00983A;enable-background:new ;}
|
|
||||||
.st1{fill:#F2F3F3;}
|
|
||||||
.st2{fill:none;stroke:#7A8387;stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round;}
|
|
||||||
.st3{fill:#00983A;}
|
|
||||||
.st4{fill:#F2F3F3;stroke:#7A8387;stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round;}
|
|
||||||
.st5{fill:none;stroke:#576174;stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round;}
|
|
||||||
.st6{fill:none;stroke:#576174;stroke-width:1.2;stroke-linecap:square;stroke-linejoin:round;}
|
|
||||||
.st7{font-family:'Courier-Bold';}
|
|
||||||
.st8{font-size:16.7604px;}
|
|
||||||
.st9{fill:none;stroke:#00983A;stroke-linecap:round;stroke-linejoin:round;}
|
|
||||||
.st10{fill:#7A8387;}
|
|
||||||
.st11{fill:#576174;}
|
|
||||||
.st12{fill:none;stroke:#576174;stroke-linecap:round;stroke-linejoin:round;}
|
|
||||||
.st13{fill:none;stroke:#7A8387;stroke-linecap:round;stroke-linejoin:round;}
|
|
||||||
.st14{fill:#333A45;}
|
|
||||||
</style>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<polyline class="st0" points="577.2,72.8 282.4,72.8 282.4,48 577.2,48 "/>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<polyline class="st1" points="122.6,72.8 5.9,72.8 5.9,48 122.6,48 "/>
|
|
||||||
<polyline class="st2" points="831.51,72.8 5.5,72.8 5.5,48 831.51,48 "/>
|
|
||||||
<polyline class="st3" points="282.7,72.5 122.5,72.5 122.5,47.7 282.7,47.7 "/>
|
|
||||||
<line class="st2" x1="122.5" y1="26.6" x2="122.5" y2="87.8"/>
|
|
||||||
<line class="st2" x1="283.3" y1="26.6" x2="283.3" y2="87.8"/>
|
|
||||||
<line class="st2" x1="576.8" y1="26.6" x2="576.8" y2="87.8"/>
|
|
||||||
<path class="st4" d="M831.51,72.8"/>
|
|
||||||
<line class="st5" x1="153.5" y1="48.3" x2="153.5" y2="72"/>
|
|
||||||
<line class="st2" x1="36.5" y1="48.3" x2="36.5" y2="72"/>
|
|
||||||
<line class="st2" x1="67.6" y1="48.3" x2="67.6" y2="72"/>
|
|
||||||
<line class="st5" x1="186" y1="48.3" x2="186" y2="72"/>
|
|
||||||
<line class="st5" x1="218.4" y1="48.3" x2="218.4" y2="72"/>
|
|
||||||
<line class="st5" x1="250.9" y1="48.3" x2="250.9" y2="72"/>
|
|
||||||
<line class="st2" x1="315.9" y1="48.3" x2="315.9" y2="72"/>
|
|
||||||
<line class="st2" x1="348.4" y1="48.3" x2="348.4" y2="72"/>
|
|
||||||
<line class="st2" x1="381.2" y1="48.3" x2="381.2" y2="72"/>
|
|
||||||
<line class="st2" x1="413.8" y1="48.3" x2="413.8" y2="72"/>
|
|
||||||
<line class="st2" x1="446.3" y1="48.3" x2="446.3" y2="72"/>
|
|
||||||
<line class="st2" x1="478.9" y1="48.3" x2="478.9" y2="72"/>
|
|
||||||
<line class="st5" x1="511.51" y1="48.3" x2="511.51" y2="72"/>
|
|
||||||
<line class="st2" x1="511.51" y1="48.3" x2="511.51" y2="72"/>
|
|
||||||
<line class="st5" x1="544.01" y1="48.3" x2="544.01" y2="72"/>
|
|
||||||
<line class="st2" x1="544.1" y1="48.3" x2="544.1" y2="72"/>
|
|
||||||
<line class="st6" x1="283.3" y1="73" x2="122.5" y2="72.8"/>
|
|
||||||
<line class="st6" x1="122.5" y1="48" x2="283.3" y2="48.1"/>
|
|
||||||
<path class="st4" d="M385.5,73"/>
|
|
||||||
<path class="st4" d="M385.5,49.3"/>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 127.5176 105.8013)" class="st3 st7 st8">buf</text>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<line class="st9" x1="122.2" y1="105.6" x2="122.2" y2="94.6"/>
|
|
||||||
<g>
|
|
||||||
<polygon class="st3" points="119.8,94.9 124.6,94.9 122.2,92.5 "/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 286.6495 105.8008)" class="st3 st7 st8">len=5</text>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<line class="st9" x1="283.3" y1="105.6" x2="283.3" y2="94.6"/>
|
|
||||||
<g>
|
|
||||||
<polygon class="st3" points="280.9,94.9 285.8,94.9 283.3,92.5 "/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 581.4624 105.8013)" class="st3 st7 st8">size=16</text>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<line class="st9" x1="576.9" y1="105.6" x2="576.9" y2="94.6"/>
|
|
||||||
<g>
|
|
||||||
<polygon class="st3" points="574.51,94.9 579.4,94.9 576.9,92.5 "/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<path class="st10" d="M687.51,60.7c0,0.9-0.7,1.6-1.6,1.6s-1.6-0.7-1.6-1.6c0-0.9,0.7-1.6,1.6-1.6S687.51,59.9,687.51,60.7z"/>
|
|
||||||
<path class="st10" d="M701.2,60.7c0,0.9-0.7,1.6-1.6,1.6s-1.6-0.7-1.6-1.6c0-0.9,0.7-1.6,1.6-1.6S701.2,59.9,701.2,60.7z"/>
|
|
||||||
<path class="st10" d="M714.9,60.7c0,0.9-0.7,1.6-1.6,1.6c-0.9,0-1.6-0.7-1.6-1.6c0-0.9,0.7-1.6,1.6-1.6
|
|
||||||
C714.2,59.1,714.9,59.9,714.9,60.7z"/>
|
|
||||||
<path class="st10" d="M728.7,60.7c0,0.9-0.7,1.6-1.6,1.6s-1.6-0.7-1.6-1.6c0-0.9,0.7-1.6,1.6-1.6
|
|
||||||
C728.01,59.1,728.7,59.9,728.7,60.7z"/>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<path class="st10" d="M82.8,60.7c0,0.9-0.7,1.6-1.6,1.6s-1.6-0.7-1.6-1.6c0-0.9,0.7-1.6,1.6-1.6S82.8,59.9,82.8,60.7z"/>
|
|
||||||
<path class="st10" d="M96.5,60.7c0,0.9-0.7,1.6-1.6,1.6s-1.6-0.7-1.6-1.6c0-0.9,0.7-1.6,1.6-1.6C95.8,59.1,96.5,59.9,96.5,60.7
|
|
||||||
z"/>
|
|
||||||
<path class="st10" d="M110.2,60.7c0,0.9-0.7,1.6-1.6,1.6s-1.6-0.7-1.6-1.6c0-0.9,0.7-1.6,1.6-1.6S110.2,59.9,110.2,60.7z"/>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 180.6541 26.8123)" class="st11 st7 st8">data</text>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 387.363 26.8123)" class="st10 st7 st8">free space</text>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<line class="st12" x1="272.2" y1="33.6" x2="133.5" y2="33.6"/>
|
|
||||||
<g>
|
|
||||||
<polygon class="st11" points="271.9,36.2 273.5,33.6 271.9,31.1 271.8,31.1 271.8,36.2 "/>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<polygon class="st11" points="133.8,36.1 133.8,31.2 131.4,33.6 "/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<line class="st13" x1="563.7" y1="33.6" x2="295.9" y2="33.6"/>
|
|
||||||
<g>
|
|
||||||
<polygon class="st10" points="563.4,36.1 563.4,31.2 565.8,33.6 "/>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<polygon class="st10" points="296.2,36.1 296.2,31.2 293.7,33.6 "/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 615.4679 25.1898)" class="st10 st7 st8">non-allocated space</text>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<line class="st13" x1="593.7" y1="33.6" x2="829.7" y2="33.6"/>
|
|
||||||
<g>
|
|
||||||
<polygon class="st10" points="829.4,31.2 829.4,36.1 831.8,33.6 "/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<line class="st13" x1="678.7" y1="33.6" x2="589.7" y2="33.6"/>
|
|
||||||
<g>
|
|
||||||
<polygon class="st10" points="590.01,36.1 590.01,31.2 587.6,33.6 "/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 133.1212 64.9593)" class="st14 st7 st8">h</text>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 165.1564 64.9593)" class="st14 st7 st8">e</text>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 196.8744 64.9593)" class="st14 st7 st8">l</text>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 229.8611 64.9593)" class="st14 st7 st8">l</text>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 262.2135 64.9593)" class="st14 st7 st8">o</text>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 1.811981e-04 105.8011)" class="st3 st7 st8">0</text>
|
|
||||||
</g>
|
|
||||||
<line class="st2" x1="5.5" y1="26.4" x2="5.5" y2="87.6"/>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 7.1 KiB |
@@ -1,347 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!-- Generator: Adobe Illustrator 26.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
|
||||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
|
||||||
viewBox="0 0 869.6 247.73" style="enable-background:new 0 0 869.6 247.73;" xml:space="preserve">
|
|
||||||
<style type="text/css">
|
|
||||||
.st0{opacity:0.2;fill:#00983A;enable-background:new ;}
|
|
||||||
.st1{fill:#00983A;}
|
|
||||||
.st2{fill:#FF80A4;}
|
|
||||||
.st3{fill:#F2F3F3;}
|
|
||||||
.st4{fill:none;stroke:#7A8387;stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round;}
|
|
||||||
.st5{fill:#F2F3F3;stroke:#7A8387;stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round;}
|
|
||||||
.st6{fill:none;stroke:#576174;stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round;}
|
|
||||||
.st7{fill:none;stroke:#576174;stroke-width:1.2;stroke-linejoin:round;}
|
|
||||||
.st8{fill:none;stroke:#576174;stroke-width:1.2;stroke-linecap:square;stroke-linejoin:round;}
|
|
||||||
.st9{font-family:'Courier-Bold';}
|
|
||||||
.st10{font-size:16.7604px;}
|
|
||||||
.st11{fill:none;stroke:#00983A;stroke-linecap:round;stroke-linejoin:round;}
|
|
||||||
.st12{fill:#7A8387;}
|
|
||||||
.st13{fill:#576174;}
|
|
||||||
.st14{fill:none;stroke:#576174;stroke-linecap:round;stroke-linejoin:round;}
|
|
||||||
.st15{fill:none;stroke:#7A8387;stroke-linecap:round;stroke-linejoin:round;}
|
|
||||||
.st16{fill:#333A45;}
|
|
||||||
</style>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<polyline class="st0" points="577.2,72.8 282.4,72.8 282.4,48 577.2,48 "/>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<rect x="250.9" y="47.7" class="st1" width="32.4" height="24.8"/>
|
|
||||||
<rect x="153.5" y="47.7" class="st2" width="97.3" height="24.8"/>
|
|
||||||
<polyline class="st3" points="122.6,72.8 5.9,72.8 5.9,48 122.6,48 "/>
|
|
||||||
<polyline class="st4" points="831.51,72.8 5.5,72.8 5.5,48 831.51,48 "/>
|
|
||||||
<rect x="122.5" y="47.7" class="st1" width="31" height="24.8"/>
|
|
||||||
<line class="st4" x1="122.5" y1="26.6" x2="122.5" y2="87.8"/>
|
|
||||||
<line class="st4" x1="576.8" y1="26.6" x2="576.8" y2="87.8"/>
|
|
||||||
<path class="st5" d="M831.51,72.8"/>
|
|
||||||
<line class="st6" x1="153.5" y1="48.3" x2="153.5" y2="72"/>
|
|
||||||
<line class="st4" x1="36.5" y1="48.3" x2="36.5" y2="72"/>
|
|
||||||
<line class="st4" x1="67.6" y1="48.3" x2="67.6" y2="72"/>
|
|
||||||
<line class="st6" x1="186" y1="48.3" x2="186" y2="72"/>
|
|
||||||
<line class="st6" x1="218.4" y1="48.3" x2="218.4" y2="72"/>
|
|
||||||
<line class="st7" x1="250.9" y1="73" x2="250.81" y2="47.7"/>
|
|
||||||
<line class="st4" x1="315.9" y1="48.3" x2="315.9" y2="72"/>
|
|
||||||
<line class="st4" x1="348.4" y1="48.3" x2="348.4" y2="72"/>
|
|
||||||
<line class="st4" x1="381.2" y1="48.3" x2="381.2" y2="72"/>
|
|
||||||
<line class="st4" x1="413.8" y1="48.3" x2="413.8" y2="72"/>
|
|
||||||
<line class="st4" x1="446.3" y1="48.3" x2="446.3" y2="72"/>
|
|
||||||
<line class="st4" x1="478.9" y1="48.3" x2="478.9" y2="72"/>
|
|
||||||
<line class="st6" x1="511.51" y1="48.3" x2="511.51" y2="72"/>
|
|
||||||
<line class="st4" x1="511.51" y1="48.3" x2="511.51" y2="72"/>
|
|
||||||
<line class="st6" x1="544.01" y1="48.3" x2="544.01" y2="72"/>
|
|
||||||
<line class="st4" x1="544.1" y1="48.3" x2="544.1" y2="72"/>
|
|
||||||
<line class="st8" x1="283.3" y1="73" x2="122.5" y2="72.8"/>
|
|
||||||
<line class="st8" x1="122.5" y1="48" x2="283.3" y2="48.1"/>
|
|
||||||
<path class="st5" d="M385.5,73"/>
|
|
||||||
<path class="st5" d="M385.5,49.3"/>
|
|
||||||
<line class="st4" x1="283.3" y1="26.6" x2="283.3" y2="87.8"/>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 127.5176 105.8013)" class="st1 st9 st10">buf</text>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<line class="st11" x1="122.2" y1="105.6" x2="122.2" y2="94.6"/>
|
|
||||||
<g>
|
|
||||||
<polygon class="st1" points="119.8,94.9 124.6,94.9 122.2,92.5 "/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 286.6495 105.8008)" class="st1 st9 st10">len=5</text>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<line class="st11" x1="283.3" y1="105.6" x2="283.3" y2="94.6"/>
|
|
||||||
<g>
|
|
||||||
<polygon class="st1" points="280.9,94.9 285.8,94.9 283.3,92.5 "/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 581.4624 105.8013)" class="st1 st9 st10">size=16</text>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<line class="st11" x1="576.9" y1="105.6" x2="576.9" y2="94.6"/>
|
|
||||||
<g>
|
|
||||||
<polygon class="st1" points="574.51,94.9 579.4,94.9 576.9,92.5 "/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<path class="st12" d="M687.51,60.7c0,0.9-0.7,1.6-1.6,1.6s-1.6-0.7-1.6-1.6c0-0.9,0.7-1.6,1.6-1.6S687.51,59.9,687.51,60.7z"/>
|
|
||||||
<path class="st12" d="M701.2,60.7c0,0.9-0.7,1.6-1.6,1.6s-1.6-0.7-1.6-1.6c0-0.9,0.7-1.6,1.6-1.6S701.2,59.9,701.2,60.7z"/>
|
|
||||||
<path class="st12" d="M714.9,60.7c0,0.9-0.7,1.6-1.6,1.6c-0.9,0-1.6-0.7-1.6-1.6c0-0.9,0.7-1.6,1.6-1.6
|
|
||||||
C714.2,59.1,714.9,59.9,714.9,60.7z"/>
|
|
||||||
<path class="st12" d="M728.7,60.7c0,0.9-0.7,1.6-1.6,1.6s-1.6-0.7-1.6-1.6c0-0.9,0.7-1.6,1.6-1.6
|
|
||||||
C728.01,59.1,728.7,59.9,728.7,60.7z"/>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<path class="st12" d="M82.8,60.7c0,0.9-0.7,1.6-1.6,1.6s-1.6-0.7-1.6-1.6c0-0.9,0.7-1.6,1.6-1.6S82.8,59.9,82.8,60.7z"/>
|
|
||||||
<path class="st12" d="M96.5,60.7c0,0.9-0.7,1.6-1.6,1.6s-1.6-0.7-1.6-1.6c0-0.9,0.7-1.6,1.6-1.6C95.8,59.1,96.5,59.9,96.5,60.7
|
|
||||||
z"/>
|
|
||||||
<path class="st12" d="M110.2,60.7c0,0.9-0.7,1.6-1.6,1.6s-1.6-0.7-1.6-1.6c0-0.9,0.7-1.6,1.6-1.6S110.2,59.9,110.2,60.7z"/>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 180.6541 26.8123)" class="st13 st9 st10">data</text>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 387.363 26.8123)" class="st12 st9 st10">free space</text>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<line class="st14" x1="272.2" y1="33.6" x2="133.5" y2="33.6"/>
|
|
||||||
<g>
|
|
||||||
<polygon class="st13" points="271.9,36.2 273.5,33.6 271.9,31.1 271.8,31.1 271.8,36.2 "/>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<polygon class="st13" points="133.8,36.1 133.8,31.2 131.4,33.6 "/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<line class="st15" x1="563.7" y1="33.6" x2="295.9" y2="33.6"/>
|
|
||||||
<g>
|
|
||||||
<polygon class="st12" points="563.4,36.1 563.4,31.2 565.8,33.6 "/>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<polygon class="st12" points="296.2,36.1 296.2,31.2 293.7,33.6 "/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 615.4679 25.1898)" class="st12 st9 st10">non-allocated space</text>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<line class="st15" x1="593.7" y1="33.6" x2="829.7" y2="33.6"/>
|
|
||||||
<g>
|
|
||||||
<polygon class="st12" points="829.4,31.2 829.4,36.1 831.8,33.6 "/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<line class="st15" x1="678.7" y1="33.6" x2="589.7" y2="33.6"/>
|
|
||||||
<g>
|
|
||||||
<polygon class="st12" points="590.01,36.1 590.01,31.2 587.6,33.6 "/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 133.1212 64.9593)" class="st16 st9 st10">h</text>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 165.1564 64.9593)" class="st16 st9 st10">e</text>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 196.8744 64.9593)" class="st16 st9 st10">l</text>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 229.8611 64.9593)" class="st16 st9 st10">l</text>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 262.2135 64.9593)" class="st16 st9 st10">o</text>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 1.811981e-04 105.8011)" class="st1 st9 st10">0</text>
|
|
||||||
</g>
|
|
||||||
<line class="st4" x1="5.5" y1="26.4" x2="5.5" y2="87.6"/>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<polyline class="st0" points="577.2,207.99 186.3,207.99 186.3,183.19 577.2,183.19 "/>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<polyline class="st3" points="122.6,207.99 5.9,207.99 5.9,183.19 122.6,183.19 "/>
|
|
||||||
<polyline class="st4" points="831.51,207.99 5.5,207.99 5.5,183.19 831.51,183.19 "/>
|
|
||||||
<polyline class="st1" points="186.3,207.69 122.5,207.69 122.5,182.89 186.3,182.89 "/>
|
|
||||||
<line class="st4" x1="122.5" y1="161.79" x2="122.5" y2="222.99"/>
|
|
||||||
<line class="st4" x1="186" y1="161.79" x2="186" y2="222.99"/>
|
|
||||||
<line class="st4" x1="576.8" y1="161.79" x2="576.8" y2="222.99"/>
|
|
||||||
<path class="st5" d="M831.51,207.99"/>
|
|
||||||
<line class="st6" x1="153.5" y1="183.49" x2="153.5" y2="207.19"/>
|
|
||||||
<line class="st4" x1="36.5" y1="183.49" x2="36.5" y2="207.19"/>
|
|
||||||
<line class="st4" x1="67.6" y1="183.49" x2="67.6" y2="207.19"/>
|
|
||||||
<line class="st6" x1="186" y1="183.49" x2="186" y2="207.99"/>
|
|
||||||
<line class="st4" x1="218.4" y1="183.49" x2="218.4" y2="207.19"/>
|
|
||||||
<line class="st4" x1="250.9" y1="183.49" x2="250.9" y2="207.19"/>
|
|
||||||
<line class="st4" x1="283.3" y1="183.49" x2="283.3" y2="207.19"/>
|
|
||||||
<line class="st4" x1="315.9" y1="183.49" x2="315.9" y2="207.19"/>
|
|
||||||
<line class="st4" x1="348.4" y1="183.49" x2="348.4" y2="207.19"/>
|
|
||||||
<line class="st4" x1="381.2" y1="183.49" x2="381.2" y2="207.19"/>
|
|
||||||
<line class="st4" x1="413.8" y1="183.49" x2="413.8" y2="207.19"/>
|
|
||||||
<line class="st4" x1="446.3" y1="183.49" x2="446.3" y2="207.19"/>
|
|
||||||
<line class="st4" x1="478.9" y1="183.49" x2="478.9" y2="207.19"/>
|
|
||||||
<line class="st6" x1="511.51" y1="183.49" x2="511.51" y2="207.19"/>
|
|
||||||
<line class="st4" x1="511.51" y1="183.49" x2="511.51" y2="207.19"/>
|
|
||||||
<line class="st6" x1="544.01" y1="183.49" x2="544.01" y2="207.19"/>
|
|
||||||
<line class="st4" x1="544.1" y1="183.49" x2="544.1" y2="207.19"/>
|
|
||||||
<line class="st8" x1="186" y1="208.19" x2="122.5" y2="207.99"/>
|
|
||||||
<line class="st8" x1="122.5" y1="183.19" x2="186" y2="183.29"/>
|
|
||||||
<path class="st5" d="M385.5,208.19"/>
|
|
||||||
<path class="st5" d="M385.5,184.49"/>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 127.5176 240.9952)" class="st1 st9 st10">buf</text>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<line class="st11" x1="122.2" y1="240.79" x2="122.2" y2="229.79"/>
|
|
||||||
<g>
|
|
||||||
<polygon class="st1" points="119.8,230.09 124.6,230.09 122.2,227.69 "/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 189.2273 240.9947)" class="st1 st9 st10">len=2</text>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<line class="st11" x1="185.88" y1="240.79" x2="185.88" y2="229.79"/>
|
|
||||||
<g>
|
|
||||||
<polygon class="st1" points="183.48,230.09 188.38,230.09 185.88,227.69 "/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 581.4624 240.9952)" class="st1 st9 st10">size=16</text>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<line class="st11" x1="576.9" y1="240.79" x2="576.9" y2="229.79"/>
|
|
||||||
<g>
|
|
||||||
<polygon class="st1" points="574.51,230.09 579.4,230.09 576.9,227.69 "/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<path class="st12" d="M687.51,195.89c0,0.9-0.7,1.6-1.6,1.6s-1.6-0.7-1.6-1.6c0-0.9,0.7-1.6,1.6-1.6
|
|
||||||
S687.51,195.09,687.51,195.89z"/>
|
|
||||||
<path class="st12" d="M701.2,195.89c0,0.9-0.7,1.6-1.6,1.6s-1.6-0.7-1.6-1.6c0-0.9,0.7-1.6,1.6-1.6S701.2,195.09,701.2,195.89z
|
|
||||||
"/>
|
|
||||||
<path class="st12" d="M714.9,195.89c0,0.9-0.7,1.6-1.6,1.6c-0.9,0-1.6-0.7-1.6-1.6c0-0.9,0.7-1.6,1.6-1.6
|
|
||||||
S714.9,195.09,714.9,195.89z"/>
|
|
||||||
<path class="st12" d="M728.7,195.89c0,0.9-0.7,1.6-1.6,1.6s-1.6-0.7-1.6-1.6c0-0.9,0.7-1.6,1.6-1.6
|
|
||||||
C728.01,194.29,728.7,195.09,728.7,195.89z"/>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<path class="st12" d="M82.8,195.89c0,0.9-0.7,1.6-1.6,1.6s-1.6-0.7-1.6-1.6c0-0.9,0.7-1.6,1.6-1.6S82.8,195.09,82.8,195.89z"/>
|
|
||||||
<path class="st12" d="M96.5,195.89c0,0.9-0.7,1.6-1.6,1.6s-1.6-0.7-1.6-1.6c0-0.9,0.7-1.6,1.6-1.6
|
|
||||||
C95.8,194.29,96.5,195.09,96.5,195.89z"/>
|
|
||||||
<path class="st12" d="M110.2,195.89c0,0.9-0.7,1.6-1.6,1.6s-1.6-0.7-1.6-1.6c0-0.9,0.7-1.6,1.6-1.6S110.2,195.09,110.2,195.89z
|
|
||||||
"/>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 133.6541 162.0062)" class="st13 st9 st10">data</text>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 327.363 162.0062)" class="st12 st9 st10">free space</text>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<line class="st14" x1="175.2" y1="168.79" x2="133.5" y2="168.79"/>
|
|
||||||
<g>
|
|
||||||
<polygon class="st13" points="174.9,171.39 176.5,168.79 174.9,166.29 174.8,166.29 174.8,171.39 "/>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<polygon class="st13" points="133.8,171.29 133.8,166.39 131.4,168.79 "/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<line class="st15" x1="563.7" y1="168.79" x2="197.49" y2="168.79"/>
|
|
||||||
<g>
|
|
||||||
<polygon class="st12" points="563.4,171.29 563.4,166.39 565.8,168.79 "/>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<polygon class="st12" points="197.79,171.29 197.79,166.39 195.29,168.79 "/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 615.4679 160.3837)" class="st12 st9 st10">non-allocated space</text>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<line class="st15" x1="593.7" y1="168.79" x2="829.7" y2="168.79"/>
|
|
||||||
<g>
|
|
||||||
<polygon class="st12" points="829.4,166.39 829.4,171.29 831.8,168.79 "/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<line class="st15" x1="678.7" y1="168.79" x2="589.7" y2="168.79"/>
|
|
||||||
<g>
|
|
||||||
<polygon class="st12" points="590.01,171.29 590.01,166.39 587.6,168.79 "/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 133.1212 200.1532)" class="st16 st9 st10">h</text>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 165.1565 200.1532)" class="st16 st9 st10">o</text>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<text transform="matrix(1 0 0 1 1.811981e-04 240.995)" class="st1 st9 st10">0</text>
|
|
||||||
</g>
|
|
||||||
<line class="st4" x1="5.5" y1="161.59" x2="5.5" y2="222.79"/>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 13 KiB |
@@ -1,14 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "Arduino.h"
|
|
||||||
|
|
||||||
#include <errno.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <time.h>
|
|
||||||
|
|
||||||
#define MG_ARCH MG_ARCH_CUSTOM
|
|
||||||
#define MG_ENABLE_SOCKET 0
|
|
||||||
#define MG_ENABLE_MIP 1
|
|
||||||
#define mkdir(a, b) (-1)
|
|
||||||
//#define MG_ENABLE_LOG 0
|
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
#include <SPI.h>
|
|
||||||
#include "mongoose.h"
|
|
||||||
|
|
||||||
#define SS_PIN 3 // Slave select pin
|
|
||||||
struct mg_mgr mgr; // Mongoose event manager
|
|
||||||
struct mip_spi spi = {
|
|
||||||
NULL, // SPI data
|
|
||||||
[](void *) { digitalWrite(SS_PIN, LOW); }, // begin transation
|
|
||||||
[](void *) { digitalWrite(SS_PIN, HIGH); }, // end transaction
|
|
||||||
[](void *, uint8_t c) { return SPI.transfer(c); }, // execute transaction
|
|
||||||
};
|
|
||||||
struct mip_if mif = {.mac = {2, 0, 1, 2, 3, 5}}; // MIP network interface
|
|
||||||
|
|
||||||
void setup() {
|
|
||||||
Serial.begin(115200);
|
|
||||||
pinMode(SS_PIN, OUTPUT);
|
|
||||||
SPI.begin();
|
|
||||||
|
|
||||||
// Set logging function to a serial print
|
|
||||||
mg_log_set_fn([](char ch, void *) { Serial.print(ch); }, NULL);
|
|
||||||
mg_mgr_init(&mgr);
|
|
||||||
|
|
||||||
delay(3000);
|
|
||||||
MG_INFO(("Starting TCP/IP stack..."));
|
|
||||||
|
|
||||||
mif.driver = &mip_driver_w5500;
|
|
||||||
mif.driver_data = &spi;
|
|
||||||
mip_init(&mgr, &mif);
|
|
||||||
|
|
||||||
// Start a 5 sec timer, print status message periodically
|
|
||||||
mg_timer_add(
|
|
||||||
&mgr, 5000, MG_TIMER_REPEAT,
|
|
||||||
[](void *) {
|
|
||||||
MG_INFO(("ethernet: %s", mip_driver_w5500.up(&mif) ? "up" : "down"));
|
|
||||||
},
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
// Setup HTTP listener. Respond "ok" on any HTTP request
|
|
||||||
mg_http_listen(
|
|
||||||
&mgr, "http://0.0.0.0",
|
|
||||||
[](struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
|
|
||||||
if (ev == MG_EV_HTTP_MSG) mg_http_reply(c, 200, "", "ok\n");
|
|
||||||
},
|
|
||||||
&mgr);
|
|
||||||
}
|
|
||||||
|
|
||||||
void loop() {
|
|
||||||
mg_mgr_poll(&mgr, 1);
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
PROG ?= example
|
|
||||||
CFLAGS ?= -DMG_IO_SIZE=8192 -DMG_ENABLE_LINES
|
|
||||||
|
|
||||||
all: $(PROG)
|
|
||||||
$(DEBUGGER) ./$(PROG) $(ARGS)
|
|
||||||
|
|
||||||
$(PROG): main.c
|
|
||||||
$(CC) ../../mongoose.c -I../.. -W -Wall $(CFLAGS) -o $(PROG) main.c
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -rf $(PROG) *.o *.dSYM *.gcov *.gcno *.gcda *.obj *.exe *.ilk *.pdb
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
See detailed tutorial at https://mongoose.ws/tutorials/captive-dns-portal/
|
|
||||||
@@ -1,58 +0,0 @@
|
|||||||
// Copyright (c) 2020 Cesanta Software Limited
|
|
||||||
// All rights reserved
|
|
||||||
//
|
|
||||||
// Example captive DNS server (captive portal).
|
|
||||||
// 1. Run `make`. This builds and starts a server on port 5533
|
|
||||||
// 2. Run `dig -t A www.google.com -4 @localhost -p 5533`
|
|
||||||
|
|
||||||
#include "mongoose.h"
|
|
||||||
|
|
||||||
static const char *s_listen_url = "udp://0.0.0.0:5533";
|
|
||||||
|
|
||||||
// DNS answer section. We response with IP 1.2.3.4 - you can change it
|
|
||||||
// in the last 4 bytes of this array
|
|
||||||
uint8_t answer[] = {
|
|
||||||
0xc0, 0x0c, // Point to the name in the DNS question
|
|
||||||
0, 1, // 2 bytes - record type, A
|
|
||||||
0, 1, // 2 bytes - address class, INET
|
|
||||||
0, 0, 0, 120, // 4 bytes - TTL
|
|
||||||
0, 4, // 2 bytes - address length
|
|
||||||
1, 2, 3, 4 // 4 bytes - IP address
|
|
||||||
};
|
|
||||||
|
|
||||||
static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
|
|
||||||
if (ev == MG_EV_OPEN) {
|
|
||||||
c->is_hexdumping = 1;
|
|
||||||
} else if (ev == MG_EV_READ) {
|
|
||||||
struct mg_dns_rr rr; // Parse first question, offset 12 is header size
|
|
||||||
size_t n = mg_dns_parse_rr(c->recv.buf, c->recv.len, 12, true, &rr);
|
|
||||||
MG_INFO(("DNS request parsed, result=%d", (int) n));
|
|
||||||
if (n > 0) {
|
|
||||||
char buf[512];
|
|
||||||
struct mg_dns_header *h = (struct mg_dns_header *) buf;
|
|
||||||
memset(buf, 0, sizeof(buf)); // Clear the whole datagram
|
|
||||||
h->txnid = ((struct mg_dns_header *) c->recv.buf)->txnid; // Copy tnxid
|
|
||||||
h->num_questions = mg_htons(1); // We use only the 1st question
|
|
||||||
h->num_answers = mg_htons(1); // And only one answer
|
|
||||||
h->flags = mg_htons(0x8400); // Authoritative response
|
|
||||||
memcpy(buf + sizeof(*h), c->recv.buf + sizeof(*h), n); // Copy question
|
|
||||||
memcpy(buf + sizeof(*h) + n, answer, sizeof(answer)); // And answer
|
|
||||||
mg_send(c, buf, 12 + n + sizeof(answer)); // And send it!
|
|
||||||
}
|
|
||||||
mg_iobuf_del(&c->recv, 0, c->recv.len);
|
|
||||||
}
|
|
||||||
(void) fn_data;
|
|
||||||
(void) ev_data;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(void) {
|
|
||||||
struct mg_mgr mgr;
|
|
||||||
|
|
||||||
mg_log_set(MG_LL_DEBUG); // Set log level
|
|
||||||
mg_mgr_init(&mgr); // Initialise event manager
|
|
||||||
mg_listen(&mgr, s_listen_url, fn, NULL); // Start DNS server
|
|
||||||
for (;;) mg_mgr_poll(&mgr, 1000); // Event loop
|
|
||||||
mg_mgr_free(&mgr);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
PROG ?= example
|
|
||||||
SOURCES ?= ../../mongoose.c main.c net.c packed_fs.c
|
|
||||||
CFLAGS ?= -I../.. -DMG_ENABLE_PACKED_FS=1 -DMG_ENABLE_LINES=1 $(EXTRA)
|
|
||||||
FILES_TO_EMBED ?= $(wildcard web_root/*)
|
|
||||||
ROOT ?= $(realpath $(CURDIR)/../../..)
|
|
||||||
DOCKER ?= docker run --rm -e Tmp=. -e WINEDEBUG=-all -v $(ROOT):$(ROOT) -w $(CURDIR)
|
|
||||||
VC98 ?= $(DOCKER) mdashnet/vc98 wine
|
|
||||||
MINGW ?= $(DOCKER) mdashnet/mingw
|
|
||||||
|
|
||||||
ifeq "$(SSL)" "MBEDTLS"
|
|
||||||
CFLAGS += -DMG_ENABLE_MBEDTLS=1 -I$(MBEDTLS)/include -L$(MBEDTLS)/lib -lmbedtls -lmbedcrypto -lmbedx509
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq "$(SSL)" "OPENSSL"
|
|
||||||
CFLAGS += -DMG_ENABLE_OPENSSL=1 -I$(OPENSSL)/include -L$(OPENSSL)/lib -lssl -lcrypto
|
|
||||||
endif
|
|
||||||
|
|
||||||
all: $(PROG)
|
|
||||||
$(RUN) ./$(PROG)
|
|
||||||
|
|
||||||
$(PROG): $(SOURCES) $(FILES_TO_EMBED)
|
|
||||||
$(CC) ../../test/pack.c -o pack
|
|
||||||
./pack $(FILES_TO_EMBED) > packed_fs.c
|
|
||||||
$(CC) -W -Wall -Wextra -O0 -g3 $(CFLAGS) -o $(PROG) $(SOURCES)
|
|
||||||
|
|
||||||
|
|
||||||
mingw: $(SOURCES) $(FILES_TO_EMBED)
|
|
||||||
$(MINGW) i686-w64-mingw32-gcc $(CFLAGS) ../../test/pack.c -o pack.exe
|
|
||||||
$(MINGW) wine cmd /c 'pack.exe $(FILES_TO_EMBED) > packed_fs.c'
|
|
||||||
$(MINGW) i686-w64-mingw32-gcc $(CFLAGS) $(SOURCES) -lws2_32 -o $(PROG).exe
|
|
||||||
$(MINGW) wine $(PROG).exe
|
|
||||||
|
|
||||||
vc98: $(SOURCES) $(FILES_TO_EMBED)
|
|
||||||
$(VC98) cl.exe /nologo $(CFLAGS) ../../test/pack.c /Fepack.exe
|
|
||||||
$(VC98) cmd /c 'pack.exe $(FILES_TO_EMBED) > packed_fs.c'
|
|
||||||
$(VC98) cl.exe /nologo /O2 $(CFLAGS) $(SOURCES) /Fe$(PROG).exe
|
|
||||||
$(VC98) $(PROG).exe
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -rf $(PROG) *.o *.dSYM *.gcov *.gcno *.gcda *.obj *.exe *.ilk *.pdb log.txt pack
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
# A complete device dashboard
|
|
||||||
|
|
||||||
This example is a demonstration of how Mongoose Library could be integrated
|
|
||||||
into an embedded device and provide a complete device dashboard with the
|
|
||||||
following features:
|
|
||||||
|
|
||||||
- Authentication: login-protected dashboard
|
|
||||||
- Multiple logins with different permissions (admin and user)
|
|
||||||
- Web UI is fully embedded into the server/firmware binary, and does not
|
|
||||||
need a filesystem to serve it. UI is resilient to FS problems
|
|
||||||
- Administrators can change server settings
|
|
||||||
- All changes are propagates to all connected clients
|
|
||||||
- A device is connected to the external MQTT server
|
|
||||||
- Logged in clients can send/receive messages to a device which get
|
|
||||||
forwarded to MQTT
|
|
||||||
|
|
||||||
# Screenshots
|
|
||||||
|
|
||||||
This is a login screen that prompts for user/password
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
# Main dashboard
|
|
||||||
|
|
||||||
A main dashboard page shows and interactive MQTT console
|
|
||||||
|
|
||||||

|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../../test/data/ca.pem
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
// Copyright (c) 2020-2022 Cesanta Software Limited
|
|
||||||
// All rights reserved
|
|
||||||
|
|
||||||
#include "mongoose.h"
|
|
||||||
const char *s_listening_url = "http://0.0.0.0:8000";
|
|
||||||
|
|
||||||
void device_dashboard_fn(struct mg_connection *, int, void *, void *);
|
|
||||||
|
|
||||||
int main(void) {
|
|
||||||
struct mg_mgr mgr;
|
|
||||||
mg_log_set(MG_LL_DEBUG); // Set debug log level
|
|
||||||
mg_mgr_init(&mgr);
|
|
||||||
mg_http_listen(&mgr, s_listening_url, device_dashboard_fn, &mgr);
|
|
||||||
MG_INFO(("Listening on %s", s_listening_url));
|
|
||||||
while (mgr.conns != NULL) mg_mgr_poll(&mgr, 500);
|
|
||||||
mg_mgr_free(&mgr);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -1,239 +0,0 @@
|
|||||||
// Copyright (c) 2020-2022 Cesanta Software Limited
|
|
||||||
// All rights reserved
|
|
||||||
|
|
||||||
#include "mongoose.h"
|
|
||||||
|
|
||||||
#if !defined(MQTT_SERVER)
|
|
||||||
#define MQTT_SERVER "mqtt://broker.hivemq.com:1883"
|
|
||||||
#endif
|
|
||||||
#define MQTT_PUBLISH_TOPIC "mg/my_device"
|
|
||||||
#define MQTT_SUBSCRIBE_TOPIC "mg/#"
|
|
||||||
|
|
||||||
static time_t s_boot_timestamp = 0; // Updated by SNTP
|
|
||||||
#ifndef DISABLE_ROUTING
|
|
||||||
static struct mg_connection *s_sntp_conn = NULL; // SNTP connection
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Define a system time alternative
|
|
||||||
time_t ourtime(time_t *tp) {
|
|
||||||
time_t t = s_boot_timestamp + (time_t) (mg_millis() / 1000);
|
|
||||||
if (tp != NULL) *tp = t;
|
|
||||||
return t;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Authenticated user.
|
|
||||||
// A user can be authenticated by:
|
|
||||||
// - a name:pass pair
|
|
||||||
// - a token
|
|
||||||
// When a user is shown a login screen, she enters a user:pass. If successful,
|
|
||||||
// a server returns user info which includes token. From that point on,
|
|
||||||
// client can use token for authentication. Tokens could be refreshed/changed
|
|
||||||
// on a server side, forcing clients to re-login.
|
|
||||||
struct user {
|
|
||||||
const char *name, *pass, *token;
|
|
||||||
};
|
|
||||||
|
|
||||||
// This is a configuration structure we're going to show on a dashboard
|
|
||||||
static struct config {
|
|
||||||
char *url, *pub, *sub; // MQTT settings
|
|
||||||
} s_config;
|
|
||||||
|
|
||||||
static struct mg_connection *s_mqtt = NULL; // MQTT connection
|
|
||||||
static bool s_connected = false; // MQTT connection established
|
|
||||||
|
|
||||||
// Try to update a single configuration value
|
|
||||||
static void update_config(struct mg_str *body, const char *name, char **value) {
|
|
||||||
char buf[256];
|
|
||||||
if (mg_http_get_var(body, name, buf, sizeof(buf)) > 0) {
|
|
||||||
free(*value);
|
|
||||||
*value = strdup(buf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse HTTP requests, return authenticated user or NULL
|
|
||||||
static struct user *getuser(struct mg_http_message *hm) {
|
|
||||||
// In production, make passwords strong and tokens randomly generated
|
|
||||||
// In this example, user list is kept in RAM. In production, it can
|
|
||||||
// be backed by file, database, or some other method.
|
|
||||||
static struct user users[] = {
|
|
||||||
{"admin", "pass0", "admin_token"},
|
|
||||||
{"user1", "pass1", "user1_token"},
|
|
||||||
{"user2", "pass2", "user2_token"},
|
|
||||||
{NULL, NULL, NULL},
|
|
||||||
};
|
|
||||||
char user[256], pass[256];
|
|
||||||
struct user *u;
|
|
||||||
mg_http_creds(hm, user, sizeof(user), pass, sizeof(pass));
|
|
||||||
if (user[0] != '\0' && pass[0] != '\0') {
|
|
||||||
// Both user and password is set, search by user/password
|
|
||||||
for (u = users; u->name != NULL; u++)
|
|
||||||
if (strcmp(user, u->name) == 0 && strcmp(pass, u->pass) == 0) return u;
|
|
||||||
} else if (user[0] == '\0') {
|
|
||||||
// Only password is set, search by token
|
|
||||||
for (u = users; u->name != NULL; u++)
|
|
||||||
if (strcmp(pass, u->token) == 0) return u;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Notify all config watchers about the config change
|
|
||||||
static void send_notification(struct mg_mgr *mgr, const char *fmt, ...) {
|
|
||||||
struct mg_connection *c;
|
|
||||||
for (c = mgr->conns; c != NULL; c = c->next) {
|
|
||||||
if (c->data[0] == 'W') {
|
|
||||||
va_list ap;
|
|
||||||
va_start(ap, fmt);
|
|
||||||
mg_ws_vprintf(c, WEBSOCKET_OP_TEXT, fmt, &ap);
|
|
||||||
va_end(ap);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Send simulated metrics data to the dashboard, for chart rendering
|
|
||||||
static void timer_metrics_fn(void *param) {
|
|
||||||
send_notification(param, "{%Q:%Q,%Q:[%lu, %d]}", "name", "metrics", "data",
|
|
||||||
(unsigned long) ourtime(NULL),
|
|
||||||
10 + (int) ((double) rand() * 10 / RAND_MAX));
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef DISABLE_ROUTING
|
|
||||||
|
|
||||||
// MQTT event handler function
|
|
||||||
static void mqtt_fn(struct mg_connection *c, int ev, void *ev_data, void *fnd) {
|
|
||||||
if (ev == MG_EV_CONNECT && mg_url_is_ssl(s_config.url)) {
|
|
||||||
struct mg_tls_opts opts = {.ca = "ca.pem",
|
|
||||||
.srvname = mg_url_host(s_config.url)};
|
|
||||||
mg_tls_init(c, &opts);
|
|
||||||
} else if (ev == MG_EV_MQTT_OPEN) {
|
|
||||||
s_connected = true;
|
|
||||||
c->is_hexdumping = 1;
|
|
||||||
mg_mqtt_sub(s_mqtt, mg_str(s_config.sub), 2);
|
|
||||||
send_notification(c->mgr, "{%Q:%Q,%Q:null}", "name", "config", "data");
|
|
||||||
MG_INFO(("MQTT connected, server %s", MQTT_SERVER));
|
|
||||||
} else if (ev == MG_EV_MQTT_MSG) {
|
|
||||||
struct mg_mqtt_message *mm = ev_data;
|
|
||||||
send_notification(c->mgr, "{%Q:%Q,%Q:{%Q: %.*Q, %Q: %.*Q, %Q: %d}}", "name",
|
|
||||||
"message", "data", "topic", (int) mm->topic.len,
|
|
||||||
mm->topic.ptr, "data", (int) mm->data.len, mm->data.ptr,
|
|
||||||
"qos", (int) mm->qos);
|
|
||||||
} else if (ev == MG_EV_MQTT_CMD) {
|
|
||||||
struct mg_mqtt_message *mm = (struct mg_mqtt_message *) ev_data;
|
|
||||||
MG_DEBUG(("%lu cmd %d qos %d", c->id, mm->cmd, mm->qos));
|
|
||||||
} else if (ev == MG_EV_CLOSE) {
|
|
||||||
s_mqtt = NULL;
|
|
||||||
if (s_connected) {
|
|
||||||
s_connected = false;
|
|
||||||
send_notification(c->mgr, "{%Q:%Q,%Q:null}", "name", "config", "data");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
(void) fnd;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Keep MQTT connection open - reconnect if closed
|
|
||||||
static void timer_mqtt_fn(void *param) {
|
|
||||||
struct mg_mgr *mgr = (struct mg_mgr *) param;
|
|
||||||
if (s_mqtt == NULL) {
|
|
||||||
struct mg_mqtt_opts opts;
|
|
||||||
memset(&opts, 0, sizeof(opts));
|
|
||||||
s_mqtt = mg_mqtt_connect(mgr, s_config.url, &opts, mqtt_fn, NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// SNTP connection event handler. When we get a response from an SNTP server,
|
|
||||||
// adjust s_boot_timestamp. We'll get a valid time from that point on
|
|
||||||
static void sfn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
|
|
||||||
if (ev == MG_EV_SNTP_TIME) {
|
|
||||||
uint64_t t = *(uint64_t *) ev_data;
|
|
||||||
s_boot_timestamp = (time_t) ((t - mg_millis()) / 1000);
|
|
||||||
c->is_closing = 1;
|
|
||||||
} else if (ev == MG_EV_CLOSE) {
|
|
||||||
s_sntp_conn = NULL;
|
|
||||||
}
|
|
||||||
(void) fn_data;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void timer_sntp_fn(void *param) { // SNTP timer function. Sync up time
|
|
||||||
struct mg_mgr *mgr = (struct mg_mgr *) param;
|
|
||||||
if (s_sntp_conn == NULL && s_boot_timestamp == 0) {
|
|
||||||
s_sntp_conn = mg_sntp_connect(mgr, NULL, sfn, NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// HTTP request handler function
|
|
||||||
void device_dashboard_fn(struct mg_connection *c, int ev, void *ev_data,
|
|
||||||
void *fn_data) {
|
|
||||||
if (ev == MG_EV_OPEN && c->is_listening) {
|
|
||||||
mg_timer_add(c->mgr, 1000, MG_TIMER_REPEAT, timer_metrics_fn, c->mgr);
|
|
||||||
#ifndef DISABLE_ROUTING
|
|
||||||
mg_timer_add(c->mgr, 1000, MG_TIMER_REPEAT, timer_mqtt_fn, c->mgr);
|
|
||||||
mg_timer_add(c->mgr, 1000, MG_TIMER_REPEAT, timer_sntp_fn, c->mgr);
|
|
||||||
#endif
|
|
||||||
s_config.url = strdup(MQTT_SERVER);
|
|
||||||
s_config.pub = strdup(MQTT_PUBLISH_TOPIC);
|
|
||||||
s_config.sub = strdup(MQTT_SUBSCRIBE_TOPIC);
|
|
||||||
} else if (ev == MG_EV_HTTP_MSG) {
|
|
||||||
struct mg_http_message *hm = (struct mg_http_message *) ev_data;
|
|
||||||
struct user *u = getuser(hm);
|
|
||||||
// MG_INFO(("%p [%.*s] auth %s", c->fd, (int) hm->uri.len, hm->uri.ptr,
|
|
||||||
// u ? u->name : "NULL"));
|
|
||||||
if (mg_http_match_uri(hm, "/api/hi")) {
|
|
||||||
mg_http_reply(c, 200, "", "hi\n"); // Testing endpoint
|
|
||||||
} else if (mg_http_match_uri(hm, "/api/debug")) {
|
|
||||||
int level = 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 if (u == NULL && mg_http_match_uri(hm, "/api/#")) {
|
|
||||||
// All URIs starting with /api/ must be authenticated
|
|
||||||
mg_http_reply(c, 403, "", "Denied\n");
|
|
||||||
} else if (mg_http_match_uri(hm, "/api/config/get")) {
|
|
||||||
#ifdef DISABLE_ROUTING
|
|
||||||
mg_http_reply(c, 200, NULL, "{%Q:%Q,%Q:%Q,%Q:%Q}\n", "url", s_config.url,
|
|
||||||
"pub", s_config.pub, "sub", s_config.sub);
|
|
||||||
#else
|
|
||||||
mg_http_reply(c, 200, NULL, "{%Q:%Q,%Q:%Q,%Q:%Q,%Q:%s}\n", "url",
|
|
||||||
s_config.url, "pub", s_config.pub, "sub", s_config.sub,
|
|
||||||
"connected", s_connected ? "true" : "false");
|
|
||||||
#endif
|
|
||||||
} else if (mg_http_match_uri(hm, "/api/config/set")) {
|
|
||||||
// Admins only
|
|
||||||
if (strcmp(u->name, "admin") == 0) {
|
|
||||||
update_config(&hm->body, "url", &s_config.url);
|
|
||||||
update_config(&hm->body, "pub", &s_config.pub);
|
|
||||||
update_config(&hm->body, "sub", &s_config.sub);
|
|
||||||
if (s_mqtt) s_mqtt->is_closing = 1; // Ask to disconnect from MQTT
|
|
||||||
send_notification(fn_data, "{%Q:%Q,%Q:null}", "name", "config", "data");
|
|
||||||
mg_http_reply(c, 200, "", "ok\n");
|
|
||||||
} else {
|
|
||||||
mg_http_reply(c, 403, "", "Denied\n");
|
|
||||||
}
|
|
||||||
} else if (mg_http_match_uri(hm, "/api/message/send")) {
|
|
||||||
char buf[256];
|
|
||||||
if (s_connected &&
|
|
||||||
mg_http_get_var(&hm->body, "message", buf, sizeof(buf)) > 0) {
|
|
||||||
mg_mqtt_pub(s_mqtt, mg_str(s_config.pub), mg_str(buf), 1, false);
|
|
||||||
}
|
|
||||||
mg_http_reply(c, 200, "", "ok\n");
|
|
||||||
} else if (mg_http_match_uri(hm, "/api/watch")) {
|
|
||||||
c->data[0] = 'W'; // Mark ourselves as a event listener
|
|
||||||
mg_ws_upgrade(c, hm, NULL);
|
|
||||||
} else if (mg_http_match_uri(hm, "/api/login")) {
|
|
||||||
mg_http_reply(c, 200, NULL, "{%Q:%Q,%Q:%Q}\n", "user", u->name, "token",
|
|
||||||
u->token);
|
|
||||||
} else {
|
|
||||||
struct mg_http_serve_opts opts;
|
|
||||||
memset(&opts, 0, sizeof(opts));
|
|
||||||
#if 1
|
|
||||||
opts.root_dir = "/web_root";
|
|
||||||
opts.fs = &mg_fs_packed;
|
|
||||||
#else
|
|
||||||
opts.root_dir = "web_root";
|
|
||||||
#endif
|
|
||||||
mg_http_serve_dir(c, ev_data, &opts);
|
|
||||||
}
|
|
||||||
MG_DEBUG(("%lu %.*s %.*s -> %.*s", c->id, (int) hm->method.len,
|
|
||||||
hm->method.ptr, (int) hm->uri.len, hm->uri.ptr, (int) 3,
|
|
||||||
&c->send.buf[9]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
Before Width: | Height: | Size: 283 KiB |
|
Before Width: | Height: | Size: 65 KiB |
@@ -1,385 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
import {Component, h, html, render, useEffect, useState, useRef} from './preact.min.js';
|
|
||||||
|
|
||||||
var devaddr = "address:port";
|
|
||||||
|
|
||||||
const MaxMetricsDataPoints = 50;
|
|
||||||
|
|
||||||
// This simple publish/subscribe is used to pass notifications that were
|
|
||||||
// received from the server, to all child components of the app.
|
|
||||||
var PubSub = (function() {
|
|
||||||
var handlers = {}, id = 0;
|
|
||||||
return {
|
|
||||||
subscribe: function(fn) {
|
|
||||||
handlers[id++] = fn;
|
|
||||||
},
|
|
||||||
unsubscribe: function(id) {
|
|
||||||
delete handlers[id];
|
|
||||||
},
|
|
||||||
publish: function(data) {
|
|
||||||
for (var k in handlers) handlers[k](data);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
})();
|
|
||||||
|
|
||||||
const Nav = props => html`
|
|
||||||
<div style="background: #333; padding: 0.5em; color: #fff;">
|
|
||||||
<div class="container d-flex">
|
|
||||||
<div style="flex: 1 1 auto; display: flex; align-items: center;">
|
|
||||||
<b>Your Product</b>
|
|
||||||
</div>
|
|
||||||
<div style="display: flex; align-items: center; flex: 0 0 auto; ">
|
|
||||||
<span>Logged in as:</span>
|
|
||||||
<span style="padding: 0 0.5em;"><img src="user.png" height="22" /></span>
|
|
||||||
<span>${props.user}</span>
|
|
||||||
<a class="btn" onclick=${props.logout}
|
|
||||||
style="margin-left: 1em; font-size: 0.8em; background: #8aa;">logout</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>`;
|
|
||||||
|
|
||||||
|
|
||||||
const Hero = props => html`
|
|
||||||
<div class="section">
|
|
||||||
<div style="margin-top: 1em; background: #eee; padding: 1em; border-radius: 0.5em; color: #777; ">
|
|
||||||
<h1 style="margin: 0.2em 0;">Interactive Device Dashboard</h1>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
This device dashboard is developed using the modern and compact Preact framework,
|
|
||||||
in order to fit on very small devices. This is
|
|
||||||
a <a href="https://mongoose.ws/tutorials/http-server/">hybrid server</a> which
|
|
||||||
provides both static and dynamic content. Static files, like CSS/JS/HTML
|
|
||||||
or images, are compiled into the server binary.
|
|
||||||
|
|
||||||
This UI uses the REST API implemented by the device, which you can examine
|
|
||||||
using <code>curl</code> command-line utility:
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<div><code>curl -u admin:pass0 ${devaddr}/api/config/get</code> </div>
|
|
||||||
<div><code>curl -u admin:pass0 ${devaddr}/api/config/set -d 'pub=mg/topic'</code> </div>
|
|
||||||
<div><code>curl -u admin:pass0 ${devaddr}/api/message/send -d 'message=hello'</code> </div>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
The device can send notifications to this dashboard at anytime. Notifications
|
|
||||||
are sent over WebSocket at URI <code>/api/watch</code> as JSON strings: <code>{"name": "..", "data": ...}</code>
|
|
||||||
<div>Try <code>wscat --auth user1:pass1 --connect ws://${devaddr}/api/watch</code></div>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>`;
|
|
||||||
|
|
||||||
const Login = function(props) {
|
|
||||||
const [user, setUser] = useState('');
|
|
||||||
const [pass, setPass] = useState('');
|
|
||||||
const login = ev =>
|
|
||||||
fetch(
|
|
||||||
'/api/login',
|
|
||||||
{headers: {Authorization: 'Basic ' + btoa(user + ':' + pass)}})
|
|
||||||
.then(r => r.json())
|
|
||||||
.then(r => r && props.login(r))
|
|
||||||
.catch(err => err);
|
|
||||||
return html`
|
|
||||||
<div class="rounded border" style="max-width: 480px; margin: 0 auto; margin-top: 5em; background: #eee; ">
|
|
||||||
<div style="padding: 2em; ">
|
|
||||||
<h1 style="color: #666;">Device Dashboard Login </h1>
|
|
||||||
<div style="margin: 0.5em 0;">
|
|
||||||
<input type='text' placeholder='Name' style="width: 100%;"
|
|
||||||
oninput=${ev => setUser(ev.target.value)} value=${user} />
|
|
||||||
</div>
|
|
||||||
<div style="margin: 0.5em 0;">
|
|
||||||
<input type="password" placeholder="Password" style="width: 100%;"
|
|
||||||
oninput=${ev => setPass(ev.target.value)} value=${pass}
|
|
||||||
onchange=${login} />
|
|
||||||
</div>
|
|
||||||
<div style="margin: 1em 0;">
|
|
||||||
<button class="btn" style="width: 100%; background: #8aa;"
|
|
||||||
disabled=${!user || !pass} onclick=${login}> Login </button>
|
|
||||||
</div>
|
|
||||||
<div style="color: #777; margin-top: 2em;">
|
|
||||||
Valid logins: admin:pass0, user1:pass1, user2:pass2
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>`;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
const Configuration = function(props) {
|
|
||||||
const [url, setUrl] = useState(props.config.url || '');
|
|
||||||
const [pub, setPub] = useState(props.config.pub || '');
|
|
||||||
const [sub, setSub] = useState(props.config.sub || '');
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
setUrl(props.config.url);
|
|
||||||
setPub(props.config.pub);
|
|
||||||
setSub(props.config.sub);
|
|
||||||
}, [props.config]);
|
|
||||||
|
|
||||||
const update = (name, val) => fetch('/api/config/set', {
|
|
||||||
method: 'post',
|
|
||||||
body: `${name}=${encodeURIComponent(val)}`
|
|
||||||
}).catch(err => err);
|
|
||||||
const updateurl = ev => update('url', url);
|
|
||||||
const updatepub = ev => update('pub', pub);
|
|
||||||
const updatesub = ev => update('sub', sub);
|
|
||||||
|
|
||||||
// console.log(props, [url, pub, sub]);
|
|
||||||
return html`
|
|
||||||
<div class="section">
|
|
||||||
<h3 style="background: #c03434; color: #fff; padding: 0.4em;">
|
|
||||||
Device Configuration</h3>
|
|
||||||
<div style="margin: 0.5em 0; display: flex;">
|
|
||||||
<span class="addon nowrap">MQTT server:</span>
|
|
||||||
<input type="text" style="flex: 1 100%;"
|
|
||||||
value=${url} onchange=${updateurl}
|
|
||||||
oninput=${ev => setUrl(ev.target.value)} />
|
|
||||||
<button class="btn" disabled=${!url} onclick=${updateurl}
|
|
||||||
style="margin-left: 1em; background: #8aa;">Update</button>
|
|
||||||
</div>
|
|
||||||
<div style="margin: 0.5em 0; display: flex; ">
|
|
||||||
<span class="addon nowrap">Subscribe topic:</span>
|
|
||||||
<input type="text" style="flex: 1 100%;"
|
|
||||||
value=${sub} onchange=${updatesub}
|
|
||||||
oninput=${ev => setSub(ev.target.value)} />
|
|
||||||
<button class="btn" disabled=${!sub} onclick=${updatesub}
|
|
||||||
style="margin-left: 1em; background: #8aa;">Update</button>
|
|
||||||
</div>
|
|
||||||
<div style="margin: 0.5em 0; display: flex;">
|
|
||||||
<span class="addon nowrap">Publish topic:</span>
|
|
||||||
<input type="text" style="flex: 1 100%;"
|
|
||||||
value=${pub} onchange=${updatepub}
|
|
||||||
oninput=${ev => setPub(ev.target.value)} />
|
|
||||||
<button class="btn" disabled=${!pub} onclick=${updatepub}
|
|
||||||
style="margin-left: 1em; background: #8aa;">Update</button>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
You can use <a href="http://www.hivemq.com/demos/websocket-client/">
|
|
||||||
HiveMQ Websocket web client</a> to send messages to this console.
|
|
||||||
</div>
|
|
||||||
<div class="msg">
|
|
||||||
The device keeps a persistent connection to the configured MQTT server.
|
|
||||||
Changes to this configuration are propagated to all dashboards: try
|
|
||||||
changing them in this dashboard and observe changes in other opened
|
|
||||||
dashboards.
|
|
||||||
</div><div class="msg">
|
|
||||||
Note: administrators can see this section and can change device
|
|
||||||
configuration, whilst users cannot.
|
|
||||||
</div>
|
|
||||||
</div>`;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
const Message = m => html`<div style="margin: 0.5em 0;">
|
|
||||||
<span class="qos">qos: ${m.message.qos} </span>
|
|
||||||
<span class="topic">topic: ${m.message.topic} </span>
|
|
||||||
<span class="data">data: ${m.message.data}</span>
|
|
||||||
</div>`;
|
|
||||||
|
|
||||||
const Messages = function(props) {
|
|
||||||
const [messages, setMessages] = useState([]);
|
|
||||||
const [txt, setTxt] = useState('');
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const id = PubSub.subscribe(function(msg) {
|
|
||||||
if (msg.name == 'message') setMessages(x => x.concat([msg.data]));
|
|
||||||
});
|
|
||||||
return PubSub.unsubscribe(id);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const sendmessage = ev => fetch('/api/message/send', {
|
|
||||||
method: 'post',
|
|
||||||
body: `message=${encodeURIComponent(txt)}`
|
|
||||||
}).then(r => setTxt(''));
|
|
||||||
const routing = "connected" in props.config;
|
|
||||||
const connstatus = !routing ? 'This device has no MQTT functionality' : props.config.connected ? 'connected' : 'disconnected';
|
|
||||||
return html`
|
|
||||||
<div class="section">
|
|
||||||
<h3 style="background: #30c040; color: #fff; padding: 0.4em;">MQTT messages</h3>
|
|
||||||
<div>
|
|
||||||
MQTT server status: <b>${connstatus}</b>
|
|
||||||
</div>
|
|
||||||
<div style="height: 10em; overflow: auto; padding: 0.5em; " class="border">
|
|
||||||
${messages.map(message => h(Message, {message}))}
|
|
||||||
</div>
|
|
||||||
<div style="margin: 0.5em 0; display: flex">
|
|
||||||
<span class="addon nowrap">Publish message:</span>
|
|
||||||
<input placeholder="type and press enter..." style="flex: 1 100%;"
|
|
||||||
value=${txt} onchange=${sendmessage} disabled=${!routing}
|
|
||||||
oninput=${ev => setTxt(ev.target.value)} />
|
|
||||||
</div>
|
|
||||||
<div class="msg">
|
|
||||||
The message gets passed to the device via REST. Then the device sends it to
|
|
||||||
the MQTT server over MQTT. All MQTT messages on a subscribed topic
|
|
||||||
received by the device, are propagated to this dashboard via /api/watch.
|
|
||||||
</div>
|
|
||||||
</div>`;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Expected arguments:
|
|
||||||
// data: timeseries, e.g. [ [1654361352, 19], [1654361353, 18], ... ]
|
|
||||||
// width, height, yticks, xticks, ymin, ymax, xmin, xmax
|
|
||||||
const SVG = function(props) {
|
|
||||||
// w
|
|
||||||
// +---------------------+
|
|
||||||
// | h1 |
|
|
||||||
// | +-----------+ |
|
|
||||||
// | | | | h
|
|
||||||
// | w1 | | w2 |
|
|
||||||
// | +-----------+ |
|
|
||||||
// | h2 |
|
|
||||||
// +---------------------+
|
|
||||||
//
|
|
||||||
let w = props.width, h = props.height, w1 = 30, w2 = 0, h1 = 8, h2 = 18;
|
|
||||||
let yticks = props.yticks || 4, xticks = props.xticks || 5;
|
|
||||||
let data = props.data || [];
|
|
||||||
let ymin = props.ymin || 0;
|
|
||||||
let ymax = props.ymax || Math.max.apply(null, data.map(p => p[1]));
|
|
||||||
let xmin = props.xmin || Math.min.apply(null, data.map(p => p[0]));
|
|
||||||
let xmax = props.xmax || Math.max.apply(null, data.map(p => p[0]));
|
|
||||||
|
|
||||||
// Y-axis tick lines and labels
|
|
||||||
let yta = (new Array(yticks + 1)).fill(0).map((_, i) => i); // indices
|
|
||||||
let yti = i => h - h2 - (h - h1 - h2) * i / yticks; // index's Y
|
|
||||||
let ytv = i => (ymax - ymin) * i / yticks;
|
|
||||||
let ytl = y => html`<line x1=${w1} y1=${y} x2=${w} y2=${y} class="tick"/>`;
|
|
||||||
let ytt = (y, v) => html`<text x=0 y=${y + 5} class="label">${v}</text>`;
|
|
||||||
|
|
||||||
// X-axis tick lines and labels
|
|
||||||
let datefmt = unix => (new Date(unix * 1000)).toISOString().substr(14, 5);
|
|
||||||
let xta = (new Array(xticks + 1)).fill(0).map((_, i) => i); // indices
|
|
||||||
let xti = i => w1 + (w - w1 - w2) * i / xticks; // index's X
|
|
||||||
let xtv = i => datefmt(xmin + (xmax - xmin) * i / xticks);
|
|
||||||
let xtl = x => html`<path d="M ${x},${h1} L ${x},${h - h2}" class="tick"/>`;
|
|
||||||
let xtt = (x, v) =>
|
|
||||||
html`<text x=${x - 15} y=${h - 2} class="label">${v}</text>`;
|
|
||||||
|
|
||||||
// Transform data points array into coordinate
|
|
||||||
let dx = v => w1 + (v - xmin) / ((xmax - xmin) || 1) * (w - w1 - w2);
|
|
||||||
let dy = v => h - h2 - (v - ymin) / ((ymax - ymin) || 1) * (h - h1 - h2);
|
|
||||||
let dd = data.map(p => [Math.round(dx(p[0])), Math.round(dy(p[1]))]);
|
|
||||||
let ddl = dd.length;
|
|
||||||
// And plot the data as <path> element
|
|
||||||
let begin0 = ddl ? `M ${dd[0][0]},${dd[0][1]}` : `M 0,0`;
|
|
||||||
let begin = `M ${w1},${h - h2}`; // Initial point
|
|
||||||
let end = ddl ? `L ${dd[ddl - 1][0]},${h - h2}` : `L ${w1},${h - h2}`;
|
|
||||||
let series = ddl ? dd.map(p => `L ${p[0]} ${p[1]}`) : [];
|
|
||||||
|
|
||||||
return html`
|
|
||||||
<svg viewBox="0 0 ${w} ${h}">
|
|
||||||
<style>
|
|
||||||
.axis { stroke: #aaa; fill: none; }
|
|
||||||
.label { stroke: #aaa; font-size: 13px; }
|
|
||||||
.tick { stroke: #ccc; fill: none; stroke-dasharray: 5; }
|
|
||||||
.seriesbg { stroke: none; fill: rgba(200,225,255, 0.25)}
|
|
||||||
.series { stroke: #25a; fill: none; }
|
|
||||||
</style>
|
|
||||||
${yta.map(i => ytl(yti(i)))}
|
|
||||||
${yta.map(i => ytt(yti(i), ytv(i)))}
|
|
||||||
${xta.map(i => xtl(xti(i)))}
|
|
||||||
${data.length ? xta.map(i => xtt(xti(i), xtv(i))) : ''}
|
|
||||||
<path d="${begin} ${series.join(' ')} ${end}" class="seriesbg" />
|
|
||||||
<path d="${begin0} ${series.join(' ')}" class="series" />
|
|
||||||
</svg>`;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
const Chart = function(props) {
|
|
||||||
const [data, setData] = useState([]);
|
|
||||||
useEffect(() => {
|
|
||||||
const id = PubSub.subscribe(function(msg) {
|
|
||||||
if (msg.name != 'metrics') return;
|
|
||||||
setData(x => x.concat([msg.data]).splice(-MaxMetricsDataPoints));
|
|
||||||
});
|
|
||||||
return PubSub.unsubscribe(id);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
let xmax = 0, missing = MaxMetricsDataPoints - data.length;
|
|
||||||
if (missing > 0) xmax = Math.round(Date.now() / 1000) + missing;
|
|
||||||
return html`
|
|
||||||
<div class="section">
|
|
||||||
<h3 style="background: #ec3; color: #fff; padding: 0.4em;">Data Chart</h3>
|
|
||||||
<div style="overflow: auto; padding: 0.5em;" class="">
|
|
||||||
<${SVG} height=240 width=600 ymin=0 ymax=20 xmax=${xmax} data=${data} />
|
|
||||||
</div>
|
|
||||||
<div class="msg">
|
|
||||||
This chart plots live sensor data, sent by the device via /api/watch.
|
|
||||||
</div>
|
|
||||||
</div>`;
|
|
||||||
};
|
|
||||||
|
|
||||||
const App = function(props) {
|
|
||||||
const [user, setUser] = useState('');
|
|
||||||
const [config, setConfig] = useState({});
|
|
||||||
|
|
||||||
const getconfig = () =>
|
|
||||||
fetch('/api/config/get', {headers: {Authorization: ''}})
|
|
||||||
.then(r => r.json())
|
|
||||||
.then(r => setConfig(r))
|
|
||||||
.catch(err => console.log(err));
|
|
||||||
|
|
||||||
// Watch for notifications. As soon as a notification arrives, pass it on
|
|
||||||
// to all subscribed components
|
|
||||||
const watch = function() {
|
|
||||||
var l = window.location, proto = l.protocol.replace('http', 'ws');
|
|
||||||
var tid, wsURI = proto + '//' + l.host + '/api/watch'
|
|
||||||
var reconnect = function() {
|
|
||||||
var ws = new WebSocket(wsURI);
|
|
||||||
// ws.onopen = () => console.log('ws connected');
|
|
||||||
ws.onmessage = function(ev) {
|
|
||||||
try {
|
|
||||||
var msg = JSON.parse(ev.data);
|
|
||||||
PubSub.publish(msg);
|
|
||||||
// if (msg.name != 'metrics') console.log('ws->', msg);
|
|
||||||
} catch (e) {
|
|
||||||
console.log('Invalid ws frame:', ev.data); // eslint-disable-line
|
|
||||||
}
|
|
||||||
};
|
|
||||||
ws.onclose = function() {
|
|
||||||
clearTimeout(tid);
|
|
||||||
tid = setTimeout(reconnect, 1000);
|
|
||||||
console.log('ws disconnected');
|
|
||||||
};
|
|
||||||
};
|
|
||||||
reconnect();
|
|
||||||
};
|
|
||||||
|
|
||||||
const login = function(u) {
|
|
||||||
document.cookie = `access_token=${u.token}; Secure, HttpOnly; SameSite=Lax; path=/; max-age=3600`;
|
|
||||||
setUser(u.user);
|
|
||||||
if (location.search.substring(1) == 'nows') {
|
|
||||||
// If query string is ?nows, then do not connect to websocket. For debug.
|
|
||||||
} else {
|
|
||||||
watch(); // Connect to websocket, receive constant graph updates
|
|
||||||
}
|
|
||||||
return getconfig();
|
|
||||||
};
|
|
||||||
|
|
||||||
const logout = ev => {
|
|
||||||
document.cookie = `access_token=; Secure, HttpOnly; SameSite=Lax; path=/; max-age=0`;
|
|
||||||
setUser('');
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
// Called once at init time
|
|
||||||
PubSub.subscribe(msg => msg.name == 'config' && getconfig());
|
|
||||||
fetch('/api/login', {headers: {Authorization: ''}})
|
|
||||||
.then(r => r.json())
|
|
||||||
.then(r => login(r))
|
|
||||||
.catch(err => setUser(''));
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
if (!user) return html`<${Login} login=${login} />`;
|
|
||||||
|
|
||||||
return html`
|
|
||||||
<${Nav} user=${user} logout=${logout} />
|
|
||||||
<div class="container">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col col-6"><${Hero} /></div>
|
|
||||||
<div class="col col-6"><${Chart} /></div>
|
|
||||||
<div class="col col-6">
|
|
||||||
${user == 'admin' && h(Configuration, {config})}
|
|
||||||
</div>
|
|
||||||
<div class="col col-6"><${Messages} config=${config} /></div>
|
|
||||||
</div>
|
|
||||||
</div>`;
|
|
||||||
};
|
|
||||||
|
|
||||||
window.onload = () => render(h(App), document.body);
|
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
PROG ?= example
|
|
||||||
SOURCES ?= ../../mongoose.c main.c packed_fs.c
|
|
||||||
CFLAGS ?= -I../.. -DMG_ENABLE_PACKED_FS=1 -DMG_ENABLE_LINES=1 $(EXTRA)
|
|
||||||
FILES_TO_EMBED ?= $(wildcard web_root/*)
|
|
||||||
ROOT ?= $(realpath $(CURDIR)/../../..)
|
|
||||||
DOCKER ?= docker run --rm -e Tmp=. -e WINEDEBUG=-all -v $(ROOT):$(ROOT) -w $(CURDIR)
|
|
||||||
VC98 ?= $(DOCKER) mdashnet/vc98 wine
|
|
||||||
MINGW ?= $(DOCKER) mdashnet/mingw
|
|
||||||
|
|
||||||
all: $(PROG)
|
|
||||||
$(RUN) ./$(PROG)
|
|
||||||
|
|
||||||
$(PROG): $(SOURCES) $(FILES_TO_EMBED)
|
|
||||||
$(CC) ../../test/pack.c -o pack
|
|
||||||
./pack $(FILES_TO_EMBED) > packed_fs.c
|
|
||||||
$(CC) -W -Wall -Wextra -O0 -g3 $(CFLAGS) -o $(PROG) $(SOURCES)
|
|
||||||
|
|
||||||
|
|
||||||
mingw: $(SOURCES) $(FILES_TO_EMBED)
|
|
||||||
$(MINGW) i686-w64-mingw32-gcc $(CFLAGS) ../../test/pack.c -o pack.exe
|
|
||||||
$(MINGW) wine cmd /c 'pack.exe $(FILES_TO_EMBED) > packed_fs.c'
|
|
||||||
$(MINGW) i686-w64-mingw32-gcc $(CFLAGS) $(SOURCES) -lws2_32 -o $(PROG).exe
|
|
||||||
$(MINGW) wine $(PROG).exe
|
|
||||||
|
|
||||||
vc98: $(SOURCES) $(FILES_TO_EMBED)
|
|
||||||
$(VC98) cl.exe /nologo $(CFLAGS) ../../test/pack.c /Fepack.exe
|
|
||||||
$(VC98) cmd /c 'pack.exe $(FILES_TO_EMBED) > packed_fs.c'
|
|
||||||
$(VC98) cl.exe /nologo /O2 $(CFLAGS) $(SOURCES) /Fe$(PROG).exe
|
|
||||||
$(VC98) $(PROG).exe
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -rf $(PROG) *.o *.dSYM *.gcov *.gcno *.gcda *.obj *.exe *.ilk *.pdb log.txt pack
|
|
||||||
|
|
||||||
.PHONY: compress expand gzipped plain all
|
|
||||||
|
|
||||||
gzipped: compress
|
|
||||||
$(MAKE) all
|
|
||||||
|
|
||||||
plain: expand
|
|
||||||
$(MAKE) all
|
|
||||||
|
|
||||||
compress:
|
|
||||||
for file in $(FILES_TO_EMBED) ; do \
|
|
||||||
gzip -q $$file ; \
|
|
||||||
done
|
|
||||||
|
|
||||||
expand:
|
|
||||||
for file in $(FILES_TO_EMBED) ; do \
|
|
||||||
gunzip -q $$file ; \
|
|
||||||
done
|
|
||||||
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
// Copyright (c) 2022 Cesanta Software Limited
|
|
||||||
// All rights reserved
|
|
||||||
|
|
||||||
#include "mongoose.h"
|
|
||||||
|
|
||||||
const char *s_listening_url = "http://0.0.0.0:8000";
|
|
||||||
|
|
||||||
// HTTP request handler function
|
|
||||||
void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
|
|
||||||
if (ev == MG_EV_HTTP_MSG) {
|
|
||||||
struct mg_http_serve_opts opts = {
|
|
||||||
.root_dir = "/web_root",
|
|
||||||
.fs = &mg_fs_packed
|
|
||||||
};
|
|
||||||
mg_http_serve_dir(c, ev_data, &opts);
|
|
||||||
}
|
|
||||||
(void) fn_data;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(void) {
|
|
||||||
struct mg_mgr mgr;
|
|
||||||
mg_log_set(MG_LL_INFO);
|
|
||||||
mg_mgr_init(&mgr);
|
|
||||||
mg_http_listen(&mgr, s_listening_url, fn, NULL);
|
|
||||||
while (true) mg_mgr_poll(&mgr, 500);
|
|
||||||
mg_mgr_free(&mgr);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
THISDIR = $(realpath $(CURDIR))
|
|
||||||
ROOTDIR = $(realpath $(CURDIR)/../../..)
|
|
||||||
DOCKER ?= docker run --rm $(DA) -v $(ROOTDIR):$(ROOTDIR) -w $(THISDIR) espressif/idf
|
|
||||||
CMD ?= idf.py build
|
|
||||||
PORT ?= /dev/ttyUSB0
|
|
||||||
|
|
||||||
all: example
|
|
||||||
|
|
||||||
example:
|
|
||||||
true
|
|
||||||
|
|
||||||
build: Makefile $(wildcard main/*)
|
|
||||||
$(DOCKER) $(CMD)
|
|
||||||
|
|
||||||
flash:
|
|
||||||
flash: CMD = idf.py flash
|
|
||||||
flash: DA = --device $(PORT)
|
|
||||||
flash: build
|
|
||||||
|
|
||||||
.PHONY: build
|
|
||||||
|
|
||||||
dashboard.hex: build
|
|
||||||
esputil mkhex \
|
|
||||||
0x8000 build/partition_table/partition-table.bin \
|
|
||||||
0x1000 build/bootloader/bootloader.bin \
|
|
||||||
0x100000 build/mongoose-esp32-example.bin > $@
|
|
||||||
|
|
||||||
flash2: dashboard.hex
|
|
||||||
esputil -p $(PORT) -b 921600 -fp 0x220 flash dashboard.hex
|
|
||||||
esputil -p $(PORT) monitor
|
|
||||||
|
|
||||||
ESPTOOL ?= esptool.py
|
|
||||||
|
|
||||||
flash3:
|
|
||||||
cd build && $(ESPTOOL) --chip esp32 -p $(PORT) -b 460800 --before=default_reset --after=hard_reset write_flash --flash_mode dio --flash_freq 40m --flash_size 2MB 0x8000 partition_table/partition-table.bin 0x1000 bootloader/bootloader.bin 0x100000 mongoose-esp32-example.bin
|
|
||||||
|
|
||||||
clean:
|
|
||||||
test -d build && $(DOCKER) rm -rf build sdkconfig || true
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
idf_component_register(SRCS "main.c"
|
|
||||||
"wifi.c"
|
|
||||||
"net.c"
|
|
||||||
"packed_fs.c"
|
|
||||||
"mongoose.c")
|
|
||||||
component_compile_options(-DMG_ENABLE_LINES)
|
|
||||||
component_compile_options(-DMG_ENABLE_PACKED_FS)
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
// Copyright (c) 2020 Cesanta Software Limited
|
|
||||||
// All rights reserved
|
|
||||||
|
|
||||||
#include "esp_spiffs.h"
|
|
||||||
//#include "freertos/FreeRTOS.h"
|
|
||||||
#include "mongoose.h"
|
|
||||||
|
|
||||||
const char *s_listening_url = "http://0.0.0.0:80";
|
|
||||||
void device_dashboard_fn(struct mg_connection *, int, void *, void *);
|
|
||||||
|
|
||||||
#define WIFI_SSID "YOUR_WIFI_NETWORK_NAME" // SET THIS!
|
|
||||||
#define WIFI_PASS "YOUR_WIFI_PASSWORD" // SET THIS!
|
|
||||||
#define FS_ROOT "/spiffs"
|
|
||||||
|
|
||||||
void app_main(void) {
|
|
||||||
// Mount filesystem
|
|
||||||
esp_vfs_spiffs_conf_t conf = {
|
|
||||||
.base_path = FS_ROOT, .max_files = 20, .format_if_mount_failed = true};
|
|
||||||
int res = esp_vfs_spiffs_register(&conf);
|
|
||||||
MG_INFO(("FS %s, %d", conf.base_path, res));
|
|
||||||
mg_file_printf(&mg_fs_posix, FS_ROOT "/hello.txt", "%s", "hello from ESP");
|
|
||||||
|
|
||||||
// Setup wifi. This function is implemented in wifi.c
|
|
||||||
// It blocks until connected to the configured WiFi network
|
|
||||||
void wifi_init(const char *ssid, const char *pass);
|
|
||||||
wifi_init(WIFI_SSID, WIFI_PASS);
|
|
||||||
|
|
||||||
// Connected to WiFi, now start HTTP server
|
|
||||||
struct mg_mgr mgr;
|
|
||||||
mg_log_set(MG_LL_DEBUG); // Set log level
|
|
||||||
mg_mgr_init(&mgr);
|
|
||||||
MG_INFO(("Mongoose v%s on %s", MG_VERSION, s_listening_url));
|
|
||||||
mg_http_listen(&mgr, s_listening_url, device_dashboard_fn, &mgr);
|
|
||||||
for (;;) mg_mgr_poll(&mgr, 1000); // Infinite event loop
|
|
||||||
}
|
|
||||||
@@ -1,104 +0,0 @@
|
|||||||
// Code taken from the ESP32 IDF WiFi station Example
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
#include "esp_event.h"
|
|
||||||
#include "esp_log.h"
|
|
||||||
#include "esp_system.h"
|
|
||||||
#include "esp_wifi.h"
|
|
||||||
#include "freertos/FreeRTOS.h"
|
|
||||||
#include "freertos/event_groups.h"
|
|
||||||
#include "freertos/task.h"
|
|
||||||
#include "nvs_flash.h"
|
|
||||||
|
|
||||||
#include "lwip/err.h"
|
|
||||||
#include "lwip/sys.h"
|
|
||||||
|
|
||||||
#include "mongoose.h"
|
|
||||||
|
|
||||||
static EventGroupHandle_t s_wifi_event_group;
|
|
||||||
|
|
||||||
/* The event group allows multiple bits for each event, but we only care about
|
|
||||||
* two events:
|
|
||||||
* - we are connected to the AP with an IP
|
|
||||||
* - we failed to connect after the maximum amount of retries */
|
|
||||||
#define WIFI_CONNECTED_BIT BIT0
|
|
||||||
#define WIFI_FAIL_BIT BIT1
|
|
||||||
|
|
||||||
static int s_retry_num = 0;
|
|
||||||
|
|
||||||
static void event_handler(void *arg, esp_event_base_t event_base,
|
|
||||||
int32_t event_id, void *event_data) {
|
|
||||||
if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) {
|
|
||||||
esp_wifi_connect();
|
|
||||||
} else if (event_base == WIFI_EVENT &&
|
|
||||||
event_id == WIFI_EVENT_STA_DISCONNECTED) {
|
|
||||||
if (s_retry_num < 3) {
|
|
||||||
esp_wifi_connect();
|
|
||||||
s_retry_num++;
|
|
||||||
MG_INFO(("retry to connect to the AP"));
|
|
||||||
} else {
|
|
||||||
xEventGroupSetBits(s_wifi_event_group, WIFI_FAIL_BIT);
|
|
||||||
}
|
|
||||||
MG_ERROR(("connect to the AP fail"));
|
|
||||||
} else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
|
|
||||||
ip_event_got_ip_t *event = (ip_event_got_ip_t *) event_data;
|
|
||||||
MG_INFO(("IP ADDRESS:" IPSTR, IP2STR(&event->ip_info.ip)));
|
|
||||||
s_retry_num = 0;
|
|
||||||
xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void wifi_init(const char *ssid, const char *pass) {
|
|
||||||
esp_err_t ret = nvs_flash_init();
|
|
||||||
if (ret == ESP_ERR_NVS_NO_FREE_PAGES ||
|
|
||||||
ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
|
|
||||||
ESP_ERROR_CHECK(nvs_flash_erase());
|
|
||||||
ret = nvs_flash_init();
|
|
||||||
}
|
|
||||||
ESP_ERROR_CHECK(ret);
|
|
||||||
|
|
||||||
s_wifi_event_group = xEventGroupCreate();
|
|
||||||
|
|
||||||
ESP_ERROR_CHECK(esp_netif_init());
|
|
||||||
|
|
||||||
ESP_ERROR_CHECK(esp_event_loop_create_default());
|
|
||||||
esp_netif_create_default_wifi_sta();
|
|
||||||
|
|
||||||
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
|
|
||||||
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
|
|
||||||
|
|
||||||
esp_event_handler_instance_t instance_any_id;
|
|
||||||
esp_event_handler_instance_t instance_got_ip;
|
|
||||||
ESP_ERROR_CHECK(esp_event_handler_instance_register(
|
|
||||||
WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL, &instance_any_id));
|
|
||||||
ESP_ERROR_CHECK(esp_event_handler_instance_register(
|
|
||||||
IP_EVENT, IP_EVENT_STA_GOT_IP, &event_handler, NULL, &instance_got_ip));
|
|
||||||
|
|
||||||
wifi_config_t c = {.sta = {.threshold = {.authmode = WIFI_AUTH_WPA2_PSK},
|
|
||||||
.pmf_cfg = {.capable = true, .required = false}}};
|
|
||||||
snprintf((char *) c.sta.ssid, sizeof(c.sta.ssid), "%s", ssid);
|
|
||||||
snprintf((char *) c.sta.password, sizeof(c.sta.password), "%s", pass);
|
|
||||||
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
|
|
||||||
ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &c));
|
|
||||||
ESP_ERROR_CHECK(esp_wifi_start());
|
|
||||||
MG_DEBUG(("wifi_init_sta finished."));
|
|
||||||
|
|
||||||
EventBits_t bits = xEventGroupWaitBits(s_wifi_event_group,
|
|
||||||
WIFI_CONNECTED_BIT | WIFI_FAIL_BIT,
|
|
||||||
pdFALSE, pdFALSE, portMAX_DELAY);
|
|
||||||
|
|
||||||
if (bits & WIFI_CONNECTED_BIT) {
|
|
||||||
MG_INFO(("connected to ap SSID:%s password:%s", ssid, pass));
|
|
||||||
} else if (bits & WIFI_FAIL_BIT) {
|
|
||||||
MG_ERROR(("Failed to connect to SSID:%s, password:%s", ssid, pass));
|
|
||||||
} else {
|
|
||||||
MG_ERROR(("UNEXPECTED EVENT"));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The event will not be processed after unregister */
|
|
||||||
ESP_ERROR_CHECK(esp_event_handler_instance_unregister(
|
|
||||||
IP_EVENT, IP_EVENT_STA_GOT_IP, instance_got_ip));
|
|
||||||
ESP_ERROR_CHECK(esp_event_handler_instance_unregister(
|
|
||||||
WIFI_EVENT, ESP_EVENT_ANY_ID, instance_any_id));
|
|
||||||
vEventGroupDelete(s_wifi_event_group);
|
|
||||||
}
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
CWD = $(realpath $(CURDIR))
|
|
||||||
MNT = $(realpath $(CURDIR)/../../..)
|
|
||||||
PORT ?= /dev/ttyUSB0
|
|
||||||
CMD ?= build
|
|
||||||
|
|
||||||
all: example
|
|
||||||
|
|
||||||
example:
|
|
||||||
true
|
|
||||||
|
|
||||||
build: Makefile $(wildcard main/*)
|
|
||||||
docker run --rm $(DA) -v $(MNT):$(MNT) -w $(CWD) espressif/idf idf.py $(CMD)
|
|
||||||
|
|
||||||
flash:
|
|
||||||
flash: CMD = flash
|
|
||||||
flash: DA = --device $(PORT)
|
|
||||||
flash: build
|
|
||||||
|
|
||||||
.PHONY: build
|
|
||||||
|
|
||||||
bridge.hex: build
|
|
||||||
esputil mkhex \
|
|
||||||
0x8000 build/partition_table/partition-table.bin \
|
|
||||||
0x1000 build/bootloader/bootloader.bin \
|
|
||||||
0x100000 build/mongoose-esp32-example.bin > $@
|
|
||||||
|
|
||||||
flash2: bridge.hex
|
|
||||||
esputil -p $(PORT) -b 921600 -fp 0x220 flash bridge.hex
|
|
||||||
esputil -p $(PORT) monitor
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -rf build
|
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
# A UART to network bridge for ESP32
|
|
||||||
|
|
||||||
This example is a demonstration of how Mongoose Library could be integrated
|
|
||||||
into an embedded device and provide a UART-to-Network bridge capability:
|
|
||||||
|
|
||||||
- A device opens listening TCP port and Websocket port and waits for connections
|
|
||||||
- When a client connects, data is exchanged with the device's UART
|
|
||||||
- Everything that client send, is sent to the UART
|
|
||||||
- Everything that is read from the UART, gets sent to the client
|
|
||||||
- Multiple clients are allowed
|
|
||||||
- Live UART console allows to talk to the UART from the web page
|
|
||||||
- Web UI is hardcoded into the binary and does not need a filesystem
|
|
||||||
|
|
||||||
# Screenshots
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
# Build and flash
|
|
||||||
|
|
||||||
Build requires Docker installed, and uses Espressif's ESP-IDF docker image:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
make build
|
|
||||||
make flash PORT=/dev/YOURSERIAL
|
|
||||||
```
|
|
||||||
|
|
||||||
# Flash pre-built firmware
|
|
||||||
|
|
||||||
You can flash a pre-built firmware to the ESP32 device using the following
|
|
||||||
instructions:
|
|
||||||
|
|
||||||
1. Connect your ESP32 device to the workstation. It should be accessible
|
|
||||||
via a serial port
|
|
||||||
2. Download and unzip ESP32 flashing tool from https://mongoose.ws/downloads/esputil.zip
|
|
||||||
3. Download a prebuilt firmware https://mongoose.ws/downloads/uart-bridge.hex into the unzipped directory
|
|
||||||
4. Start command prompt (or terminal on Mac/Linux). Run `cd
|
|
||||||
PATH/TO/esputil` to go into the unzipped `esputil/` directory. After that, run
|
|
||||||
the following command (change `COMPORT` to the board's serial port):
|
|
||||||
|
|
||||||
| OS | Command |
|
|
||||||
| ------- | ------- |
|
|
||||||
| Windows | <pre><code class="language-bash">.\windows\esputil -p COMPORT flash uart-bridge.hex</code></pre>|
|
|
||||||
| Linux | <pre><code class="language-bash">./linux/esputil -p COMPORT flash uart-bridge.hex</pre> |
|
|
||||||
| MacOS | <pre><code class="language-bash">./macos/esputil -p COMPORT flash uart-bridge.hex</code></pre> |
|
|
||||||
|
|
||||||
Next step is to monitor and follow the instructions.
|
|
||||||
|
|
||||||
```sh
|
|
||||||
esputil -p COMPORT monitor
|
|
||||||
```
|
|
||||||
|
|
||||||
Note: if monitor command shows constant restarts, the flash parameters
|
|
||||||
settings can be wrong. Reflash your device with `-fp ...` flash parameters
|
|
||||||
settings. For example, WROOM-32 based boards use `-fp 0x220`:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
esputil -p COMPORT -fp 0x220 flash uart-bridge.hex
|
|
||||||
```
|
|
||||||
|
|
||||||
For more on possible options for flash parameters, see
|
|
||||||
https://github.com/cpq/esputil#flash-parameters
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
idf_component_register(SRCS "main.c"
|
|
||||||
"wifi.c"
|
|
||||||
"uart.c"
|
|
||||||
"cli.c"
|
|
||||||
"net.c"
|
|
||||||
"packed_fs.c"
|
|
||||||
"mongoose.c")
|
|
||||||
component_compile_options(-DMG_ENABLE_LINES=1)
|
|
||||||
component_compile_options(-DMG_ENABLE_PACKED_FS=1)
|
|
||||||
component_compile_options(-DUART_API_IMPLEMENTED=1)
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
// Copyright (c) 2020 Cesanta Software Limited
|
|
||||||
// All rights reserved
|
|
||||||
|
|
||||||
#include "main.h"
|
|
||||||
|
|
||||||
const char *s_listening_url = "http://0.0.0.0:80";
|
|
||||||
|
|
||||||
char *config_read(void) {
|
|
||||||
return mg_file_read(&mg_fs_posix, FS_ROOT "/config.json", NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
void config_write(struct mg_str config) {
|
|
||||||
mg_file_write(&mg_fs_posix, FS_ROOT "/config.json", config.ptr, config.len);
|
|
||||||
}
|
|
||||||
|
|
||||||
void app_main(void) {
|
|
||||||
// Mount filesystem
|
|
||||||
esp_vfs_spiffs_conf_t conf = {
|
|
||||||
.base_path = FS_ROOT, .max_files = 20, .format_if_mount_failed = true};
|
|
||||||
int res = esp_vfs_spiffs_register(&conf);
|
|
||||||
MG_INFO(("FS at %s initialised, status: %d", conf.base_path, res));
|
|
||||||
|
|
||||||
// Try to connect to wifi by using saved WiFi credentials
|
|
||||||
char *json = mg_file_read(&mg_fs_posix, WIFI_FILE, NULL);
|
|
||||||
if (json != NULL) {
|
|
||||||
char *ssid = mg_json_get_str(mg_str(json), "$.ssid");
|
|
||||||
char *pass = mg_json_get_str(mg_str(json), "$.pass");
|
|
||||||
while (!wifi_init(ssid, pass)) (void) 0;
|
|
||||||
free(ssid);
|
|
||||||
free(pass);
|
|
||||||
free(json);
|
|
||||||
} else {
|
|
||||||
// If WiFi is not configured, run CLI until configured
|
|
||||||
MG_INFO(("WiFi is not configured, running CLI. Press enter"));
|
|
||||||
cli_init();
|
|
||||||
for (;;) {
|
|
||||||
uint8_t ch = getchar();
|
|
||||||
cli(ch);
|
|
||||||
usleep(10000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Connected to WiFi, now start HTTP server
|
|
||||||
struct mg_mgr mgr;
|
|
||||||
mg_mgr_init(&mgr);
|
|
||||||
mg_log_set(MG_LL_DEBUG); // Set log level
|
|
||||||
MG_INFO(("Mongoose v%s on %s", MG_VERSION, s_listening_url));
|
|
||||||
mg_http_listen(&mgr, s_listening_url, uart_bridge_fn, &mgr);
|
|
||||||
for (;;) mg_mgr_poll(&mgr, 10); // Infinite event loop
|
|
||||||
}
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "mongoose.h"
|
|
||||||
|
|
||||||
#include "driver/gpio.h"
|
|
||||||
#include "driver/uart.h"
|
|
||||||
#include "esp_spiffs.h"
|
|
||||||
#include "freertos/FreeRTOS.h"
|
|
||||||
|
|
||||||
#define FS_ROOT "/spiffs"
|
|
||||||
#define WIFI_FILE FS_ROOT "/wifi.json"
|
|
||||||
#define UART_NO 1
|
|
||||||
|
|
||||||
void uart_bridge_fn(struct mg_connection *, int, void *, void *);
|
|
||||||
int uart_read(void *buf, size_t len);
|
|
||||||
bool wifi_init(const char *ssid, const char *pass);
|
|
||||||
void cli(uint8_t ch);
|
|
||||||
void cli_init(void);
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../../../uart-bridge/net.c
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../../../uart-bridge/packed_fs.c
|
|
||||||
@@ -1,108 +0,0 @@
|
|||||||
// Code taken from the ESP32 IDF WiFi station Example
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
#include "esp_event.h"
|
|
||||||
#include "esp_log.h"
|
|
||||||
#include "esp_system.h"
|
|
||||||
#include "esp_wifi.h"
|
|
||||||
#include "freertos/FreeRTOS.h"
|
|
||||||
#include "freertos/event_groups.h"
|
|
||||||
#include "freertos/task.h"
|
|
||||||
#include "nvs_flash.h"
|
|
||||||
|
|
||||||
#include "lwip/err.h"
|
|
||||||
#include "lwip/sys.h"
|
|
||||||
|
|
||||||
#include "mongoose.h"
|
|
||||||
|
|
||||||
static EventGroupHandle_t s_wifi_event_group;
|
|
||||||
|
|
||||||
/* The event group allows multiple bits for each event, but we only care about
|
|
||||||
* two events:
|
|
||||||
* - we are connected to the AP with an IP
|
|
||||||
* - we failed to connect after the maximum amount of retries */
|
|
||||||
#define WIFI_CONNECTED_BIT BIT0
|
|
||||||
#define WIFI_FAIL_BIT BIT1
|
|
||||||
|
|
||||||
static int s_retry_num = 0;
|
|
||||||
|
|
||||||
static void event_handler(void *arg, esp_event_base_t event_base,
|
|
||||||
int32_t event_id, void *event_data) {
|
|
||||||
if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) {
|
|
||||||
esp_wifi_connect();
|
|
||||||
} else if (event_base == WIFI_EVENT &&
|
|
||||||
event_id == WIFI_EVENT_STA_DISCONNECTED) {
|
|
||||||
if (s_retry_num < 3) {
|
|
||||||
esp_wifi_connect();
|
|
||||||
s_retry_num++;
|
|
||||||
MG_INFO(("retry to connect to the AP"));
|
|
||||||
} else {
|
|
||||||
xEventGroupSetBits(s_wifi_event_group, WIFI_FAIL_BIT);
|
|
||||||
}
|
|
||||||
MG_ERROR(("connect to the AP fail"));
|
|
||||||
} else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
|
|
||||||
ip_event_got_ip_t *event = (ip_event_got_ip_t *) event_data;
|
|
||||||
MG_INFO(("IP ADDRESS: " IPSTR ". Go to:", IP2STR(&event->ip_info.ip)));
|
|
||||||
MG_INFO(("http://" IPSTR, IP2STR(&event->ip_info.ip)));
|
|
||||||
s_retry_num = 0;
|
|
||||||
xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool wifi_init(const char *ssid, const char *pass) {
|
|
||||||
bool result = false;
|
|
||||||
esp_err_t ret = nvs_flash_init();
|
|
||||||
if (ret == ESP_ERR_NVS_NO_FREE_PAGES ||
|
|
||||||
ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
|
|
||||||
ESP_ERROR_CHECK(nvs_flash_erase());
|
|
||||||
ret = nvs_flash_init();
|
|
||||||
}
|
|
||||||
ESP_ERROR_CHECK(ret);
|
|
||||||
|
|
||||||
s_wifi_event_group = xEventGroupCreate();
|
|
||||||
|
|
||||||
ESP_ERROR_CHECK(esp_netif_init());
|
|
||||||
|
|
||||||
ESP_ERROR_CHECK(esp_event_loop_create_default());
|
|
||||||
esp_netif_create_default_wifi_sta();
|
|
||||||
|
|
||||||
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
|
|
||||||
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
|
|
||||||
|
|
||||||
esp_event_handler_instance_t instance_any_id;
|
|
||||||
esp_event_handler_instance_t instance_got_ip;
|
|
||||||
ESP_ERROR_CHECK(esp_event_handler_instance_register(
|
|
||||||
WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL, &instance_any_id));
|
|
||||||
ESP_ERROR_CHECK(esp_event_handler_instance_register(
|
|
||||||
IP_EVENT, IP_EVENT_STA_GOT_IP, &event_handler, NULL, &instance_got_ip));
|
|
||||||
|
|
||||||
wifi_config_t c = {.sta = {.threshold = {.authmode = WIFI_AUTH_WPA2_PSK},
|
|
||||||
.pmf_cfg = {.capable = true, .required = false}}};
|
|
||||||
snprintf((char *) c.sta.ssid, sizeof(c.sta.ssid), "%s", ssid);
|
|
||||||
snprintf((char *) c.sta.password, sizeof(c.sta.password), "%s", pass);
|
|
||||||
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
|
|
||||||
ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &c));
|
|
||||||
ESP_ERROR_CHECK(esp_wifi_start());
|
|
||||||
MG_DEBUG(("wifi_init_sta finished."));
|
|
||||||
|
|
||||||
EventBits_t bits = xEventGroupWaitBits(s_wifi_event_group,
|
|
||||||
WIFI_CONNECTED_BIT | WIFI_FAIL_BIT,
|
|
||||||
pdFALSE, pdFALSE, portMAX_DELAY);
|
|
||||||
|
|
||||||
if (bits & WIFI_CONNECTED_BIT) {
|
|
||||||
MG_INFO(("connected to ap SSID:%s", ssid));
|
|
||||||
result = true;
|
|
||||||
} else if (bits & WIFI_FAIL_BIT) {
|
|
||||||
MG_ERROR(("Failed to connect to SSID:%s, password:%s", ssid, pass));
|
|
||||||
} else {
|
|
||||||
MG_ERROR(("UNEXPECTED EVENT"));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The event will not be processed after unregister */
|
|
||||||
ESP_ERROR_CHECK(esp_event_handler_instance_unregister(
|
|
||||||
IP_EVENT, IP_EVENT_STA_GOT_IP, instance_got_ip));
|
|
||||||
ESP_ERROR_CHECK(esp_event_handler_instance_unregister(
|
|
||||||
WIFI_EVENT, ESP_EVENT_ANY_ID, instance_any_id));
|
|
||||||
vEventGroupDelete(s_wifi_event_group);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
# Name, Type, SubType, Offset, Size, Flags
|
|
||||||
nvs, data, nvs, 0x9000, 0x6000,
|
|
||||||
phy_init, data, phy, 0xf000, 0x1000,
|
|
||||||
storage, data, spiffs, 0x10000, 0x10000,
|
|
||||||
factory, app, factory, 0x100000, 1M,
|
|
||||||
|
@@ -1,45 +0,0 @@
|
|||||||
THISDIR = $(realpath $(CURDIR))
|
|
||||||
ROOTDIR = $(realpath $(CURDIR)/../../..)
|
|
||||||
DOCKER ?= docker run --rm $(DA) -v $(ROOTDIR):$(ROOTDIR) -w $(THISDIR) docker.io/mdashnet/8266
|
|
||||||
CMD ?= make -C src defconfig app
|
|
||||||
PORT ?= /dev/ttyUSB0
|
|
||||||
|
|
||||||
all: example
|
|
||||||
|
|
||||||
example:
|
|
||||||
true
|
|
||||||
|
|
||||||
build: Makefile $(wildcard src/main/*)
|
|
||||||
$(DOCKER) $(CMD)
|
|
||||||
|
|
||||||
flash:
|
|
||||||
flash: CMD = python /esp/components/esptool_py/esptool/esptool.py \
|
|
||||||
--chip esp8266 --port $(PORT) --baud 115200 --before default_reset \
|
|
||||||
--after hard_reset write_flash -z --flash_mode dio --flash_freq 40m \
|
|
||||||
--flash_size 2MB 0x10000 $(THISDIR)/src/build/mongoose-example.bin
|
|
||||||
flash: DA = --device $(PORT)
|
|
||||||
flash: build
|
|
||||||
|
|
||||||
buildall:
|
|
||||||
buildall: CMD = make -C src all
|
|
||||||
buildall: build
|
|
||||||
|
|
||||||
flashall:
|
|
||||||
flashall: CMD = python /esp/components/esptool_py/esptool/esptool.py \
|
|
||||||
--chip esp8266 --port $(PORT) --baud 115200 --before default_reset \
|
|
||||||
--after hard_reset write_flash -z --flash_mode dio --flash_freq 40m \
|
|
||||||
--flash_size 2MB 0x0 $(THISDIR)/src/build/bootloader/bootloader.bin \
|
|
||||||
0x10000 $(THISDIR)/src/build/mongoose-example.bin \
|
|
||||||
0x8000 $(THISDIR)/src/build/partitions_singleapp.bin
|
|
||||||
flashall: DA = --device $(PORT)
|
|
||||||
flashall: build
|
|
||||||
|
|
||||||
monitor:
|
|
||||||
monitor: CMD = /esp/tools/idf_monitor.py --port $(PORT) $(THISDIR)/src/build/mongoose-example.elf
|
|
||||||
monitor: build
|
|
||||||
|
|
||||||
.PHONY: build
|
|
||||||
|
|
||||||
clean:
|
|
||||||
test -d src/build && $(DOCKER) rm -rf src/build || true
|
|
||||||
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
# An example ESP8266 application
|
|
||||||
|
|
||||||
To build this application, follow these steps:
|
|
||||||
|
|
||||||
1. Make sure you have Docker installed
|
|
||||||
2. Clone whole mongoose repository on your machine:
|
|
||||||
```sh
|
|
||||||
git clone https://github.com/cesanta/mongoose.git
|
|
||||||
```
|
|
||||||
3. Start command line or terminal, and go into the example's directory:
|
|
||||||
```sh
|
|
||||||
cd mongoose/examples/esp8266
|
|
||||||
```
|
|
||||||
4. Run `make`. This invokes a Docker-based build. A firmware will be built
|
|
||||||
in the `src/build/` directory:
|
|
||||||
```sh
|
|
||||||
make build
|
|
||||||
```
|
|
||||||
5. Flash your ESP8266. If you have esptool.py installed, the build process will end telling you the command to flash your device. You can just run `make` again to use Docker:
|
|
||||||
```sh
|
|
||||||
make flash PORT=/your/serial
|
|
||||||
```
|
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
// Copyright (c) 2020 Cesanta Software Limited
|
|
||||||
// All rights reserved
|
|
||||||
|
|
||||||
#include "mongoose.h"
|
|
||||||
|
|
||||||
#define WIFI_SSID "WIFI_NETWORK" // SET THIS!
|
|
||||||
#define WIFI_PASS "WIFI_PASSWORD" // SET THIS!
|
|
||||||
|
|
||||||
#define SERVER_URL "http://0.0.0.0:80"
|
|
||||||
#define CLIENT_URL "http://info.cern.ch"
|
|
||||||
|
|
||||||
// Event handler for an server (accepted) connection
|
|
||||||
static void cb(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
|
|
||||||
if (ev == MG_EV_HTTP_MSG) {
|
|
||||||
mg_http_reply(c, 200, "", "Hello from ESP!\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Event handler for a client connection - fetch the first web page in history
|
|
||||||
// To enable TLS for HTTP,
|
|
||||||
// 1. Copy "ca.pem" file to the ESP8266 flash FS
|
|
||||||
// 2. Add TLS init snippet for the connection, see examples/http-client
|
|
||||||
static void cb2(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
|
|
||||||
if (ev == MG_EV_CONNECT) {
|
|
||||||
struct mg_str s = mg_url_host(CLIENT_URL);
|
|
||||||
mg_printf(c, "GET / HTTP/1.0\r\nHost: %.*s\r\n\r\n", (int) s.len, s.ptr);
|
|
||||||
} else if (ev == MG_EV_HTTP_MSG) {
|
|
||||||
struct mg_http_message *hm = ev_data; // Print HTTP response
|
|
||||||
MG_INFO(("Fetched:\n%.*s", (int) hm->message.len, hm->message.ptr));
|
|
||||||
c->is_closing = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Called after we're connected to WiFi network
|
|
||||||
static void run_mongoose(void) {
|
|
||||||
struct mg_mgr mgr;
|
|
||||||
mg_log_set(MG_LL_DEBUG); // Set log level
|
|
||||||
mg_mgr_init(&mgr);
|
|
||||||
mg_http_listen(&mgr, SERVER_URL, cb, &mgr); // Listening server
|
|
||||||
mg_http_connect(&mgr, CLIENT_URL, cb2, &mgr); // Example client
|
|
||||||
MG_INFO(("Starting Mongoose web server v%s", MG_VERSION));
|
|
||||||
for (;;) mg_mgr_poll(&mgr, 1000);
|
|
||||||
mg_mgr_free(&mgr);
|
|
||||||
}
|
|
||||||
|
|
||||||
void app_main(void) {
|
|
||||||
// Setup wifi. This function is implemented in wifi.c
|
|
||||||
// It blocks until connected to the configured WiFi network
|
|
||||||
void wifi_init(const char *ssid, const char *pass);
|
|
||||||
wifi_init(WIFI_SSID, WIFI_PASS);
|
|
||||||
|
|
||||||
// Done connecting to WiFi, now start HTTP server
|
|
||||||
run_mongoose();
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
PROG ?= example
|
|
||||||
|
|
||||||
all: $(PROG)
|
|
||||||
$(DEBUGGER) ./$(PROG)
|
|
||||||
|
|
||||||
$(PROG):
|
|
||||||
$(CC) ../../mongoose.c -I../.. $(CFLAGS) $(EXTRA) -o $(PROG) main.c
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -rf $(PROG) *.o *.dSYM *.gcov *.gcno *.gcda *.obj *.exe *.ilk *.pdb log.txt
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
See detailed tutorial at https://mongoose.ws/tutorials/file-uploads/
|
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
// Copyright (c) 2021 Cesanta Software Limited
|
|
||||||
// All rights reserved
|
|
||||||
|
|
||||||
#include "mongoose.h"
|
|
||||||
|
|
||||||
// HTTP request handler function. It implements the following endpoints:
|
|
||||||
// /upload - prints all submitted form elements
|
|
||||||
// all other URI - serves web_root/ directory
|
|
||||||
//
|
|
||||||
// ///////////////// IMPORTANT //////////////////////////
|
|
||||||
//
|
|
||||||
// Mongoose has a limit on input buffer, which also limits maximum upload size.
|
|
||||||
// It is controlled by the MG_MAX_RECV_SIZE constant, which is set by
|
|
||||||
// default to (3 * 1024 * 1024), i.e. 3 megabytes.
|
|
||||||
// Use -DMG_MAX_BUF_SIZE=NEW_LIMIT to override it.
|
|
||||||
//
|
|
||||||
// Also, consider changing -DMG_IO_SIZE=SOME_BIG_VALUE to increase IO buffer
|
|
||||||
// increment when reading data.
|
|
||||||
static void cb(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
|
|
||||||
if (ev == MG_EV_HTTP_MSG) {
|
|
||||||
struct mg_http_message *hm = (struct mg_http_message *) ev_data;
|
|
||||||
MG_INFO(("New request to: [%.*s], body size: %lu", (int) hm->uri.len,
|
|
||||||
hm->uri.ptr, (unsigned long) hm->body.len));
|
|
||||||
if (mg_http_match_uri(hm, "/upload")) {
|
|
||||||
struct mg_http_part part;
|
|
||||||
size_t ofs = 0;
|
|
||||||
while ((ofs = mg_http_next_multipart(hm->body, ofs, &part)) > 0) {
|
|
||||||
MG_INFO(("Chunk name: [%.*s] filename: [%.*s] length: %lu bytes",
|
|
||||||
(int) part.name.len, part.name.ptr, (int) part.filename.len,
|
|
||||||
part.filename.ptr, (unsigned long) part.body.len));
|
|
||||||
}
|
|
||||||
mg_http_reply(c, 200, "", "Thank you!");
|
|
||||||
} else {
|
|
||||||
struct mg_http_serve_opts opts = {.root_dir = "web_root"};
|
|
||||||
mg_http_serve_dir(c, ev_data, &opts);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(void) {
|
|
||||||
struct mg_mgr mgr;
|
|
||||||
|
|
||||||
mg_mgr_init(&mgr);
|
|
||||||
mg_log_set(MG_LL_DEBUG); // Set log level
|
|
||||||
mg_http_listen(&mgr, "http://localhost:8000", cb, NULL);
|
|
||||||
|
|
||||||
for (;;) mg_mgr_poll(&mgr, 50);
|
|
||||||
mg_mgr_free(&mgr);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
PROG ?= example
|
|
||||||
|
|
||||||
all: $(PROG)
|
|
||||||
$(DEBUGGER) ./$(PROG)
|
|
||||||
|
|
||||||
$(PROG):
|
|
||||||
$(CC) ../../mongoose.c -I../.. $(CFLAGS) $(EXTRA) -o $(PROG) main.c
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -rf $(PROG) *.o *.dSYM *.gcov *.gcno *.gcda *.obj *.exe *.ilk *.pdb log.txt
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
See detailed tutorial at https://mongoose.ws/tutorials/file-uploads/
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
// Copyright (c) 2020 Cesanta Software Limited
|
|
||||||
// All rights reserved
|
|
||||||
|
|
||||||
#include "mongoose.h"
|
|
||||||
|
|
||||||
// HTTP request handler function. It implements the following endpoints:
|
|
||||||
// /upload - Saves the next file chunk
|
|
||||||
// all other URI - serves web_root/ directory
|
|
||||||
static void cb(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
|
|
||||||
if (ev == MG_EV_HTTP_MSG) {
|
|
||||||
struct mg_http_message *hm = (struct mg_http_message *) ev_data;
|
|
||||||
if (mg_http_match_uri(hm, "/upload")) {
|
|
||||||
char path[80], name[64];
|
|
||||||
mg_http_get_var(&hm->query, "name", name, sizeof(name));
|
|
||||||
if (name[0] == '\0') {
|
|
||||||
mg_http_reply(c, 400, "", "%s", "name required");
|
|
||||||
} else {
|
|
||||||
mg_snprintf(path, sizeof(path), "/tmp/%s", name);
|
|
||||||
mg_http_upload(c, hm, &mg_fs_posix, mg_remove_double_dots(path), 99999);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
struct mg_http_serve_opts opts = {.root_dir = "web_root"};
|
|
||||||
mg_http_serve_dir(c, ev_data, &opts);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(void) {
|
|
||||||
struct mg_mgr mgr;
|
|
||||||
struct mg_timer t1;
|
|
||||||
|
|
||||||
mg_mgr_init(&mgr);
|
|
||||||
mg_log_set(MG_LL_DEBUG); // Set log level
|
|
||||||
mg_http_listen(&mgr, "http://localhost:8000", cb, NULL);
|
|
||||||
|
|
||||||
for (;;) mg_mgr_poll(&mgr, 50);
|
|
||||||
mg_mgr_free(&mgr);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
PROG ?= example
|
|
||||||
|
|
||||||
all: $(PROG)
|
|
||||||
$(DEBUGGER) ./$(PROG)
|
|
||||||
|
|
||||||
$(PROG):
|
|
||||||
$(CC) ../../mongoose.c -I../.. $(CFLAGS) $(EXTRA) -o $(PROG) main.c
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -rf $(PROG) *.o *.dSYM *.gcov *.gcno *.gcda *.obj *.exe *.ilk *.pdb log.txt
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
See detailed tutorial at https://mongoose.ws/tutorials/file-uploads/
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
// Copyright (c) 2020 Cesanta Software Limited
|
|
||||||
// All rights reserved
|
|
||||||
//
|
|
||||||
// Streaming upload example. Demonstrates how to use chunked encoding
|
|
||||||
// to send large payload in smaller chunks. To test, use curl utility:
|
|
||||||
//
|
|
||||||
// curl http://localhost:8000/upload?name=a.txt --data-binary @large_file.txt
|
|
||||||
|
|
||||||
#include "mongoose.h"
|
|
||||||
|
|
||||||
// HTTP request handler function. It implements the following endpoints:
|
|
||||||
// /upload - Saves the next file chunk
|
|
||||||
// all other URI - serves web_root/ directory
|
|
||||||
static void cb(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
|
|
||||||
struct mg_http_message *hm = (struct mg_http_message *) ev_data;
|
|
||||||
if (ev == MG_EV_HTTP_CHUNK && mg_http_match_uri(hm, "/upload")) {
|
|
||||||
MG_INFO(("Got chunk len %lu", (unsigned long) hm->chunk.len));
|
|
||||||
MG_INFO(("Query string: [%.*s]", (int) hm->query.len, hm->query.ptr));
|
|
||||||
// MG_INFO(("Chunk data:\n%.*s", (int) hm->chunk.len, hm->chunk.ptr));
|
|
||||||
mg_http_delete_chunk(c, hm);
|
|
||||||
if (hm->chunk.len == 0) {
|
|
||||||
MG_INFO(("Last chunk received, sending response"));
|
|
||||||
mg_http_reply(c, 200, "", "ok (chunked)\n");
|
|
||||||
}
|
|
||||||
} else if (ev == MG_EV_HTTP_MSG) {
|
|
||||||
struct mg_http_serve_opts opts = {.root_dir = "web_root"};
|
|
||||||
mg_http_serve_dir(c, hm, &opts);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(void) {
|
|
||||||
struct mg_mgr mgr;
|
|
||||||
|
|
||||||
mg_mgr_init(&mgr);
|
|
||||||
mg_log_set(MG_LL_DEBUG); // Set debug log level
|
|
||||||
mg_http_listen(&mgr, "http://localhost:8000", cb, NULL);
|
|
||||||
|
|
||||||
for (;;) mg_mgr_poll(&mgr, 50);
|
|
||||||
mg_mgr_free(&mgr);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -1,64 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<title>example</title>
|
|
||||||
<meta charset="utf-8" />
|
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
||||||
<style>
|
|
||||||
#container { margin-right: auto; margin-left: auto; max-width: 480px; }
|
|
||||||
#info { background: #e0f0f0; border-radius: .5em; padding: 2em; }
|
|
||||||
#wrapper { margin-top: 1em; }
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div id="container">
|
|
||||||
<div id="info">
|
|
||||||
Mongoose always buffers a full HTTP message before invoking
|
|
||||||
MG_EV_HTTP_MSG event. Big POST request require of lot
|
|
||||||
of RAM to buffer everything.
|
|
||||||
<br><br>
|
|
||||||
In order to upload large files to a memory-constrained system, use
|
|
||||||
<code>MG_EV_HTTP_CHUNK</code> on a server side. It fires when
|
|
||||||
a partial HTTP message has been received (or a chunk-encoded chunk).
|
|
||||||
Use <code>mg_http_delete_chunk()</code> to release chunk memory.
|
|
||||||
When 0-sized chunk is received, that's the end of the message.
|
|
||||||
Use <code>MG_MAX_RECV_SIZE</code> build constant to limit
|
|
||||||
maximum chunk size on a server side.
|
|
||||||
<br><br>
|
|
||||||
In this example, JavaScript code uses "fetch()" browser API.
|
|
||||||
Uploaded file is not saved, but rather printed by server side.
|
|
||||||
</div>
|
|
||||||
<div id="wrapper">
|
|
||||||
<input type="file" id="el1" style="display: none"/>
|
|
||||||
<button id="el2">choose file...</button>
|
|
||||||
<div id="el3" style="margin-top: 1em;"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
<script>
|
|
||||||
|
|
||||||
// When user clicks on a button, trigger file selection dialog
|
|
||||||
document.getElementById('el2').onclick = function(ev) {
|
|
||||||
document.getElementById('el1').click();
|
|
||||||
};
|
|
||||||
|
|
||||||
// If user selected a file, read it into memory and trigger sendFileData()
|
|
||||||
document.getElementById('el1').onchange = function(ev) {
|
|
||||||
if (!ev.target.files[0]) return;
|
|
||||||
var f = ev.target.files[0], r = new FileReader();
|
|
||||||
r.readAsArrayBuffer(f);
|
|
||||||
r.onload = function() {
|
|
||||||
ev.target.value = '';
|
|
||||||
document.getElementById('el3').innerText = 'Uploading...';
|
|
||||||
fetch('/upload?name=' + encodeURIComponent(f.name), {
|
|
||||||
method: 'POST',
|
|
||||||
body: r.result,
|
|
||||||
}).then(function(res) {
|
|
||||||
document.getElementById('el3').innerText = 'Uploaded ' + r.result.byteLength + ' bytes';
|
|
||||||
});
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
</script>
|
|
||||||
</html>
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
PROG ?= example
|
|
||||||
ROOT ?= $(realpath $(CURDIR)/../..)
|
|
||||||
CFLAGS ?= -DMG_ENABLE_LINES $(EXTRA_CFLAGS)
|
|
||||||
LIN = docker run -it --rm -v $(ROOT):$(ROOT) -w $(CURDIR) mdashnet/cc2
|
|
||||||
SSL = ?
|
|
||||||
|
|
||||||
ifeq "$(SSL)" "MBEDTLS"
|
|
||||||
CFLAGS += -DMG_ENABLE_MBEDTLS=1 -lmbedtls -lmbedcrypto -lmbedx509
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq "$(SSL)" "OPENSSL"
|
|
||||||
CFLAGS += -DMG_ENABLE_OPENSSL=1 -lssl -lcrypto
|
|
||||||
endif
|
|
||||||
|
|
||||||
all: $(PROG)
|
|
||||||
$(RUN) ./$(PROG) $(ARGS)
|
|
||||||
|
|
||||||
$(PROG): main.c
|
|
||||||
$(CC) ../../mongoose.c -I../.. -W -Wall $(CFLAGS) -o $(PROG) main.c
|
|
||||||
|
|
||||||
linux: all
|
|
||||||
linux: CFLAGS += -O2 -g -fsanitize=address,undefined,shift,null,return,bounds,alignment,object-size,bool,enum -static-libasan
|
|
||||||
linux: CC = $(LIN) cc
|
|
||||||
linux: RUN = $(LIN)
|
|
||||||
|
|
||||||
|
|
||||||
ROOT ?= $(realpath $(CURDIR)/../..)
|
|
||||||
DOCKER = docker run -it --rm -e Tmp=. -e WINEDEBUG=-all -v $(ROOT):$(ROOT) -w $(CURDIR)
|
|
||||||
WDEFS = -DMG_ENABLE_MBEDTLS -DMG_ENABLE_LINES -Imbedtls/include -Imbedtls/library $(EXTRA)
|
|
||||||
WFLAGS = /nologo -O2 -I. -I../.. ws2_32.lib advapi32.lib /link /out:$(PROG).exe
|
|
||||||
WSRCS = ../../mongoose.c main.c mbedtls/library/*.c
|
|
||||||
$(PROG).exe: main.c mbedtls
|
|
||||||
$(DOCKER) mdashnet/vc2017 wine cl $(WSRCS) $(WDEFS) $(WFLAGS)
|
|
||||||
vc2017: ARGS = https://cesanta.com
|
|
||||||
vc2017: $(PROG).exe
|
|
||||||
$(DOCKER) mdashnet/vc2017 wine $(PROG).exe $(ARGS)
|
|
||||||
mbedtls:
|
|
||||||
git clone --depth 1 -b v3.1.0 https://github.com/ARMmbed/mbedtls
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -rf $(PROG) _CL* *.o *.dSYM *.gcov *.gcno *.gcda *.obj *.exe *.ilk *.pdb mbedtls
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
See detailed tutorial at https://mongoose.ws/tutorials/http-client/
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../../test/data/ca.pem
|
|
||||||
@@ -1,72 +0,0 @@
|
|||||||
// Copyright (c) 2021 Cesanta Software Limited
|
|
||||||
// All rights reserved
|
|
||||||
//
|
|
||||||
// Example HTTP client. Connect to `s_url`, send request, wait for a response,
|
|
||||||
// print the response and exit.
|
|
||||||
// You can change `s_url` from the command line by executing: ./example YOUR_URL
|
|
||||||
//
|
|
||||||
// To enable SSL/TLS, make SSL=OPENSSL or make SSL=MBEDTLS
|
|
||||||
|
|
||||||
#include "mongoose.h"
|
|
||||||
|
|
||||||
// The very first web page in history. You can replace it from command line
|
|
||||||
static const char *s_url = "http://info.cern.ch/";
|
|
||||||
static const char *s_post_data = NULL; // POST data
|
|
||||||
static const uint64_t s_timeout_ms = 1500; // Connect timeout in milliseconds
|
|
||||||
|
|
||||||
// Print HTTP response and signal that we're done
|
|
||||||
static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
|
|
||||||
if (ev == MG_EV_OPEN) {
|
|
||||||
// Connection created. Store connect expiration time in c->data
|
|
||||||
*(uint64_t *) c->data = mg_millis() + s_timeout_ms;
|
|
||||||
} else if (ev == MG_EV_POLL) {
|
|
||||||
if (mg_millis() > *(uint64_t *) c->data &&
|
|
||||||
(c->is_connecting || c->is_resolving)) {
|
|
||||||
mg_error(c, "Connect timeout");
|
|
||||||
}
|
|
||||||
} else if (ev == MG_EV_CONNECT) {
|
|
||||||
// Connected to server. Extract host name from URL
|
|
||||||
struct mg_str host = mg_url_host(s_url);
|
|
||||||
|
|
||||||
// If s_url is https://, tell client connection to use TLS
|
|
||||||
if (mg_url_is_ssl(s_url)) {
|
|
||||||
struct mg_tls_opts opts = {.ca = "ca.pem", .srvname = host};
|
|
||||||
mg_tls_init(c, &opts);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Send request
|
|
||||||
int content_length = s_post_data ? strlen(s_post_data) : 0;
|
|
||||||
mg_printf(c,
|
|
||||||
"%s %s HTTP/1.0\r\n"
|
|
||||||
"Host: %.*s\r\n"
|
|
||||||
"Content-Type: octet-stream\r\n"
|
|
||||||
"Content-Length: %d\r\n"
|
|
||||||
"\r\n",
|
|
||||||
s_post_data ? "POST" : "GET", mg_url_uri(s_url), (int) host.len,
|
|
||||||
host.ptr, content_length);
|
|
||||||
mg_send(c, s_post_data, content_length);
|
|
||||||
} else if (ev == MG_EV_HTTP_MSG) {
|
|
||||||
// Response is received. Print it
|
|
||||||
struct mg_http_message *hm = (struct mg_http_message *) ev_data;
|
|
||||||
printf("%.*s", (int) hm->message.len, hm->message.ptr);
|
|
||||||
c->is_closing = 1; // Tell mongoose to close this connection
|
|
||||||
*(bool *) fn_data = true; // Tell event loop to stop
|
|
||||||
} else if (ev == MG_EV_ERROR) {
|
|
||||||
*(bool *) fn_data = true; // Error, tell event loop to stop
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
|
||||||
const char *log_level = getenv("LOG_LEVEL"); // Allow user to set log level
|
|
||||||
if (log_level == NULL) log_level = "4"; // Default is verbose
|
|
||||||
|
|
||||||
struct mg_mgr mgr; // Event manager
|
|
||||||
bool done = false; // Event handler flips it to true
|
|
||||||
if (argc > 1) s_url = argv[1]; // Use URL provided in the command line
|
|
||||||
mg_log_set(atoi(log_level)); // Set to 0 to disable debug
|
|
||||||
mg_mgr_init(&mgr); // Initialise event manager
|
|
||||||
mg_http_connect(&mgr, s_url, fn, &done); // Create client connection
|
|
||||||
while (!done) mg_mgr_poll(&mgr, 50); // Event manager loops until 'done'
|
|
||||||
mg_mgr_free(&mgr); // Free resources
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
PROG ?= example
|
|
||||||
ARGS ?= 167.235.63.238:3128 http://info.cern.ch/
|
|
||||||
SSL = ?
|
|
||||||
|
|
||||||
ifeq "$(SSL)" "MBEDTLS"
|
|
||||||
CFLAGS += -DMG_ENABLE_MBEDTLS=1 -lmbedtls -lmbedcrypto -lmbedx509
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq "$(SSL)" "OPENSSL"
|
|
||||||
CFLAGS += -DMG_ENABLE_OPENSSL=1 -lssl -lcrypto
|
|
||||||
endif
|
|
||||||
|
|
||||||
all: $(PROG)
|
|
||||||
$(DEBUGGER) ./$(PROG) $(ARGS)
|
|
||||||
|
|
||||||
|
|
||||||
$(PROG): main.c
|
|
||||||
$(CC) ../../mongoose.c -I../.. -W -Wall $(CFLAGS) $(EXTRA_CFLAGS) -o $(PROG) main.c
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -rf $(PROG) *.o *.dSYM *.gcov *.gcno *.gcda *.obj *.exe *.ilk *.pdb
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../../test/data/ca.pem
|
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
// Copyright (c) 2020 Cesanta Software Limited
|
|
||||||
// All rights reserved
|
|
||||||
//
|
|
||||||
// Example HTTP client that uses a proxy server. Usage:
|
|
||||||
// make
|
|
||||||
// ./example PROXY:PORT http://www.ladyada.net
|
|
||||||
//
|
|
||||||
// To enable SSL/TLS, make SSL=OPENSSL or make SSL=MBEDTLS
|
|
||||||
//
|
|
||||||
#include "mongoose.h"
|
|
||||||
|
|
||||||
// Print HTTP response and signal that we're done
|
|
||||||
static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
|
|
||||||
const char *url = fn_data;
|
|
||||||
static bool connected;
|
|
||||||
if (ev == MG_EV_HTTP_MSG) {
|
|
||||||
struct mg_http_message *hm = (struct mg_http_message *) ev_data;
|
|
||||||
printf("%.*s", (int) hm->message.len, hm->message.ptr);
|
|
||||||
exit(EXIT_SUCCESS);
|
|
||||||
} else if (ev == MG_EV_CONNECT) {
|
|
||||||
// Proxy TCP connection established. Send CONNECT request
|
|
||||||
struct mg_str host = mg_url_host(url);
|
|
||||||
// c->is_hexdumping = 1;
|
|
||||||
mg_printf(c, "CONNECT %.*s:%hu HTTP/1.1\r\nHost: %.*s:%hu\r\n\r\n",
|
|
||||||
(int) host.len, host.ptr, mg_url_port(url), (int) host.len,
|
|
||||||
host.ptr, mg_url_port(url));
|
|
||||||
// If target URL is SSL/TLS, command client connection to use TLS
|
|
||||||
if (mg_url_is_ssl(url)) {
|
|
||||||
struct mg_tls_opts opts = {.ca = "ca.pem"};
|
|
||||||
mg_tls_init(c, &opts);
|
|
||||||
}
|
|
||||||
} else if (!connected && ev == MG_EV_READ) {
|
|
||||||
struct mg_http_message hm;
|
|
||||||
int n = mg_http_parse((char *) c->recv.buf, c->recv.len, &hm);
|
|
||||||
if (n > 0) {
|
|
||||||
struct mg_str host = mg_url_host(url);
|
|
||||||
// CONNECT response - tunnel is established
|
|
||||||
connected = true;
|
|
||||||
MG_DEBUG(
|
|
||||||
("Connected to proxy, status: %.*s", (int) hm.uri.len, hm.uri.ptr));
|
|
||||||
mg_iobuf_del(&c->recv, 0, n);
|
|
||||||
// Send request to the target server
|
|
||||||
mg_printf(c, "GET %s HTTP/1.0\r\n"
|
|
||||||
"Host: %.*s\r\n"
|
|
||||||
"\r\n",
|
|
||||||
mg_url_uri(url), (int) host.len, host.ptr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
|
||||||
struct mg_mgr mgr;
|
|
||||||
|
|
||||||
if (argc != 3) {
|
|
||||||
fprintf(stderr, "Usage: %s PROXY_URL URL\n", argv[0]);
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
mg_mgr_init(&mgr); // Initialise event manager
|
|
||||||
mg_http_connect(&mgr, argv[1], fn, argv[2]); // Connect to the proxy
|
|
||||||
for (;;) mg_mgr_poll(&mgr, 1000); // Event loop
|
|
||||||
mg_mgr_free(&mgr);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
PROG ?= example
|
|
||||||
CFLAGS ?= -W -Wall -DMG_ENABLE_LINES=1
|
|
||||||
SSL = ?
|
|
||||||
|
|
||||||
ifeq "$(SSL)" "MBEDTLS"
|
|
||||||
CFLAGS += -DMG_ENABLE_MBEDTLS=1 -lmbedtls -lmbedcrypto -lmbedx509
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq "$(SSL)" "OPENSSL"
|
|
||||||
CFLAGS += -DMG_ENABLE_OPENSSL=1 -lssl -lcrypto
|
|
||||||
endif
|
|
||||||
|
|
||||||
all: $(PROG)
|
|
||||||
$(DEBUGGER) ./$(PROG) $(ARGS)
|
|
||||||
|
|
||||||
$(PROG): main.c
|
|
||||||
$(CC) ../../mongoose.c -I../.. $(CFLAGS) $(EFLAGS) -o $(PROG) main.c
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -rf $(PROG) *.o *.dSYM *.gcov *.gcno *.gcda *.obj *.exe *.ilk *.pdb
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../../test/data/ca.pem
|
|
||||||
@@ -1,66 +0,0 @@
|
|||||||
// Copyright (c) 2020 Cesanta Software Limited
|
|
||||||
// All rights reserved
|
|
||||||
//
|
|
||||||
// HTTP server example. This server serves both static and dynamic content.
|
|
||||||
// It opens two ports: plain HTTP on port 8000 and HTTP on port 8443.
|
|
||||||
// It implements the following endpoints:
|
|
||||||
// /api/stats - respond with free-formatted stats on current connections
|
|
||||||
// /api/f2/:id - wildcard example, respond with JSON string {"result": "URI"}
|
|
||||||
// any other URI serves static files from s_root_dir
|
|
||||||
//
|
|
||||||
// To enable SSL/TLS (using self-signed certificates in PEM files),
|
|
||||||
// 1. make SSL=OPENSSL or make SSL=MBEDTLS
|
|
||||||
// 2. curl -k https://127.0.0.1:8443
|
|
||||||
|
|
||||||
#include "mongoose.h"
|
|
||||||
|
|
||||||
static const char *s_http_addr = "http://0.0.0.0:8000"; // HTTP port
|
|
||||||
static const char *s_https_addr = "https://0.0.0.0:8443"; // HTTPS port
|
|
||||||
static const char *s_root_dir = ".";
|
|
||||||
|
|
||||||
// We use the same event handler function for HTTP and HTTPS connections
|
|
||||||
// fn_data is NULL for plain HTTP, and non-NULL for HTTPS
|
|
||||||
static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
|
|
||||||
if (ev == MG_EV_ACCEPT && fn_data != NULL) {
|
|
||||||
struct mg_tls_opts opts = {
|
|
||||||
//.ca = "ca.pem", // Uncomment to enable two-way SSL
|
|
||||||
.cert = "server.pem", // Certificate PEM file
|
|
||||||
.certkey = "server.pem", // This pem contains both cert and key
|
|
||||||
};
|
|
||||||
mg_tls_init(c, &opts);
|
|
||||||
} 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/stats")) {
|
|
||||||
// Print some statistics about currently established connections
|
|
||||||
mg_printf(c, "HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n");
|
|
||||||
mg_http_printf_chunk(c, "ID PROTO TYPE LOCAL REMOTE\n");
|
|
||||||
for (struct mg_connection *t = c->mgr->conns; t != NULL; t = t->next) {
|
|
||||||
mg_http_printf_chunk(c, "%-3lu %4s %s %I %I\n", t->id,
|
|
||||||
t->is_udp ? "UDP" : "TCP",
|
|
||||||
t->is_listening ? "LISTENING"
|
|
||||||
: t->is_accepted ? "ACCEPTED "
|
|
||||||
: "CONNECTED",
|
|
||||||
4, &t->loc.ip, 4, &t->rem.ip);
|
|
||||||
}
|
|
||||||
mg_http_printf_chunk(c, ""); // Don't forget the last empty chunk
|
|
||||||
} else if (mg_http_match_uri(hm, "/api/f2/*")) {
|
|
||||||
mg_http_reply(c, 200, "", "{\"result\": \"%.*s\"}\n", (int) hm->uri.len,
|
|
||||||
hm->uri.ptr);
|
|
||||||
} else {
|
|
||||||
struct mg_http_serve_opts opts = {.root_dir = s_root_dir};
|
|
||||||
mg_http_serve_dir(c, ev_data, &opts);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
(void) fn_data;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(void) {
|
|
||||||
struct mg_mgr mgr; // Event manager
|
|
||||||
mg_log_set(MG_LL_DEBUG); // Set log level
|
|
||||||
mg_mgr_init(&mgr); // Initialise event manager
|
|
||||||
mg_http_listen(&mgr, s_http_addr, fn, NULL); // Create HTTP listener
|
|
||||||
mg_http_listen(&mgr, s_https_addr, fn, (void *) 1); // HTTPS listener
|
|
||||||
for (;;) mg_mgr_poll(&mgr, 1000); // Infinite event loop
|
|
||||||
mg_mgr_free(&mgr);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
PROG ?= example
|
|
||||||
CFLAGS ?= -DMG_IO_SIZE=128
|
|
||||||
SSL = ?
|
|
||||||
|
|
||||||
ifeq "$(SSL)" "MBEDTLS"
|
|
||||||
CFLAGS += -DMG_ENABLE_MBEDTLS=1 -lmbedtls -lmbedcrypto -lmbedx509
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq "$(SSL)" "OPENSSL"
|
|
||||||
CFLAGS += -DMG_ENABLE_OPENSSL=1 -lssl -lcrypto
|
|
||||||
endif
|
|
||||||
|
|
||||||
all: $(PROG)
|
|
||||||
$(DEBUGGER) ./$(PROG) $(ARGS)
|
|
||||||
|
|
||||||
|
|
||||||
$(PROG): main.c
|
|
||||||
$(CC) ../../mongoose.c -I../.. -W -Wall $(CFLAGS) $(EXTRA_CFLAGS) -o $(PROG) main.c
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -rf $(PROG) *.o *.dSYM *.gcov *.gcno *.gcda *.obj *.exe *.ilk *.pdb
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../../test/data/ca.pem
|
|
||||||
@@ -1,85 +0,0 @@
|
|||||||
// Copyright (c) 2020 Cesanta Software Limited
|
|
||||||
// All rights reserved
|
|
||||||
//
|
|
||||||
// Example HTTP reverse proxy
|
|
||||||
// 1. Run `make`. This builds and starts a proxy on port 8000
|
|
||||||
// 2. Start your browser, go to https://localhost:8000
|
|
||||||
//
|
|
||||||
// To enable SSL/TLS, add SSL=OPENSSL or SSL=MBEDTLS
|
|
||||||
|
|
||||||
static const char *s_backend_url =
|
|
||||||
#if defined(MG_ENABLE_MBEDTLS) || defined(MG_ENABLE_OPENSSL)
|
|
||||||
"https://cesanta.com";
|
|
||||||
#else
|
|
||||||
"http://info.cern.ch";
|
|
||||||
#endif
|
|
||||||
static const char *s_listen_url = "http://localhost:8000";
|
|
||||||
|
|
||||||
#include "mongoose.h"
|
|
||||||
|
|
||||||
// Forward client request to the backend connection, rewriting the Host header
|
|
||||||
static void forward_request(struct mg_http_message *hm,
|
|
||||||
struct mg_connection *c) {
|
|
||||||
size_t i, max = sizeof(hm->headers) / sizeof(hm->headers[0]);
|
|
||||||
struct mg_str host = mg_url_host(s_backend_url);
|
|
||||||
mg_printf(c, "%.*s\r\n",
|
|
||||||
(int) (hm->proto.ptr + hm->proto.len - hm->message.ptr),
|
|
||||||
hm->message.ptr);
|
|
||||||
for (i = 0; i < max && hm->headers[i].name.len > 0; i++) {
|
|
||||||
struct mg_str *k = &hm->headers[i].name, *v = &hm->headers[i].value;
|
|
||||||
if (mg_strcmp(*k, mg_str("Host")) == 0) v = &host;
|
|
||||||
mg_printf(c, "%.*s: %.*s\r\n", (int) k->len, k->ptr, (int) v->len, v->ptr);
|
|
||||||
}
|
|
||||||
mg_send(c, "\r\n", 2);
|
|
||||||
mg_send(c, hm->body.ptr, hm->body.len);
|
|
||||||
MG_DEBUG(("FORWARDING: %.*s %.*s", (int) hm->method.len, hm->method.ptr,
|
|
||||||
(int) hm->uri.len, hm->uri.ptr));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void fn2(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
|
|
||||||
struct mg_connection *c2 = fn_data;
|
|
||||||
if (ev == MG_EV_READ) {
|
|
||||||
// All incoming data from the backend, forward to the client
|
|
||||||
if (c2 != NULL) mg_send(c2, c->recv.buf, c->recv.len);
|
|
||||||
mg_iobuf_del(&c->recv, 0, c->recv.len);
|
|
||||||
} else if (ev == MG_EV_CLOSE) {
|
|
||||||
if (c2 != NULL) c2->fn_data = NULL;
|
|
||||||
}
|
|
||||||
(void) ev_data;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
|
|
||||||
struct mg_connection *c2 = fn_data;
|
|
||||||
if (ev == MG_EV_HTTP_MSG) {
|
|
||||||
struct mg_http_message *hm = (struct mg_http_message *) ev_data;
|
|
||||||
// Client request, create backend connection Note that we're passing
|
|
||||||
// client connection `c` as fn_data for the created backend connection.
|
|
||||||
c2 = mg_connect(c->mgr, s_backend_url, fn2, c);
|
|
||||||
if (c2 == NULL) {
|
|
||||||
mg_error(c, "Cannot create backend connection");
|
|
||||||
} else {
|
|
||||||
if (mg_url_is_ssl(s_backend_url)) {
|
|
||||||
struct mg_tls_opts opts = {.ca = "ca.pem"};
|
|
||||||
mg_tls_init(c2, &opts);
|
|
||||||
}
|
|
||||||
c->fn_data = c2;
|
|
||||||
forward_request(hm, c2);
|
|
||||||
c2->is_hexdumping = 1;
|
|
||||||
}
|
|
||||||
} else if (ev == MG_EV_CLOSE) {
|
|
||||||
if (c2 != NULL) c2->is_closing = 1;
|
|
||||||
if (c2 != NULL) c2->fn_data = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(void) {
|
|
||||||
struct mg_mgr mgr;
|
|
||||||
|
|
||||||
mg_log_set(MG_LL_DEBUG); // Set log level
|
|
||||||
mg_mgr_init(&mgr); // Initialise event manager
|
|
||||||
mg_http_listen(&mgr, s_listen_url, fn, NULL); // Start proxy
|
|
||||||
for (;;) mg_mgr_poll(&mgr, 1000); // Event loop
|
|
||||||
mg_mgr_free(&mgr);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
PROG ?= example
|
|
||||||
ROOT ?= $(realpath $(CURDIR)/../..)
|
|
||||||
DEFS ?= -DMG_ENABLE_LINES=1 -DMG_ENABLE_IPV6=1 -DMG_ENABLE_SSI=1 -DMG_HTTP_DIRLIST_TIME=1
|
|
||||||
CFLAGS ?= -I../.. -W -Wall $(DEFS) $(EXTRA)
|
|
||||||
VCFLAGS = /nologo /W3 /O2 /I../.. $(DEFS) $(EXTRA) /link /incremental:no /machine:IX86
|
|
||||||
VC98 = docker run -it --rm -e Tmp=. -v $(ROOT):$(ROOT) -w $(CURDIR) mdashnet/vc98
|
|
||||||
|
|
||||||
all: $(PROG)
|
|
||||||
$(RUN) ./$(PROG) $(ARGS)
|
|
||||||
|
|
||||||
$(PROG): main.c Makefile
|
|
||||||
$(CC) ../../mongoose.c main.c -I../.. $(CFLAGS) -o $@
|
|
||||||
|
|
||||||
mongoose.exe: main.c
|
|
||||||
$(VC98) wine cl ../../mongoose.c main.c $(VCFLAGS) ws2_32.lib /out:$@
|
|
||||||
|
|
||||||
mingw:
|
|
||||||
gcc ../../mongoose.c main.c -I../.. -W -Wall $(DEFS) -D_POSIX_C_SOURCE=200000L -lws2_32 -o mongoose.exe
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -rf $(PROG) *.o *.dSYM *.gcov *.gcno *.gcda *.obj *.exe *.ilk *.pdb mongoose mongoose_* mongoose.*
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
See detailed tutorial at https://mongoose.ws/tutorials/http-server/
|
|
||||||
@@ -1,103 +0,0 @@
|
|||||||
// Copyright (c) 2020 Cesanta Software Limited
|
|
||||||
// All rights reserved
|
|
||||||
|
|
||||||
#include <signal.h>
|
|
||||||
#include "mongoose.h"
|
|
||||||
|
|
||||||
static int s_debug_level = MG_LL_INFO;
|
|
||||||
static const char *s_root_dir = ".";
|
|
||||||
static const char *s_listening_address = "http://0.0.0.0:8000";
|
|
||||||
static const char *s_enable_hexdump = "no";
|
|
||||||
static const char *s_ssi_pattern = "#.html";
|
|
||||||
|
|
||||||
// Handle interrupts, like Ctrl-C
|
|
||||||
static int s_signo;
|
|
||||||
static void signal_handler(int signo) {
|
|
||||||
s_signo = signo;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Event handler for the listening connection.
|
|
||||||
// Simply serve static files from `s_root_dir`
|
|
||||||
static void cb(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
|
|
||||||
if (ev == MG_EV_HTTP_MSG) {
|
|
||||||
struct mg_http_message *hm = ev_data, tmp = {0};
|
|
||||||
struct mg_str unknown = mg_str_n("?", 1), *cl;
|
|
||||||
struct mg_http_serve_opts opts = {0};
|
|
||||||
opts.root_dir = s_root_dir;
|
|
||||||
opts.ssi_pattern = s_ssi_pattern;
|
|
||||||
mg_http_serve_dir(c, hm, &opts);
|
|
||||||
mg_http_parse((char *) c->send.buf, c->send.len, &tmp);
|
|
||||||
cl = mg_http_get_header(&tmp, "Content-Length");
|
|
||||||
if (cl == NULL) cl = &unknown;
|
|
||||||
MG_INFO(("%.*s %.*s %.*s %.*s", (int) hm->method.len, hm->method.ptr,
|
|
||||||
(int) hm->uri.len, hm->uri.ptr, (int) tmp.uri.len, tmp.uri.ptr,
|
|
||||||
(int) cl->len, cl->ptr));
|
|
||||||
}
|
|
||||||
(void) fn_data;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void usage(const char *prog) {
|
|
||||||
fprintf(stderr,
|
|
||||||
"Mongoose v.%s\n"
|
|
||||||
"Usage: %s OPTIONS\n"
|
|
||||||
" -H yes|no - enable traffic hexdump, default: '%s'\n"
|
|
||||||
" -S PAT - SSI filename pattern, default: '%s'\n"
|
|
||||||
" -d DIR - directory to serve, default: '%s'\n"
|
|
||||||
" -l ADDR - listening address, default: '%s'\n"
|
|
||||||
" -v LEVEL - debug level, from 0 to 4, default: %d\n",
|
|
||||||
MG_VERSION, prog, s_enable_hexdump, s_ssi_pattern, s_root_dir,
|
|
||||||
s_listening_address, s_debug_level);
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
|
||||||
char path[MG_PATH_MAX] = ".";
|
|
||||||
struct mg_mgr mgr;
|
|
||||||
struct mg_connection *c;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
// Parse command-line flags
|
|
||||||
for (i = 1; i < argc; i++) {
|
|
||||||
if (strcmp(argv[i], "-d") == 0) {
|
|
||||||
s_root_dir = argv[++i];
|
|
||||||
} else if (strcmp(argv[i], "-H") == 0) {
|
|
||||||
s_enable_hexdump = argv[++i];
|
|
||||||
} else if (strcmp(argv[i], "-S") == 0) {
|
|
||||||
s_ssi_pattern = argv[++i];
|
|
||||||
} else if (strcmp(argv[i], "-l") == 0) {
|
|
||||||
s_listening_address = argv[++i];
|
|
||||||
} else if (strcmp(argv[i], "-v") == 0) {
|
|
||||||
s_debug_level = atoi(argv[++i]);
|
|
||||||
} else {
|
|
||||||
usage(argv[0]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Root directory must not contain double dots. Make it absolute
|
|
||||||
// Do the conversion only if the root dir spec does not contain overrides
|
|
||||||
if (strchr(s_root_dir, ',') == NULL) {
|
|
||||||
realpath(s_root_dir, path);
|
|
||||||
s_root_dir = path;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialise stuff
|
|
||||||
signal(SIGINT, signal_handler);
|
|
||||||
signal(SIGTERM, signal_handler);
|
|
||||||
mg_log_set(s_debug_level);
|
|
||||||
mg_mgr_init(&mgr);
|
|
||||||
if ((c = mg_http_listen(&mgr, s_listening_address, cb, &mgr)) == NULL) {
|
|
||||||
MG_ERROR(("Cannot listen on %s. Use http://ADDR:PORT or :PORT",
|
|
||||||
s_listening_address));
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
if (mg_casecmp(s_enable_hexdump, "yes") == 0) c->is_hexdumping = 1;
|
|
||||||
|
|
||||||
// Start infinite event loop
|
|
||||||
MG_INFO(("Mongoose version : v%s", MG_VERSION));
|
|
||||||
MG_INFO(("Listening on : %s", s_listening_address));
|
|
||||||
MG_INFO(("Web root : [%s]", s_root_dir));
|
|
||||||
while (s_signo == 0) mg_mgr_poll(&mgr, 1000);
|
|
||||||
mg_mgr_free(&mgr);
|
|
||||||
MG_INFO(("Exiting on signal %d", s_signo));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
PROG ?= example
|
|
||||||
CFLAGS ?= -DMG_ENABLE_LINES $(EXTRA)
|
|
||||||
|
|
||||||
ifneq ($(MBEDTLS),)
|
|
||||||
CFLAGS += -DMG_ENABLE_MBEDTLS=1 -I$(MBEDTLS)/include -I/usr/include
|
|
||||||
CFLAGS += -L$(MBEDTLS)/lib -lmbedtls -lmbedcrypto -lmbedx509
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifneq ($(OPENSSL),)
|
|
||||||
CFLAGS += -DMG_ENABLE_OPENSSL=1 -I$(OPENSSL)/include
|
|
||||||
CFLAGS += -L$(OPENSSL)/lib -lssl -lcrypto
|
|
||||||
endif
|
|
||||||
|
|
||||||
all: $(PROG)
|
|
||||||
$(DEBUGGER) ./$(PROG) $(ARGS)
|
|
||||||
|
|
||||||
|
|
||||||
$(PROG): main.c
|
|
||||||
$(CC) ../../mongoose.c -I../.. -W -Wall $(CFLAGS) -o $(PROG) main.c
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -rf $(PROG) *.o *.dSYM *.gcov *.gcno *.gcda *.obj *.exe *.ilk *.pdb
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../../test/data/ca.pem
|
|
||||||
@@ -1,70 +0,0 @@
|
|||||||
// Copyright (c) 2021 Cesanta Software Limited
|
|
||||||
// All rights reserved
|
|
||||||
//
|
|
||||||
// Example HTTP client.
|
|
||||||
// Instead of buffering the whole HTTP response in memory and wait for the
|
|
||||||
// MG_EV_HTTP_MSG event, this client catches MG_EV_HTTP_CHUNK events and
|
|
||||||
// prints them. This is useful to download large content without spooling
|
|
||||||
// everything to memory, or catch chunked content.
|
|
||||||
//
|
|
||||||
// You can change `s_url` from the command line by executing: ./example YOUR_URL
|
|
||||||
//
|
|
||||||
// To enable SSL/TLS for this client, build it like this:
|
|
||||||
// make MBEDTLS=/path/to/your/mbedtls/installation
|
|
||||||
// make OPENSSL=/path/to/your/openssl/installation
|
|
||||||
|
|
||||||
#include "mongoose.h"
|
|
||||||
|
|
||||||
// The very first web page in history. You can replace it from command line
|
|
||||||
static const char *s_url = "http://info.cern.ch";
|
|
||||||
|
|
||||||
// Print HTTP response and signal that we're done
|
|
||||||
static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
|
|
||||||
if (ev == MG_EV_CONNECT) {
|
|
||||||
// Connected to server. Extract host name from URL
|
|
||||||
struct mg_str host = mg_url_host(s_url);
|
|
||||||
|
|
||||||
// If s_url is https://, tell client connection to use TLS
|
|
||||||
if (mg_url_is_ssl(s_url)) {
|
|
||||||
struct mg_tls_opts opts = {.ca = "ca.pem", .srvname = host};
|
|
||||||
mg_tls_init(c, &opts);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Send request
|
|
||||||
mg_printf(c,
|
|
||||||
"GET %s HTTP/1.1\r\n"
|
|
||||||
"Connection: keep-alive\r\n"
|
|
||||||
"Keep-Alive: timeout=60\r\n"
|
|
||||||
"Host: %.*s\r\n"
|
|
||||||
"\r\n",
|
|
||||||
mg_url_uri(s_url), (int) host.len, host.ptr);
|
|
||||||
} else if (ev == MG_EV_HTTP_CHUNK) {
|
|
||||||
struct mg_http_message *hm = (struct mg_http_message *) ev_data;
|
|
||||||
fwrite(hm->chunk.ptr, 1, hm->chunk.len, stdout);
|
|
||||||
// fprintf(stderr, "c %u\n", (unsigned) hm->chunk.len);
|
|
||||||
mg_http_delete_chunk(c, hm);
|
|
||||||
if (hm->chunk.len == 0) *(bool *) fn_data = true; // Last chunk
|
|
||||||
} else if (ev == MG_EV_HTTP_MSG) {
|
|
||||||
// Response is received. Print it
|
|
||||||
struct mg_http_message *hm = (struct mg_http_message *) ev_data;
|
|
||||||
fwrite(hm->body.ptr, 1, hm->body.len, stdout);
|
|
||||||
c->is_closing = 1; // Tell mongoose to close this connection
|
|
||||||
*(bool *) fn_data = true; // Tell event loop to stop
|
|
||||||
} else if (ev == MG_EV_ERROR) {
|
|
||||||
*(bool *) fn_data = true; // Error, tell event loop to stop
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
|
||||||
struct mg_mgr mgr; // Event manager
|
|
||||||
bool done = false; // Event handler flips it to true
|
|
||||||
const char *log_level = getenv("V"); // Log level
|
|
||||||
if (log_level == NULL) log_level = "3"; // If not set, set to DEBUG
|
|
||||||
mg_log_set(atoi(log_level)); // Set to 0 to disable debug log
|
|
||||||
if (argc > 1) s_url = argv[1]; // Use URL from command line
|
|
||||||
mg_mgr_init(&mgr); // Initialise event manager
|
|
||||||
mg_http_connect(&mgr, s_url, fn, &done); // Create client connection
|
|
||||||
while (!done) mg_mgr_poll(&mgr, 1000); // Infinite event loop
|
|
||||||
mg_mgr_free(&mgr); // Free resources
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
PROG ?= example
|
|
||||||
CFLAGS ?= -W -Wall -Wextra -O0 -g
|
|
||||||
|
|
||||||
all: $(PROG)
|
|
||||||
$(RUN) ./$(PROG) $(ARGS)
|
|
||||||
|
|
||||||
$(PROG): main.c
|
|
||||||
$(CC) ../../mongoose.c -I../.. -W -Wall -DMG_ENABLE_LINES=1 $(CFLAGS) -o $(PROG) main.c
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -rf $(PROG) *.o *.dSYM *.gcov *.gcno *.gcda *.obj *.exe *.ilk *.pdb
|
|
||||||
@@ -1,89 +0,0 @@
|
|||||||
// Copyright (c) 2021 Cesanta Software Limited
|
|
||||||
// All rights reserved
|
|
||||||
//
|
|
||||||
// Example that demonstrates how to send a large responses with limited memory.
|
|
||||||
// We're going to send a JSON array of many integer values, s_data.
|
|
||||||
// The idea is to send a response in small chunks, and let the client request
|
|
||||||
// the next chunk.
|
|
||||||
// Periodically, s_data changes, which is tracked by s_version.
|
|
||||||
// Client requests a range and a version, to ensure data integrity.
|
|
||||||
//
|
|
||||||
// 1. Start this server, type `make`
|
|
||||||
// 2. Open http://localhost:8000 in your browser
|
|
||||||
|
|
||||||
#include "mongoose.h"
|
|
||||||
|
|
||||||
static const char *s_listen_on = "http://localhost:8000";
|
|
||||||
static const char *s_root_dir = "web_root";
|
|
||||||
|
|
||||||
#define DATA_SIZE 10000 // Total number of elements
|
|
||||||
#define CHUNK_SIZE 100 // Max number returned in one API call
|
|
||||||
static int s_data[DATA_SIZE]; // Simulate some complex big data
|
|
||||||
static long s_version = 0; // Data "version"
|
|
||||||
|
|
||||||
static long getparam(struct mg_http_message *hm, const char *json_path) {
|
|
||||||
double dv = 0;
|
|
||||||
mg_json_get_num(hm->body, json_path, &dv);
|
|
||||||
return dv;
|
|
||||||
}
|
|
||||||
|
|
||||||
static size_t printdata(mg_pfn_t out, void *ptr, va_list *ap) {
|
|
||||||
unsigned start = va_arg(*ap, unsigned);
|
|
||||||
unsigned max = start + CHUNK_SIZE;
|
|
||||||
const char *comma = "";
|
|
||||||
size_t n = 0;
|
|
||||||
if (max > DATA_SIZE) max = DATA_SIZE;
|
|
||||||
while (start < max) {
|
|
||||||
n += mg_xprintf(out, ptr, "%s%d", comma, s_data[start]);
|
|
||||||
comma = ",";
|
|
||||||
start++;
|
|
||||||
}
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
|
|
||||||
if (ev == MG_EV_HTTP_MSG) {
|
|
||||||
struct mg_http_message *hm = ev_data;
|
|
||||||
if (mg_http_match_uri(hm, "/api/data")) {
|
|
||||||
const char *headers = "content-type: text/json\r\n";
|
|
||||||
long start = getparam(hm, "$.start");
|
|
||||||
long version = getparam(hm, "$.version");
|
|
||||||
MG_DEBUG(("%.*s", (int) hm->body.len, hm->body.ptr));
|
|
||||||
if (version > 0 && version != s_version) {
|
|
||||||
// Version mismatch: s_data has changed while client fetches it
|
|
||||||
// Tell client to restart
|
|
||||||
mg_http_reply(c, 200, headers, "{%Q:%Q, %Q:%ld}", "error",
|
|
||||||
"wrong version", "version", version);
|
|
||||||
} else {
|
|
||||||
// Return data, up to CHUNK_SIZE elements
|
|
||||||
mg_http_reply(c, 200, headers, "{%Q:%ld,%Q:%ld,%Q:[%M]}", "version",
|
|
||||||
s_version, "start", start, "data", printdata, start);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
struct mg_http_serve_opts opts = {0};
|
|
||||||
opts.root_dir = s_root_dir;
|
|
||||||
mg_http_serve_dir(c, hm, &opts);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
(void) fn_data;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void timer_fn(void *arg) {
|
|
||||||
for (int i = 0; i < DATA_SIZE; i++) {
|
|
||||||
s_data[i] = rand();
|
|
||||||
}
|
|
||||||
s_version++;
|
|
||||||
(void) arg;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(void) {
|
|
||||||
struct mg_mgr mgr;
|
|
||||||
mg_mgr_init(&mgr);
|
|
||||||
srand(time(NULL));
|
|
||||||
mg_timer_add(&mgr, 5000, MG_TIMER_REPEAT | MG_TIMER_RUN_NOW, timer_fn, NULL);
|
|
||||||
mg_http_listen(&mgr, s_listen_on, fn, NULL);
|
|
||||||
MG_INFO(("Listening on %s", s_listen_on));
|
|
||||||
for (;;) mg_mgr_poll(&mgr, 1000);
|
|
||||||
mg_mgr_free(&mgr);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
NAME ?= $(notdir $(CURDIR))
|
|
||||||
|
|
||||||
build:
|
|
||||||
git clone --depth 1 https://github.com/mongoose-examples/$(NAME)
|
|
||||||
cp ./../../../mongoose.[ch] $(NAME)
|
|
||||||
make -C $(NAME) build
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -rf $(NAME)
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
PROG ?= example
|
|
||||||
|
|
||||||
all: $(PROG)
|
|
||||||
$(DEBUGGER) ./$(PROG) $(ARGS)
|
|
||||||
|
|
||||||
$(PROG): main.c
|
|
||||||
$(CC) main.c ../../mongoose.c -I../.. -W -Wall -DMG_ENABLE_LINES=1 $(CFLAGS) -o $(PROG)
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -rf $(PROG) *.o *.dSYM *.gcov *.gcno *.gcda *.obj *.exe *.ilk *.pdb
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
See detailed tutorial at https://mongoose.ws/tutorials/json-rpc-over-websocket/
|
|
||||||
@@ -1,84 +0,0 @@
|
|||||||
// Copyright (c) 2020 Cesanta Software Limited
|
|
||||||
// All rights reserved
|
|
||||||
//
|
|
||||||
// See https://mongoose.ws/tutorials/json-rpc-over-websocket/
|
|
||||||
|
|
||||||
#include "mongoose.h"
|
|
||||||
|
|
||||||
static const char *s_listen_on = "ws://localhost:8000";
|
|
||||||
static const char *s_web_root = "web_root";
|
|
||||||
static struct mg_rpc *s_rpc_head = NULL;
|
|
||||||
|
|
||||||
static void rpc_sum(struct mg_rpc_req *r) {
|
|
||||||
double a = 0.0, b = 0.0;
|
|
||||||
mg_json_get_num(r->frame, "$.params[0]", &a);
|
|
||||||
mg_json_get_num(r->frame, "$.params[1]", &b);
|
|
||||||
mg_rpc_ok(r, "%g", a + b);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void rpc_mul(struct mg_rpc_req *r) {
|
|
||||||
double a = 0.0, b = 0.0;
|
|
||||||
mg_json_get_num(r->frame, "$.params[0]", &a);
|
|
||||||
mg_json_get_num(r->frame, "$.params[1]", &b);
|
|
||||||
mg_rpc_ok(r, "%g", a * b);
|
|
||||||
}
|
|
||||||
|
|
||||||
// This RESTful server implements the following endpoints:
|
|
||||||
// /websocket - upgrade to Websocket, and implement websocket echo server
|
|
||||||
// any other URI serves static files from s_web_root
|
|
||||||
static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
|
|
||||||
if (ev == MG_EV_OPEN) {
|
|
||||||
// c->is_hexdumping = 1;
|
|
||||||
} else if (ev == MG_EV_WS_OPEN) {
|
|
||||||
c->data[0] = 'W'; // Mark this connection as an established WS client
|
|
||||||
} else if (ev == MG_EV_HTTP_MSG) {
|
|
||||||
struct mg_http_message *hm = (struct mg_http_message *) ev_data;
|
|
||||||
if (mg_http_match_uri(hm, "/websocket")) {
|
|
||||||
// Upgrade to websocket. From now on, a connection is a full-duplex
|
|
||||||
// Websocket connection, which will receive MG_EV_WS_MSG events.
|
|
||||||
mg_ws_upgrade(c, hm, NULL);
|
|
||||||
} else {
|
|
||||||
// Serve static files
|
|
||||||
struct mg_http_serve_opts opts = {.root_dir = s_web_root};
|
|
||||||
mg_http_serve_dir(c, ev_data, &opts);
|
|
||||||
}
|
|
||||||
} else if (ev == MG_EV_WS_MSG) {
|
|
||||||
// Got websocket frame. Received data is wm->data
|
|
||||||
struct mg_ws_message *wm = (struct mg_ws_message *) ev_data;
|
|
||||||
struct mg_iobuf io = {0, 0, 0, 512};
|
|
||||||
struct mg_rpc_req r = {&s_rpc_head, 0, mg_pfn_iobuf, &io, 0, wm->data};
|
|
||||||
mg_rpc_process(&r);
|
|
||||||
if (io.buf) mg_ws_send(c, (char *) io.buf, io.len, WEBSOCKET_OP_TEXT);
|
|
||||||
mg_iobuf_free(&io);
|
|
||||||
}
|
|
||||||
(void) fn_data;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void timer_fn(void *arg) {
|
|
||||||
struct mg_mgr *mgr = (struct mg_mgr *) arg;
|
|
||||||
// Broadcast message to all connected websocket clients.
|
|
||||||
for (struct mg_connection *c = mgr->conns; c != NULL; c = c->next) {
|
|
||||||
if (c->data[0] != 'W') continue;
|
|
||||||
mg_ws_printf(c, WEBSOCKET_OP_TEXT, "{%Q:%Q,%Q:[%d,%d,%d]}", "method",
|
|
||||||
"notification1", "params", 1, 2, 3);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(void) {
|
|
||||||
struct mg_mgr mgr; // Event manager
|
|
||||||
mg_mgr_init(&mgr); // Init event manager
|
|
||||||
mg_log_set(MG_LL_DEBUG); // Set log level
|
|
||||||
mg_timer_add(&mgr, 5000, MG_TIMER_REPEAT, timer_fn, &mgr); // Init timer
|
|
||||||
|
|
||||||
// Configure JSON-RPC functions we're going to handle
|
|
||||||
mg_rpc_add(&s_rpc_head, mg_str("sum"), rpc_sum, NULL);
|
|
||||||
mg_rpc_add(&s_rpc_head, mg_str("mul"), rpc_mul, NULL);
|
|
||||||
mg_rpc_add(&s_rpc_head, mg_str("rpc.list"), mg_rpc_list, &s_rpc_head);
|
|
||||||
|
|
||||||
printf("Starting WS listener on %s/websocket\n", s_listen_on);
|
|
||||||
mg_http_listen(&mgr, s_listen_on, fn, NULL); // Create HTTP listener
|
|
||||||
for (;;) mg_mgr_poll(&mgr, 1000); // Infinite event loop
|
|
||||||
mg_mgr_free(&mgr); // Deallocate event manager
|
|
||||||
mg_rpc_del(&s_rpc_head, NULL); // Deallocate RPC handlers
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
PROG ?= example
|
|
||||||
|
|
||||||
all: $(PROG)
|
|
||||||
$(DEBUGGER) ./$(PROG)
|
|
||||||
|
|
||||||
$(PROG):
|
|
||||||
$(CC) ../../mongoose.c -I../.. $(CFLAGS) $(EXTRA) -o $(PROG) main.c
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -rf $(PROG) *.o *.dSYM *.gcov *.gcno *.gcda *.obj *.exe *.ilk *.pdb log.txt
|
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
// Copyright (c) 2020 Cesanta Software Limited
|
|
||||||
// All rights reserved
|
|
||||||
|
|
||||||
#include "mongoose.h"
|
|
||||||
|
|
||||||
// HTTP request handler function. It implements the following endpoints:
|
|
||||||
// /api/log/static - returns contents of log.txt file
|
|
||||||
// /api/log/live - hangs forever, and returns live log messages
|
|
||||||
// all other URI - serves web_root/ directory
|
|
||||||
static void cb(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
|
|
||||||
if (ev == MG_EV_HTTP_MSG) {
|
|
||||||
struct mg_http_message *hm = (struct mg_http_message *) ev_data;
|
|
||||||
if (mg_http_match_uri(hm, "/api/log/static")) {
|
|
||||||
struct mg_http_serve_opts opts = {.root_dir = NULL};
|
|
||||||
mg_http_serve_file(c, hm, "log.txt", &opts);
|
|
||||||
} else if (mg_http_match_uri(hm, "/api/log/live")) {
|
|
||||||
c->data[0] = 'L'; // Mark that connection as live log listener
|
|
||||||
mg_printf(c, "HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n");
|
|
||||||
} else {
|
|
||||||
struct mg_http_serve_opts opts = {.root_dir = "web_root"};
|
|
||||||
mg_http_serve_dir(c, ev_data, &opts);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void log_message(const char *filename, const char *message) {
|
|
||||||
FILE *fp = fopen(filename, "a");
|
|
||||||
if (fp != NULL) {
|
|
||||||
fprintf(fp, "%s", message);
|
|
||||||
fclose(fp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void broadcast_message(struct mg_mgr *mgr, const char *message) {
|
|
||||||
struct mg_connection *c;
|
|
||||||
for (c = mgr->conns; c != NULL; c = c->next) {
|
|
||||||
if (c->data[0] == 'L') mg_http_printf_chunk(c, "%s", message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Timer function - called periodically.
|
|
||||||
// Prepare log message. Save it to a file, and broadcast.
|
|
||||||
static void timer_fn(void *arg) {
|
|
||||||
char buf[64];
|
|
||||||
snprintf(buf, sizeof(buf), "Time is: %lu\n", (unsigned long) time(NULL));
|
|
||||||
log_message("log.txt", buf);
|
|
||||||
broadcast_message(arg, buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(void) {
|
|
||||||
struct mg_mgr mgr;
|
|
||||||
|
|
||||||
mg_mgr_init(&mgr);
|
|
||||||
mg_http_listen(&mgr, "http://localhost:8000", cb, NULL);
|
|
||||||
mg_timer_add(&mgr, 1000, MG_TIMER_REPEAT, timer_fn, &mgr);
|
|
||||||
|
|
||||||
for (;;) mg_mgr_poll(&mgr, 50);
|
|
||||||
mg_mgr_free(&mgr);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
PROG ?= example
|
|
||||||
DEFS ?= -DMG_ENABLE_LINES=1 -DMG_ENABLE_MIP=1 -DMG_ENABLE_SOCKET=0 -DMG_ENABLE_PACKED_FS=1 -I../..
|
|
||||||
CFLAGS ?= -W -Wall $(EXTRA_CFLAGS)
|
|
||||||
LIBS ?= -lpcap
|
|
||||||
SOURCES = main.c ../../mongoose.c ../device-dashboard/net.c ../device-dashboard/packed_fs.c
|
|
||||||
|
|
||||||
ifeq "$(SSL)" "MBEDTLS"
|
|
||||||
CFLAGS += -DMG_ENABLE_MBEDTLS=1 -lmbedtls -lmbedcrypto -lmbedx509 -I$(MBEDTLS)/include -L$(MBEDTLS)/lib
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq "$(SSL)" "OPENSSL"
|
|
||||||
CFLAGS += -DMG_ENABLE_OPENSSL=1 -lssl -lcrypto -I$(OPENSSL)/include -L$(OPENSSL)/lib
|
|
||||||
endif
|
|
||||||
|
|
||||||
all: $(PROG)
|
|
||||||
$(RUN) ./$(PROG) $(ARGS)
|
|
||||||
|
|
||||||
$(PROG): main.c
|
|
||||||
$(CC) $(SOURCES) $(CFLAGS) $(DEFS) -o $(PROG) $(LIBS)
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -rf $(PROG) *.o *.dSYM *.gcov *.gcno *.gcda *.obj *.exe *.ilk *.pdb
|
|
||||||
@@ -1,246 +0,0 @@
|
|||||||
# MIP TCP / IP stack over pcap
|
|
||||||
|
|
||||||
This example allows to use Mongoose's MIP built-in TCP/IP stack on systems
|
|
||||||
that support pcap API, i.e. have libpcap library installed. The application
|
|
||||||
opens an interface and uses `pcap_next_ex()` for reading packets from the
|
|
||||||
interface, and `pcap_inject()` to write packets to the interface.
|
|
||||||
|
|
||||||
NOTE: depending on the libcap implementation, the injected packets may
|
|
||||||
or may not be looped back to the interface's TCP/IP stack. If they are
|
|
||||||
not looped back, then it is necessary to create a separate interface that
|
|
||||||
is bridged to the target interface - see MacOS example below.
|
|
||||||
|
|
||||||
## MacOS setup
|
|
||||||
|
|
||||||
MacOS has support for `feth` (fake ethernet) interfaces. One can create a pair
|
|
||||||
of `feth` interfaces and interlink them. Once a `feth` interface is assigned
|
|
||||||
a peer and an IP address, anything that gets injected to it, appears on a
|
|
||||||
peer interface and vice versa.
|
|
||||||
|
|
||||||
```sh
|
|
||||||
$ sudo ifconfig feth0 create
|
|
||||||
$ sudo ifconfig feth1 create
|
|
||||||
$ sudo ifconfig feth1 peer feth0 # Link two fake ethernet ifaces together
|
|
||||||
$ sudo ifconfig feth1 10.10 # Assign 10.0.0.10 to feth1
|
|
||||||
$ sudo ifconfig feth0 up
|
|
||||||
$ sudo ifconfig feth1 up
|
|
||||||
```
|
|
||||||
|
|
||||||
Now we have two Ethernet interfaces, `feth0` and `feth1`, interlinked and
|
|
||||||
active. On your Mac, go to "System Preferences" / Sharing, enable "Internet
|
|
||||||
Sharing" and choose "Thunderbolt bridge". This enables DHCP on the `bridge0`
|
|
||||||
interface, which is bridge for all Thunderbolt devices, and adds necessary
|
|
||||||
routes to the WiFi interface. On my system it gets `192.168.2.1` IP address,
|
|
||||||
and serves `192.168.2/24` net. We should add one of our fake interfaces to
|
|
||||||
this bridge:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
$ sudo ifconfig bridge0 addm feth1
|
|
||||||
```
|
|
||||||
|
|
||||||
We can start an example using the `feth0`:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
$ make -C examples/mip-pcap/ clean all ARGS="-i feth0"
|
|
||||||
...
|
|
||||||
2386718 3 mip.c:279:arp_cache_add ARP cache: added 0xc0a80201 @ 36:77:4d:be:e0:80
|
|
||||||
2386718 2 mip.c:300:onstatechange READY, IP: 192.168.2.17
|
|
||||||
```
|
|
||||||
|
|
||||||
The diagram of the setup is below:
|
|
||||||
|
|
||||||
```
|
|
||||||
┌──────────► 192.168.2.1 bridge0
|
|
||||||
│ routing DHCP │
|
|
||||||
│ ┌──────────────────┴──────────────────┐
|
|
||||||
▼ │ │ 192.168.2.17
|
|
||||||
│ ┌─────────┐ fake ethernet pair ┌─────────┐
|
|
||||||
192.168.0.10 │ │ feth1 ├────────────┬───────┤ feth0 │
|
|
||||||
┌─────────┐ │ └─────────┘ │ └────┬────┘
|
|
||||||
│ en0 │ │ │ │
|
|
||||||
└────┬────┘ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │
|
|
||||||
│ │ │ en1 │ │ en2 │ │ en3 │ │ mip-pcap
|
|
||||||
│ └────┬────┘ └────┬────┘ └────┬────┘ │
|
|
||||||
WiFi │ │ │ │ │
|
|
||||||
└──────┼───────────┼───────────┼──────┘
|
|
||||||
│ │ │ │
|
|
||||||
▼
|
|
||||||
Internet Thunderbolt Ethernet
|
|
||||||
```
|
|
||||||
|
|
||||||
## Linux setup
|
|
||||||
|
|
||||||
The quick and simple options are:
|
|
||||||
|
|
||||||
- Open your loopback device (probably `lo`), in which case MIP is only reachable from your machine, and MIP also sees echoes of its own traffic.
|
|
||||||
- Open your Ethernet/WiFi device (probably `eth0` or `enpXsY` for Ethernet), in which case MIP can access the network and the Internet but is not reachable from within your machine
|
|
||||||
- If you happen to have a virtual bridge interface (for linking several virtual machines together, for example) (probably `br0` or `virbr0`), you can open it, but it will behave as opening the underlying physical interface.
|
|
||||||
|
|
||||||
For best results, you should create a virtual interface, which you can use as is, attach to a virtual bridge, or forward/masquerade its traffic.
|
|
||||||
|
|
||||||
```sh
|
|
||||||
$ sudo ip link add my0 type veth peer [name] my1
|
|
||||||
$ sudo ip link set my0 up
|
|
||||||
$ sudo ip link set my1 up
|
|
||||||
```
|
|
||||||
|
|
||||||
In some systems, like for example RHEL7, _name_ is mandatory; in others you might need not to add it, that is why we represented it here using square brackets.
|
|
||||||
|
|
||||||
### Use a virtual interface
|
|
||||||
|
|
||||||
This is similar to using the loopback device, MIP is only reachable from the hosting machine, but you can add forwarding and masquerading later. Once you have your virtual interface up and running with an IP address, you can configure any services on one end, let's say `my1`, while you open the other end, `my0` with MIP.
|
|
||||||
|
|
||||||
- Add an IP address to one end of the pipe
|
|
||||||
```sh
|
|
||||||
$ sudo ip addr add 192.168.0.1/24 dev my1
|
|
||||||
```
|
|
||||||
- Start your DHCP server at that interface serving that subnet, or otherwise configure MIP to use a fixed address within that subnet.
|
|
||||||
- Now start the example opening the other end of the virtual interface:
|
|
||||||
```sh
|
|
||||||
$ make -C examples/mip-pcap/ clean all ARGS="-i my0"
|
|
||||||
```
|
|
||||||
- In some systems, you will probably need superuser privileges to open the device:
|
|
||||||
```sh
|
|
||||||
$ sudo examples/mip-pcap/example -i my0
|
|
||||||
```
|
|
||||||
|
|
||||||
```
|
|
||||||
[DHCP server for 192.168.0.x]
|
|
||||||
192.168.0.1 192.168.0.x
|
|
||||||
┌─────────┐ virtual eth pair ┌─────────┐
|
|
||||||
│ my1 ├────────────────────┤ my0 │
|
|
||||||
└─────────┘ └────┬────┘
|
|
||||||
│
|
|
||||||
│
|
|
||||||
mip-pcap
|
|
||||||
```
|
|
||||||
|
|
||||||
As you can't access any other host than your workstation, you need to add any required services (as DNS) there, and configure Mongoose appropriately. This is a foundation, you can expand it by choosing one of the solutions that follow.
|
|
||||||
|
|
||||||
### Bridge to your network
|
|
||||||
|
|
||||||
We will attach one end of the virtual interface to a bridge, which will also be attached to your network interface. In this case, MIP will have access to your network (and through it, to the Internet) and will also be reachable from your own workstation and other hosts in your network. You don't need to add IP addresses as in the example above, unless you don't have a DHCP server in your network, in which case you will configure MIP for a fixed address in your subnet.
|
|
||||||
|
|
||||||
- If you don't already have a virtual bridge interface, as mentioned above, you'll have to create it and attach your network interface (NIC) to it. Your IP address has to be assigned to the bridge, instead of the NIC. If you are using DHCP, the client must run on the bridge interface instead of the NIC.
|
|
||||||
```sh
|
|
||||||
$ ip link add virbr0 type bridge
|
|
||||||
$ sudo ip link set virbr0 up
|
|
||||||
$ sudo ip addr del 10.1.0.10/24 dev enp9s0
|
|
||||||
$ sudo ip link set enp9s0 master virbr0
|
|
||||||
$ sudo ip addr add 10.1.0.10/24 dev virbr0
|
|
||||||
```
|
|
||||||
Check using `ifconfig`, and try to ping some host in your network
|
|
||||||
- Attach one end of the virtual interface to the bridge:
|
|
||||||
```sh
|
|
||||||
$ sudo ip link set my1 master virbr0
|
|
||||||
```
|
|
||||||
- If everything is fine, you'll see your interface pair state is UP:
|
|
||||||
```sh
|
|
||||||
$ ip link show master virbr0
|
|
||||||
2: enp9s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master virbr0 state UP mode DEFAULT group default qlen 1000
|
|
||||||
link/ether 30:5a:3a:08:db:90 brd ff:ff:ff:ff:ff:ff
|
|
||||||
396: my1@my0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master virbr0 state UP mode DEFAULT group default qlen 1000
|
|
||||||
link/ether b6:ee:bc:53:f2:6e brd ff:ff:ff:ff:ff:ff
|
|
||||||
```
|
|
||||||
- Now start the example opening the other end of the virtual interface:
|
|
||||||
```sh
|
|
||||||
$ make -C examples/mip-pcap/ clean all ARGS="-i my0"
|
|
||||||
```
|
|
||||||
- In some systems, you will probably need superuser privileges to open the device:
|
|
||||||
```sh
|
|
||||||
$ sudo examples/mip-pcap/example -i my0
|
|
||||||
```
|
|
||||||
|
|
||||||
```
|
|
||||||
10.1.0.10
|
|
||||||
virbr0
|
|
||||||
│
|
|
||||||
┌──────────────────┴──────────────────┐
|
|
||||||
│ │ 10.1.0.x
|
|
||||||
│ ┌─────────┐ virtual eth pair ┌─────────┐
|
|
||||||
│ │ my1 ├────────────┬───────┤ my0 │
|
|
||||||
│ └─────────┘ │ └────┬────┘
|
|
||||||
│ │ │
|
|
||||||
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │
|
|
||||||
│ │ vnet1 │ │ enp9s0 │ │ vnet2 │ │ mip-pcap
|
|
||||||
│ └────┬────┘ └────┬────┘ └────┬────┘ │
|
|
||||||
│ │ │ │ │
|
|
||||||
└──────┼───────────┼───────────┼──────┘
|
|
||||||
│ │ │
|
|
||||||
│
|
|
||||||
Ethernet [WiFi]
|
|
||||||
│ Local LAN 10.1.0.x
|
|
||||||
│ DHCP server, router
|
|
||||||
▼
|
|
||||||
Internet
|
|
||||||
```
|
|
||||||
|
|
||||||
If you have _Docker_ running, it may introduce firewall rules that will disrupt your bridging.
|
|
||||||
|
|
||||||
### Forward/Masquerade
|
|
||||||
|
|
||||||
Once you have your virtual interface up and running with an IP address, you can use your Linux to NAT and forward MIP traffic to another interface, for example the one that connects you to the Internet. In this case, MIP will have access to the Internet and will also be reachable from your own workstation; but not from any other hosts in your local network (if there is one). You can use this setup with a direct connection to the Internet or being part of a network, when you want to isolate MIP from the rest of your network.
|
|
||||||
|
|
||||||
- We assume you already have a firewall in place (you should); to configure masquerading and forwarding do:
|
|
||||||
```sh
|
|
||||||
$ sudo iptables -t nat -A POSTROUTING -o enp9s0 -j MASQUERADE
|
|
||||||
$ echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward
|
|
||||||
```
|
|
||||||
Remember to use the proper network interface name
|
|
||||||
- Now start the example opening the other end of the virtual interface:
|
|
||||||
```sh
|
|
||||||
$ make -C examples/mip-pcap/ clean all ARGS="-i my0"
|
|
||||||
```
|
|
||||||
- In some systems, you will probably need superuser privileges to open the device:
|
|
||||||
```sh
|
|
||||||
$ sudo examples/mip-pcap/example -i my0
|
|
||||||
```
|
|
||||||
|
|
||||||
```
|
|
||||||
[DHCP server for 192.168.0.x]
|
|
||||||
┌────────────► 192.168.0.1 192.168.0.x
|
|
||||||
│ forwarding ┌─────────┐ virtual eth pair ┌─────────┐
|
|
||||||
│ masquerading │ my1 ├────────────────────┤ my0 │
|
|
||||||
│ └─────────┘ └────┬────┘
|
|
||||||
▼ │
|
|
||||||
Your IP (LAN / Public) │
|
|
||||||
┌─────────┐ mip-pcap
|
|
||||||
│ enp9s0 │
|
|
||||||
└────┬────┘
|
|
||||||
│
|
|
||||||
│
|
|
||||||
Ethernet
|
|
||||||
│
|
|
||||||
▼
|
|
||||||
Internet
|
|
||||||
```
|
|
||||||
|
|
||||||
You can also use this setup if your NIC is part of a bridge (for example: you have virtual machines); in that case:
|
|
||||||
- use the bridge interface for masquerading, instead of the Ethernet (your IP now belongs to the virtual bridge, not the NIC):
|
|
||||||
```sh
|
|
||||||
$ sudo iptables -t nat -A POSTROUTING -o virbr0 -j MASQUERADE
|
|
||||||
$ echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward
|
|
||||||
```
|
|
||||||
Remember to use the proper bridge interface name
|
|
||||||
|
|
||||||
```
|
|
||||||
[DHCP server for 192.168.0.x]
|
|
||||||
10.1.0.10 ◀──────────────► 192.168.0.1 192.168.0.x
|
|
||||||
virbr0 forwarding ┌─────────┐ virtual eth pair ┌─────────┐
|
|
||||||
│ masquerading │ my1 ├────────────────────┤ my0 │
|
|
||||||
│ └─────────┘ └────┬────┘
|
|
||||||
┌──────────────────┴──────────────────┐ │
|
|
||||||
│ │ │
|
|
||||||
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ mip-pcap
|
|
||||||
│ │ vnet1 │ │ enp9s0 │ │ vnet2 │ │
|
|
||||||
│ └────┬────┘ └────┬────┘ └────┬────┘ │
|
|
||||||
│ │ │ │ │
|
|
||||||
└──────┼───────────┼───────────┼──────┘
|
|
||||||
│ │ │
|
|
||||||
│
|
|
||||||
Ethernet [WiFi]
|
|
||||||
│ Local LAN 10.1.0.x
|
|
||||||
│ DHCP server, router
|
|
||||||
▼
|
|
||||||
Internet
|
|
||||||
```
|
|
||||||