Compare commits

..
92 Commits
Author SHA1 Message Date
Deomid Ryabkov ab650ec5c9 Merge branch 'dev' 2019-03-04 15:19:32 +00:00
Deomid Ryabkov 8f36597048 Mongoose 6.14
PUBLISHED_FROM=3e6e17d1f1cfb05efc37d76279dcbedb7f1add5d
2019-03-04 15:15:35 +00:00
Deomid Ryabkov d0213ee90a ESP32: Add support for the 3/4 key encoding scheme
* Add calculated redundancy values when writing eFuse blocks 1-3
 * Perform 192 -> 256 bit key extension when encrypting images for flashing

Fixes https://github.com/cesanta/mos-tool/issues/37

CL: mos: ESP32: Add support for the 3/4 key encoding scheme

PUBLISHED_FROM=16639fb25d5200550ad2097929239d896e188b5b
2019-03-04 09:18:28 +00:00
Deomid Ryabkov 1e9fabe1ca Fix handling of WS handshake error response
Check response code, make sure it's 101.
Pass http_message to the client to keep it appraised.
This represents a slight change in the API -
in case of an error MG_EV_WEBSOCKET_HANDSHAKE_DONE will now be delivered where previosuly connection would just hang.
Clients that do not examine the argument may for a moment think handshake has succeeded but in fact connection will be closed immediately.

CL: mg: Fix handling of WS handshake error response

PUBLISHED_FROM=645a43d9e5bee216e54411f85827c9b974e9a7d1
2019-02-14 21:19:34 +00:00
Deomid Ryabkov 148d3f0562 STM32F2 and Particle Electron board support
CL: STM32F2 and Particle Electron board support

PUBLISHED_FROM=20dede6546e9f99d2829508177924790d87e985a
2019-02-12 13:36:54 +00:00
Deomid Ryabkov c3057df3f5 Fix mongoose CI test
CL: none

PUBLISHED_FROM=9510e460251c250cb6a67a40edc0af515044f9fe
2019-02-08 17:38:56 +00:00
Deomid Ryabkov 0b2e474d52 Improve ESP flasher baud rate setting
Use old baud rate and autodetected divider to calculate new divider.

This works better with higher baud rates and drifting clocks.

CL: mos: Improve ESP flasher baud rate setting

PUBLISHED_FROM=7761e756c3ae7cc76e3b9a4fe3e40d06a779b2e8
2019-02-08 17:38:55 +00:00
Deomid Ryabkov 95a36b1759 Log file:line instead of function; add cs_log_set_file_level()
cs_log_set_filter() is removed in favor of cs_log_set_file_level() which
allows setting log verbosity of individual files and/or lines.

E.g.: `mg_=1,mjs=1,=4` - level for for everything except mjs and mongoose.

We use the fact that we are usually pretty careful with our file names and use prefixes consistently.

In mos, `debug.file_level` sets the option on boot and `Sys.SetDebug` is updated to parse `file_level` option to change it at runtime.

CL: Log file:line instead of function; add cs_log_set_file_level()

PUBLISHED_FROM=49f18d4d0d3dd224865129a4f8fe6cccd1d9bc12
2019-01-30 12:57:19 +00:00
Deomid Ryabkov 86ffa3a3ea Properly support MQTT wildcards when matching topics
CL: mg: Properly support MQTT wildcards when matching topics

PUBLISHED_FROM=aa60a71d488f4b56dff0951886c8a9a4066fd4f2
2019-01-22 12:19:04 +00:00
Deomid Ryabkov 69e2b2985d Add mg_strfree()
CL: Add mg_strfree()

PUBLISHED_FROM=b80566218986e0607a9d2758bf776a1031b27212
2019-01-16 22:48:59 +00:00
Бобби c431904b56 Send extra options with OPTIONS
CL: Send extra options with OPTIONS. Integrate https://github.com/cesanta/mongoose/pull/657

PUBLISHED_FROM=6ee609a92febd8d908f7713f94fb73657443a09a
2019-01-16 11:33:57 +00:00
Deomid Ryabkov c2a10601b9 Fix nsleep100 on STM32
CL: Fix nsleep100 on STM32

PUBLISHED_FROM=cabb98a0541bac9bb66bfa702d54bf8ff20063e7
2019-01-08 20:43:55 +00:00
Deomid Ryabkov e9a8e5468d Convert Python scripts to Python 3, delete unused ones
CL: none

PUBLISHED_FROM=4bbc2175634e20a726dd4b2dadff57f945b261d0
2018-12-25 20:38:58 +00:00
Sergey Lyubka 22e602debb Check for NULL in tcp_recved_tcpip()
CL: Check for NULL in tcp_recved_tcpip()

PUBLISHED_FROM=3f5bbc2e35b79d363eac4b99a1f0d17c9b81d4ec
2018-12-21 13:03:48 +00:00
Deomid Ryabkov 455cec67a5 CC3220: Enterprise auth support
CL: wifi: CC3220: Enterprise auth support

PUBLISHED_FROM=ce445eb5b740073c9a3f9811f1acd404ce134f2e
2018-12-18 18:19:21 +00:00
Deomid Ryabkov e2dfac946d Ensure that user sees all the data before connection is closed
If user throttles receive by setting recv_mbuf_limit,
after the net interface reports connection as closed we must wait
for data to trickle through before disposing of it.
There can still b data in the buffers (e.g. SSL).

CL: mg: Ensure that user sees all the data before connection is closed

PUBLISHED_FROM=22be0fa368950a9fdb03cfb00febc7c0a1674b01
2018-12-10 21:04:49 +00:00
Бобби c198d2e5f1 Make MG_CTL_MSG_MESSAGE_SIZE overridable
CL: Make MG_CTL_MSG_MESSAGE_SIZE overridable

Fix https://github.com/cesanta/mongoose/pull/987

PUBLISHED_FROM=b0a7c67297b98f616c9eadcd3c34b8747939c918
2018-12-07 10:04:00 +00:00
Deomid Ryabkov 9a70abef24 Add mbuf_append_and_free() and mbuf_move()
CL: Add mbuf_append_and_free() and mbuf_move()

PUBLISHED_FROM=bdf73906dd93b2ebeace160596508e15480b54b4
2018-12-05 21:49:01 +00:00
Deomid Ryabkov 53e1c469a2 Add ability for multipart data handler to provide pushback
It can specify how much data was actually processed and the rest will be re-delivered on next poll.

CL: mg: Add ability for multipart data handler to provide pushback

PUBLISHED_FROM=e0168c5064c3a32921c9209bc09f4da2079cd616
2018-12-05 16:02:56 +00:00
Deomid Ryabkov 139c2061a8 Add create-fw-bundle command
Replacement for fw_meta.py commands and also supports unbundling .hex files.

General syntax is:

```
 $ mos create-fw-bundle -o fw.zip part1:prop1=val1,prop2=val2,... part2:...
```

Example of building a mos fw bundle for ESP8266:
```
 $ mos create-fw-bundle -o fw.zip --platform esp8266 --build-info=build_info.json \
    boot:addr=0x0,src=rboot.bin,update=false \
    boot_cfg:addr=0x7000,size=0x1000,fill=0xff \
    fw:addr=0x100000,src=demo-c.bin \
    fs:src=fs.bin,type=fs,addr=0x8000,fs_size=262144,fs_block_size=4096,fs_page_size=256,fs_erase_size=4096
```

Example of converting a HEX file to a bundle:
```
 $ mos create-fw-bundle -o fw.zip host:type=host,src=hostfw.hex
```

CL: mos: Add create-fw-bundle command

PUBLISHED_FROM=35f52ea53e4b5900463415257323a4c08cf45deb
2018-11-28 20:34:06 +00:00
Deomid Ryabkov 15b361fbac Add mbuf_clear()
PUBLISHED_FROM=754b98b3000b24ad3b3d9cc0b4c480ca005a1c3f
2018-11-23 15:50:55 +00:00
Deomid Ryabkov 3130e59244 Stop reading if connection is closing
CL: none

PUBLISHED_FROM=3b74ca02e2960bbbf130f6d95aef679f2917e824
2018-11-02 18:12:34 +00:00
Deomid Ryabkov 93286836f9 Read all available data during recv poll
CL: mg: Read all available data during recv poll

PUBLISHED_FROM=b081025b9fb392c988924c7097b5333c38053f6f
2018-11-02 14:50:32 +00:00
Deomid Ryabkov 91b57aa9a8 Add MG_MK_STR_N() and mg_str_starts_with()
CL: Add MG_MK_STR_N() and mg_str_starts_with()

PUBLISHED_FROM=f01003efc6aa6ff45fa99c7ad6e5319f5002f22d
2018-10-29 15:50:31 +00:00
Deomid Ryabkov 220231e647 Fix digest auth result comparison
Should use length of the exected response, not the response sent by the user.

CL: mg: Fix digest auth result comparison

PUBLISHED_FROM=23375133b8babac0b276b51395917ad975e1bd3c
2018-10-15 16:47:18 +00:00
Deomid Ryabkov c438bb0bc5 Make mg_rpc more easily portable
CL: none

PUBLISHED_FROM=2e77d72cdf82454349a7fe29cc77bd0b90ac4369
2018-10-09 12:04:12 +00:00
Deomid Ryabkov 95afa323c0 Merge pull request #978 from cesanta/dev
Mongoose 6.13
2018-10-08 14:06:45 +01:00
Deomid Ryabkov bc56353a79 Mongoose 6.13
CL: none

PUBLISHED_FROM=32418b7da17a68193e88405547152f58a4dd877f
2018-10-08 12:20:32 +00:00
Deomid Ryabkov 1ffccdb7b2 Remove a spammy log line
PUBLISHED_FROM=b3ec2b3b43a464700a6e6d75b7336f823549cce3
2018-10-04 15:48:48 +00:00
Deomid Ryabkov e79fe4b8f0 Update mbedTLS to 2.13.1
CL: Update mbedTLS to 2.13.1

PUBLISHED_FROM=bd1216f727605a901f062a044c0c0ca762f4a6d1
2018-10-04 10:06:35 +00:00
Deomid Ryabkov aaf1fc3a4a Schedule a poll when LwIP reports TCP data sent
PUBLISHED_FROM=0cf3029d9a9b851882325e2298b878bc83fc2d33
2018-09-28 11:03:47 +00:00
Deomid Ryabkov 8b42353039 Check HTTP chunk size, ensure it's reasonable
CL: mg: Check HTTP chunk size, ensure it's reasonable

PUBLISHED_FROM=d9f6babd314c092b42ce9e7fe31d6b30a38366a2
2018-09-27 12:51:21 +00:00
Deomid Ryabkov 05c687e251 Fix handling of keepalive HTTP requests/responses
Clean the HTTP connection state when ia request/response has been fully
buffered and handler invoked.

Fixes https://github.com/cesanta/mongoose/issues/971

CL: mg: Fix handling of keepalive HTTP requests/responses

PUBLISHED_FROM=70c854aa306aacb9161f6ee48841f38dc0312e6b
2018-09-27 12:51:18 +00:00
Deomid Ryabkov 492b8f6950 CC3200: Fix boot loader regression
Go back to Ubuntu 16.04 and older gcc-arm (4.9.3).

Boot loader just won't run when compiled with newer GCC (7.x).
It's likely that it can be fixed with compile switches but I couldn't figure it out quickly, so going to just downgrade for now to get it back to workign state.

CL: CC3200: Fix boot loader regression

PUBLISHED_FROM=b70b03bd17e03c7dae02328b32b855f3ca3ad6a9
2018-09-25 20:32:35 +00:00
Deomid Ryabkov 8ccee82059 Add mgos_gpio_blink()
CL: Add mgos_gpio_blink()

PUBLISHED_FROM=a5d2e2f44413d1ab363abeeaf0fb497bd8f63d6d
2018-09-25 20:32:33 +00:00
Deomid Ryabkov b99a94a652 Fix build w/o logging
PUBLISHED_FROM=694346bd6562c55e5ab00886df47f7cbfb0a3720
2018-09-25 11:34:05 +00:00
Deomid Ryabkov 41e5d7e471 Use mbedTLS from mongoose-os-libs/mbedtls
mbedTLS is just another lib now

CL: Use mbedTLS from mongoose-os-libs/mbedtls

PUBLISHED_FROM=bae4739d22e871bd268b8a3233dbb69634770243
2018-09-20 20:38:11 +00:00
Sergey Lyubka 1adea37c45 Integrate https://github.com/cesanta/mongoose/pull/667, fix documentation
CL: Integrate https://github.com/cesanta/mongoose/pull/667, fix documentation

PUBLISHED_FROM=80a939fc3276b89c29716e7373f674dba86769ee
2018-09-20 15:34:36 +00:00
Deomid Ryabkov 98f6c8aa4f Trim recv_mbuf when we know the size of the data
CL: none

PUBLISHED_FROM=e354b67ab6f8246af50c601f5f70d36c029601ea
2018-09-17 16:04:00 +00:00
Deomid Ryabkov 341ae53e85 Update mongoose.h (amalgamation)
PUBLISHED_FROM=1fbe72f99bda5745c4b9b9def0601bdc5bf70e65
2018-09-14 21:19:15 +00:00
Sergey Lyubka 291fc024cd Docs nits
CL: Docs nits

PUBLISHED_FROM=1a2fc8080d94673acf300c6f07aba3a1e6272295
2018-09-14 08:03:58 +00:00
Deomid Ryabkov f63d833a33 Update STM32 build image
* Update CubeL4 to 1.13.0
 * Rebuild OurTLS with `-DMBEDTLS_X509_CA_CHAIN_ON_DISK`
 * Add `-Wextra` and fix build issues

CL: Update STM32 build image

PUBLISHED_FROM=a7eacff7580bab6c6e40bdaf6164df575a717c55
2018-09-11 11:49:08 +00:00
Deomid Ryabkov ab035901f8 ISM43XXX networking support (TCP, UDP client)
Listeners still TODO

CL: ISM43XXX networking support (TCP, UDP client)

PUBLISHED_FROM=b58ba88b9e6bd7b55ccb607d0b69cea98cb52fa5
2018-09-11 06:34:08 +00:00
Deomid Ryabkov 20f54059ad STM32: Make LWIP optional
CL: STM32: Make LWIP optional

PUBLISHED_FROM=eebffe7800a74d7b69aafd95e476b2e90328be98
2018-09-06 11:27:58 +00:00
Deomid Ryabkov 563c31303e Add net_if_null, a no-op net interface
Can be used for cases where device has no networking but mongoose is still needed for its event loop.

CL: mg: Add net_if_null, a no-op net interface

PUBLISHED_FROM=e79b4a8667508bbde1437dda9dad77ce3a3aa630
2018-09-06 08:34:17 +00:00
Deomid Ryabkov 421e099f2b Refactor mg polling
* Change return type of mg_mgr_poll to return number of events
 * Add mg_mgr_min_timer
 * Refactor main poll loop to remove LwIP-specific stuff

CL: Refactor mg polling

PUBLISHED_FROM=dc94618b32fa3c84a2f053bd04d134297780ec82
2018-09-06 06:34:18 +00:00
Бобби 955d4a3129 Fix file upload on windows
CL: Fix https://github.com/cesanta/mongoose/issues/962 - file upload on windows

PUBLISHED_FROM=85688eee147a1df468cca92f4ac61526ce9c02bf
2018-08-21 15:06:40 +00:00
Deomid Ryabkov b84981ad03 STM32 OTA support for L475-IOT01 and DISCO-F746
A smattering of other related changes

CL: STM32 OTA support for L475-IOT01 and DISCO-F746

PUBLISHED_FROM=e7142337086d09ba21437455b22d00db47ab33f1
2018-08-18 07:49:30 +00:00
Deomid Ryabkov 777b8e94e2 Merge branch 'dev' (Mongoose 6.12) 2018-08-13 19:30:06 +03:00
Sergey Lyubka 6df642623a Delete CONTRIBUTING.md 2018-08-13 19:28:18 +03:00
Deomid Ryabkov 0a3e186f11 Mongoose 6.12
CL: Mongoose 6.12

PUBLISHED_FROM=8008e4db2f6d94d972fb6e1077525e262c8744aa
2018-08-13 14:41:42 +00:00
Deomid Ryabkov c2d83a9db0 Don't touch send_mbuf when sending MQTT messages
h/t @M4GNV5

Fixes https://github.com/cesanta/mongoose/issues/943
Closes https://github.com/cesanta/mongoose/issues/944

CL: mg: Don't touch send_mbuf when sending MQTT messages

PUBLISHED_FROM=da7b4f8acec2e403caa4addd5739d036a6a74c76
2018-08-13 14:04:49 +00:00
Deomid Ryabkov f33d3a4e02 Fix body length calculation in mg_handle_cgi
Fixes https://nvd.nist.gov/vuln/detail/CVE-2018-10945

CL: mg: Fix body length calculation in mg_handle_cgi

PUBLISHED_FROM=0c30cf36fdb67c75f6148468701e23d6ee72d953
2018-08-13 13:05:22 +00:00
Deomid Ryabkov 86b8a56b05 Add host name verification for OpenSSL
Closes https://github.com/cesanta/mongoose/pull/955

CL: mg: Add host name verification for OpenSSL

PUBLISHED_FROM=e35dd636ba7ce63116f0a38031074d22f6cd5dac
2018-08-13 13:05:21 +00:00
Бобби ac6ec15aed Make esp8266 compilation a little less verbose
CL: Make esp8266 compilation a little less verbose

PUBLISHED_FROM=0ec1412ea32243f263d52fbe0877ecca1efc5aef
2018-07-23 15:26:47 +00:00
Deomid Ryabkov 31632c6361 Fix build with CS_ENABLE_STDIO=0
Closes https://github.com/cesanta/mongoose/pull/945

CL: Fix build with CS_ENABLE_STDIO=0

PUBLISHED_FROM=7d15f17fc42241facdba5b1004b5b7f3dda599dc
2018-07-12 20:42:45 +00:00
Deomid Ryabkov 98c99279c3 Fix warnings on newer versions of GCC
PUBLISHED_FROM=f1d25145446057fed9e8d634ca637364ca43a5e8
2018-07-09 08:34:29 +00:00
Deomid Ryabkov cdb8d7b692 Add mg_strstrip: trims whitespace at the ends of s
CL: Add mg_strstrip: trims whitespace at the ends of s

PUBLISHED_FROM=a7e10054ac25fa2b3a878876da93a6b30d9507b3
2018-07-07 14:04:42 +00:00
Deomid Ryabkov 93ac3e19f0 Stringify multi-word macros correctly
Use vararg macros for this.

PUBLISHED_FROM=735c40b79dedef17a1fdbb5b846e984df0ae7018
2018-07-03 15:05:23 +00:00
Deomid Ryabkov 6a51af9efe Fix a bug in mg_mgr_init_opt with opts.num_ifaces
h/t @YankunLi

Closes https://github.com/cesanta/mongoose/pull/939

CL: mg: Fix a bug in mg_mgr_init_opt with opts.num_ifaces

PUBLISHED_FROM=a87518b3505429a3cf9cd6d84b3b781e7dbdcfd5
2018-06-27 08:50:07 +00:00
Deomid Ryabkov 9d73b3470b Add LFS (littleFS) library
CL: mos support for LFS (littlefs) https://github.com/ARMmbed/littlefs

PUBLISHED_FROM=e72957b4fb2c78949af4cf6d5bfef135ddba9fd9
2018-06-26 16:49:42 +00:00
Deomid Ryabkov 1c8449cea6 Fix pipelining issue with multipart upload
Do not clear buffer at the end of multipart request to allow following request to proceed.

Closes https://github.com/cesanta/mongoose/pull/940

CL: mg: Fix pipelining issue with multipart upload

PUBLISHED_FROM=cc7d38b126eaa863553ee4e124cfafcd72030fcf
2018-06-26 12:05:04 +00:00
Deomid Ryabkov 3bbbd41196 Add missing CC3220 sub-header to mongoose.h
CL: Add missing CC3220 sub-header to mongoose.h

PUBLISHED_FROM=a143485b629109c6e16c66b035f02f7552f76129
2018-06-21 16:34:56 +00:00
Deomid Ryabkov 339bbee0df mg_file_upload_handler: Support multiple files
curl -F file1 -F file2 ...

Add a unit test and fix a minor memory leak when returning an error.

CL: mg_file_upload_handler: Support multiple files

PUBLISHED_FROM=5c4bf2be676346fb782e80f50f79df6a6721ac88
2018-06-20 13:35:31 +00:00
Deomid Ryabkov 9ba6eb716d mg_lwip: Fix race during clean conenction teardown
Set CLOSE_IMMEDIATELY flag when destroying conn.
This avoid some races in LWIP adapter.

CL: mg_lwip: Fix race during clean conenction teardown

PUBLISHED_FROM=5c67982390dfaf83527e85d1291f64c6050aa932
2018-06-18 16:35:04 +00:00
Deomid Ryabkov d949c19c7e mgos_nsleep100 impl for ARM-based platforms
startup cleanup on CC3220

CL: none

PUBLISHED_FROM=0998fad82fbcdbde30dca42833f2e48d148592bf
2018-06-06 08:04:33 +00:00
Deomid Ryabkov 1299d6118f Add MG_HIDE_SERVER_INFO
Closes https://github.com/cesanta/mos-libs/pull/2

CL: Add MG_HIDE_SERVER_INFO

PUBLISHED_FROM=ed8a5b65f1c8238df414cd1c1f8bb1f579082f55
2018-05-17 16:20:44 +00:00
Deomid Ryabkov 244ff92e78 Minor build optimization
PUBLISHED_FROM=9997c64ed0c713b5b8b29df7a49b532e880eac53
2018-05-10 19:05:40 +00:00
Deomid Ryabkov 53f34dea04 Fix TZ on ESP8266
CL: Fix TZ on ESP8266

PUBLISHED_FROM=435a501a8b52524bccb67bb5a8ae7e09dfb4d44a
2018-04-26 15:26:39 +00:00
Sergey Lyubka 1f5c3fac31 Delete CONTRIBUTING.md 2018-04-17 15:08:35 +01:00
Sergey Lyubka 7014258c8d Remove copyright notices - that explained in the CLA.
CL: none

PUBLISHED_FROM=9cb4b915906d471ef5de4e0825567d0b942d3f7b
2018-04-17 11:45:31 +00:00
Deomid Ryabkov 1614e7ba8d Restore FFI-ability of struct mg_str
mgos_dlsym needs to include mg_str for ffi_exports to be able to use it

PUBLISHED_FROM=a2dd167c8e8f9e9b7316a856f19a4603080c3632
2018-04-13 17:12:07 +00:00
Deomid Ryabkov 43b5a4e735 Add a special attribute to printf-like funcs
Enables extra compile-time checks

CL: none

PUBLISHED_FROM=9f7d658fbda5c721cf40293bf29967bb056d0437
2018-04-13 17:12:06 +00:00
Deomid Ryabkov 43191db63e Fix boot loader UART baud rate on soft reboot
Also remove `-O3` optimization flasg, it negates `-Os`. Saves ~400 bytes.

CL: none

PUBLISHED_FROM=f40f42e4f54a8e0e003ab65ec8f5838c2d932876
2018-04-11 18:35:15 +00:00
Deomid Ryabkov e89be2e944 Add mg_url_encode_opt()
CL: Add `mg_url_encode_opt()` - a parametrized version of `mg_url_encode()`

PUBLISHED_FROM=17fa57a7a5325b51b6e3aef3855eac4e82c35782
2018-04-10 11:04:31 +00:00
Deomid Ryabkov c2fbff6d0e Fix mg_http_parse_header
Per standard, cookies are delimited by `; `.

CL: Fix mg_http_parse_header: treat ";" as a delimiter.

PUBLISHED_FROM=039243c30f5fabf4a4700a43506f841b3268306a
2018-04-10 10:19:36 +00:00
Deomid Ryabkov b8eca17c55 Reamalgam mongoose.{c,h}
PUBLISHED_FROM=8828792097bd19774472b8a2e61420565684d174
2018-04-03 16:08:21 +00:00
Sergey Lyubka 4650e491df Apache license to common/
CL: Apache license to common/

PUBLISHED_FROM=901e9e4b12a31289b3515d1f86dd56a7f0f35c5e
2018-04-03 11:49:59 +00:00
Deomid Ryabkov 3e33e57707 Mongoose net_if and ssl_if refactoring
A major cleanup, disentangling net_if and ssl_if.
Pulled a lot of common logic into the core and reduced size of net_if implementations.

CL: Mongoose net_if and ssl_if refactoring

PUBLISHED_FROM=29bd4dcb264a1fd96b3dd164e2d880e1c2c0921e
2018-03-30 23:19:49 +00:00
Deomid Ryabkov c80f4c5313 Fix an edge case in multipart HTTP upload parsing
Consume buffer as soon as we know there is no boundary there, no need to delay until next chunk arrives.
This prevents stall where buffer fills up in one go and next chunk never arrives.

CL: Fix an edge case in multipart HTTP upload parsing

PUBLISHED_FROM=025f9001d272df2a75ece22b199b1944d5db9840
2018-03-30 19:35:20 +00:00
Deomid Ryabkov 132ecbec2f Fix Mongoose and Frozen include paths
In preparation for making moving to lib.
Reduce amount of makefile copypasta a bit.

CL: none

PUBLISHED_FROM=70a016491f9605e37708385bdd698f48a8d64119
2018-03-28 14:12:23 +00:00
Deomid Ryabkov 0a90cab44a Improve mbuf allocation behavior
* Limit total amount of headroom, in absolute terms (`MBUF_SIZE_MAX_HEADROOM`).
 * If unable to allocate with headroom, fall back to allocating the required minimum.
 * For mOS, set default `MBUF_SIZE_MULTIPLIER` to 2 to avoid floating point operations.
   Since max headroom size is now capped to 128 bytes, this will not result in much of a bloat.

PUBLISHED_FROM=11d4fc65a46a805bb7c8960f89a3d0b753c58bb8
2018-03-22 07:49:57 +00:00
Serge A. Zaitsev d16dbc197f mongoose: fix http pipeline
mongoose: fix formatting

mongoose: fix formatting

mongoose: remove debugging messages

PUBLISHED_FROM=1194e018001cc5f2b598096593d7aac4ec8dc04d
2018-03-20 16:41:56 +00:00
Serge A. Zaitsev 127f27e375 mongoose: unit test for http get pipeline
PUBLISHED_FROM=00e8634913232eb2e50a0d739f85e81706dbc400
2018-03-17 16:35:04 +00:00
novlean 6523cc4da0 2018
PUBLISHED_FROM=63ce52177f5f13cb76f0fcb4689efb65a04318a2
2018-03-12 21:20:20 +00:00
novlean 2516da1c89 updated to 2018 2018-03-12 16:49:45 +00:00
Serge A. Zaitsev 0ae2b82b60 freshen: early attempts to make ota and config work
freshen: implement ota rollback

freshen: api for rpc

freshen: implement rpc api (without transport)

PUBLISHED_FROM=9f935f676161c81464a0dc53d5d8d085b2437ffb
2018-02-27 14:19:33 +00:00
Sergey Lyubka dab526936f Add missing test files to mongoose repo
PUBLISHED_FROM=9a81cc34aa0039a75c851bc3685055f46936252e
2018-02-23 11:19:42 +00:00
Бобби 780077d118 Fix mg_socketpair for lwip + UDP
CL: Fix mg_socketpair for lwip + UDP

PUBLISHED_FROM=6dd09136b3837016026523fb34acb5cc893cadbe
2018-02-18 16:49:38 +00:00
Deomid Ryabkov ad8f1d88d4 Fix buffer size passed to inet_ntop()
Fixes https://github.com/cesanta/mongoose-os/issues/394

CL: Fix buffer size passed to inet_ntop()

PUBLISHED_FROM=4a6702527627ccbb780f45200274b09a28be69ee
2018-02-13 12:49:53 +00:00
Deomid Ryabkov a3c4a48ef7 Make sure test assertions are evaluated once
E.g. if `ASSERT_EQ(myfunc(), 123)` fails, `myfunc()` would be invoked again to print the actual value.
This can cause confusion sometimes.
To avoid this, we cast arguments to double, which is wide enough for most cases and we provide a variant for 64 bit value types for when it's not.
We also perform a check and fail if argument to the check results in loss of precision.

CL: none

PUBLISHED_FROM=a14551289d92e8a5dead21d16471ebddebe938a8
2018-02-10 12:19:40 +00:00
Deomid Ryabkov 84a11fe3b1 Count both tests and individual checks
CL: none

PUBLISHED_FROM=ab7f50e1c68154832e862ebfb4a02d385ef7c6be
2018-02-08 19:20:00 +00:00
125 changed files with 5524 additions and 3188 deletions

No files matched your search

-8
View File
@@ -1,8 +0,0 @@
People who have agreed to the
[Cesanta CLA](https://docs.cesanta.com/contributors_la.shtml)
can make contributions. Note that the CLA isn't a copyright
_assigment_ but rather a copyright _license_.
You retain the copyright on your contributions.
We follow the Google C/C++ style guide: https://google.github.io/styleguide/cppguide.html
We'd appreciate if your contribution follows the same style guide.
+1 -1
View File
@@ -1,5 +1,5 @@
Copyright (c) 2004-2013 Sergey Lyubka <valenok@gmail.com> Copyright (c) 2004-2013 Sergey Lyubka <valenok@gmail.com>
Copyright (c) 2013-2016 Cesanta Software Limited Copyright (c) 2013-2018 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 -1
View File
@@ -62,7 +62,7 @@ the functionality:
# Contributions # Contributions
To submit contributions, sign [Cesanta CLA](https://cesanta.com/cla.html) To submit contributions, sign [Cesanta CLA](https://cesanta.com/cla.html)
and send GitHub pull request. You retain the copyright on your contributions. and send GitHub pull request.
# Looking for a pre-compiled Mongoose web server Windows or Mac binary? # Looking for a pre-compiled Mongoose web server Windows or Mac binary?
- [Download pre-compiled Mongoose web server binary.](https://www.cesanta.com/binary.html) - [Download pre-compiled Mongoose web server binary.](https://www.cesanta.com/binary.html)
+4 -1
View File
@@ -1,12 +1,15 @@
--- ---
title: "Memory Buffers" title: "mbuf.h"
symbol_kind: "intro" symbol_kind: "intro"
decl_name: "mbuf.h" decl_name: "mbuf.h"
items: items:
- { name: mbuf_append.md } - { name: mbuf_append.md }
- { name: mbuf_append_and_free.md }
- { name: mbuf_clear.md }
- { name: mbuf_free.md } - { name: mbuf_free.md }
- { name: mbuf_init.md } - { name: mbuf_init.md }
- { name: mbuf_insert.md } - { name: mbuf_insert.md }
- { name: mbuf_move.md }
- { name: mbuf_remove.md } - { name: mbuf_remove.md }
- { name: mbuf_resize.md } - { name: mbuf_resize.md }
- { name: mbuf_trim.md } - { name: mbuf_trim.md }
+13
View File
@@ -0,0 +1,13 @@
---
title: "mbuf_append_and_free()"
decl_name: "mbuf_append_and_free"
symbol_kind: "func"
signature: |
size_t mbuf_append_and_free(struct mbuf *, void *data, size_t data_size);
---
Appends data to the Mbuf and frees it (data must be heap-allocated).
Returns the number of bytes appended or 0 if out of memory.
data is freed irrespective of return value.
+10
View File
@@ -0,0 +1,10 @@
---
title: "mbuf_clear()"
decl_name: "mbuf_clear"
symbol_kind: "func"
signature: |
void mbuf_clear(struct mbuf *);
---
Removes all the data from mbuf (if any).
+10
View File
@@ -0,0 +1,10 @@
---
title: "mbuf_move()"
decl_name: "mbuf_move"
symbol_kind: "func"
signature: |
void mbuf_move(struct mbuf *from, struct mbuf *to);
---
Moves the state from one mbuf to the other.
@@ -30,7 +30,9 @@ The user-defined event handler will receive following extra events:
- MG_EV_WEBSOCKET_HANDSHAKE_REQUEST: server has received the WebSocket - MG_EV_WEBSOCKET_HANDSHAKE_REQUEST: server has received the WebSocket
handshake request. `ev_data` contains parsed HTTP request. handshake request. `ev_data` contains parsed HTTP request.
- MG_EV_WEBSOCKET_HANDSHAKE_DONE: server has completed the WebSocket - MG_EV_WEBSOCKET_HANDSHAKE_DONE: server has completed the WebSocket
handshake. `ev_data` is `NULL`. handshake. `ev_data` is a `struct http_message` containing the
client's request (server mode) or server's response (client).
In client mode handler can examine `resp_code`, which should be 101.
- MG_EV_WEBSOCKET_FRAME: new WebSocket frame has arrived. `ev_data` is - MG_EV_WEBSOCKET_FRAME: new WebSocket frame has arrived. `ev_data` is
`struct websocket_message *` `struct websocket_message *`
@@ -9,6 +9,14 @@ signature: |
struct mg_str data; struct mg_str data;
int status; /* <0 on error */ int status; /* <0 on error */
void *user_data; void *user_data;
/*
* User handler can indicate how much of the data was consumed
* by setting this variable. By default, it is assumed that all
* data has been consumed by the handler.
* If not all data was consumed, user's handler will be invoked again later
* with the remainder.
*/
size_t num_data_consumed;
}; };
--- ---
+1 -1
View File
@@ -16,5 +16,5 @@ that can be, and must be, called from a different (non-IO) thread.
`func` callback function will be called by the IO thread for each `func` callback function will be called by the IO thread for each
connection. When called, the event will be `MG_EV_POLL`, and a message will connection. When called, the event will be `MG_EV_POLL`, and a message will
be passed as the `ev_data` pointer. Maximum message size is capped be passed as the `ev_data` pointer. Maximum message size is capped
by `MG_CTL_MSG_MESSAGE_SIZE` which is set to 8192 bytes. by `MG_CTL_MSG_MESSAGE_SIZE` which is set to 8192 bytes by default.
+1 -1
View File
@@ -3,7 +3,7 @@ title: "mg_mgr_free()"
decl_name: "mg_mgr_free" decl_name: "mg_mgr_free"
symbol_kind: "func" symbol_kind: "func"
signature: | signature: |
void mg_mgr_free(struct mg_mgr *); void mg_mgr_free(struct mg_mgr *mgr);
--- ---
De-initialises Mongoose manager. De-initialises Mongoose manager.
+2 -2
View File
@@ -3,11 +3,11 @@ title: "mg_mgr_poll()"
decl_name: "mg_mgr_poll" decl_name: "mg_mgr_poll"
symbol_kind: "func" symbol_kind: "func"
signature: | signature: |
time_t mg_mgr_poll(struct mg_mgr *, int milli); int mg_mgr_poll(struct mg_mgr *mgr, int milli);
--- ---
This function performs the actual IO and must be called in a loop This function performs the actual IO and must be called in a loop
(an event loop). It returns the current timestamp. (an event loop). It returns number of user events generated (except POLLs).
`milli` is the maximum number of milliseconds to sleep. `milli` is the maximum number of milliseconds to sleep.
`mg_mgr_poll()` checks all connections for IO readiness. If at least one `mg_mgr_poll()` checks all connections for IO readiness. If at least one
of the connections is IO-ready, `mg_mgr_poll()` triggers the respective of the connections is IO-ready, `mg_mgr_poll()` triggers the respective
@@ -46,6 +46,7 @@ signature: |
#define MG_F_WANT_READ (1 << 6) /* SSL specific */ #define MG_F_WANT_READ (1 << 6) /* SSL specific */
#define MG_F_WANT_WRITE (1 << 7) /* SSL specific */ #define MG_F_WANT_WRITE (1 << 7) /* SSL specific */
#define MG_F_IS_WEBSOCKET (1 << 8) /* Websocket specific */ #define MG_F_IS_WEBSOCKET (1 << 8) /* Websocket specific */
#define MG_F_RECV_AND_CLOSE (1 << 9) /* Drain rx and close the connection. */
/* Flags that are settable by user */ /* Flags that are settable by user */
#define MG_F_SEND_AND_CLOSE (1 << 10) /* Push remaining data and close */ #define MG_F_SEND_AND_CLOSE (1 << 10) /* Push remaining data and close */
+1
View File
@@ -13,6 +13,7 @@ signature: |
#endif #endif
void *user_data; /* User data */ void *user_data; /* User data */
int num_ifaces; int num_ifaces;
int num_calls;
struct mg_iface **ifaces; /* network interfaces */ struct mg_iface **ifaces; /* network interfaces */
const char *nameserver; /* DNS server to use */ const char *nameserver; /* DNS server to use */
}; };
+1 -4
View File
@@ -6,8 +6,5 @@ signature: |
struct mg_str mg_url_encode(const struct mg_str src); struct mg_str mg_url_encode(const struct mg_str src);
--- ---
URL-escape the specified string. Same as `mg_url_encode_opt(src, "._-$,;~()/", 0)`.
All non-printable characters are escaped, plus `._-$,;~()/`.
Input need not be NUL-terminated, but the returned string is.
Returned string is heap-allocated and must be free()'d.
+1 -1
View File
@@ -7,7 +7,7 @@ flags are meant to be set only by the user event handler to tell Mongoose how to
behave. Below is a list of connection flags that are meant to be set by event behave. Below is a list of connection flags that are meant to be set by event
handlers: handlers:
* `MG_F_FINISHED_SENDING_DATA` tells Mongoose that all data has been appended * `MG_F_SEND_AND_CLOSE` tells Mongoose that all data has been appended
to the `send_mbuf`. As soon as Mongoose sends it to the socket, the to the `send_mbuf`. As soon as Mongoose sends it to the socket, the
connection will be closed. connection will be closed.
* `MG_F_BUFFER_BUT_DONT_SEND` tells Mongoose to append data to the `send_mbuf` * `MG_F_BUFFER_BUT_DONT_SEND` tells Mongoose to append data to the `send_mbuf`
+2 -1
View File
@@ -98,7 +98,8 @@ bool bm222_get_data(struct bm222_ctx *ctx) {
s->y = v[3]; s->y = v[3];
s->z = v[5]; s->z = v[5];
if (d > max_d) max_d = d; if (d > max_d) max_d = d;
LOG(LL_VERBOSE_DEBUG, ("dx %d dy %d dz %d d %d", dx, dy, dz, d)); LOG(LL_VERBOSE_DEBUG,
("dx %d dy %d dz %d d %d", (int) dx, (int) dy, (int) dz, (int) d));
} }
} }
return (overflow ? bm222_fifo_init(ctx) : true); /* Clear the ovf flag. */ return (overflow ? bm222_fifo_init(ctx) : true); /* Clear the ovf flag. */
+84 -14
View File
@@ -1,11 +1,25 @@
/* /*
* Copyright (c) 2014-2016 Cesanta Software Limited * Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved * All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
#ifndef CS_COMMON_CS_DBG_H_ #ifndef CS_COMMON_CS_DBG_H_
#define CS_COMMON_CS_DBG_H_ #define CS_COMMON_CS_DBG_H_
#include "common/platform.h"
#if CS_ENABLE_STDIO #if CS_ENABLE_STDIO
#include <stdio.h> #include <stdio.h>
#endif #endif
@@ -14,6 +28,10 @@
#define CS_ENABLE_DEBUG 0 #define CS_ENABLE_DEBUG 0
#endif #endif
#ifndef CS_LOG_PREFIX_LEN
#define CS_LOG_PREFIX_LEN 24
#endif
#ifndef CS_LOG_ENABLE_TS_DIFF #ifndef CS_LOG_ENABLE_TS_DIFF
#define CS_LOG_ENABLE_TS_DIFF 0 #define CS_LOG_ENABLE_TS_DIFF 0
#endif #endif
@@ -22,6 +40,9 @@
extern "C" { extern "C" {
#endif /* __cplusplus */ #endif /* __cplusplus */
/*
* Log level; `LL_INFO` is the default. Use `cs_log_set_level()` to change it.
*/
enum cs_log_level { enum cs_log_level {
LL_NONE = -1, LL_NONE = -1,
LL_ERROR = 0, LL_ERROR = 0,
@@ -34,29 +55,78 @@ enum cs_log_level {
_LL_MAX = 5, _LL_MAX = 5,
}; };
/*
* Set max log level to print; messages with the level above the given one will
* not be printed.
*/
void cs_log_set_level(enum cs_log_level level); void cs_log_set_level(enum cs_log_level level);
/*
* A comma-separated set of prefix=level.
* prefix is matched against the log prefix exactly as printed, including line
* number, but partial match is ok. Check stops on first matching entry.
* If nothing matches, default level is used.
*
* Examples:
* main.c:=4 - everything from main C at verbose debug level.
* mongoose.c=1,mjs.c=1,=4 - everything at verbose debug except mg_* and mjs_*
*
*/
void cs_log_set_file_level(const char *file_level);
/*
* Helper function which prints message prefix with the given `level`.
* If message should be printed (according to the current log level
* and filter), prints the prefix and returns 1, otherwise returns 0.
*
* Clients should typically just use `LOG()` macro.
*/
int cs_log_print_prefix(enum cs_log_level level, const char *fname, int line);
extern enum cs_log_level cs_log_level;
#if CS_ENABLE_STDIO #if CS_ENABLE_STDIO
/*
* Set file to write logs into. If `NULL`, logs go to `stderr`.
*/
void cs_log_set_file(FILE *file); void cs_log_set_file(FILE *file);
extern enum cs_log_level cs_log_threshold; /*
void cs_log_print_prefix(const char *func); * Prints log to the current log file, appends "\n" in the end and flushes the
void cs_log_printf(const char *fmt, ...); * stream.
*/
void cs_log_printf(const char *fmt, ...) PRINTF_LIKE(1, 2);
#define LOG(l, x) \ #if CS_ENABLE_STDIO
if (cs_log_threshold >= l) { \
cs_log_print_prefix(__func__); \ /*
cs_log_printf x; \ * Format and print message `x` with the given level `l`. Example:
} *
* ```c
* LOG(LL_INFO, ("my info message: %d", 123));
* LOG(LL_DEBUG, ("my debug message: %d", 123));
* ```
*/
#define LOG(l, x) \
do { \
if (cs_log_print_prefix(l, __FILE__, __LINE__)) { \
cs_log_printf x; \
} \
} while (0)
#else
#define LOG(l, x) ((void) l)
#endif
#ifndef CS_NDEBUG #ifndef CS_NDEBUG
#define DBG(x) \ /*
if (cs_log_threshold >= LL_VERBOSE_DEBUG) { \ * Shortcut for `LOG(LL_VERBOSE_DEBUG, (...))`
cs_log_print_prefix(__func__); \ */
cs_log_printf x; \ #define DBG(x) LOG(LL_VERBOSE_DEBUG, x)
}
#else /* NDEBUG */ #else /* NDEBUG */
+2 -2
View File
@@ -50,7 +50,7 @@
#define BM222_ADDR 0x18 #define BM222_ADDR 0x18
#define TMP006_ADDR 0x41 #define TMP006_ADDR 0x41
void fs_slfs_set_new_file_size(const char *name, size_t size); void fs_slfs_set_file_size(const char *name, size_t size);
static const char *upload_form = static const char *upload_form =
"\ "\
@@ -70,7 +70,7 @@ static struct mg_str upload_fname(struct mg_connection *nc,
if (nc->user_data != NULL) { if (nc->user_data != NULL) {
intptr_t cl = (intptr_t) nc->user_data; intptr_t cl = (intptr_t) nc->user_data;
if (cl >= 0) { if (cl >= 0) {
fs_slfs_set_new_file_size(fn + 3, cl); fs_slfs_set_file_size(fn + 3, cl);
} }
} }
lfn.len = fname.len + 4; lfn.len = fname.len + 4;
+2 -2
View File
@@ -25,7 +25,7 @@ void SimpleLinkWlanEventHandler(SlWlanEvent_t *e) {
LOG(LL_INFO, ("WiFi: station disconnected")); LOG(LL_INFO, ("WiFi: station disconnected"));
break; break;
default: default:
LOG(LL_INFO, ("WiFi: event %d", e->Event)); LOG(LL_INFO, ("WiFi: event %d", (int) e->Event));
} }
} }
@@ -39,7 +39,7 @@ void SimpleLinkNetAppEventHandler(SlNetAppEvent_t *e) {
} else if (e->Event == SL_NETAPP_IP_LEASED_EVENT) { } else if (e->Event == SL_NETAPP_IP_LEASED_EVENT) {
LOG(LL_INFO, ("IP leased")); LOG(LL_INFO, ("IP leased"));
} else { } else {
LOG(LL_INFO, ("NetApp event %d", e->Event)); LOG(LL_INFO, ("NetApp event %d", (int) e->Event));
} }
} }
@@ -14,7 +14,6 @@ static int s_done = 0;
static int s_is_connected = 0; static int s_is_connected = 0;
static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) { static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
struct websocket_message *wm = (struct websocket_message *) ev_data;
(void) nc; (void) nc;
switch (ev) { switch (ev) {
@@ -26,8 +25,14 @@ static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
break; break;
} }
case MG_EV_WEBSOCKET_HANDSHAKE_DONE: { case MG_EV_WEBSOCKET_HANDSHAKE_DONE: {
printf("-- Connected\n"); struct http_message *hm = (struct http_message *) ev_data;
s_is_connected = 1; if (hm->resp_code == 101) {
printf("-- Connected\n");
s_is_connected = 1;
} else {
printf("-- Connection failed! HTTP code %d\n", hm->resp_code);
/* Connection will be closed after this. */
}
break; break;
} }
case MG_EV_POLL: { case MG_EV_POLL: {
@@ -66,6 +71,7 @@ static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
break; break;
} }
case MG_EV_WEBSOCKET_FRAME: { case MG_EV_WEBSOCKET_FRAME: {
struct websocket_message *wm = (struct websocket_message *) ev_data;
printf("%.*s\n", (int) wm->size, wm->data); printf("%.*s\n", (int) wm->size, wm->data);
break; break;
} }
+1794 -1378
View File
File diff suppressed because it is too large. Load diff
+521 -60
View File
@@ -23,7 +23,7 @@
#ifndef CS_MONGOOSE_SRC_COMMON_H_ #ifndef CS_MONGOOSE_SRC_COMMON_H_
#define CS_MONGOOSE_SRC_COMMON_H_ #define CS_MONGOOSE_SRC_COMMON_H_
#define MG_VERSION "6.11" #define MG_VERSION "6.14"
/* Local tweaks, applied before any of Mongoose's own headers. */ /* Local tweaks, applied before any of Mongoose's own headers. */
#ifdef MG_LOCALS #ifdef MG_LOCALS
@@ -105,6 +105,7 @@
#define MG_NET_IF_SIMPLELINK 2 #define MG_NET_IF_SIMPLELINK 2
#define MG_NET_IF_LWIP_LOW_LEVEL 3 #define MG_NET_IF_LWIP_LOW_LEVEL 3
#define MG_NET_IF_PIC32 4 #define MG_NET_IF_PIC32 4
#define MG_NET_IF_NULL 5
#define MG_SSL_IF_OPENSSL 1 #define MG_SSL_IF_OPENSSL 1
#define MG_SSL_IF_MBEDTLS 2 #define MG_SSL_IF_MBEDTLS 2
@@ -128,8 +129,18 @@
/* Common stuff */ /* Common stuff */
#if !defined(PRINTF_LIKE)
#if defined(__GNUC__) || defined(__clang__) || defined(__TI_COMPILER_VERSION__)
#define PRINTF_LIKE(f, a) __attribute__((format(printf, f, a)))
#else
#define PRINTF_LIKE(f, a)
#endif
#endif
#if !defined(WEAK) #if !defined(WEAK)
#if (defined(__GNUC__) || defined(__TI_COMPILER_VERSION__)) && !defined(_WIN32) #if (defined(__GNUC__) || defined(__clang__) || \
defined(__TI_COMPILER_VERSION__)) && \
!defined(_WIN32)
#define WEAK __attribute__((weak)) #define WEAK __attribute__((weak))
#else #else
#define WEAK #define WEAK
@@ -493,8 +504,20 @@ typedef struct stat cs_stat_t;
#line 1 "common/platforms/platform_esp32.h" #line 1 "common/platforms/platform_esp32.h"
#endif #endif
/* /*
* Copyright (c) 2014-2016 Cesanta Software Limited * Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved * All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
#ifndef CS_COMMON_PLATFORMS_PLATFORM_ESP32_H_ #ifndef CS_COMMON_PLATFORMS_PLATFORM_ESP32_H_
@@ -538,8 +561,20 @@ typedef struct stat cs_stat_t;
#line 1 "common/platforms/platform_esp8266.h" #line 1 "common/platforms/platform_esp8266.h"
#endif #endif
/* /*
* Copyright (c) 2014-2016 Cesanta Software Limited * Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved * All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
#ifndef CS_COMMON_PLATFORMS_PLATFORM_ESP8266_H_ #ifndef CS_COMMON_PLATFORMS_PLATFORM_ESP8266_H_
@@ -569,10 +604,6 @@ typedef struct stat cs_stat_t;
#define __cdecl #define __cdecl
#define _FILE_OFFSET_BITS 32 #define _FILE_OFFSET_BITS 32
#if !defined(RTOS_SDK) && !defined(__cplusplus)
#define fileno(x) -1
#endif
#define MG_LWIP 1 #define MG_LWIP 1
/* struct timeval is defined in sys/time.h. */ /* struct timeval is defined in sys/time.h. */
@@ -603,8 +634,20 @@ typedef struct stat cs_stat_t;
#line 1 "common/platforms/platform_cc3100.h" #line 1 "common/platforms/platform_cc3100.h"
#endif #endif
/* /*
* Copyright (c) 2014-2016 Cesanta Software Limited * Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved * All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
#ifndef CS_COMMON_PLATFORMS_PLATFORM_CC3100_H_ #ifndef CS_COMMON_PLATFORMS_PLATFORM_CC3100_H_
@@ -652,8 +695,20 @@ int inet_pton(int af, const char *src, void *dst);
#line 1 "common/platforms/platform_cc3200.h" #line 1 "common/platforms/platform_cc3200.h"
#endif #endif
/* /*
* Copyright (c) 2014-2016 Cesanta Software Limited * Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved * All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
#ifndef CS_COMMON_PLATFORMS_PLATFORM_CC3200_H_ #ifndef CS_COMMON_PLATFORMS_PLATFORM_CC3200_H_
@@ -774,11 +829,147 @@ int stat(const char *pathname, struct stat *st);
#endif /* CS_PLATFORM == CS_P_CC3200 */ #endif /* CS_PLATFORM == CS_P_CC3200 */
#endif /* CS_COMMON_PLATFORMS_PLATFORM_CC3200_H_ */ #endif /* CS_COMMON_PLATFORMS_PLATFORM_CC3200_H_ */
#ifdef MG_MODULE_LINES #ifdef MG_MODULE_LINES
#line 1 "common/platforms/platform_cc3220.h"
#endif
/*
* Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CS_COMMON_PLATFORMS_PLATFORM_CC3220_H_
#define CS_COMMON_PLATFORMS_PLATFORM_CC3220_H_
#if CS_PLATFORM == CS_P_CC3220
#include <assert.h>
#include <ctype.h>
#include <errno.h>
#include <inttypes.h>
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#include <time.h>
#ifndef __TI_COMPILER_VERSION__
#include <fcntl.h>
#include <sys/time.h>
#endif
#define MG_NET_IF MG_NET_IF_SIMPLELINK
#ifndef MG_SSL_IF
#define MG_SSL_IF MG_SSL_IF_SIMPLELINK
#endif
/* Only SPIFFS supports directories, SLFS does not. */
#if defined(CC3220_FS_SPIFFS) && !defined(MG_ENABLE_DIRECTORY_LISTING)
#define MG_ENABLE_DIRECTORY_LISTING 1
#endif
/* Amalgamated: #include "common/platforms/simplelink/cs_simplelink.h" */
typedef int sock_t;
#define INVALID_SOCKET (-1)
#define SIZE_T_FMT "u"
typedef struct stat cs_stat_t;
#define DIRSEP '/'
#define to64(x) strtoll(x, NULL, 10)
#define INT64_FMT PRId64
#define INT64_X_FMT PRIx64
#define __cdecl
#define fileno(x) -1
/* Some functions we implement for Mongoose. */
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __TI_COMPILER_VERSION__
struct SlTimeval_t;
#define timeval SlTimeval_t
int gettimeofday(struct timeval *t, void *tz);
int settimeofday(const struct timeval *tv, const void *tz);
int asprintf(char **strp, const char *fmt, ...);
#endif
/* TI's libc does not have stat & friends, add them. */
#ifdef __TI_COMPILER_VERSION__
#include <file.h>
typedef unsigned int mode_t;
typedef size_t _off_t;
typedef long ssize_t;
struct stat {
int st_ino;
mode_t st_mode;
int st_nlink;
time_t st_mtime;
off_t st_size;
};
int _stat(const char *pathname, struct stat *st);
int stat(const char *pathname, struct stat *st);
#define __S_IFMT 0170000
#define __S_IFDIR 0040000
#define __S_IFCHR 0020000
#define __S_IFREG 0100000
#define __S_ISTYPE(mode, mask) (((mode) &__S_IFMT) == (mask))
#define S_IFDIR __S_IFDIR
#define S_IFCHR __S_IFCHR
#define S_IFREG __S_IFREG
#define S_ISDIR(mode) __S_ISTYPE((mode), __S_IFDIR)
#define S_ISREG(mode) __S_ISTYPE((mode), __S_IFREG)
#endif /* __TI_COMPILER_VERSION__ */
#ifndef CS_ENABLE_STDIO
#define CS_ENABLE_STDIO 1
#endif
#ifdef __cplusplus
}
#endif
#endif /* CS_PLATFORM == CS_P_CC3220 */
#endif /* CS_COMMON_PLATFORMS_PLATFORM_CC3200_H_ */
#ifdef MG_MODULE_LINES
#line 1 "common/platforms/platform_msp432.h" #line 1 "common/platforms/platform_msp432.h"
#endif #endif
/* /*
* Copyright (c) 2014-2016 Cesanta Software Limited * Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved * All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
#ifndef CS_COMMON_PLATFORMS_PLATFORM_MSP432_H_ #ifndef CS_COMMON_PLATFORMS_PLATFORM_MSP432_H_
@@ -885,8 +1076,20 @@ int _stat(const char *pathname, struct stat *st);
#line 1 "common/platforms/platform_tm4c129.h" #line 1 "common/platforms/platform_tm4c129.h"
#endif #endif
/* /*
* Copyright (c) 2014-2016 Cesanta Software Limited * Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved * All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
#ifndef CS_COMMON_PLATFORMS_PLATFORM_TM4C129_H_ #ifndef CS_COMMON_PLATFORMS_PLATFORM_TM4C129_H_
@@ -945,8 +1148,20 @@ typedef struct stat cs_stat_t;
#line 1 "common/platforms/platform_mbed.h" #line 1 "common/platforms/platform_mbed.h"
#endif #endif
/* /*
* Copyright (c) 2014-2016 Cesanta Software Limited * Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved * All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
#ifndef CS_COMMON_PLATFORMS_PLATFORM_MBED_H_ #ifndef CS_COMMON_PLATFORMS_PLATFORM_MBED_H_
@@ -1029,8 +1244,20 @@ in_addr_t inet_addr(const char *cp);
#line 1 "common/platforms/platform_nrf51.h" #line 1 "common/platforms/platform_nrf51.h"
#endif #endif
/* /*
* Copyright (c) 2014-2016 Cesanta Software Limited * Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved * All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
#ifndef CS_COMMON_PLATFORMS_PLATFORM_NRF51_H_ #ifndef CS_COMMON_PLATFORMS_PLATFORM_NRF51_H_
#define CS_COMMON_PLATFORMS_PLATFORM_NRF51_H_ #define CS_COMMON_PLATFORMS_PLATFORM_NRF51_H_
@@ -1074,8 +1301,20 @@ int gettimeofday(struct timeval *tp, void *tzp);
#line 1 "common/platforms/platform_nrf52.h" #line 1 "common/platforms/platform_nrf52.h"
#endif #endif
/* /*
* Copyright (c) 2014-2016 Cesanta Software Limited * Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved * All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
#ifndef CS_COMMON_PLATFORMS_PLATFORM_NRF52_H_ #ifndef CS_COMMON_PLATFORMS_PLATFORM_NRF52_H_
#define CS_COMMON_PLATFORMS_PLATFORM_NRF52_H_ #define CS_COMMON_PLATFORMS_PLATFORM_NRF52_H_
@@ -1122,8 +1361,20 @@ int gettimeofday(struct timeval *tp, void *tzp);
#line 1 "common/platforms/simplelink/cs_simplelink.h" #line 1 "common/platforms/simplelink/cs_simplelink.h"
#endif #endif
/* /*
* Copyright (c) 2014-2016 Cesanta Software Limited * Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved * All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
#ifndef CS_COMMON_PLATFORMS_SIMPLELINK_CS_SIMPLELINK_H_ #ifndef CS_COMMON_PLATFORMS_SIMPLELINK_CS_SIMPLELINK_H_
@@ -1280,7 +1531,7 @@ int sl_set_ssl_opts(int sock, struct mg_connection *nc);
#endif /* SL_MAJOR_VERSION_NUM < 2 */ #endif /* SL_MAJOR_VERSION_NUM < 2 */
int slfs_open(const unsigned char *fname, uint32_t flags); int slfs_open(const unsigned char *fname, uint32_t flags, uint32_t *token);
#endif /* MG_NET_IF == MG_NET_IF_SIMPLELINK */ #endif /* MG_NET_IF == MG_NET_IF_SIMPLELINK */
@@ -1493,8 +1744,20 @@ const char *strerror();
#line 1 "common/platforms/platform_nxp_lpc.h" #line 1 "common/platforms/platform_nxp_lpc.h"
#endif #endif
/* /*
* Copyright (c) 2014-2016 Cesanta Software Limited * Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved * All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
#ifndef CS_COMMON_PLATFORMS_PLATFORM_NXP_LPC_H_ #ifndef CS_COMMON_PLATFORMS_PLATFORM_NXP_LPC_H_
@@ -1549,8 +1812,20 @@ typedef struct stat cs_stat_t;
#line 1 "common/platforms/platform_nxp_kinetis.h" #line 1 "common/platforms/platform_nxp_kinetis.h"
#endif #endif
/* /*
* Copyright (c) 2014-2016 Cesanta Software Limited * Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved * All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
#ifndef CS_COMMON_PLATFORMS_PLATFORM_NXP_KINETIS_H_ #ifndef CS_COMMON_PLATFORMS_PLATFORM_NXP_KINETIS_H_
@@ -1583,8 +1858,20 @@ typedef struct stat cs_stat_t;
#line 1 "common/platforms/platform_pic32.h" #line 1 "common/platforms/platform_pic32.h"
#endif #endif
/* /*
* Copyright (c) 2014-2016 Cesanta Software Limited * Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved * All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
#ifndef CS_COMMON_PLATFORMS_PLATFORM_PIC32_H_ #ifndef CS_COMMON_PLATFORMS_PLATFORM_PIC32_H_
@@ -1623,8 +1910,20 @@ char *inet_ntoa(struct in_addr in);
#line 1 "common/platforms/platform_stm32.h" #line 1 "common/platforms/platform_stm32.h"
#endif #endif
/* /*
* Copyright (c) 2014-2016 Cesanta Software Limited * Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved * All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
#ifndef CS_COMMON_PLATFORMS_PLATFORM_STM32_H_ #ifndef CS_COMMON_PLATFORMS_PLATFORM_STM32_H_
@@ -1646,7 +1945,7 @@ char *inet_ntoa(struct in_addr in);
#include <stm32_sdk_hal.h> #include <stm32_sdk_hal.h>
#define to64(x) strtoll(x, NULL, 10) #define to64(x) strtoll(x, NULL, 10)
#define INT64_FMT PRId64 #define INT64_FMT "lld"
#define SIZE_T_FMT "u" #define SIZE_T_FMT "u"
typedef struct stat cs_stat_t; typedef struct stat cs_stat_t;
#define DIRSEP '/' #define DIRSEP '/'
@@ -1665,8 +1964,20 @@ typedef struct stat cs_stat_t;
#line 1 "common/platforms/lwip/mg_lwip.h" #line 1 "common/platforms/lwip/mg_lwip.h"
#endif #endif
/* /*
* Copyright (c) 2014-2016 Cesanta Software Limited * Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved * All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
#ifndef CS_COMMON_PLATFORMS_LWIP_MG_LWIP_H_ #ifndef CS_COMMON_PLATFORMS_LWIP_MG_LWIP_H_
@@ -1720,7 +2031,6 @@ typedef int sock_t;
#if MG_NET_IF == MG_NET_IF_LWIP_LOW_LEVEL #if MG_NET_IF == MG_NET_IF_LWIP_LOW_LEVEL
struct mg_mgr; struct mg_mgr;
struct mg_connection; struct mg_connection;
uint32_t mg_lwip_get_poll_delay_ms(struct mg_mgr *mgr);
void mg_lwip_set_keepalive_params(struct mg_connection *nc, int idle, void mg_lwip_set_keepalive_params(struct mg_connection *nc, int idle,
int interval, int count); int interval, int count);
#endif #endif
@@ -1737,8 +2047,20 @@ void mg_lwip_set_keepalive_params(struct mg_connection *nc, int idle,
#line 1 "common/cs_md5.h" #line 1 "common/cs_md5.h"
#endif #endif
/* /*
* Copyright (c) 2014 Cesanta Software Limited * Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved * All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
#ifndef CS_COMMON_MD5_H_ #ifndef CS_COMMON_MD5_H_
@@ -1773,8 +2095,20 @@ void cs_md5_final(unsigned char *md, cs_md5_ctx *c);
#line 1 "common/cs_sha1.h" #line 1 "common/cs_sha1.h"
#endif #endif
/* /*
* Copyright (c) 2014 Cesanta Software Limited * Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved * All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
#ifndef CS_COMMON_SHA1_H_ #ifndef CS_COMMON_SHA1_H_
@@ -1815,8 +2149,20 @@ void cs_hmac_sha1(const unsigned char *key, size_t key_len,
#line 1 "common/cs_time.h" #line 1 "common/cs_time.h"
#endif #endif
/* /*
* Copyright (c) 2014-2016 Cesanta Software Limited * Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved * All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
#ifndef CS_COMMON_CS_TIME_H_ #ifndef CS_COMMON_CS_TIME_H_
@@ -1848,8 +2194,20 @@ double cs_timegm(const struct tm *tm);
#line 1 "common/mg_str.h" #line 1 "common/mg_str.h"
#endif #endif
/* /*
* Copyright (c) 2014-2016 Cesanta Software Limited * Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved * All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
#ifndef CS_COMMON_MG_STR_H_ #ifndef CS_COMMON_MG_STR_H_
@@ -1857,8 +2215,6 @@ double cs_timegm(const struct tm *tm);
#include <stddef.h> #include <stddef.h>
/* Amalgamated: #include "common/platform.h" */
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
@@ -1883,6 +2239,8 @@ struct mg_str mg_mk_str_n(const char *s, size_t len);
/* Macro for initializing mg_str. */ /* Macro for initializing mg_str. */
#define MG_MK_STR(str_literal) \ #define MG_MK_STR(str_literal) \
{ str_literal, sizeof(str_literal) - 1 } { str_literal, sizeof(str_literal) - 1 }
#define MG_MK_STR_N(str_literal, len) \
{ str_literal, len }
#define MG_NULL_STR \ #define MG_NULL_STR \
{ NULL, 0 } { NULL, 0 }
@@ -1922,11 +2280,22 @@ int mg_strcmp(const struct mg_str str1, const struct mg_str str2);
*/ */
int mg_strncmp(const struct mg_str str1, const struct mg_str str2, size_t n); int mg_strncmp(const struct mg_str str1, const struct mg_str str2, size_t n);
/*
* Free the string (assuming it was heap allocated).
*/
void mg_strfree(struct mg_str *s);
/* /*
* Finds the first occurrence of a substring `needle` in the `haystack`. * Finds the first occurrence of a substring `needle` in the `haystack`.
*/ */
const char *mg_strstr(const struct mg_str haystack, const struct mg_str needle); const char *mg_strstr(const struct mg_str haystack, const struct mg_str needle);
/* Strip whitespace at the start and the end of s */
struct mg_str mg_strstrip(struct mg_str s);
/* Returns 1 if s starts with the given prefix. */
int mg_str_starts_with(struct mg_str s, struct mg_str prefix);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
@@ -1936,13 +2305,23 @@ const char *mg_strstr(const struct mg_str haystack, const struct mg_str needle);
#line 1 "common/mbuf.h" #line 1 "common/mbuf.h"
#endif #endif
/* /*
* Copyright (c) 2015 Cesanta Software Limited * Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved * All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
/* /*
* === Memory Buffers
*
* Mbufs are mutable/growing memory buffers, like C++ strings. * Mbufs are mutable/growing memory buffers, like C++ strings.
* Mbuf can append data to the end of a buffer or insert data into arbitrary * Mbuf can append data to the end of a buffer or insert data into arbitrary
* position in the middle of a buffer. The buffer grows automatically when * position in the middle of a buffer. The buffer grows automatically when
@@ -1963,6 +2342,14 @@ extern "C" {
#define MBUF_SIZE_MULTIPLIER 1.5 #define MBUF_SIZE_MULTIPLIER 1.5
#endif #endif
#ifndef MBUF_SIZE_MAX_HEADROOM
#ifdef BUFSIZ
#define MBUF_SIZE_MAX_HEADROOM BUFSIZ
#else
#define MBUF_SIZE_MAX_HEADROOM 1024
#endif
#endif
/* Memory buffer descriptor */ /* Memory buffer descriptor */
struct mbuf { struct mbuf {
char *buf; /* Buffer pointer */ char *buf; /* Buffer pointer */
@@ -1986,6 +2373,14 @@ void mbuf_free(struct mbuf *);
*/ */
size_t mbuf_append(struct mbuf *, const void *data, size_t data_size); size_t mbuf_append(struct mbuf *, const void *data, size_t data_size);
/*
* Appends data to the Mbuf and frees it (data must be heap-allocated).
*
* Returns the number of bytes appended or 0 if out of memory.
* data is freed irrespective of return value.
*/
size_t mbuf_append_and_free(struct mbuf *, void *data, size_t data_size);
/* /*
* Inserts data at a specified offset in the Mbuf. * Inserts data at a specified offset in the Mbuf.
* *
@@ -2006,6 +2401,12 @@ void mbuf_remove(struct mbuf *, size_t data_size);
*/ */
void mbuf_resize(struct mbuf *, size_t new_size); void mbuf_resize(struct mbuf *, size_t new_size);
/* Moves the state from one mbuf to the other. */
void mbuf_move(struct mbuf *from, struct mbuf *to);
/* Removes all the data from mbuf (if any). */
void mbuf_clear(struct mbuf *);
/* Shrinks an Mbuf by resizing its `size` to `len`. */ /* Shrinks an Mbuf by resizing its `size` to `len`. */
void mbuf_trim(struct mbuf *); void mbuf_trim(struct mbuf *);
@@ -2018,8 +2419,20 @@ void mbuf_trim(struct mbuf *);
#line 1 "common/cs_base64.h" #line 1 "common/cs_base64.h"
#endif #endif
/* /*
* Copyright (c) 2014 Cesanta Software Limited * Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved * All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
#ifndef CS_COMMON_CS_BASE64_H_ #ifndef CS_COMMON_CS_BASE64_H_
@@ -2054,6 +2467,14 @@ void cs_base64_finish(struct cs_base64_ctx *ctx);
void cs_base64_encode(const unsigned char *src, int src_len, char *dst); void cs_base64_encode(const unsigned char *src, int src_len, char *dst);
void cs_fprint_base64(FILE *f, const unsigned char *src, int src_len); void cs_fprint_base64(FILE *f, const unsigned char *src, int src_len);
/*
* Decodes a base64 string `s` length `len` into `dst`.
* `dst` must have enough space to hold the result.
* `*dec_len` will contain the resulting length of the string in `dst`
* while return value will return number of processed bytes in `src`.
* Return value == len indicates successful processing of all the data.
*/
int cs_base64_decode(const unsigned char *s, int len, char *dst, int *dec_len); int cs_base64_decode(const unsigned char *s, int len, char *dst, int *dec_len);
#ifdef __cplusplus #ifdef __cplusplus
@@ -2067,8 +2488,20 @@ int cs_base64_decode(const unsigned char *s, int len, char *dst, int *dec_len);
#line 1 "common/str_util.h" #line 1 "common/str_util.h"
#endif #endif
/* /*
* Copyright (c) 2015 Cesanta Software Limited * Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved * All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
#ifndef CS_COMMON_STR_UTIL_H_ #ifndef CS_COMMON_STR_UTIL_H_
@@ -2092,7 +2525,11 @@ int cs_base64_decode(const unsigned char *s, int len, char *dst, int *dec_len);
* Expands to a string representation of its argument: e.g. * Expands to a string representation of its argument: e.g.
* `CS_STRINGIFY_LIT(5) expands to "5"` * `CS_STRINGIFY_LIT(5) expands to "5"`
*/ */
#if !defined(_MSC_VER) || _MSC_VER >= 1900
#define CS_STRINGIFY_LIT(...) #__VA_ARGS__
#else
#define CS_STRINGIFY_LIT(x) #x #define CS_STRINGIFY_LIT(x) #x
#endif
/* /*
* Expands to a string representation of its argument, which is allowed * Expands to a string representation of its argument, which is allowed
@@ -2117,7 +2554,8 @@ size_t c_strnlen(const char *s, size_t maxlen);
/* /*
* Equivalent of standard `snprintf()`. * Equivalent of standard `snprintf()`.
*/ */
int c_snprintf(char *buf, size_t buf_size, const char *format, ...); int c_snprintf(char *buf, size_t buf_size, const char *format, ...)
PRINTF_LIKE(3, 4);
/* /*
* Equivalent of standard `vsnprintf()`. * Equivalent of standard `vsnprintf()`.
@@ -2185,7 +2623,8 @@ int mg_casecmp(const char *s1, const char *s2);
* *
* The purpose of this is to avoid malloc-ing if generated strings are small. * The purpose of this is to avoid malloc-ing if generated strings are small.
*/ */
int mg_asprintf(char **buf, size_t size, const char *fmt, ...); int mg_asprintf(char **buf, size_t size, const char *fmt, ...)
PRINTF_LIKE(3, 4);
/* Same as mg_asprintf, but takes varargs list. */ /* Same as mg_asprintf, but takes varargs list. */
int mg_avprintf(char **buf, size_t size, const char *fmt, va_list ap); int mg_avprintf(char **buf, size_t size, const char *fmt, va_list ap);
@@ -2208,6 +2647,8 @@ const char *mg_next_comma_list_entry(const char *list, struct mg_str *val,
/* /*
* Like `mg_next_comma_list_entry()`, but takes `list` as `struct mg_str`. * Like `mg_next_comma_list_entry()`, but takes `list` as `struct mg_str`.
* NB: Test return value's .p, not .len. On last itreation that yields result
* .len will be 0 but .p will not. When finished, .p will be NULL.
*/ */
struct mg_str mg_next_comma_list_entry_n(struct mg_str list, struct mg_str *val, struct mg_str mg_next_comma_list_entry_n(struct mg_str list, struct mg_str *val,
struct mg_str *eq_val); struct mg_str *eq_val);
@@ -3237,10 +3678,12 @@ struct mg_iface_vtable {
void (*connect_udp)(struct mg_connection *nc); void (*connect_udp)(struct mg_connection *nc);
/* Send functions for TCP and UDP. Sent data is copied before return. */ /* Send functions for TCP and UDP. Sent data is copied before return. */
void (*tcp_send)(struct mg_connection *nc, const void *buf, size_t len); int (*tcp_send)(struct mg_connection *nc, const void *buf, size_t len);
void (*udp_send)(struct mg_connection *nc, const void *buf, size_t len); int (*udp_send)(struct mg_connection *nc, const void *buf, size_t len);
void (*recved)(struct mg_connection *nc, size_t len); int (*tcp_recv)(struct mg_connection *nc, void *buf, size_t len);
int (*udp_recv)(struct mg_connection *nc, void *buf, size_t len,
union socket_address *sa, size_t *sa_len);
/* Perform interface-related connection initialization. Return 1 on ok. */ /* Perform interface-related connection initialization. Return 1 on ok. */
int (*create_conn)(struct mg_connection *nc); int (*create_conn)(struct mg_connection *nc);
@@ -3281,19 +3724,15 @@ void mg_if_accept_tcp_cb(struct mg_connection *nc, union socket_address *sa,
/* Callback invoked by connect methods. err = 0 -> ok, != 0 -> error. */ /* Callback invoked by connect methods. err = 0 -> ok, != 0 -> error. */
void mg_if_connect_cb(struct mg_connection *nc, int err); void mg_if_connect_cb(struct mg_connection *nc, int err);
/* Callback that reports that data has been put on the wire. */
void mg_if_sent_cb(struct mg_connection *nc, int num_sent);
/* /*
* Receive callback. * Callback that tells the core that data can be received.
* if `own` is true, buf must be heap-allocated and ownership is transferred * Core will use tcp/udp_recv to retrieve the data.
* to the core.
* Core will acknowledge consumption by calling iface::recved.
*/ */
void mg_if_recv_tcp_cb(struct mg_connection *nc, void *buf, int len, int own); void mg_if_can_recv_cb(struct mg_connection *nc);
void mg_if_can_send_cb(struct mg_connection *nc);
/* /*
* Receive callback. * Receive callback.
* buf must be heap-allocated and ownership is transferred to the core. * buf must be heap-allocated and ownership is transferred to the core.
* Core will acknowledge consumption by calling iface::recved.
*/ */
void mg_if_recv_udp_cb(struct mg_connection *nc, void *buf, int len, void mg_if_recv_udp_cb(struct mg_connection *nc, void *buf, int len,
union socket_address *sa, size_t sa_len); union socket_address *sa, size_t sa_len);
@@ -3301,10 +3740,13 @@ void mg_if_recv_udp_cb(struct mg_connection *nc, void *buf, int len,
/* void mg_if_close_conn(struct mg_connection *nc); */ /* void mg_if_close_conn(struct mg_connection *nc); */
/* Deliver a POLL event to the connection. */ /* Deliver a POLL event to the connection. */
void mg_if_poll(struct mg_connection *nc, time_t now); int mg_if_poll(struct mg_connection *nc, double now);
/* Deliver a TIMER event to the connection. */ /*
void mg_if_timer(struct mg_connection *c, double now); * Return minimal timer value amoung connections in the manager.
* Returns 0 if there aren't any timers.
*/
double mg_mgr_min_timer(const struct mg_mgr *mgr);
#ifdef __cplusplus #ifdef __cplusplus
} }
@@ -3463,6 +3905,7 @@ struct mg_mgr {
#endif #endif
void *user_data; /* User data */ void *user_data; /* User data */
int num_ifaces; int num_ifaces;
int num_calls;
struct mg_iface **ifaces; /* network interfaces */ struct mg_iface **ifaces; /* network interfaces */
const char *nameserver; /* DNS server to use */ const char *nameserver; /* DNS server to use */
}; };
@@ -3513,6 +3956,7 @@ struct mg_connection {
#define MG_F_WANT_READ (1 << 6) /* SSL specific */ #define MG_F_WANT_READ (1 << 6) /* SSL specific */
#define MG_F_WANT_WRITE (1 << 7) /* SSL specific */ #define MG_F_WANT_WRITE (1 << 7) /* SSL specific */
#define MG_F_IS_WEBSOCKET (1 << 8) /* Websocket specific */ #define MG_F_IS_WEBSOCKET (1 << 8) /* Websocket specific */
#define MG_F_RECV_AND_CLOSE (1 << 9) /* Drain rx and close the connection. */
/* Flags that are settable by user */ /* Flags that are settable by user */
#define MG_F_SEND_AND_CLOSE (1 << 10) /* Push remaining data and close */ #define MG_F_SEND_AND_CLOSE (1 << 10) /* Push remaining data and close */
@@ -3575,17 +4019,17 @@ void mg_mgr_init_opt(struct mg_mgr *mgr, void *user_data,
* *
* Closes and deallocates all active connections. * Closes and deallocates all active connections.
*/ */
void mg_mgr_free(struct mg_mgr *); void mg_mgr_free(struct mg_mgr *mgr);
/* /*
* This function performs the actual IO and must be called in a loop * This function performs the actual IO and must be called in a loop
* (an event loop). It returns the current timestamp. * (an event loop). It returns number of user events generated (except POLLs).
* `milli` is the maximum number of milliseconds to sleep. * `milli` is the maximum number of milliseconds to sleep.
* `mg_mgr_poll()` checks all connections for IO readiness. If at least one * `mg_mgr_poll()` checks all connections for IO readiness. If at least one
* of the connections is IO-ready, `mg_mgr_poll()` triggers the respective * of the connections is IO-ready, `mg_mgr_poll()` triggers the respective
* event handlers and returns. * event handlers and returns.
*/ */
time_t mg_mgr_poll(struct mg_mgr *, int milli); int mg_mgr_poll(struct mg_mgr *mgr, int milli);
#if MG_ENABLE_BROADCAST #if MG_ENABLE_BROADCAST
/* /*
@@ -3598,7 +4042,7 @@ time_t mg_mgr_poll(struct mg_mgr *, int milli);
* `func` callback function will be called by the IO thread for each * `func` callback function will be called by the IO thread for each
* connection. When called, the event will be `MG_EV_POLL`, and a message will * connection. When called, the event will be `MG_EV_POLL`, and a message will
* be passed as the `ev_data` pointer. Maximum message size is capped * be passed as the `ev_data` pointer. Maximum message size is capped
* by `MG_CTL_MSG_MESSAGE_SIZE` which is set to 8192 bytes. * by `MG_CTL_MSG_MESSAGE_SIZE` which is set to 8192 bytes by default.
*/ */
void mg_broadcast(struct mg_mgr *mgr, mg_event_handler_t cb, void *data, void mg_broadcast(struct mg_mgr *mgr, mg_event_handler_t cb, void *data,
size_t len); size_t len);
@@ -4234,10 +4678,17 @@ void mg_basic_auth_header(const struct mg_str user, const struct mg_str pass,
/* /*
* URL-escape the specified string. * URL-escape the specified string.
* All non-printable characters are escaped, plus `._-$,;~()/`. * All characters acept letters, numbers and characters listed in
* `safe` are escaped. If `hex_upper`is true, `A-F` are used for hex digits.
* Input need not be NUL-terminated, but the returned string is. * Input need not be NUL-terminated, but the returned string is.
* Returned string is heap-allocated and must be free()'d. * Returned string is heap-allocated and must be free()'d.
*/ */
#define MG_URL_ENCODE_F_SPACE_AS_PLUS (1 << 0)
#define MG_URL_ENCODE_F_UPPERCASE_HEX (1 << 1)
struct mg_str mg_url_encode_opt(const struct mg_str src,
const struct mg_str safe, unsigned int flags);
/* Same as `mg_url_encode_opt(src, "._-$,;~()/", 0)`. */
struct mg_str mg_url_encode(const struct mg_str src); struct mg_str mg_url_encode(const struct mg_str src);
#ifdef __cplusplus #ifdef __cplusplus
@@ -4329,6 +4780,14 @@ struct mg_http_multipart_part {
struct mg_str data; struct mg_str data;
int status; /* <0 on error */ int status; /* <0 on error */
void *user_data; void *user_data;
/*
* User handler can indicate how much of the data was consumed
* by setting this variable. By default, it is assumed that all
* data has been consumed by the handler.
* If not all data was consumed, user's handler will be invoked again later
* with the remainder.
*/
size_t num_data_consumed;
}; };
/* SSI call context */ /* SSI call context */
@@ -4347,7 +4806,7 @@ struct mg_ssi_call_ctx {
#if MG_ENABLE_HTTP_WEBSOCKET #if MG_ENABLE_HTTP_WEBSOCKET
#define MG_EV_WEBSOCKET_HANDSHAKE_REQUEST 111 /* struct http_message * */ #define MG_EV_WEBSOCKET_HANDSHAKE_REQUEST 111 /* struct http_message * */
#define MG_EV_WEBSOCKET_HANDSHAKE_DONE 112 /* NULL */ #define MG_EV_WEBSOCKET_HANDSHAKE_DONE 112 /* struct http_message * */
#define MG_EV_WEBSOCKET_FRAME 113 /* struct websocket_message * */ #define MG_EV_WEBSOCKET_FRAME 113 /* struct websocket_message * */
#define MG_EV_WEBSOCKET_CONTROL_FRAME 114 /* struct websocket_message * */ #define MG_EV_WEBSOCKET_CONTROL_FRAME 114 /* struct websocket_message * */
#endif #endif
@@ -4386,7 +4845,9 @@ struct mg_ssi_call_ctx {
* - MG_EV_WEBSOCKET_HANDSHAKE_REQUEST: server has received the WebSocket * - MG_EV_WEBSOCKET_HANDSHAKE_REQUEST: server has received the WebSocket
* handshake request. `ev_data` contains parsed HTTP request. * handshake request. `ev_data` contains parsed HTTP request.
* - MG_EV_WEBSOCKET_HANDSHAKE_DONE: server has completed the WebSocket * - MG_EV_WEBSOCKET_HANDSHAKE_DONE: server has completed the WebSocket
* handshake. `ev_data` is `NULL`. * handshake. `ev_data` is a `struct http_message` containing the
* client's request (server mode) or server's response (client).
* In client mode handler can examine `resp_code`, which should be 101.
* - MG_EV_WEBSOCKET_FRAME: new WebSocket frame has arrived. `ev_data` is * - MG_EV_WEBSOCKET_FRAME: new WebSocket frame has arrived. `ev_data` is
* `struct websocket_message *` * `struct websocket_message *`
* *
@@ -4680,9 +5141,9 @@ int mg_http_parse_header2(struct mg_str *hdr, const char *var_name, char **buf,
int mg_http_parse_header(struct mg_str *hdr, const char *var_name, char *buf, int mg_http_parse_header(struct mg_str *hdr, const char *var_name, char *buf,
size_t buf_size) size_t buf_size)
#ifdef __GNUC__ #ifdef __GNUC__
__attribute__((deprecated)); __attribute__((deprecated))
#endif #endif
; ;
/* /*
* Gets and parses the Authorization: Basic header * Gets and parses the Authorization: Basic header
+67 -29
View File
@@ -1,6 +1,18 @@
/* /*
* Copyright (c) 2014-2016 Cesanta Software Limited * Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved * All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
#include "common/cs_dbg.h" #include "common/cs_dbg.h"
@@ -12,19 +24,17 @@
#include "common/cs_time.h" #include "common/cs_time.h"
#include "common/str_util.h" #include "common/str_util.h"
enum cs_log_level cs_log_threshold WEAK = enum cs_log_level cs_log_level WEAK =
#if CS_ENABLE_DEBUG #if CS_ENABLE_DEBUG
LL_VERBOSE_DEBUG; LL_VERBOSE_DEBUG;
#else #else
LL_ERROR; LL_ERROR;
#endif #endif
static char *s_filter_pattern = NULL;
static size_t s_filter_pattern_len;
void cs_log_set_filter(const char *pattern) WEAK;
#if CS_ENABLE_STDIO #if CS_ENABLE_STDIO
static char *s_file_level = NULL;
void cs_log_set_file_level(const char *file_level) WEAK;
FILE *cs_log_file WEAK = NULL; FILE *cs_log_file WEAK = NULL;
@@ -34,34 +44,62 @@ double cs_log_ts WEAK;
enum cs_log_level cs_log_cur_msg_level WEAK = LL_NONE; enum cs_log_level cs_log_cur_msg_level WEAK = LL_NONE;
void cs_log_set_filter(const char *pattern) { void cs_log_set_file_level(const char *file_level) {
free(s_filter_pattern); char *fl = s_file_level;
if (pattern != NULL) { if (file_level != NULL) {
s_filter_pattern = strdup(pattern); s_file_level = strdup(file_level);
s_filter_pattern_len = strlen(pattern);
} else { } else {
s_filter_pattern = NULL; s_file_level = NULL;
s_filter_pattern_len = 0;
} }
free(fl);
} }
int cs_log_print_prefix(enum cs_log_level, const char *, const char *) WEAK; int cs_log_print_prefix(enum cs_log_level level, const char *file, int ln) WEAK;
int cs_log_print_prefix(enum cs_log_level level, const char *func, int cs_log_print_prefix(enum cs_log_level level, const char *file, int ln) {
const char *filename) { char prefix[CS_LOG_PREFIX_LEN], *q;
char prefix[21]; const char *p;
size_t fl = 0, ll = 0, pl = 0;
if (level > cs_log_threshold) return 0; if (level > cs_log_level && s_file_level == NULL) return 0;
if (s_filter_pattern != NULL &&
mg_match_prefix(s_filter_pattern, s_filter_pattern_len, func) == 0 && p = file + strlen(file);
mg_match_prefix(s_filter_pattern, s_filter_pattern_len, filename) == 0) {
return 0; while (p != file) {
const char c = *(p - 1);
if (c == '/' || c == '\\') break;
p--;
fl++;
}
ll = (ln < 10000 ? (ln < 1000 ? (ln < 100 ? (ln < 10 ? 1 : 2) : 3) : 4) : 5);
if (fl > (sizeof(prefix) - ll - 2)) fl = (sizeof(prefix) - ll - 2);
pl = fl + 1 + ll;
memcpy(prefix, p, fl);
q = prefix + pl;
memset(q, ' ', sizeof(prefix) - pl);
do {
*(--q) = '0' + (ln % 10);
ln /= 10;
} while (ln > 0);
*(--q) = ':';
if (s_file_level != NULL) {
enum cs_log_level pll = cs_log_level;
struct mg_str fl = mg_mk_str(s_file_level), ps = MG_MK_STR_N(prefix, pl);
struct mg_str k, v;
while ((fl = mg_next_comma_list_entry_n(fl, &k, &v)).p != NULL) {
bool yes = !(!mg_str_starts_with(ps, k) || v.len == 0);
if (!yes) continue;
pll = (enum cs_log_level)(*v.p - '0');
break;
}
if (level > pll) return 0;
} }
strncpy(prefix, func, 20);
prefix[20] = '\0';
if (cs_log_file == NULL) cs_log_file = stderr; if (cs_log_file == NULL) cs_log_file = stderr;
cs_log_cur_msg_level = level; cs_log_cur_msg_level = level;
fprintf(cs_log_file, "%-20s ", prefix); fwrite(prefix, 1, sizeof(prefix), cs_log_file);
#if CS_LOG_ENABLE_TS_DIFF #if CS_LOG_ENABLE_TS_DIFF
{ {
double now = cs_time(); double now = cs_time();
@@ -90,15 +128,15 @@ void cs_log_set_file(FILE *file) {
#else #else
void cs_log_set_filter(const char *pattern) { void cs_log_set_file_level(const char *file_level) {
(void) pattern; (void) file_level;
} }
#endif /* CS_ENABLE_STDIO */ #endif /* CS_ENABLE_STDIO */
void cs_log_set_level(enum cs_log_level level) WEAK; void cs_log_set_level(enum cs_log_level level) WEAK;
void cs_log_set_level(enum cs_log_level level) { void cs_log_set_level(enum cs_log_level level) {
cs_log_threshold = level; cs_log_level = level;
#if CS_LOG_ENABLE_TS_DIFF && CS_ENABLE_STDIO #if CS_LOG_ENABLE_TS_DIFF && CS_ENABLE_STDIO
cs_log_ts = cs_time(); cs_log_ts = cs_time();
#endif #endif
+44 -45
View File
@@ -1,6 +1,18 @@
/* /*
* Copyright (c) 2014-2016 Cesanta Software Limited * Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved * All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
#ifndef CS_COMMON_CS_DBG_H_ #ifndef CS_COMMON_CS_DBG_H_
@@ -16,6 +28,10 @@
#define CS_ENABLE_DEBUG 0 #define CS_ENABLE_DEBUG 0
#endif #endif
#ifndef CS_LOG_PREFIX_LEN
#define CS_LOG_PREFIX_LEN 24
#endif
#ifndef CS_LOG_ENABLE_TS_DIFF #ifndef CS_LOG_ENABLE_TS_DIFF
#define CS_LOG_ENABLE_TS_DIFF 0 #define CS_LOG_ENABLE_TS_DIFF 0
#endif #endif
@@ -46,51 +62,28 @@ enum cs_log_level {
void cs_log_set_level(enum cs_log_level level); void cs_log_set_level(enum cs_log_level level);
/* /*
* Set log filter. NULL (a default) logs everything. * A comma-separated set of prefix=level.
* Otherwise, function name and file name will be tested against the given * prefix is matched against the log prefix exactly as printed, including line
* pattern, and only matching messages will be printed. * number, but partial match is ok. Check stops on first matching entry.
* If nothing matches, default level is used.
* *
* For the pattern syntax, refer to `mg_match_prefix()` in `str_util.h`. * Examples:
* main.c:=4 - everything from main C at verbose debug level.
* mongoose.c=1,mjs.c=1,=4 - everything at verbose debug except mg_* and mjs_*
* *
* Example:
* ```c
* void foo(void) {
* LOG(LL_INFO, ("hello from foo"));
* }
*
* void bar(void) {
* LOG(LL_INFO, ("hello from bar"));
* }
*
* void test(void) {
* cs_log_set_filter(NULL);
* foo();
* bar();
*
* cs_log_set_filter("f*");
* foo();
* bar(); // Will NOT print anything
*
* cs_log_set_filter("bar");
* foo(); // Will NOT print anything
* bar();
* }
* ```
*/ */
void cs_log_set_filter(const char *pattern); void cs_log_set_file_level(const char *file_level);
/* /*
* Helper function which prints message prefix with the given `level`, function * Helper function which prints message prefix with the given `level`.
* name `func` and `filename`. If message should be printed (accordingly to the * If message should be printed (according to the current log level
* current log level and filter), prints the prefix and returns 1, otherwise * and filter), prints the prefix and returns 1, otherwise returns 0.
* returns 0.
* *
* Clients should typically just use `LOG()` macro. * Clients should typically just use `LOG()` macro.
*/ */
int cs_log_print_prefix(enum cs_log_level level, const char *func, int cs_log_print_prefix(enum cs_log_level level, const char *fname, int line);
const char *filename);
extern enum cs_log_level cs_log_threshold; extern enum cs_log_level cs_log_level;
#if CS_ENABLE_STDIO #if CS_ENABLE_STDIO
@@ -103,11 +96,9 @@ void cs_log_set_file(FILE *file);
* Prints log to the current log file, appends "\n" in the end and flushes the * Prints log to the current log file, appends "\n" in the end and flushes the
* stream. * stream.
*/ */
void cs_log_printf(const char *fmt, ...) void cs_log_printf(const char *fmt, ...) PRINTF_LIKE(1, 2);
#ifdef __GNUC__
__attribute__((format(printf, 1, 2))) #if CS_ENABLE_STDIO
#endif
;
/* /*
* Format and print message `x` with the given level `l`. Example: * Format and print message `x` with the given level `l`. Example:
@@ -117,11 +108,19 @@ void cs_log_printf(const char *fmt, ...)
* LOG(LL_DEBUG, ("my debug message: %d", 123)); * LOG(LL_DEBUG, ("my debug message: %d", 123));
* ``` * ```
*/ */
#define LOG(l, x) \ #define LOG(l, x) \
do { \ do { \
if (cs_log_print_prefix(l, __func__, __FILE__)) cs_log_printf x; \ if (cs_log_print_prefix(l, __FILE__, __LINE__)) { \
cs_log_printf x; \
} \
} while (0) } while (0)
#else
#define LOG(l, x) ((void) l)
#endif
#ifndef CS_NDEBUG #ifndef CS_NDEBUG
/* /*
+13 -1
View File
@@ -1,6 +1,18 @@
/* /*
* Copyright (c) 2014 Cesanta Software Limited * Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved * All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
#ifndef CS_COMMON_MD5_H_ #ifndef CS_COMMON_MD5_H_
+13 -1
View File
@@ -1,6 +1,18 @@
/* /*
* Copyright (c) 2014-2016 Cesanta Software Limited * Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved * All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
#include "common/cs_time.h" #include "common/cs_time.h"
+13 -1
View File
@@ -1,6 +1,18 @@
/* /*
* Copyright (c) 2014-2016 Cesanta Software Limited * Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved * All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
#ifndef CS_COMMON_CS_TIME_H_ #ifndef CS_COMMON_CS_TIME_H_
+13 -1
View File
@@ -1,6 +1,18 @@
/* /*
* Copyright (c) 2014-2016 Cesanta Software Limited * Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved * All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
#ifndef CS_COMMON_MG_MEM_H_ #ifndef CS_COMMON_MG_MEM_H_
+12 -1
View File
@@ -69,6 +69,7 @@
#define MG_NET_IF_SIMPLELINK 2 #define MG_NET_IF_SIMPLELINK 2
#define MG_NET_IF_LWIP_LOW_LEVEL 3 #define MG_NET_IF_LWIP_LOW_LEVEL 3
#define MG_NET_IF_PIC32 4 #define MG_NET_IF_PIC32 4
#define MG_NET_IF_NULL 5
#define MG_SSL_IF_OPENSSL 1 #define MG_SSL_IF_OPENSSL 1
#define MG_SSL_IF_MBEDTLS 2 #define MG_SSL_IF_MBEDTLS 2
@@ -92,8 +93,18 @@
/* Common stuff */ /* Common stuff */
#if !defined(PRINTF_LIKE)
#if defined(__GNUC__) || defined(__clang__) || defined(__TI_COMPILER_VERSION__)
#define PRINTF_LIKE(f, a) __attribute__((format(printf, f, a)))
#else
#define PRINTF_LIKE(f, a)
#endif
#endif
#if !defined(WEAK) #if !defined(WEAK)
#if (defined(__GNUC__) || defined(__TI_COMPILER_VERSION__)) && !defined(_WIN32) #if (defined(__GNUC__) || defined(__clang__) || \
defined(__TI_COMPILER_VERSION__)) && \
!defined(_WIN32)
#define WEAK __attribute__((weak)) #define WEAK __attribute__((weak))
#else #else
#define WEAK #define WEAK
+30 -7
View File
@@ -1,6 +1,18 @@
/* /*
* Copyright (c) 2014-2017 Cesanta Software Limited * Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved * All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
#include <stdint.h> #include <stdint.h>
@@ -15,6 +27,10 @@
#include "mgos_core_dump.h" #include "mgos_core_dump.h"
#include "mgos_hal.h" #include "mgos_hal.h"
#ifndef MGOS_ENABLE_CORE_DUMP
#define MGOS_ENABLE_CORE_DUMP 1
#endif
struct arm_exc_frame { struct arm_exc_frame {
uint32_t r0; uint32_t r0;
uint32_t r1; uint32_t r1;
@@ -41,7 +57,7 @@ struct arm_gdb_reg_file {
uint32_t fpscr; uint32_t fpscr;
} __attribute__((packed)); } __attribute__((packed));
#if ARM_HAVE_FPU #if ARM_HAVE_FPU && !defined(MGOS_BOOT_BUILD)
static void save_s16_s31(uint32_t *dst) { static void save_s16_s31(uint32_t *dst) {
__asm volatile( __asm volatile(
"\ "\
@@ -79,6 +95,7 @@ void arm_exc_handler_bottom(uint8_t isr_no, struct arm_exc_frame *ef,
struct arm_gdb_reg_file *rf) { struct arm_gdb_reg_file *rf) {
char buf[8]; char buf[8];
const char *name; const char *name;
(void) ef;
portDISABLE_INTERRUPTS(); portDISABLE_INTERRUPTS();
switch (isr_no) { switch (isr_no) {
case 0: case 0:
@@ -122,16 +139,20 @@ void arm_exc_handler_bottom(uint8_t isr_no, struct arm_exc_frame *ef,
name = "SysTick"; name = "SysTick";
break; break;
default: { default: {
#ifndef MGOS_BOOT_BUILD
sprintf(buf, "IRQ%u", isr_no - 16); sprintf(buf, "IRQ%u", isr_no - 16);
#endif
name = buf; name = buf;
} }
} }
mgos_cd_printf("\n\n--- Exception %u (%s) ---\n", isr_no, name); mgos_cd_printf("\n\n--- Exception %u (%s) ---\n", isr_no, name);
if (rf != NULL) { if (rf != NULL) {
mgos_cd_printf(" R0: 0x%08lx R1: 0x%08lx R2: 0x%08lx R3: 0x%08lx\n", mgos_cd_printf(
rf->r[0], rf->r[1], rf->r[2], rf->r[3]); " R%d: 0x%08lx R%d: 0x%08lx R%d: 0x%08lx R%d: 0x%08lx\n", 0,
mgos_cd_printf(" R4: 0x%08lx R5: 0x%08lx R6: 0x%08lx R7: 0x%08lx\n", rf->r[0], 1, rf->r[1], 2, rf->r[2], 3, rf->r[3]);
rf->r[4], rf->r[5], rf->r[6], rf->r[7]); mgos_cd_printf(
" R%d: 0x%08lx R%d: 0x%08lx R%d: 0x%08lx R%d: 0x%08lx\n", 4,
rf->r[4], 5, rf->r[5], 6, rf->r[6], 7, rf->r[7]);
mgos_cd_printf(" R8: 0x%08lx R9: 0x%08lx R10: 0x%08lx R11: 0x%08lx\n", mgos_cd_printf(" R8: 0x%08lx R9: 0x%08lx R10: 0x%08lx R11: 0x%08lx\n",
rf->r[8], rf->r[9], rf->r[10], rf->r[11]); rf->r[8], rf->r[9], rf->r[10], rf->r[11]);
mgos_cd_printf(" R12: 0x%08lx SP: 0x%08lx LR: 0x%08lx PC: 0x%08lx\n", mgos_cd_printf(" R12: 0x%08lx SP: 0x%08lx LR: 0x%08lx PC: 0x%08lx\n",
@@ -139,7 +160,7 @@ void arm_exc_handler_bottom(uint8_t isr_no, struct arm_exc_frame *ef,
mgos_cd_printf(" PSR: 0x%08lx\n", rf->cpsr); mgos_cd_printf(" PSR: 0x%08lx\n", rf->cpsr);
} }
memset(rf->d, 0, sizeof(rf->d)); memset(rf->d, 0, sizeof(rf->d));
#if ARM_HAVE_FPU #if ARM_HAVE_FPU && !defined(MGOS_BOOT_BUILD)
rf->fpscr = ef->fpscr; rf->fpscr = ef->fpscr;
memcpy((uint8_t *) rf->d, ef->s, sizeof(ef->s)); memcpy((uint8_t *) rf->d, ef->s, sizeof(ef->s));
print_fpu_regs((uint32_t *) rf->d, 0, ARRAY_SIZE(ef->s)); print_fpu_regs((uint32_t *) rf->d, 0, ARRAY_SIZE(ef->s));
@@ -152,10 +173,12 @@ void arm_exc_handler_bottom(uint8_t isr_no, struct arm_exc_frame *ef,
#else #else
rf->fpscr = 0; rf->fpscr = 0;
#endif #endif
#if MGOS_ENABLE_CORE_DUMP
mgos_cd_emit_header(); mgos_cd_emit_header();
mgos_cd_emit_section(MGOS_CORE_DUMP_SECTION_REGS, rf, sizeof(*rf)); mgos_cd_emit_section(MGOS_CORE_DUMP_SECTION_REGS, rf, sizeof(*rf));
mgos_cd_emit_section("SRAM", (void *) SRAM_BASE_ADDR, SRAM_SIZE); mgos_cd_emit_section("SRAM", (void *) SRAM_BASE_ADDR, SRAM_SIZE);
mgos_cd_emit_footer(); mgos_cd_emit_footer();
#endif
#ifdef MGOS_HALT_ON_EXCEPTION #ifdef MGOS_HALT_ON_EXCEPTION
mgos_cd_printf("Halting\n"); mgos_cd_printf("Halting\n");
while (1) { while (1) {
+34
View File
@@ -0,0 +1,34 @@
/*
* Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <math.h>
#include "mgos.h"
#include "mgos_system.h"
void (*mgos_nsleep100)(uint32_t n);
uint32_t mgos_nsleep100_loop_count = 0;
/* Provided by arm_nsleep100_{m4,m7}.S for M4 and M7 respectively. */
extern void mgos_nsleep100_impl(uint32_t n);
void mgos_nsleep100_cal(void) {
uint32_t cpu_freq = mgos_get_cpu_freq();
/* # of instruction cycles per 100 ns */
mgos_nsleep100_loop_count =
roundf((100.0f / 1000000000.0f) / (1.0f / cpu_freq));
mgos_nsleep100 = mgos_nsleep100_impl;
}
@@ -0,0 +1,50 @@
/*
* Copyright (c) 2014-2019 Cesanta Software Limited
* All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
.arch armv7e-m
.syntax unified
.thumb
/* These are required to satisfy TI linker. */
.eabi_attribute Tag_ABI_align_needed, 1
.eabi_attribute Tag_ABI_align_preserved, 1
.global mgos_nsleep100_impl
.global mgos_nsleep100_loop_count
#ifdef STM32
.section .RamFunc.mgos_nsleep100_impl
#else
.section .iram.mgos_nsleep100_impl
#endif
.type mgos_nsleep100_impl, %function
.align 4
mgos_nsleep100_impl:
ldr r3, =mgos_nsleep100_loop_count
ldr r3, [r3]
mul r0, r3
mov r1, #6
udiv r0, r0, r1
cbz r0, xxx
lxx:
subs r0, #1
bne lxx
xxx:
bx lr
.align 4
.size mgos_nsleep100_impl, . - mgos_nsleep100_impl
@@ -0,0 +1,54 @@
/*
* Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
.arch armv7e-m
.syntax unified
.thumb
/* These are required to satisfy TI linker. */
.eabi_attribute Tag_ABI_align_needed, 1
.eabi_attribute Tag_ABI_align_preserved, 1
.global mgos_nsleep100_impl
.global mgos_nsleep100_loop_count
#ifdef STM32
.section .RamFunc.mgos_nsleep100_impl
#else
.section .iram.mgos_nsleep100_impl
#endif
.type mgos_nsleep100_impl, %function
.align 4
mgos_nsleep100_impl:
ldr r3, =mgos_nsleep100_loop_count
ldr r3, [r3]
mul r0, r3
#ifdef STM32L4
mov r1, #3
#else
mov r1, #6
#endif
udiv r0, r0, r1
cbz r0, xxx
lxx:
subs r0, #1
bne lxx
xxx:
bx lr
.align 4
.size mgos_nsleep100_impl, . - mgos_nsleep100_impl
@@ -0,0 +1,49 @@
/*
* Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
.arch armv7e-m
.syntax unified
.thumb
/* These are required to satisfy TI linker. */
.eabi_attribute Tag_ABI_align_needed, 1
.eabi_attribute Tag_ABI_align_preserved, 1
.global mgos_nsleep100_impl
.global mgos_nsleep100_loop_count
#ifdef STM32
.section .RamFunc.mgos_nsleep100_impl
#else
.section .iram.mgos_nsleep100_impl
#endif
.type mgos_nsleep100_impl, %function
.align 4
mgos_nsleep100_impl:
ldr r3, =mgos_nsleep100_loop_count
ldr r3, [r3]
/* Because of speculative fetch, the core loop only takes 1 cycle. */
muls r0, r3
cbz r0, xxx
lxx:
subs r0, #1
bne lxx
xxx:
bx lr
.align 4
.size mgos_nsleep100_impl, . - mgos_nsleep100_impl
+13 -1
View File
@@ -1,6 +1,18 @@
/* /*
* Copyright (c) 2014-2016 Cesanta Software Limited * Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved * All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
#if CS_PLATFORM == CS_P_CC3200 #if CS_PLATFORM == CS_P_CC3200
+2 -2
View File
@@ -29,11 +29,11 @@ $(SDK_OBJS): CFLAGS += -include common/platform.h
# cc flags,file # cc flags,file
define cc define cc
$(vecho) "GCC $2 -> $@" $(vecho) "GCC $2"
$(Q) $(CC_WRAPPER) $(CC) -c $1 -o $@ $2 $(Q) $(CC_WRAPPER) $(CC) -c $1 -o $@ $2
endef endef
define cxx define cxx
$(vecho) "G++ $2 -> $@" $(vecho) "G++ $2"
$(Q) $(CC_WRAPPER) $(CXX) -c $1 -o $@ $2 $(Q) $(CC_WRAPPER) $(CXX) -c $1 -o $@ $2
endef endef
+3 -3
View File
@@ -17,17 +17,17 @@ CXXFLAGS += $(TI_C_CXX_FLAGS) $(C_CXX_FLAGS)
# cc flags,file # cc flags,file
define cc define cc
$(vecho) "TICC $2 -> $@" $(vecho) "TICC $2"
$(Q) $(CC_WRAPPER) $(CC) -c --preproc_with_compile -ppd=$@.d $1 --output_file=$@ $2 $(Q) $(CC_WRAPPER) $(CC) -c --preproc_with_compile -ppd=$@.d $1 --output_file=$@ $2
endef endef
define cxx define cxx
$(vecho) "TICXX $2 -> $@" $(vecho) "TICXX $2"
$(Q) $(CC_WRAPPER) $(CC) -c --preproc_with_compile -ppd=$@.d $1 --output_file=$@ $2 $(Q) $(CC_WRAPPER) $(CC) -c --preproc_with_compile -ppd=$@.d $1 --output_file=$@ $2
endef endef
# asm flags,file # asm flags,file
define asm define asm
$(vecho) "TIASM $2 -> $@" $(vecho) "TIASM $2"
$(Q) $(CC_WRAPPER) $(CC) -c $1 --output_file=$@ $2 $(Q) $(CC_WRAPPER) $(CC) -c $1 --output_file=$@ $2
endef endef
+40 -20
View File
@@ -1,20 +1,18 @@
/* /*
* Copyright (c) 2014-2016 Cesanta Software Limited * Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved * All rights reserved
* *
* Spiffy flasher. Implements strong checksums (MD5) and can use higher * Licensed under the Apache License, Version 2.0 (the ""License"");
* baud rates. Actual max baud rate will differe from device to device, * you may not use this file except in compliance with the License.
* but 921K seems to be common. * You may obtain a copy of the License at
* *
* SLIP protocol is used for communication. * http://www.apache.org/licenses/LICENSE-2.0
* First packet is a single byte - command number.
* After that, a packet with a variable number of 32-bit (LE) arguments,
* depending on command.
* *
* Then command produces variable number of packets of output, but first * Unless required by applicable law or agreed to in writing, software
* packet of length 1 is the response code: 0 for success, non-zero - error. * distributed under the License is distributed on an ""AS IS"" BASIS,
* * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See individual command description below. * See the License for the specific language governing permissions and
* limitations under the License.
*/ */
#include "stub_flasher.h" #include "stub_flasher.h"
@@ -27,7 +25,7 @@
#if defined(ESP8266) #if defined(ESP8266)
#include "eagle_soc.h" #include "eagle_soc.h"
#include "ets_sys.h" #include "ets_sys.h"
#include "../../../miniz.c" #include "miniz.c"
#elif defined(ESP32) #elif defined(ESP32)
#include "rom/efuse.h" #include "rom/efuse.h"
#include "rom/miniz.h" #include "rom/miniz.h"
@@ -40,7 +38,7 @@
#include "uart.h" #include "uart.h"
/* Param: baud rate. */ /* Param: baud rate. */
uint32_t params[1] __attribute__((section(".params"))); uint32_t params[2] __attribute__((section(".params")));
#define FLASH_BLOCK_SIZE 65536 #define FLASH_BLOCK_SIZE 65536
#define FLASH_SECTOR_SIZE 4096 #define FLASH_SECTOR_SIZE 4096
@@ -472,6 +470,27 @@ uint8_t cmd_loop(void) {
resp = 0; resp = 0;
break; break;
} }
case CMD_READ_REG: {
len = SLIP_recv(args, sizeof(args));
if (len == 4) {
uint32_t value = READ_PERI_REG((uint32_t *) args[0]);
SLIP_send(&value, sizeof(value));
resp = 0;
} else {
resp = 0x91;
}
break;
}
case CMD_WRITE_REG: {
len = SLIP_recv(args, sizeof(args));
if (len == 8) {
WRITE_PERI_REG((uint32_t *) args[0], args[1]);
resp = 0;
} else {
resp = 0xa1;
}
break;
}
} }
SLIP_send(&resp, 1); SLIP_send(&resp, 1);
} while (cmd != CMD_BOOT_FW && cmd != CMD_REBOOT); } while (cmd != CMD_BOOT_FW && cmd != CMD_REBOOT);
@@ -479,8 +498,7 @@ uint8_t cmd_loop(void) {
} }
void stub_main1(void) { void stub_main1(void) {
uint32_t baud_rate = params[0]; uint32_t old_baud_rate = params[0], new_baud_rate = params[1];
uint32_t greeting = 0x4941484f; /* OHAI */
uint8_t last_cmd; uint8_t last_cmd;
/* This points at us right now, reset for next boot. */ /* This points at us right now, reset for next boot. */
@@ -489,6 +507,7 @@ void stub_main1(void) {
/* Selects SPI functions for flash pins. */ /* Selects SPI functions for flash pins. */
#if defined(ESP8266) #if defined(ESP8266)
SelectSpiFunction(); SelectSpiFunction();
spi_flash_attach();
SET_PERI_REG_MASK(0x3FF00014, 1); /* Switch to 160 MHz */ SET_PERI_REG_MASK(0x3FF00014, 1); /* Switch to 160 MHz */
#elif defined(ESP32) #elif defined(ESP32)
esp_rom_spiflash_attach(ets_efuse_get_spiconfig(), 0 /* legacy */); esp_rom_spiflash_attach(ets_efuse_get_spiconfig(), 0 /* legacy */);
@@ -498,9 +517,10 @@ void stub_main1(void) {
0 /* deviceId */, 16 * 1024 * 1024 /* chip_size */, FLASH_BLOCK_SIZE, 0 /* deviceId */, 16 * 1024 * 1024 /* chip_size */, FLASH_BLOCK_SIZE,
FLASH_SECTOR_SIZE, FLASH_PAGE_SIZE, 0xffff /* status_mask */); FLASH_SECTOR_SIZE, FLASH_PAGE_SIZE, 0xffff /* status_mask */);
if (baud_rate > 0) { uint32_t old_div = 0;
if (new_baud_rate > 0) {
ets_delay_us(10000); ets_delay_us(10000);
set_baud_rate(0, baud_rate); old_div = set_baud_rate(0, old_baud_rate, new_baud_rate);
} }
/* Give host time to get ready too. */ /* Give host time to get ready too. */
@@ -511,7 +531,7 @@ void stub_main1(void) {
WRITE_PERI_REG(UART_FIFO_REG(0), 0x55); WRITE_PERI_REG(UART_FIFO_REG(0), 0x55);
} }
#else #else
SLIP_send(&greeting, 4); SLIP_send(&old_div, 4);
#endif #endif
last_cmd = cmd_loop(); last_cmd = cmd_loop();
@@ -527,7 +547,7 @@ void stub_main1(void) {
* then jumps to 0x4000108a, then checks strapping bits again (which will * then jumps to 0x4000108a, then checks strapping bits again (which will
* not have changed), and then proceeds to 0x400010a8. * not have changed), and then proceeds to 0x400010a8.
*/ */
volatile uint32_t *sp = &baud_rate; volatile uint32_t *sp = &old_baud_rate;
while (*sp != (uint32_t) 0x40001100) sp++; while (*sp != (uint32_t) 0x40001100) sp++;
*sp = 0x400010a8; *sp = 0x400010a8;
/* /*
+18
View File
@@ -91,6 +91,24 @@ enum stub_cmd {
* Output: arguments. * Output: arguments.
*/ */
CMD_ECHO = 8, CMD_ECHO = 8,
/*
* Read register value.
*
* Args: register address.
* Input: None.
* Output: register value.
*/
CMD_READ_REG = 9,
/*
* Write register value.
*
* Args: register address, value.
* Input: None.
* Output: None.
*/
CMD_WRITE_REG = 10,
}; };
#endif /* CS_COMMON_PLATFORMS_ESP8266_STUBS_STUB_FLASHER_H_ */ #endif /* CS_COMMON_PLATFORMS_ESP8266_STUBS_STUB_FLASHER_H_ */
+13 -1
View File
@@ -1,6 +1,18 @@
/* /*
* Copyright (c) 2014-2017 Cesanta Software Limited * Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved * All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
#include "soc/gpio_reg.h" #include "soc/gpio_reg.h"
+13 -1
View File
@@ -1,6 +1,18 @@
/* /*
* Copyright (c) 2014-2017 Cesanta Software Limited * Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved * All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
#pragma once #pragma once
+5
View File
@@ -42,5 +42,10 @@ SECTIONS {
INCLUDE "components/esp32/ld/esp32.rom.ld" INCLUDE "components/esp32/ld/esp32.rom.ld"
INCLUDE "components/esp32/ld/esp32.rom.spiram_incompatible_fns.ld" INCLUDE "components/esp32/ld/esp32.rom.spiram_incompatible_fns.ld"
PROVIDE(ets_isr_mask = 0x400067fc);
PROVIDE(ets_isr_unmask = 0x40006808);
PROVIDE(MD5Init = 0x4005da7c);
PROVIDE(MD5Update = 0x4005da9c);
PROVIDE(MD5Final = 0x4005db1c);
PROVIDE(esp_rom_spiflash_attach = 0x40062a6c); PROVIDE(esp_rom_spiflash_attach = 0x40062a6c);
PROVIDE(esp_rom_spiflash_config_clk = 0x40062bc8); PROVIDE(esp_rom_spiflash_config_clk = 0x40062bc8);
+11 -2
View File
@@ -1,9 +1,18 @@
/* /*
* Copyright (c) 2015 Cesanta Software Limited * Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved * All rights reserved
* *
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* *
* Stub template. * http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
#include <inttypes.h> #include <inttypes.h>
+22 -6
View File
@@ -1,15 +1,31 @@
/* /*
* Copyright (c) 2014-2016 Cesanta Software Limited * Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved * All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
#include "uart.h" #include "uart.h"
#include "rom_functions.h" #include "rom_functions.h"
void set_baud_rate(uint32_t uart_no, uint32_t baud_rate) { uint32_t set_baud_rate(uint32_t uart_no, uint32_t old_baud_rate,
uint32_t master_freq = ets_get_detected_xtal_freq() << 4; uint32_t new_baud_rate) {
master_freq += (baud_rate / 2); uint32_t uart_reg = REG_READ(UART_CLKDIV_REG(uart_no));
uint32_t div = master_freq / baud_rate; uint32_t uart_div = uart_reg & UART_CLKDIV_M;
uart_div_modify(uart_no, div); uint32_t fraction = (uart_reg >> UART_CLKDIV_FRAG_S) & UART_CLKDIV_FRAG_V;
uart_div = (uart_div << 4) + fraction;
uint32_t master_freq = uart_div * old_baud_rate;
uart_div_modify(uart_no, master_freq / new_baud_rate);
return uart_div;
} }
+15 -2
View File
@@ -1,6 +1,18 @@
/* /*
* Copyright (c) 2014-2016 Cesanta Software Limited * Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved * All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
#ifndef CS_COMMON_PLATFORMS_ESP32_STUBS_UART_H_ #ifndef CS_COMMON_PLATFORMS_ESP32_STUBS_UART_H_
@@ -8,6 +20,7 @@
#include <stdint.h> #include <stdint.h>
void set_baud_rate(uint32_t uart_no, uint32_t baud_rate); uint32_t set_baud_rate(uint32_t uart_no, uint32_t old_baud_rate,
uint32_t new_baud_rate);
#endif /* CS_COMMON_PLATFORMS_ESP32_STUBS_UART_H_ */ #endif /* CS_COMMON_PLATFORMS_ESP32_STUBS_UART_H_ */
+4 -3
View File
@@ -25,7 +25,7 @@ $(Q) $(CC_WRAPPER) $(LD) $(LIBDIRS) -T$(LD_SCRIPT) $(LDFLAGS) -o $@ \
endef endef
define compile_params define compile_params
$(vecho) "$5 $1 -> $2" $(vecho) "$5 $1"
$(Q) $(CC_WRAPPER) $3 -MD -MP $(INCDIRS) $4 -c $1 -o $2 $(Q) $(CC_WRAPPER) $3 -MD -MP $(INCDIRS) $4 -c $1 -o $2
endef endef
@@ -57,7 +57,8 @@ NO_Os_FLAGS= -fno-expensive-optimizations -fno-thread-jumps \
-fno-tree-pre -fno-tree-vrp -fno-tree-pre -fno-tree-vrp
C_CXX_FLAGS = -W -Wall -Werror -Wundef -Wno-comment -Wno-variadic-macros -Wpointer-arith \ C_CXX_FLAGS = -W -Wall -Werror -Wundef -Wno-comment -Wno-variadic-macros -Wpointer-arith \
-Os $(NO_Os_FLAGS) -g3 \ -Wno-missing-field-initializers \
-pipe -Os $(NO_Os_FLAGS) -g3 \
-Wl,-EL -fno-inline-functions \ -Wl,-EL -fno-inline-functions \
-D_XOPEN_SOURCE=500 \ -D_XOPEN_SOURCE=500 \
-nostdlib -mlongcalls -mtext-section-literals -D__ets__ -DSTATIC=static \ -nostdlib -mlongcalls -mtext-section-literals -D__ets__ -DSTATIC=static \
@@ -68,7 +69,7 @@ C_CXX_FLAGS = -W -Wall -Werror -Wundef -Wno-comment -Wno-variadic-macros -Wpoin
-DCS_PLATFORM=3 \ -DCS_PLATFORM=3 \
-ffunction-sections -fdata-sections -ffunction-sections -fdata-sections
CFLAGS = -std=c99 $(C_CXX_FLAGS) CFLAGS = -std=gnu99 $(C_CXX_FLAGS)
CXXFLAGS = -std=gnu++11 -fno-exceptions $(C_CXX_FLAGS) CXXFLAGS = -std=gnu++11 -fno-exceptions $(C_CXX_FLAGS)
# linker flags used to generate the main object file # linker flags used to generate the main object file
+14 -79
View File
@@ -1,13 +1,25 @@
/* /*
* Copyright (c) 2014-2016 Cesanta Software Limited * Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved * All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include <stdlib.h> #include <stdlib.h>
#include "mongoose/mongoose.h" #include "mongoose.h"
#ifdef RTOS_SDK #ifdef RTOS_SDK
#include "esp_libc.h" #include "esp_libc.h"
@@ -32,80 +44,3 @@ void mg_hash_sha1_v(size_t num_msgs, const uint8_t *msgs[],
const size_t *msg_lens, uint8_t *digest) { const size_t *msg_lens, uint8_t *digest) {
(void) sha1_vector(num_msgs, msgs, msg_lens, digest); (void) sha1_vector(num_msgs, msgs, msg_lens, digest);
} }
#if MG_ENABLE_SSL
#include "mbedtls/aes.h"
#include "mbedtls/sha256.h"
#define AES_PRIV_NR_POS (4 * 15)
/*
* Crypto functions in ROM/SDK.
* They come from wpa_supplicant, you can find them here https://w1.fi/cgit/
*
* Note that ROM version of the key setup function is older, does not take the
* number of bits argument and only supports AES-128. This prototype doesn't
* suit it, but since the difference is in the last aegument, it doesn't matter.
*/
extern void rijndaelKeySetupDec(void *ctx, const uint8_t *key, int bits);
extern int rijndaelKeySetupEnc(void *ctx, const uint8_t *key, int bits);
void aes_encrypt(void *ctx, const uint8_t *plain, uint8_t *crypt);
void aes_decrypt(void *ctx, const uint8_t *crypt, uint8_t *plain);
/*
* AES that comes with wpa_supplicant allocates its own AES context in
* aes_{encrypt,decrypt}_init. Ideally, we'd take that pointer and store it in
* our mbedtls_aes_context, but then a lot of space would be wasted.
* We do not call _init and go directly to key setup functions and poke number
* of rounds into the right place too. This is a bit hacky, but works fine.
* There is also a difference between older function in ROM and the one coming
* with SDK which is newer: the older one actually takes two arguments, not 3.
* But it doesn't matter, extra argument doesn't hurt and this works with both.
*/
int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key,
unsigned int keybits) {
if (keybits != 128) return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
((uint32_t *) ctx)[AES_PRIV_NR_POS] = 10;
rijndaelKeySetupEnc(ctx, key, 128);
return 0;
}
int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key,
unsigned int keybits) {
if (keybits != 128) return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
((uint32_t *) ctx)[AES_PRIV_NR_POS] = 10;
rijndaelKeySetupDec(ctx, key, 128);
return 0;
}
int mbedtls_internal_aes_encrypt(mbedtls_aes_context *ctx,
const unsigned char input[16],
unsigned char output[16]) {
aes_encrypt(ctx, input, output);
return 0;
}
int mbedtls_internal_aes_decrypt(mbedtls_aes_context *ctx,
const unsigned char input[16],
unsigned char output[16]) {
aes_decrypt(ctx, input, output);
return 0;
}
/* os_get_random uses hardware RNG, so it's cool. */
int mg_ssl_if_mbed_random(void *ctx, unsigned char *buf, size_t len) {
os_get_random(buf, len);
(void) ctx;
return 0;
}
/* For CryptoAuthLib host crypto. */
int atcac_sw_sha2_256(const uint8_t *data, size_t data_size,
uint8_t digest[32]) {
mbedtls_sha256(data, data_size, digest, false /* is_224 */);
return 0;
}
#endif /* MG_ENABLE_SSL */
@@ -1,6 +1,18 @@
/* /*
* Copyright (c) 2014-2017 Cesanta Software Limited * Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved * All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
#ifndef CS_COMMON_PLATFORMS_ESP8266_ESP_HW_WDT_REGISTER_H_ #ifndef CS_COMMON_PLATFORMS_ESP8266_ESP_HW_WDT_REGISTER_H_
@@ -1,6 +1,18 @@
/* /*
* Copyright (c) 2014-2016 Cesanta Software Limited * Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved * All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
#ifndef CS_COMMON_PLATFORMS_ESP8266_ESP_MISSING_INCLUDES_H_ #ifndef CS_COMMON_PLATFORMS_ESP8266_ESP_MISSING_INCLUDES_H_
+13 -1
View File
@@ -1,6 +1,18 @@
/* /*
* Copyright (c) 2014-2016 Cesanta Software Limited * Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved * All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
#ifndef CS_COMMON_PLATFORMS_ESP8266_ESP_SSL_KRYPTON_H_ #ifndef CS_COMMON_PLATFORMS_ESP8266_ESP_SSL_KRYPTON_H_
+13 -1
View File
@@ -1,6 +1,18 @@
/* /*
* Copyright (c) 2014 Cesanta Software Limited * Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved * All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
#include <string.h> #include <string.h>
+13 -1
View File
@@ -1,6 +1,18 @@
/* /*
* Copyright (c) 2014 Cesanta Software Limited * Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved * All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
#if ESP_UMM_ENABLE #if ESP_UMM_ENABLE
@@ -160,7 +160,8 @@ static uint8 calc_chksum(uint8 *start, uint8 *end) {
} }
#endif #endif
#define UART_CLKDIV_26MHZ(B) (52000000 + B / 2) / B #define UART_CLKDIV_80MHZ(B) (80000000 + B / 2) / B
#define UART_CLKDIV_52MHZ(B) (52000000 + B / 2) / B
// prevent this function being placed inline with main // prevent this function being placed inline with main
// to keep main's stack size as small as possible // to keep main's stack size as small as possible
@@ -182,10 +183,23 @@ uint32 NOINLINE find_image(void) {
// delay to slow boot (help see messages when debugging) // delay to slow boot (help see messages when debugging)
//ets_delay_us(2000000); //ets_delay_us(2000000);
uart_div_modify(0, UART_CLKDIV_26MHZ(115200)); /*
* UART divider depends on the APB frequency. Cold boot starts with 52MHz APB,
* SDK configures PLL, sets it to 80 and it persists across soft reset
* so on soft reset a different divider should be used. What we really want to
* know is if the PLL is running but since that is completely undocumented
* we use CPU frequency bit as a workaround: mos sets CPU to 160 MHz on startup
* so we assume that if frequency is preserved, then it's soft reset, PLL is
* running and APB is at 80 MHz.
*/
if (READ_PERI_REG(0x3ff00014) & 1) {
uart_div_modify(0, UART_CLKDIV_80MHZ(115200));
} else {
uart_div_modify(0, UART_CLKDIV_52MHZ(115200));
}
ets_delay_us(1000); ets_delay_us(1000);
ets_printf("\r\nrBoot v1.2.1 - richardaburton@gmail.com\r\n"); ets_printf("\r\nrBoot v1.2.1-cesanta1 - richardaburton@gmail.com\r\n");
// read rom header // read rom header
SPIRead(0, header, sizeof(rom_header)); SPIRead(0, header, sizeof(rom_header));
@@ -23,7 +23,7 @@ LD := $(addprefix $(XTENSA_BINDIR)/,xtensa-lx106-elf-gcc)
endif endif
CC_WRAPPER ?= CC_WRAPPER ?=
CFLAGS = -Os -O3 -Wpointer-arith -Wundef -Werror -Wl,-EL \ CFLAGS = -Os -Wpointer-arith -Wundef -Werror -Wl,-EL \
-fno-inline-functions -nostdlib -mlongcalls -mtext-section-literals \ -fno-inline-functions -nostdlib -mlongcalls -mtext-section-literals \
-D__ets__ -DIRAM='__attribute__((section(".fast.text")))' \ -D__ets__ -DIRAM='__attribute__((section(".fast.text")))' \
-DNOINSTR='__attribute__((no_instrument_function))' \ -DNOINSTR='__attribute__((no_instrument_function))' \
+3 -3
View File
@@ -23,13 +23,13 @@ all: $(STUB_ELF)
$(STUB_ELF): $(STUB) $(LIBS) $(STUB_ELF): $(STUB) $(LIBS)
@echo " CC $^ -> $@" @echo " CC $^ -> $@"
@[ -d $(BUILD_DIR) ] || mkdir $(BUILD_DIR) @[ -d $(BUILD_DIR) ] || mkdir $(BUILD_DIR)
@docker run --rm -i -v $(CURDIR)/../../../..:/src $(SDK) //bin/bash -c \ docker run --rm -i -v $(CURDIR)/../../../..:/src $(SDK) //bin/bash -c \
"cd /src/common/platforms/esp8266/stubs && \ "cd /src/common/platforms/esp8266/stubs && \
$(XT_CC) -std=c99 -Wall -Werror -Os -DESP8266 \ $(XT_CC) -std=c99 -Wall -Werror -Os -DESP8266 \
-mtext-section-literals -mlongcalls -nostdlib -fno-builtin \ -mtext-section-literals -mlongcalls -nostdlib -fno-builtin \
-I. -I/src/common/platforms/esp \ -I. -I/src/common/platforms/esp -I/src/common/platforms/esp8266 \
-I/opt/Espressif/ESP8266_SDK \ -I/opt/Espressif/ESP8266_SDK \
-Wl,-static -ffunction-sections -Wl,--gc-sections \ -Wl,-static -ffunction-sections -lgcc -Wl,--gc-sections \
-Tstub.ld $(CFLAGS) -o $@ $^" -Tstub.ld $(CFLAGS) -o $@ $^"
wrap: $(STUB_JSON) wrap: $(STUB_JSON)
@@ -41,3 +41,4 @@ INCLUDE "eagle.rom.addr.v6.ld"
PROVIDE(SPIFlashModeConfig = 0x40004568); PROVIDE(SPIFlashModeConfig = 0x40004568);
PROVIDE(SPI_erase_sector = 0x400040c0); PROVIDE(SPI_erase_sector = 0x400040c0);
PROVIDE(SPI_erase_block = 0x40004120); PROVIDE(SPI_erase_block = 0x40004120);
PROVIDE(uart_div_modify = 0x400039d8);
@@ -1,9 +1,18 @@
/* /*
* Copyright (c) 2015 Cesanta Software Limited * Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved * All rights reserved
* *
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* *
* Stub template. * http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
#include <inttypes.h> #include <inttypes.h>
+23 -5
View File
@@ -1,14 +1,32 @@
/* /*
* Copyright (c) 2014-2016 Cesanta Software Limited * Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved * All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
#include "uart.h" #include "uart.h"
#include "ets_sys.h" #include "ets_sys.h"
#define UART_CLKDIV_26MHZ(B) (52000000 + B / 2) / B #define UART_CLKDIV_M (UART_CLKDIV_CNT << UART_CLKDIV_S)
void set_baud_rate(uint32_t uart_no, uint32_t baud_rate) { void uart_div_modify(uint8_t uart_no, uint32_t div);
uint32_t div = UART_CLKDIV_26MHZ(baud_rate);
WRITE_PERI_REG(UART_CLKDIV_REG(uart_no), div & 0xfffff); uint32_t set_baud_rate(uint32_t uart_no, uint32_t old_baud_rate,
uint32_t new_baud_rate) {
uint32_t uart_reg = READ_PERI_REG(UART_CLKDIV_REG(uart_no));
uint32_t uart_div = uart_reg & UART_CLKDIV_M;
uint32_t master_freq = uart_div * old_baud_rate;
uart_div_modify(uart_no, master_freq / new_baud_rate);
return uart_div;
} }
+17 -3
View File
@@ -1,6 +1,18 @@
/* /*
* Copyright (c) 2014-2016 Cesanta Software Limited * Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved * All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
#ifndef CS_COMMON_PLATFORMS_ESP8266_STUBS_UART_H_ #ifndef CS_COMMON_PLATFORMS_ESP8266_STUBS_UART_H_
@@ -8,9 +20,11 @@
#include <stdint.h> #include <stdint.h>
void set_baud_rate(uint32_t uart_no, uint32_t baud_rate); #include "uart_register.h"
uint32_t set_baud_rate(uint32_t uart_no, uint32_t old_baud_rate,
uint32_t new_baud_rate);
#define REG_UART_BASE(i) (0x60000000 + (i) *0xf00)
#define UART_FIFO_REG(i) (REG_UART_BASE(i) + 0x0) #define UART_FIFO_REG(i) (REG_UART_BASE(i) + 0x0)
#define UART_CONF1_REG(i) (REG_UART_BASE(i) + 0x24) #define UART_CONF1_REG(i) (REG_UART_BASE(i) + 0x24)
#define UART_RX_TOUT_EN (BIT(31)) #define UART_RX_TOUT_EN (BIT(31))
@@ -1,23 +0,0 @@
#!/usr/bin/python
# Analyzers output of firmware compiler with -DESP_ENABLE_MALLOC_TRACES
import re
import sys
allocs = {}
for l in sys.stdin:
m = re.match(r'(ca|ma|re|fr) (\S+)\s*(\S*)\s*(\S*)', l)
if not m: continue
op = m.group(1)
if op in ('ca', 'ma'):
allocs[m.group(2)] = long(m.group(3))
else:
if m.group(2) in allocs:
del allocs[m.group(2)]
if op == 're':
allocs[m.group(3)] = long(m.group(4))
for k, v in sorted(allocs.iteritems()):
print k, v
+13 -2
View File
@@ -1,6 +1,18 @@
/* /*
* Copyright (c) 2014-2016 Cesanta Software Limited * Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved * All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
#ifndef CS_COMMON_PLATFORMS_LWIP_MG_LWIP_H_ #ifndef CS_COMMON_PLATFORMS_LWIP_MG_LWIP_H_
@@ -54,7 +66,6 @@ typedef int sock_t;
#if MG_NET_IF == MG_NET_IF_LWIP_LOW_LEVEL #if MG_NET_IF == MG_NET_IF_LWIP_LOW_LEVEL
struct mg_mgr; struct mg_mgr;
struct mg_connection; struct mg_connection;
uint32_t mg_lwip_get_poll_delay_ms(struct mg_mgr *mgr);
void mg_lwip_set_keepalive_params(struct mg_connection *nc, int idle, void mg_lwip_set_keepalive_params(struct mg_connection *nc, int idle,
int interval, int count); int interval, int count);
#endif #endif
+34 -108
View File
@@ -1,6 +1,18 @@
/* /*
* Copyright (c) 2014-2016 Cesanta Software Limited * Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved * All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
#if MG_NET_IF == MG_NET_IF_LWIP_LOW_LEVEL #if MG_NET_IF == MG_NET_IF_LWIP_LOW_LEVEL
@@ -41,38 +53,27 @@ void mg_ev_mgr_lwip_process_signals(struct mg_mgr *mgr) {
(struct mg_ev_mgr_lwip_data *) mgr->ifaces[MG_MAIN_IFACE]->data; (struct mg_ev_mgr_lwip_data *) mgr->ifaces[MG_MAIN_IFACE]->data;
while (md->sig_queue_len > 0) { while (md->sig_queue_len > 0) {
mgos_lock(); mgos_lock();
int sig = md->sig_queue[md->start_index].sig; int i = md->start_index;
struct mg_connection *nc = md->sig_queue[md->start_index].nc; int sig = md->sig_queue[i].sig;
struct mg_connection *nc = md->sig_queue[i].nc;
struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock; struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock;
md->start_index = (md->start_index + 1) % MG_SIG_QUEUE_LEN; md->start_index = (i + 1) % MG_SIG_QUEUE_LEN;
md->sig_queue_len--; md->sig_queue_len--;
mgos_unlock(); mgos_unlock();
if (nc->iface == NULL || nc->mgr == NULL) continue; if (nc->iface == NULL || nc->mgr == NULL) continue;
switch (sig) { switch (sig) {
case MG_SIG_CONNECT_RESULT: { case MG_SIG_CONNECT_RESULT: {
#if MG_ENABLE_SSL mg_if_connect_cb(nc, cs->err);
if (cs->err == 0 && (nc->flags & MG_F_SSL) &&
!(nc->flags & MG_F_SSL_HANDSHAKE_DONE)) {
mg_lwip_ssl_do_hs(nc);
} else
#endif
{
mg_if_connect_cb(nc, cs->err);
}
break; break;
} }
case MG_SIG_CLOSE_CONN: { case MG_SIG_CLOSE_CONN: {
nc->flags |= MG_F_SEND_AND_CLOSE;
mg_close_conn(nc); mg_close_conn(nc);
break; break;
} }
case MG_SIG_RECV: { case MG_SIG_RECV: {
cs->recv_pending = 0; cs->recv_pending = 0;
if (nc->flags & MG_F_UDP) { mg_if_can_recv_cb(nc);
mg_lwip_handle_recv_udp(nc); mbuf_trim(&nc->recv_mbuf);
} else {
mg_lwip_handle_recv_tcp(nc);
}
break; break;
} }
case MG_SIG_TOMBSTONE: { case MG_SIG_TOMBSTONE: {
@@ -87,7 +88,8 @@ void mg_ev_mgr_lwip_process_signals(struct mg_mgr *mgr) {
} }
void mg_lwip_if_init(struct mg_iface *iface) { void mg_lwip_if_init(struct mg_iface *iface) {
LOG(LL_INFO, ("%p Mongoose init", iface)); LOG(LL_INFO, ("Mongoose %s, LwIP %u.%u.%u", MG_VERSION, LWIP_VERSION_MAJOR,
LWIP_VERSION_MINOR, LWIP_VERSION_REVISION));
iface->data = MG_CALLOC(1, sizeof(struct mg_ev_mgr_lwip_data)); iface->data = MG_CALLOC(1, sizeof(struct mg_ev_mgr_lwip_data));
} }
@@ -126,42 +128,7 @@ time_t mg_lwip_if_poll(struct mg_iface *iface, int timeout_ms) {
struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock; struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock;
tmp = nc->next; tmp = nc->next;
n++; n++;
if ((nc->flags & MG_F_CLOSE_IMMEDIATELY) || if (!mg_if_poll(nc, now)) continue;
((nc->flags & MG_F_SEND_AND_CLOSE) && (nc->flags & MG_F_UDP) &&
(nc->send_mbuf.len == 0))) {
mg_close_conn(nc);
continue;
}
mg_if_poll(nc, now);
mg_if_timer(nc, now);
#if MG_ENABLE_SSL
if ((nc->flags & MG_F_SSL) && cs != NULL && cs->pcb.tcp != NULL &&
cs->pcb.tcp->state == ESTABLISHED) {
if (((nc->flags & MG_F_WANT_WRITE) ||
((nc->send_mbuf.len > 0) &&
(nc->flags & MG_F_SSL_HANDSHAKE_DONE))) &&
cs->pcb.tcp->snd_buf > 0) {
/* Can write more. */
if (nc->flags & MG_F_SSL_HANDSHAKE_DONE) {
if (!(nc->flags & MG_F_CONNECTING)) mg_lwip_ssl_send(nc);
} else {
mg_lwip_ssl_do_hs(nc);
}
}
if (cs->rx_chain != NULL || (nc->flags & MG_F_WANT_READ)) {
if (nc->flags & MG_F_SSL_HANDSHAKE_DONE) {
if (!(nc->flags & MG_F_CONNECTING)) mg_lwip_ssl_recv(nc);
} else {
mg_lwip_ssl_do_hs(nc);
}
}
} else
#endif /* MG_ENABLE_SSL */
{
if (nc->send_mbuf.len > 0 && !(nc->flags & MG_F_CONNECTING)) {
mg_lwip_send_more(nc);
}
}
if (nc->sock != INVALID_SOCKET && if (nc->sock != INVALID_SOCKET &&
!(nc->flags & (MG_F_UDP | MG_F_LISTENING)) && cs->pcb.tcp != NULL && !(nc->flags & (MG_F_UDP | MG_F_LISTENING)) && cs->pcb.tcp != NULL &&
cs->pcb.tcp->unsent != NULL) { cs->pcb.tcp->unsent != NULL) {
@@ -175,14 +142,17 @@ time_t mg_lwip_if_poll(struct mg_iface *iface, int timeout_ms) {
} }
if (nc->sock != INVALID_SOCKET) { if (nc->sock != INVALID_SOCKET) {
/* Try to consume data from cs->rx_chain */ if (mg_lwip_if_can_send(nc, cs)) {
mg_lwip_consume_rx_chain_tcp(nc); mg_if_can_send_cb(nc);
mbuf_trim(&nc->send_mbuf);
/* }
* If the connection is about to close, and rx_chain is finally empty, if (cs->rx_chain != NULL) {
* send the MG_SIG_CLOSE_CONN signal mg_if_can_recv_cb(nc);
*/ } else if (cs->draining_rx_chain) {
if (cs->draining_rx_chain && cs->rx_chain == NULL) { /*
* If the connection is about to close, and rx_chain is finally empty,
* send the MG_SIG_CLOSE_CONN signal
*/
mg_lwip_post_signal(MG_SIG_CLOSE_CONN, nc); mg_lwip_post_signal(MG_SIG_CLOSE_CONN, nc);
} }
} }
@@ -196,48 +166,4 @@ time_t mg_lwip_if_poll(struct mg_iface *iface, int timeout_ms) {
return now; return now;
} }
uint32_t mg_lwip_get_poll_delay_ms(struct mg_mgr *mgr) {
struct mg_connection *nc;
double now;
double min_timer = 0;
int num_timers = 0;
mg_ev_mgr_lwip_process_signals(mgr);
for (nc = mg_next(mgr, NULL); nc != NULL; nc = mg_next(mgr, nc)) {
struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock;
if (nc->ev_timer_time > 0) {
if (num_timers == 0 || nc->ev_timer_time < min_timer) {
min_timer = nc->ev_timer_time;
}
num_timers++;
}
if (nc->send_mbuf.len > 0
#if MG_ENABLE_SSL
|| (nc->flags & MG_F_WANT_WRITE)
#endif
) {
int can_send = 0;
/* We have stuff to send, but can we? */
if (nc->flags & MG_F_UDP) {
/* UDP is always ready for sending. */
can_send = (cs->pcb.udp != NULL);
} else {
can_send = (cs->pcb.tcp != NULL && cs->pcb.tcp->snd_buf > 0);
}
/* We want and can send, request a poll immediately. */
if (can_send) return 0;
}
}
uint32_t timeout_ms = ~0;
now = mg_time();
if (num_timers > 0) {
/* If we have a timer that is past due, do a poll ASAP. */
if (min_timer < now) return 0;
double timer_timeout_ms = (min_timer - now) * 1000 + 1 /* rounding */;
if (timer_timeout_ms < timeout_ms) {
timeout_ms = timer_timeout_ms;
}
}
return timeout_ms;
}
#endif /* MG_NET_IF == MG_NET_IF_LWIP_LOW_LEVEL */ #endif /* MG_NET_IF == MG_NET_IF_LWIP_LOW_LEVEL */
+105 -166
View File
@@ -1,6 +1,18 @@
/* /*
* Copyright (c) 2014-2016 Cesanta Software Limited * Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved * All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
#if MG_ENABLE_NET_IF_LWIP_LOW_LEVEL #if MG_ENABLE_NET_IF_LWIP_LOW_LEVEL
@@ -57,10 +69,6 @@
typedef void (*tcpip_callback_fn)(void *arg); typedef void (*tcpip_callback_fn)(void *arg);
#endif #endif
void mg_lwip_ssl_do_hs(struct mg_connection *nc);
void mg_lwip_ssl_send(struct mg_connection *nc);
void mg_lwip_ssl_recv(struct mg_connection *nc);
void mg_lwip_if_init(struct mg_iface *iface); void mg_lwip_if_init(struct mg_iface *iface);
void mg_lwip_if_free(struct mg_iface *iface); void mg_lwip_if_free(struct mg_iface *iface);
void mg_lwip_if_add_conn(struct mg_connection *nc); void mg_lwip_if_add_conn(struct mg_connection *nc);
@@ -118,7 +126,7 @@ static err_t mg_lwip_tcp_conn_cb(void *arg, struct tcp_pcb *tpcb, err_t err) {
static void mg_lwip_tcp_error_cb(void *arg, err_t err) { static void mg_lwip_tcp_error_cb(void *arg, err_t err) {
struct mg_connection *nc = (struct mg_connection *) arg; struct mg_connection *nc = (struct mg_connection *) arg;
DBG(("%p conn error %d", nc, err)); DBG(("%p conn error %d", nc, err));
if (nc == NULL) return; if (nc == NULL || (nc->flags & MG_F_CLOSE_IMMEDIATELY)) return;
struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock; struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock;
cs->pcb.tcp = NULL; /* Has already been deallocated */ cs->pcb.tcp = NULL; /* Has already been deallocated */
if (nc->flags & MG_F_CONNECTING) { if (nc->flags & MG_F_CONNECTING) {
@@ -132,10 +140,12 @@ static void mg_lwip_tcp_error_cb(void *arg, err_t err) {
static err_t mg_lwip_tcp_recv_cb(void *arg, struct tcp_pcb *tpcb, static err_t mg_lwip_tcp_recv_cb(void *arg, struct tcp_pcb *tpcb,
struct pbuf *p, err_t err) { struct pbuf *p, err_t err) {
struct mg_connection *nc = (struct mg_connection *) arg; struct mg_connection *nc = (struct mg_connection *) arg;
DBG(("%p %p %u %d", nc, tpcb, (p != NULL ? p->tot_len : 0), err)); struct mg_lwip_conn_state *cs =
(nc ? (struct mg_lwip_conn_state *) nc->sock : NULL);
DBG(("%p %p %p %p %u %d", nc, cs, tpcb, p, (p != NULL ? p->tot_len : 0),
err));
if (p == NULL) { if (p == NULL) {
if (nc != NULL && !(nc->flags & MG_F_CLOSE_IMMEDIATELY)) { if (nc != NULL && !(nc->flags & MG_F_CLOSE_IMMEDIATELY)) {
struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock;
if (cs->rx_chain != NULL) { if (cs->rx_chain != NULL) {
/* /*
* rx_chain still contains non-consumed data, don't close the * rx_chain still contains non-consumed data, don't close the
@@ -153,7 +163,6 @@ static err_t mg_lwip_tcp_recv_cb(void *arg, struct tcp_pcb *tpcb,
tcp_abort(tpcb); tcp_abort(tpcb);
return ERR_ARG; return ERR_ARG;
} }
struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock;
/* /*
* If we get a chain of more than one segment at once, we need to bump * If we get a chain of more than one segment at once, we need to bump
* refcount on the subsequent bufs to make them independent. * refcount on the subsequent bufs to make them independent.
@@ -168,7 +177,7 @@ static err_t mg_lwip_tcp_recv_cb(void *arg, struct tcp_pcb *tpcb,
} else if (pbuf_clen(cs->rx_chain) >= 4) { } else if (pbuf_clen(cs->rx_chain) >= 4) {
/* ESP SDK has a limited pool of 5 pbufs. We must not hog them all or RX /* ESP SDK has a limited pool of 5 pbufs. We must not hog them all or RX
* will be completely blocked. We already have at least 4 in the chain, * will be completely blocked. We already have at least 4 in the chain,
* this one is, so we have to make a copy and release this one. */ * this one is the last, so we have to make a copy and release this one. */
struct pbuf *np = pbuf_alloc(PBUF_RAW, p->tot_len, PBUF_RAM); struct pbuf *np = pbuf_alloc(PBUF_RAW, p->tot_len, PBUF_RAM);
if (np != NULL) { if (np != NULL) {
pbuf_copy(np, p); pbuf_copy(np, p);
@@ -176,58 +185,10 @@ static err_t mg_lwip_tcp_recv_cb(void *arg, struct tcp_pcb *tpcb,
p = np; p = np;
} }
} }
mgos_unlock();
mg_lwip_recv_common(nc, p); mg_lwip_recv_common(nc, p);
return ERR_OK;
}
static void mg_lwip_consume_rx_chain_tcp(struct mg_connection *nc) {
struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock;
if (cs->rx_chain == NULL) return;
#if MG_ENABLE_SSL
if (nc->flags & MG_F_SSL) {
if (nc->flags & MG_F_SSL_HANDSHAKE_DONE) {
mg_lwip_ssl_recv(nc);
} else {
mg_lwip_ssl_do_hs(nc);
}
return;
}
#endif
mgos_lock();
while (cs->rx_chain != NULL && nc->recv_mbuf.len < nc->recv_mbuf_limit) {
struct pbuf *seg = cs->rx_chain;
size_t seg_len = (seg->len - cs->rx_offset);
size_t buf_avail = (nc->recv_mbuf_limit - nc->recv_mbuf.len);
size_t len = MIN(seg_len, buf_avail);
char *data = (char *) MG_MALLOC(len);
if (data == NULL) {
mgos_unlock();
DBG(("OOM"));
return;
}
pbuf_copy_partial(seg, data, len, cs->rx_offset);
cs->rx_offset += len;
if (cs->rx_offset == cs->rx_chain->len) {
cs->rx_chain = pbuf_dechain(cs->rx_chain);
pbuf_free(seg);
cs->rx_offset = 0;
}
mgos_unlock();
mg_if_recv_tcp_cb(nc, data, len, 1 /* own */);
mgos_lock();
}
mgos_unlock(); mgos_unlock();
} (void) err;
return ERR_OK;
static void mg_lwip_handle_recv_tcp(struct mg_connection *nc) {
mg_lwip_consume_rx_chain_tcp(nc);
if (nc->send_mbuf.len > 0) {
mg_lwip_mgr_schedule_poll(nc->mgr);
}
} }
static err_t mg_lwip_tcp_sent_cb(void *arg, struct tcp_pcb *tpcb, static err_t mg_lwip_tcp_sent_cb(void *arg, struct tcp_pcb *tpcb,
@@ -239,6 +200,10 @@ static err_t mg_lwip_tcp_sent_cb(void *arg, struct tcp_pcb *tpcb,
nc->send_mbuf.len == 0 && tpcb->unsent == NULL && tpcb->unacked == NULL) { nc->send_mbuf.len == 0 && tpcb->unsent == NULL && tpcb->unacked == NULL) {
mg_lwip_post_signal(MG_SIG_CLOSE_CONN, nc); mg_lwip_post_signal(MG_SIG_CLOSE_CONN, nc);
} }
if (nc->send_mbuf.len > 0 || (nc->flags & MG_F_WANT_WRITE)) {
mg_lwip_mgr_schedule_poll(nc->mgr);
}
(void) num_sent;
return ERR_OK; return ERR_OK;
} }
@@ -313,13 +278,14 @@ static void mg_lwip_udp_recv_cb(void *arg, struct udp_pcb *pcb, struct pbuf *p,
/* Logic in the recv handler requires that there be exactly one data pbuf. */ /* Logic in the recv handler requires that there be exactly one data pbuf. */
p = pbuf_coalesce(p, PBUF_RAW); p = pbuf_coalesce(p, PBUF_RAW);
pbuf_chain(sap, p); pbuf_chain(sap, p);
mgos_lock();
mg_lwip_recv_common(nc, sap); mg_lwip_recv_common(nc, sap);
mgos_unlock();
(void) pcb; (void) pcb;
} }
static void mg_lwip_recv_common(struct mg_connection *nc, struct pbuf *p) { static void mg_lwip_recv_common(struct mg_connection *nc, struct pbuf *p) {
struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock; struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock;
mgos_lock();
if (cs->rx_chain == NULL) { if (cs->rx_chain == NULL) {
cs->rx_chain = p; cs->rx_chain = p;
} else { } else {
@@ -329,32 +295,30 @@ static void mg_lwip_recv_common(struct mg_connection *nc, struct pbuf *p) {
cs->recv_pending = 1; cs->recv_pending = 1;
mg_lwip_post_signal(MG_SIG_RECV, nc); mg_lwip_post_signal(MG_SIG_RECV, nc);
} }
mgos_unlock();
} }
static void mg_lwip_handle_recv_udp(struct mg_connection *nc) { static int mg_lwip_if_udp_recv(struct mg_connection *nc, void *buf, size_t len,
struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock; union socket_address *sa, size_t *sa_len) {
/* /*
* For UDP, RX chain consists of interleaved address and packet bufs: * For UDP, RX chain consists of interleaved address and packet bufs:
* Address pbuf followed by exactly one data pbuf (recv_cb took care of that). * Address pbuf followed by exactly one data pbuf (recv_cb took care of that).
*/ */
while (cs->rx_chain != NULL) { int res = 0;
struct pbuf *sap = cs->rx_chain; struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock;
struct pbuf *p = sap->next; if (nc->sock == INVALID_SOCKET) return -1;
cs->rx_chain = pbuf_dechain(p); mgos_lock();
size_t data_len = p->len; if (cs->rx_chain != NULL) {
char *data = (char *) MG_MALLOC(data_len); struct pbuf *ap = cs->rx_chain;
if (data != NULL) { struct pbuf *dp = ap->next;
pbuf_copy_partial(p, data, data_len, 0); cs->rx_chain = pbuf_dechain(dp);
pbuf_free(p); res = MIN(dp->len, len);
mg_if_recv_udp_cb(nc, data, data_len, pbuf_copy_partial(dp, buf, res, 0);
(union socket_address *) sap->payload, sap->len); pbuf_free(dp);
pbuf_free(sap); pbuf_copy_partial(ap, sa, MIN(*sa_len, ap->len), 0);
} else { pbuf_free(ap);
pbuf_free(p);
pbuf_free(sap);
}
} }
mgos_unlock();
return res;
} }
static void mg_lwip_if_connect_udp_tcpip(void *arg) { static void mg_lwip_if_connect_udp_tcpip(void *arg) {
@@ -376,13 +340,6 @@ void mg_lwip_if_connect_udp(struct mg_connection *nc) {
tcpip_callback(mg_lwip_if_connect_udp_tcpip, nc); tcpip_callback(mg_lwip_if_connect_udp_tcpip, nc);
} }
void mg_lwip_accept_conn(struct mg_connection *nc, struct tcp_pcb *tpcb) {
union socket_address sa;
SET_ADDR(&sa, &tpcb->remote_ip);
sa.sin.sin_port = htons(tpcb->remote_port);
mg_if_accept_tcp_cb(nc, &sa, sizeof(sa.sin));
}
static void tcp_close_tcpip(void *arg) { static void tcp_close_tcpip(void *arg) {
tcp_close((struct tcp_pcb *) arg); tcp_close((struct tcp_pcb *) arg);
} }
@@ -390,17 +347,11 @@ static void tcp_close_tcpip(void *arg) {
void mg_lwip_handle_accept(struct mg_connection *nc) { void mg_lwip_handle_accept(struct mg_connection *nc) {
struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock; struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock;
if (cs->pcb.tcp == NULL) return; if (cs->pcb.tcp == NULL) return;
#if MG_ENABLE_SSL union socket_address sa;
if (cs->lc->flags & MG_F_SSL) { struct tcp_pcb *tpcb = cs->pcb.tcp;
if (mg_ssl_if_conn_accept(nc, cs->lc) != MG_SSL_OK) { SET_ADDR(&sa, &tpcb->remote_ip);
LOG(LL_ERROR, ("SSL error")); sa.sin.sin_port = htons(tpcb->remote_port);
tcpip_callback(tcp_close_tcpip, cs->pcb.tcp); mg_if_accept_tcp_cb(nc, &sa, sizeof(sa.sin));
}
} else
#endif
{
mg_lwip_accept_conn(nc, cs->pcb.tcp);
}
} }
static err_t mg_lwip_accept_cb(void *arg, struct tcp_pcb *newtpcb, err_t err) { static err_t mg_lwip_accept_cb(void *arg, struct tcp_pcb *newtpcb, err_t err) {
@@ -555,16 +506,17 @@ static void mg_lwip_tcp_write_tcpip(void *arg) {
return; return;
} }
ctx->ret = len; ctx->ret = len;
(void) unsent;
(void) unacked;
} }
static int mg_lwip_tcp_write(struct mg_connection *nc, const void *data, int mg_lwip_if_tcp_send(struct mg_connection *nc, const void *buf, size_t len) {
uint16_t len) { struct mg_lwip_tcp_write_ctx ctx = {.nc = nc, .data = buf, .len = len};
struct mg_lwip_tcp_write_ctx ctx = {.nc = nc, .data = data, .len = len};
struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock; struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock;
if (nc->sock == INVALID_SOCKET) return -1;
struct tcp_pcb *tpcb = cs->pcb.tcp; struct tcp_pcb *tpcb = cs->pcb.tcp;
if (tpcb == NULL) { if (tpcb == NULL) return -1;
return -1; if (tpcb->snd_buf <= 0) return 0;
}
tcpip_callback(mg_lwip_tcp_write_tcpip, &ctx); tcpip_callback(mg_lwip_tcp_write_tcpip, &ctx);
return ctx.ret; return ctx.ret;
} }
@@ -582,18 +534,10 @@ static void udp_sendto_tcpip(void *arg) {
ctx->ret = udp_sendto(ctx->upcb, ctx->p, ctx->ip, ctx->port); ctx->ret = udp_sendto(ctx->upcb, ctx->p, ctx->ip, ctx->port);
} }
static int mg_lwip_udp_send(struct mg_connection *nc, const void *data, static int mg_lwip_if_udp_send(struct mg_connection *nc, const void *data,
uint16_t len) { size_t len) {
struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock; struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock;
if (cs->pcb.udp == NULL) { if (nc->sock == INVALID_SOCKET || cs->pcb.udp == NULL) return -1;
/*
* In case of UDP, this usually means, what
* async DNS resolve is still in progress and connection
* is not ready yet
*/
DBG(("%p socket is not connected", nc));
return -1;
}
struct udp_pcb *upcb = cs->pcb.udp; struct udp_pcb *upcb = cs->pcb.udp;
struct pbuf *p = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_RAM); struct pbuf *p = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_RAM);
#if defined(LWIP_IPV4) && LWIP_IPV4 && defined(LWIP_IPV6) && LWIP_IPV6 #if defined(LWIP_IPV4) && LWIP_IPV4 && defined(LWIP_IPV6) && LWIP_IPV6
@@ -602,46 +546,32 @@ static int mg_lwip_udp_send(struct mg_connection *nc, const void *data,
ip_addr_t ip = {.addr = nc->sa.sin.sin_addr.s_addr}; ip_addr_t ip = {.addr = nc->sa.sin.sin_addr.s_addr};
#endif #endif
u16_t port = ntohs(nc->sa.sin.sin_port); u16_t port = ntohs(nc->sa.sin.sin_port);
if (p == NULL) { if (p == NULL) return 0;
DBG(("OOM"));
return 0;
}
memcpy(p->payload, data, len); memcpy(p->payload, data, len);
struct udp_sendto_ctx ctx = {.upcb = upcb, .p = p, .ip = &ip, .port = port}; struct udp_sendto_ctx ctx = {.upcb = upcb, .p = p, .ip = &ip, .port = port};
tcpip_callback(udp_sendto_tcpip, &ctx); tcpip_callback(udp_sendto_tcpip, &ctx);
cs->err = ctx.ret; cs->err = ctx.ret;
pbuf_free(p); pbuf_free(p);
return (cs->err == ERR_OK ? len : -1); return (cs->err == ERR_OK ? (int) len : -2);
} }
static void mg_lwip_send_more(struct mg_connection *nc) { static int mg_lwip_if_can_send(struct mg_connection *nc,
int num_sent = 0; struct mg_lwip_conn_state *cs) {
if (nc->sock == INVALID_SOCKET) return; int can_send = 0;
if (nc->flags & MG_F_UDP) { if (nc->send_mbuf.len > 0 || (nc->flags & MG_F_WANT_WRITE)) {
num_sent = mg_lwip_udp_send(nc, nc->send_mbuf.buf, nc->send_mbuf.len); /* We have stuff to send, but can we? */
DBG(("%p mg_lwip_udp_send %u = %d", nc, nc->send_mbuf.len, num_sent)); if (nc->flags & MG_F_UDP) {
} else { /* UDP is always ready for sending. */
num_sent = mg_lwip_tcp_write(nc, nc->send_mbuf.buf, nc->send_mbuf.len); can_send = (cs->pcb.udp != NULL);
DBG(("%p mg_lwip_tcp_write %u = %d", nc, nc->send_mbuf.len, num_sent)); } else {
can_send = (cs->pcb.tcp != NULL && cs->pcb.tcp->snd_buf > 0);
/* See comment above. */
#if CS_PLATFORM == CS_P_ESP8266
if (cs->pcb.tcp->unacked != NULL) can_send = 0;
#endif
}
} }
if (num_sent == 0) return; return can_send;
if (num_sent > 0) {
mg_if_sent_cb(nc, num_sent);
} else {
mg_lwip_post_signal(MG_SIG_CLOSE_CONN, nc);
}
}
void mg_lwip_if_tcp_send(struct mg_connection *nc, const void *buf,
size_t len) {
mbuf_append(&nc->send_mbuf, buf, len);
mg_lwip_mgr_schedule_poll(nc->mgr);
}
void mg_lwip_if_udp_send(struct mg_connection *nc, const void *buf,
size_t len) {
mbuf_append(&nc->send_mbuf, buf, len);
mg_lwip_mgr_schedule_poll(nc->mgr);
} }
struct tcp_recved_ctx { struct tcp_recved_ctx {
@@ -651,30 +581,38 @@ struct tcp_recved_ctx {
void tcp_recved_tcpip(void *arg) { void tcp_recved_tcpip(void *arg) {
struct tcp_recved_ctx *ctx = (struct tcp_recved_ctx *) arg; struct tcp_recved_ctx *ctx = (struct tcp_recved_ctx *) arg;
tcp_recved(ctx->tpcb, ctx->len); if (ctx->tpcb != NULL) tcp_recved(ctx->tpcb, ctx->len);
} }
void mg_lwip_if_recved(struct mg_connection *nc, size_t len) { static int mg_lwip_if_tcp_recv(struct mg_connection *nc, void *buf,
if (nc->flags & MG_F_UDP) return; size_t len) {
int res = 0;
char *bufp = buf;
struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock; struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock;
if (nc->sock == INVALID_SOCKET || cs->pcb.tcp == NULL) { if (nc->sock == INVALID_SOCKET) return -1;
DBG(("%p invalid socket", nc)); mgos_lock();
return; while (cs->rx_chain != NULL && len > 0) {
struct pbuf *seg = cs->rx_chain;
size_t seg_len = (seg->len - cs->rx_offset);
size_t copy_len = MIN(len, seg_len);
pbuf_copy_partial(seg, bufp, copy_len, cs->rx_offset);
len -= copy_len;
res += copy_len;
bufp += copy_len;
cs->rx_offset += copy_len;
if (cs->rx_offset == cs->rx_chain->len) {
cs->rx_chain = pbuf_dechain(cs->rx_chain);
pbuf_free(seg);
cs->rx_offset = 0;
}
} }
DBG(("%p %p %u %u", nc, cs->pcb.tcp, len, mgos_unlock();
(cs->rx_chain ? cs->rx_chain->tot_len : 0))); if (res > 0) {
struct tcp_recved_ctx ctx = {.tpcb = cs->pcb.tcp, .len = len}; struct tcp_recved_ctx ctx = {.tpcb = cs->pcb.tcp, .len = res};
#if MG_ENABLE_SSL
if (!(nc->flags & MG_F_SSL)) {
tcpip_callback(tcp_recved_tcpip, &ctx); tcpip_callback(tcp_recved_tcpip, &ctx);
} else {
/* Currently SSL acknowledges data immediately.
* TODO(rojer): Find a way to propagate mg_lwip_if_recved. */
} }
#else return res;
tcpip_callback(tcp_recved_tcpip, &ctx);
#endif
mbuf_trim(&nc->recv_mbuf);
} }
int mg_lwip_if_create_conn(struct mg_connection *nc) { int mg_lwip_if_create_conn(struct mg_connection *nc) {
@@ -763,7 +701,8 @@ void mg_lwip_if_sock_set(struct mg_connection *nc, sock_t sock) {
mg_lwip_if_connect_udp, \ mg_lwip_if_connect_udp, \
mg_lwip_if_tcp_send, \ mg_lwip_if_tcp_send, \
mg_lwip_if_udp_send, \ mg_lwip_if_udp_send, \
mg_lwip_if_recved, \ mg_lwip_if_tcp_recv, \
mg_lwip_if_udp_recv, \
mg_lwip_if_create_conn, \ mg_lwip_if_create_conn, \
mg_lwip_if_destroy_conn, \ mg_lwip_if_destroy_conn, \
mg_lwip_if_sock_set, \ mg_lwip_if_sock_set, \
+15 -3
View File
@@ -1,6 +1,18 @@
/* /*
* Copyright (c) 2014-2016 Cesanta Software Limited * Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved * All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
#ifndef CS_COMMON_PLATFORMS_LWIP_MG_NET_IF_LWIP_H_ #ifndef CS_COMMON_PLATFORMS_LWIP_MG_NET_IF_LWIP_H_
@@ -30,9 +42,9 @@ struct mg_lwip_conn_state {
/* Last SSL write size, for retries. */ /* Last SSL write size, for retries. */
int last_ssl_write_size; int last_ssl_write_size;
/* Whether MG_SIG_RECV is already pending for this connection */ /* Whether MG_SIG_RECV is already pending for this connection */
int recv_pending : 1; int recv_pending;
/* Whether the connection is about to close, just `rx_chain` needs to drain */ /* Whether the connection is about to close, just `rx_chain` needs to drain */
int draining_rx_chain : 1; int draining_rx_chain;
}; };
enum mg_sig_type { enum mg_sig_type {
-197
View File
@@ -1,197 +0,0 @@
/*
* Copyright (c) 2014-2016 Cesanta Software Limited
* All rights reserved
*/
#if MG_ENABLE_SSL && MG_NET_IF == MG_NET_IF_LWIP_LOW_LEVEL
#include "common/mg_mem.h"
#include "common/cs_dbg.h"
#include <lwip/pbuf.h>
#include <lwip/tcp.h>
#ifndef MG_LWIP_SSL_IO_SIZE
#define MG_LWIP_SSL_IO_SIZE 1024
#endif
#ifndef MIN
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#endif
void mg_lwip_ssl_do_hs(struct mg_connection *nc) {
struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock;
int server_side = (nc->listener != NULL);
enum mg_ssl_if_result res;
if (nc->flags & MG_F_CLOSE_IMMEDIATELY) return;
res = mg_ssl_if_handshake(nc);
DBG(("%p %lu %d %d", nc, nc->flags, server_side, res));
if (res != MG_SSL_OK) {
if (res == MG_SSL_WANT_WRITE) {
nc->flags |= MG_F_WANT_WRITE;
cs->err = 0;
} else if (res == MG_SSL_WANT_READ) {
/*
* Nothing to do in particular, we are callback-driven.
* What we definitely do not need anymore is SSL reading (nothing left).
*/
nc->flags &= ~MG_F_WANT_READ;
cs->err = 0;
} else {
cs->err = res;
if (server_side) {
mg_lwip_post_signal(MG_SIG_CLOSE_CONN, nc);
} else {
mg_lwip_post_signal(MG_SIG_CONNECT_RESULT, nc);
}
}
} else {
cs->err = 0;
nc->flags &= ~MG_F_WANT_WRITE;
/*
* Handshake is done. Schedule a read immediately to consume app data
* which may already be waiting.
*/
nc->flags |= (MG_F_SSL_HANDSHAKE_DONE | MG_F_WANT_READ);
if (server_side) {
mg_lwip_accept_conn(nc, cs->pcb.tcp);
} else {
mg_lwip_post_signal(MG_SIG_CONNECT_RESULT, nc);
}
}
}
void mg_lwip_ssl_send(struct mg_connection *nc) {
if (nc->sock == INVALID_SOCKET) {
DBG(("%p invalid socket", nc));
return;
}
struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock;
/* It's ok if the buffer is empty. Return value of 0 may also be valid. */
int len = cs->last_ssl_write_size;
if (len == 0) {
len = MIN(MG_LWIP_SSL_IO_SIZE, nc->send_mbuf.len);
}
int ret = mg_ssl_if_write(nc, nc->send_mbuf.buf, len);
DBG(("%p SSL_write %u = %d", nc, len, ret));
if (ret > 0) {
mg_if_sent_cb(nc, ret);
cs->last_ssl_write_size = 0;
} else if (ret < 0) {
/* This is tricky. We must remember the exact data we were sending to retry
* exactly the same send next time. */
cs->last_ssl_write_size = len;
}
if (ret == len) {
nc->flags &= ~MG_F_WANT_WRITE;
} else if (ret == MG_SSL_WANT_WRITE) {
nc->flags |= MG_F_WANT_WRITE;
} else {
mg_lwip_post_signal(MG_SIG_CLOSE_CONN, nc);
}
}
void mg_lwip_ssl_recv(struct mg_connection *nc) {
struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock;
/* Don't deliver data before connect callback */
if (nc->flags & MG_F_CONNECTING) return;
while (nc->recv_mbuf.len < nc->recv_mbuf_limit) {
char *buf = (char *) MG_MALLOC(MG_LWIP_SSL_IO_SIZE);
if (buf == NULL) return;
int ret = mg_ssl_if_read(nc, buf, MG_LWIP_SSL_IO_SIZE);
DBG(("%p %p SSL_read %u = %d", nc, cs->rx_chain, MG_LWIP_SSL_IO_SIZE, ret));
if (ret <= 0) {
MG_FREE(buf);
if (ret == MG_SSL_WANT_WRITE) {
nc->flags |= MG_F_WANT_WRITE;
return;
} else if (ret == MG_SSL_WANT_READ) {
/*
* Nothing to do in particular, we are callback-driven.
* What we definitely do not need anymore is SSL reading (nothing left).
*/
nc->flags &= ~MG_F_WANT_READ;
cs->err = 0;
return;
} else {
mg_lwip_post_signal(MG_SIG_CLOSE_CONN, nc);
return;
}
} else {
mg_if_recv_tcp_cb(nc, buf, ret, 1 /* own */);
}
}
}
#ifdef KR_VERSION
ssize_t kr_send(int fd, const void *buf, size_t len) {
struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) fd;
int ret = mg_lwip_tcp_write(cs->nc, buf, len);
DBG(("%p mg_lwip_tcp_write %u = %d", cs->nc, len, ret));
if (ret == 0) ret = KR_IO_WOULDBLOCK;
return ret;
}
ssize_t kr_recv(int fd, void *buf, size_t len) {
struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) fd;
struct pbuf *seg = cs->rx_chain;
if (seg == NULL) {
DBG(("%u - nothing to read", len));
return KR_IO_WOULDBLOCK;
}
size_t seg_len = (seg->len - cs->rx_offset);
DBG(("%u %u %u %u", len, cs->rx_chain->len, seg_len, cs->rx_chain->tot_len));
len = MIN(len, seg_len);
pbuf_copy_partial(seg, buf, len, cs->rx_offset);
cs->rx_offset += len;
tcp_recved(cs->pcb.tcp, len);
if (cs->rx_offset == cs->rx_chain->len) {
cs->rx_chain = pbuf_dechain(cs->rx_chain);
pbuf_free(seg);
cs->rx_offset = 0;
}
return len;
}
#elif MG_SSL_IF == MG_SSL_IF_MBEDTLS
int ssl_socket_send(void *ctx, const unsigned char *buf, size_t len) {
struct mg_connection *nc = (struct mg_connection *) ctx;
struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock;
int ret = mg_lwip_tcp_write(cs->nc, buf, len);
if (ret == 0) ret = MBEDTLS_ERR_SSL_WANT_WRITE;
LOG(LL_DEBUG, ("%p %d -> %d", nc, len, ret));
return ret;
}
int ssl_socket_recv(void *ctx, unsigned char *buf, size_t len) {
struct mg_connection *nc = (struct mg_connection *) ctx;
struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock;
struct pbuf *seg = cs->rx_chain;
if (seg == NULL) {
DBG(("%u - nothing to read", len));
return MBEDTLS_ERR_SSL_WANT_READ;
}
size_t seg_len = (seg->len - cs->rx_offset);
DBG(("%u %u %u %u", len, cs->rx_chain->len, seg_len, cs->rx_chain->tot_len));
mgos_lock();
len = MIN(len, seg_len);
pbuf_copy_partial(seg, buf, len, cs->rx_offset);
cs->rx_offset += len;
/* TCP PCB may be NULL if connection has already been closed
* but we still have data to deliver to SSL. */
if (cs->pcb.tcp != NULL) tcp_recved(cs->pcb.tcp, len);
if (cs->rx_offset == cs->rx_chain->len) {
cs->rx_chain = pbuf_dechain(cs->rx_chain);
pbuf_free(seg);
cs->rx_offset = 0;
}
mgos_unlock();
LOG(LL_DEBUG, ("%p <- %d", nc, (int) len));
return len;
}
#endif
#endif /* MG_ENABLE_SSL && MG_NET_IF == MG_NET_IF_LWIP_LOW_LEVEL */
+13 -1
View File
@@ -1,6 +1,18 @@
/* /*
* Copyright (c) 2014-2016 Cesanta Software Limited * Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved * All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
#include "common/platform.h" #include "common/platform.h"
+13 -1
View File
@@ -1,6 +1,18 @@
/* /*
* Copyright (c) 2014-2016 Cesanta Software Limited * Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved * All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
#if CS_PLATFORM == CS_P_MSP432 #if CS_PLATFORM == CS_P_MSP432
+13 -1
View File
@@ -1,6 +1,18 @@
/* /*
* Copyright (c) 2014-2016 Cesanta Software Limited * Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved * All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
#if (CS_PLATFORM == CS_P_NRF51 || CS_PLATFORM == CS_P_NRF52) && \ #if (CS_PLATFORM == CS_P_NRF51 || CS_PLATFORM == CS_P_NRF52) && \
+13 -1
View File
@@ -1,6 +1,18 @@
/* /*
* Copyright (c) 2014-2016 Cesanta Software Limited * Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved * All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
#if MG_ENABLE_NET_IF_PIC32 #if MG_ENABLE_NET_IF_PIC32
+13 -1
View File
@@ -1,6 +1,18 @@
/* /*
* Copyright (c) 2014-2016 Cesanta Software Limited * Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved * All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
#ifndef CS_COMMON_PLATFORMS_PIC32_NET_IF_H_ #ifndef CS_COMMON_PLATFORMS_PIC32_NET_IF_H_
+13 -1
View File
@@ -1,6 +1,18 @@
/* /*
* Copyright (c) 2014-2016 Cesanta Software Limited * Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved * All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
#ifndef CS_COMMON_PLATFORMS_PLATFORM_CC3100_H_ #ifndef CS_COMMON_PLATFORMS_PLATFORM_CC3100_H_
+13 -1
View File
@@ -1,6 +1,18 @@
/* /*
* Copyright (c) 2014-2016 Cesanta Software Limited * Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved * All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
#ifndef CS_COMMON_PLATFORMS_PLATFORM_CC3200_H_ #ifndef CS_COMMON_PLATFORMS_PLATFORM_CC3200_H_
+15 -1
View File
@@ -1,6 +1,18 @@
/* /*
* Copyright (c) 2014-2016 Cesanta Software Limited * Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved * All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
#ifndef CS_COMMON_PLATFORMS_PLATFORM_CC3220_H_ #ifndef CS_COMMON_PLATFORMS_PLATFORM_CC3220_H_
@@ -22,7 +34,9 @@
#endif #endif
#define MG_NET_IF MG_NET_IF_SIMPLELINK #define MG_NET_IF MG_NET_IF_SIMPLELINK
#ifndef MG_SSL_IF
#define MG_SSL_IF MG_SSL_IF_SIMPLELINK #define MG_SSL_IF MG_SSL_IF_SIMPLELINK
#endif
/* Only SPIFFS supports directories, SLFS does not. */ /* Only SPIFFS supports directories, SLFS does not. */
#if defined(CC3220_FS_SPIFFS) && !defined(MG_ENABLE_DIRECTORY_LISTING) #if defined(CC3220_FS_SPIFFS) && !defined(MG_ENABLE_DIRECTORY_LISTING)
+13 -1
View File
@@ -1,6 +1,18 @@
/* /*
* Copyright (c) 2014-2016 Cesanta Software Limited * Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved * All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
#ifndef CS_COMMON_PLATFORMS_PLATFORM_ESP32_H_ #ifndef CS_COMMON_PLATFORMS_PLATFORM_ESP32_H_
+13 -5
View File
@@ -1,6 +1,18 @@
/* /*
* Copyright (c) 2014-2016 Cesanta Software Limited * Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved * All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
#ifndef CS_COMMON_PLATFORMS_PLATFORM_ESP8266_H_ #ifndef CS_COMMON_PLATFORMS_PLATFORM_ESP8266_H_
@@ -30,10 +42,6 @@ typedef struct stat cs_stat_t;
#define __cdecl #define __cdecl
#define _FILE_OFFSET_BITS 32 #define _FILE_OFFSET_BITS 32
#if !defined(RTOS_SDK) && !defined(__cplusplus)
#define fileno(x) -1
#endif
#define MG_LWIP 1 #define MG_LWIP 1
/* struct timeval is defined in sys/time.h. */ /* struct timeval is defined in sys/time.h. */
+13 -1
View File
@@ -1,6 +1,18 @@
/* /*
* Copyright (c) 2014-2016 Cesanta Software Limited * Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved * All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
#ifndef CS_COMMON_PLATFORMS_PLATFORM_MBED_H_ #ifndef CS_COMMON_PLATFORMS_PLATFORM_MBED_H_
+13 -1
View File
@@ -1,6 +1,18 @@
/* /*
* Copyright (c) 2014-2016 Cesanta Software Limited * Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved * All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
#ifndef CS_COMMON_PLATFORMS_PLATFORM_MSP432_H_ #ifndef CS_COMMON_PLATFORMS_PLATFORM_MSP432_H_
+13 -1
View File
@@ -1,6 +1,18 @@
/* /*
* Copyright (c) 2014-2016 Cesanta Software Limited * Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved * All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
#ifndef CS_COMMON_PLATFORMS_PLATFORM_NRF51_H_ #ifndef CS_COMMON_PLATFORMS_PLATFORM_NRF51_H_
#define CS_COMMON_PLATFORMS_PLATFORM_NRF51_H_ #define CS_COMMON_PLATFORMS_PLATFORM_NRF51_H_
+13 -1
View File
@@ -1,6 +1,18 @@
/* /*
* Copyright (c) 2014-2016 Cesanta Software Limited * Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved * All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
#ifndef CS_COMMON_PLATFORMS_PLATFORM_NRF52_H_ #ifndef CS_COMMON_PLATFORMS_PLATFORM_NRF52_H_
#define CS_COMMON_PLATFORMS_PLATFORM_NRF52_H_ #define CS_COMMON_PLATFORMS_PLATFORM_NRF52_H_
+13 -1
View File
@@ -1,6 +1,18 @@
/* /*
* Copyright (c) 2014-2016 Cesanta Software Limited * Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved * All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
#ifndef CS_COMMON_PLATFORMS_PLATFORM_NXP_KINETIS_H_ #ifndef CS_COMMON_PLATFORMS_PLATFORM_NXP_KINETIS_H_
+13 -1
View File
@@ -1,6 +1,18 @@
/* /*
* Copyright (c) 2014-2016 Cesanta Software Limited * Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved * All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
#ifndef CS_COMMON_PLATFORMS_PLATFORM_NXP_LPC_H_ #ifndef CS_COMMON_PLATFORMS_PLATFORM_NXP_LPC_H_
+13 -1
View File
@@ -1,6 +1,18 @@
/* /*
* Copyright (c) 2014-2016 Cesanta Software Limited * Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved * All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
#ifndef CS_COMMON_PLATFORMS_PLATFORM_PIC32_H_ #ifndef CS_COMMON_PLATFORMS_PLATFORM_PIC32_H_
+14 -2
View File
@@ -1,6 +1,18 @@
/* /*
* Copyright (c) 2014-2016 Cesanta Software Limited * Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved * All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
#ifndef CS_COMMON_PLATFORMS_PLATFORM_STM32_H_ #ifndef CS_COMMON_PLATFORMS_PLATFORM_STM32_H_
@@ -22,7 +34,7 @@
#include <stm32_sdk_hal.h> #include <stm32_sdk_hal.h>
#define to64(x) strtoll(x, NULL, 10) #define to64(x) strtoll(x, NULL, 10)
#define INT64_FMT PRId64 #define INT64_FMT "lld"
#define SIZE_T_FMT "u" #define SIZE_T_FMT "u"
typedef struct stat cs_stat_t; typedef struct stat cs_stat_t;
#define DIRSEP '/' #define DIRSEP '/'
+13 -1
View File
@@ -1,6 +1,18 @@
/* /*
* Copyright (c) 2014-2016 Cesanta Software Limited * Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved * All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
#ifndef CS_COMMON_PLATFORMS_PLATFORM_TM4C129_H_ #ifndef CS_COMMON_PLATFORMS_PLATFORM_TM4C129_H_
@@ -1,6 +1,18 @@
/* /*
* Copyright (c) 2014-2016 Cesanta Software Limited * Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved * All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
#ifndef CS_COMMON_PLATFORMS_SIMPLELINK_CS_SIMPLELINK_H_ #ifndef CS_COMMON_PLATFORMS_SIMPLELINK_CS_SIMPLELINK_H_
@@ -157,7 +169,7 @@ int sl_set_ssl_opts(int sock, struct mg_connection *nc);
#endif /* SL_MAJOR_VERSION_NUM < 2 */ #endif /* SL_MAJOR_VERSION_NUM < 2 */
int slfs_open(const unsigned char *fname, uint32_t flags); int slfs_open(const unsigned char *fname, uint32_t flags, uint32_t *token);
#endif /* MG_NET_IF == MG_NET_IF_SIMPLELINK */ #endif /* MG_NET_IF == MG_NET_IF_SIMPLELINK */
+13 -1
View File
@@ -1,6 +1,18 @@
/* /*
* Copyright (c) 2014-2016 Cesanta Software Limited * Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved * All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
#if MG_NET_IF == MG_NET_IF_SIMPLELINK && \ #if MG_NET_IF == MG_NET_IF_SIMPLELINK && \
+82 -26
View File
@@ -1,6 +1,18 @@
/* /*
* Copyright (c) 2014-2016 Cesanta Software Limited * Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved * All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
/* Standard libc interface to TI SimpleLink FS. */ /* Standard libc interface to TI SimpleLink FS. */
@@ -19,14 +31,14 @@
#include "common/mg_mem.h" #include "common/mg_mem.h"
#if SL_MAJOR_VERSION_NUM < 2 #if SL_MAJOR_VERSION_NUM < 2
int slfs_open(const unsigned char *fname, uint32_t flags) { int slfs_open(const unsigned char *fname, uint32_t flags, uint32_t *token) {
_i32 fh; _i32 fh;
_i32 r = sl_FsOpen(fname, flags, NULL /* token */, &fh); _i32 r = sl_FsOpen(fname, flags, (unsigned long *) token, &fh);
return (r < 0 ? r : fh); return (r < 0 ? r : fh);
} }
#else /* SL_MAJOR_VERSION_NUM >= 2 */ #else /* SL_MAJOR_VERSION_NUM >= 2 */
int slfs_open(const unsigned char *fname, uint32_t flags) { int slfs_open(const unsigned char *fname, uint32_t flags, uint32_t *token) {
return sl_FsOpen(fname, flags, NULL /* token */); return sl_FsOpen(fname, flags, (unsigned long *) token);
} }
#endif #endif
@@ -42,9 +54,11 @@ const char *drop_dir(const char *fname, bool *is_slfs);
#define FS_SLFS_MAX_FILE_SIZE (64 * 1024) #define FS_SLFS_MAX_FILE_SIZE (64 * 1024)
#endif #endif
struct sl_file_size_hint { struct sl_file_open_info {
char *name; char *name;
size_t size; size_t size;
uint32_t flags;
uint32_t *token;
}; };
struct sl_fd_info { struct sl_fd_info {
@@ -54,7 +68,10 @@ struct sl_fd_info {
}; };
static struct sl_fd_info s_sl_fds[MAX_OPEN_SLFS_FILES]; static struct sl_fd_info s_sl_fds[MAX_OPEN_SLFS_FILES];
static struct sl_file_size_hint s_sl_file_size_hints[MAX_OPEN_SLFS_FILES]; static struct sl_file_open_info s_sl_file_open_infos[MAX_OPEN_SLFS_FILES];
static struct sl_file_open_info *fs_slfs_find_foi(const char *name,
bool create);
static int sl_fs_to_errno(_i32 r) { static int sl_fs_to_errno(_i32 r) {
DBG(("SL error: %d", (int) r)); DBG(("SL error: %d", (int) r));
@@ -95,7 +112,13 @@ int fs_slfs_open(const char *pathname, int flags, mode_t mode) {
_u32 am = 0; _u32 am = 0;
fi->size = (size_t) -1; fi->size = (size_t) -1;
int rw = (flags & 3); int rw = (flags & 3);
size_t new_size = FS_SLFS_MAX_FILE_SIZE; size_t new_size = 0;
struct sl_file_open_info *foi =
fs_slfs_find_foi(pathname, false /* create */);
if (foi != NULL) {
LOG(LL_DEBUG, ("FOI for %s: %d 0x%x %p", pathname, (int) foi->size,
(unsigned int) foi->flags, foi->token));
}
if (rw == O_RDONLY) { if (rw == O_RDONLY) {
SlFsFileInfo_t sl_fi; SlFsFileInfo_t sl_fi;
_i32 r = sl_FsGetInfo((const _u8 *) pathname, 0, &sl_fi); _i32 r = sl_FsGetInfo((const _u8 *) pathname, 0, &sl_fi);
@@ -110,24 +133,27 @@ int fs_slfs_open(const char *pathname, int flags, mode_t mode) {
return set_errno(ENOTSUP); return set_errno(ENOTSUP);
} }
if (flags & O_CREAT) { if (flags & O_CREAT) {
size_t i; if (foi->size > 0) {
for (i = 0; i < MAX_OPEN_SLFS_FILES; i++) { new_size = foi->size;
if (s_sl_file_size_hints[i].name != NULL && } else {
strcmp(s_sl_file_size_hints[i].name, pathname) == 0) { new_size = FS_SLFS_MAX_FILE_SIZE;
new_size = s_sl_file_size_hints[i].size;
MG_FREE(s_sl_file_size_hints[i].name);
s_sl_file_size_hints[i].name = NULL;
break;
}
} }
am = FS_MODE_OPEN_CREATE(new_size, 0); am = FS_MODE_OPEN_CREATE(new_size, 0);
} else { } else {
am = SL_FS_WRITE; am = SL_FS_WRITE;
} }
#if SL_MAJOR_VERSION_NUM >= 2
am |= SL_FS_OVERWRITE;
#endif
} }
fi->fh = slfs_open((_u8 *) pathname, am); uint32_t *token = NULL;
LOG(LL_DEBUG, ("sl_FsOpen(%s, 0x%x) sz %u = %d", pathname, (int) am, if (foi != NULL) {
(unsigned int) new_size, (int) fi->fh)); am |= foi->flags;
token = foi->token;
}
fi->fh = slfs_open((_u8 *) pathname, am, token);
LOG(LL_DEBUG, ("sl_FsOpen(%s, 0x%x, %p) sz %u = %d", pathname, (int) am,
token, (unsigned int) new_size, (int) fi->fh));
int r; int r;
if (fi->fh >= 0) { if (fi->fh >= 0) {
fi->pos = 0; fi->pos = 0;
@@ -231,16 +257,46 @@ int fs_slfs_rename(const char *from, const char *to) {
return set_errno(ENOTSUP); return set_errno(ENOTSUP);
} }
void fs_slfs_set_new_file_size(const char *name, size_t size) { static struct sl_file_open_info *fs_slfs_find_foi(const char *name,
int i; bool create) {
int i = 0;
for (i = 0; i < MAX_OPEN_SLFS_FILES; i++) { for (i = 0; i < MAX_OPEN_SLFS_FILES; i++) {
if (s_sl_file_size_hints[i].name == NULL) { if (s_sl_file_open_infos[i].name != NULL &&
DBG(("File size hint: %s %d", name, (int) size)); strcmp(drop_dir(s_sl_file_open_infos[i].name, NULL), name) == 0) {
s_sl_file_size_hints[i].name = strdup(name);
s_sl_file_size_hints[i].size = size;
break; break;
} }
} }
if (i != MAX_OPEN_SLFS_FILES) return &s_sl_file_open_infos[i];
if (!create) return NULL;
for (i = 0; i < MAX_OPEN_SLFS_FILES; i++) {
if (s_sl_file_open_infos[i].name == NULL) break;
}
if (i == MAX_OPEN_SLFS_FILES) {
i = 0; /* Evict a random slot. */
}
if (s_sl_file_open_infos[i].name != NULL) {
free(s_sl_file_open_infos[i].name);
}
s_sl_file_open_infos[i].name = strdup(name);
return &s_sl_file_open_infos[i];
}
void fs_slfs_set_file_size(const char *name, size_t size) {
struct sl_file_open_info *foi = fs_slfs_find_foi(name, true /* create */);
foi->size = size;
}
void fs_slfs_set_file_flags(const char *name, uint32_t flags, uint32_t *token) {
struct sl_file_open_info *foi = fs_slfs_find_foi(name, true /* create */);
foi->flags = flags;
foi->token = token;
}
void fs_slfs_unset_file_flags(const char *name) {
struct sl_file_open_info *foi = fs_slfs_find_foi(name, false /* create */);
if (foi == NULL) return;
free(foi->name);
memset(foi, 0, sizeof(*foi));
} }
#endif /* defined(MG_FS_SLFS) || defined(CC3200_FS_SLFS) */ #endif /* defined(MG_FS_SLFS) || defined(CC3200_FS_SLFS) */
+16 -2
View File
@@ -1,6 +1,18 @@
/* /*
* Copyright (c) 2014-2016 Cesanta Software Limited * Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved * All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
#ifndef CS_COMMON_PLATFORMS_SIMPLELINK_SL_FS_SLFS_H_ #ifndef CS_COMMON_PLATFORMS_SIMPLELINK_SL_FS_SLFS_H_
@@ -27,7 +39,9 @@ off_t fs_slfs_lseek(int fd, off_t offset, int whence);
int fs_slfs_unlink(const char *filename); int fs_slfs_unlink(const char *filename);
int fs_slfs_rename(const char *from, const char *to); int fs_slfs_rename(const char *from, const char *to);
void fs_slfs_set_new_file_size(const char *name, size_t size); void fs_slfs_set_file_size(const char *name, size_t size);
void fs_slfs_set_file_flags(const char *name, uint32_t flags, uint32_t *token);
void fs_slfs_unset_file_flags(const char *name);
#endif /* defined(MG_FS_SLFS) */ #endif /* defined(MG_FS_SLFS) */
+68 -116
View File
@@ -1,6 +1,18 @@
/* /*
* Copyright (c) 2014-2016 Cesanta Software Limited * Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved * All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
#include "common/platforms/simplelink/sl_net_if.h" #include "common/platforms/simplelink/sl_net_if.h"
@@ -17,7 +29,7 @@ static sock_t mg_open_listening_socket(struct mg_connection *nc,
union socket_address *sa, int type, union socket_address *sa, int type,
int proto); int proto);
void mg_set_non_blocking_mode(sock_t sock) { static void mg_set_non_blocking_mode(sock_t sock) {
SlSockNonblocking_t opt; SlSockNonblocking_t opt;
#if SL_MAJOR_VERSION_NUM < 2 #if SL_MAJOR_VERSION_NUM < 2
opt.NonblockingEnabled = 1; opt.NonblockingEnabled = 1;
@@ -31,17 +43,19 @@ static int mg_is_error(int n) {
return (n < 0 && n != SL_ERROR_BSD_EALREADY && n != SL_ERROR_BSD_EAGAIN); return (n < 0 && n != SL_ERROR_BSD_EALREADY && n != SL_ERROR_BSD_EAGAIN);
} }
void mg_sl_if_connect_tcp(struct mg_connection *nc, static void mg_sl_if_connect_tcp(struct mg_connection *nc,
const union socket_address *sa) { const union socket_address *sa) {
int proto = 0; int proto = 0;
#if MG_ENABLE_SSL && MG_SSL_IF == MG_SSL_IF_SIMPLELINK
if (nc->flags & MG_F_SSL) proto = SL_SEC_SOCKET; if (nc->flags & MG_F_SSL) proto = SL_SEC_SOCKET;
#endif
sock_t sock = sl_Socket(AF_INET, SOCK_STREAM, proto); sock_t sock = sl_Socket(AF_INET, SOCK_STREAM, proto);
if (sock < 0) { if (sock < 0) {
nc->err = sock; nc->err = sock;
goto out; goto out;
} }
mg_sock_set(nc, sock); mg_sock_set(nc, sock);
#if MG_ENABLE_SSL #if MG_ENABLE_SSL && MG_SSL_IF == MG_SSL_IF_SIMPLELINK
nc->err = sl_set_ssl_opts(sock, nc); nc->err = sl_set_ssl_opts(sock, nc);
if (nc->err != 0) goto out; if (nc->err != 0) goto out;
#endif #endif
@@ -51,7 +65,7 @@ out:
ntohs(sa->sin.sin_port), nc->sock, proto, nc->err)); ntohs(sa->sin.sin_port), nc->sock, proto, nc->err));
} }
void mg_sl_if_connect_udp(struct mg_connection *nc) { static void mg_sl_if_connect_udp(struct mg_connection *nc) {
sock_t sock = sl_Socket(AF_INET, SOCK_DGRAM, 0); sock_t sock = sl_Socket(AF_INET, SOCK_DGRAM, 0);
if (sock < 0) { if (sock < 0) {
nc->err = sock; nc->err = sock;
@@ -61,7 +75,8 @@ void mg_sl_if_connect_udp(struct mg_connection *nc) {
nc->err = 0; nc->err = 0;
} }
int mg_sl_if_listen_tcp(struct mg_connection *nc, union socket_address *sa) { static int mg_sl_if_listen_tcp(struct mg_connection *nc,
union socket_address *sa) {
int proto = 0; int proto = 0;
if (nc->flags & MG_F_SSL) proto = SL_SEC_SOCKET; if (nc->flags & MG_F_SSL) proto = SL_SEC_SOCKET;
sock_t sock = mg_open_listening_socket(nc, sa, SOCK_STREAM, proto); sock_t sock = mg_open_listening_socket(nc, sa, SOCK_STREAM, proto);
@@ -70,27 +85,50 @@ int mg_sl_if_listen_tcp(struct mg_connection *nc, union socket_address *sa) {
return 0; return 0;
} }
int mg_sl_if_listen_udp(struct mg_connection *nc, union socket_address *sa) { static int mg_sl_if_listen_udp(struct mg_connection *nc,
union socket_address *sa) {
sock_t sock = mg_open_listening_socket(nc, sa, SOCK_DGRAM, 0); sock_t sock = mg_open_listening_socket(nc, sa, SOCK_DGRAM, 0);
if (sock == INVALID_SOCKET) return (errno ? errno : 1); if (sock == INVALID_SOCKET) return (errno ? errno : 1);
mg_sock_set(nc, sock); mg_sock_set(nc, sock);
return 0; return 0;
} }
void mg_sl_if_tcp_send(struct mg_connection *nc, const void *buf, size_t len) { static int mg_sl_if_tcp_send(struct mg_connection *nc, const void *buf,
mbuf_append(&nc->send_mbuf, buf, len); size_t len) {
int n = (int) sl_Send(nc->sock, buf, len, 0);
if (n < 0 && !mg_is_error(n)) n = 0;
return n;
} }
void mg_sl_if_udp_send(struct mg_connection *nc, const void *buf, size_t len) { static int mg_sl_if_udp_send(struct mg_connection *nc, const void *buf,
mbuf_append(&nc->send_mbuf, buf, len); size_t len) {
int n = sl_SendTo(nc->sock, buf, len, 0, &nc->sa.sa, sizeof(nc->sa.sin));
if (n < 0 && !mg_is_error(n)) n = 0;
return n;
} }
void mg_sl_if_recved(struct mg_connection *nc, size_t len) { static int mg_sl_if_tcp_recv(struct mg_connection *nc, void *buf, size_t len) {
(void) nc; int n = sl_Recv(nc->sock, buf, len, 0);
(void) len; if (n == 0) {
/* Orderly shutdown of the socket, try flushing output. */
nc->flags |= MG_F_SEND_AND_CLOSE;
} else if (n < 0 && !mg_is_error(n)) {
n = 0;
}
return n;
} }
int mg_sl_if_create_conn(struct mg_connection *nc) { static int mg_sl_if_udp_recv(struct mg_connection *nc, void *buf, size_t len,
union socket_address *sa, size_t *sa_len) {
SlSocklen_t sa_len_t = *sa_len;
int n = sl_RecvFrom(nc->sock, buf, MG_UDP_RECV_BUFFER_SIZE, 0,
(SlSockAddr_t *) sa, &sa_len_t);
*sa_len = sa_len_t;
if (n < 0 && !mg_is_error(n)) n = 0;
return n;
}
static int mg_sl_if_create_conn(struct mg_connection *nc) {
(void) nc; (void) nc;
return 1; return 1;
} }
@@ -121,7 +159,6 @@ static int mg_accept_conn(struct mg_connection *lc) {
DBG(("%p conn from %s:%d", nc, inet_ntoa(sa.sin.sin_addr), DBG(("%p conn from %s:%d", nc, inet_ntoa(sa.sin.sin_addr),
ntohs(sa.sin.sin_port))); ntohs(sa.sin.sin_port)));
mg_sock_set(nc, sock); mg_sock_set(nc, sock);
if (nc->flags & MG_F_SSL) nc->flags |= MG_F_SSL_HANDSHAKE_DONE;
mg_if_accept_tcp_cb(nc, &sa, sa_len); mg_if_accept_tcp_cb(nc, &sa, sa_len);
return 1; return 1;
} }
@@ -135,11 +172,11 @@ static sock_t mg_open_listening_socket(struct mg_connection *nc,
(sa->sa.sa_family == AF_INET) ? sizeof(sa->sin) : sizeof(sa->sin6); (sa->sa.sa_family == AF_INET) ? sizeof(sa->sin) : sizeof(sa->sin6);
sock_t sock = sl_Socket(sa->sa.sa_family, type, proto); sock_t sock = sl_Socket(sa->sa.sa_family, type, proto);
if (sock < 0) return sock; if (sock < 0) return sock;
#if MG_ENABLE_SSL && MG_SSL_IF == MG_SSL_IF_SIMPLELINK
if ((r = sl_set_ssl_opts(sock, nc)) < 0) goto clean;
#endif
if ((r = sl_Bind(sock, &sa->sa, sa_len)) < 0) goto clean; if ((r = sl_Bind(sock, &sa->sa, sa_len)) < 0) goto clean;
if (type != SOCK_DGRAM) { if (type != SOCK_DGRAM) {
#if MG_ENABLE_SSL
if ((r = sl_set_ssl_opts(sock, nc)) < 0) goto clean;
#endif
if ((r = sl_Listen(sock, SOMAXCONN)) < 0) goto clean; if ((r = sl_Listen(sock, SOMAXCONN)) < 0) goto clean;
} }
mg_set_non_blocking_mode(sock); mg_set_non_blocking_mode(sock);
@@ -151,86 +188,18 @@ clean:
return sock; return sock;
} }
static void mg_write_to_socket(struct mg_connection *nc) {
struct mbuf *io = &nc->send_mbuf;
int n = 0;
if (nc->flags & MG_F_UDP) {
n = sl_SendTo(nc->sock, io->buf, io->len, 0, &nc->sa.sa,
sizeof(nc->sa.sin));
DBG(("%p %d %d %d %s:%hu", nc, nc->sock, n, errno,
inet_ntoa(nc->sa.sin.sin_addr), ntohs(nc->sa.sin.sin_port)));
} else {
n = (int) sl_Send(nc->sock, io->buf, io->len, 0);
DBG(("%p %d bytes -> %d", nc, n, nc->sock));
}
if (n > 0) {
mg_if_sent_cb(nc, n);
} else if (n < 0 && mg_is_error(n)) {
/* Something went wrong, drop the connection. */
nc->flags |= MG_F_CLOSE_IMMEDIATELY;
}
}
MG_INTERNAL size_t recv_avail_size(struct mg_connection *conn, size_t max) {
size_t avail;
if (conn->recv_mbuf_limit < conn->recv_mbuf.len) return 0;
avail = conn->recv_mbuf_limit - conn->recv_mbuf.len;
return avail > max ? max : avail;
}
static void mg_handle_tcp_read(struct mg_connection *conn) {
int n = 0;
char *buf = (char *) MG_MALLOC(MG_TCP_RECV_BUFFER_SIZE);
if (buf == NULL) {
DBG(("OOM"));
return;
}
n = (int) sl_Recv(conn->sock, buf,
recv_avail_size(conn, MG_TCP_RECV_BUFFER_SIZE), 0);
DBG(("%p %d bytes <- %d", conn, n, conn->sock));
if (n > 0) {
mg_if_recv_tcp_cb(conn, buf, n, 1 /* own */);
} else {
MG_FREE(buf);
}
if (n == 0) {
/* Orderly shutdown of the socket, try flushing output. */
conn->flags |= MG_F_SEND_AND_CLOSE;
} else if (mg_is_error(n)) {
conn->flags |= MG_F_CLOSE_IMMEDIATELY;
}
}
static void mg_handle_udp_read(struct mg_connection *nc) {
char *buf = (char *) MG_MALLOC(MG_UDP_RECV_BUFFER_SIZE);
if (buf == NULL) return;
union socket_address sa;
socklen_t sa_len = sizeof(sa);
int n = sl_RecvFrom(nc->sock, buf, MG_UDP_RECV_BUFFER_SIZE, 0,
(SlSockAddr_t *) &sa, &sa_len);
DBG(("%p %d bytes from %s:%d", nc, n, inet_ntoa(nc->sa.sin.sin_addr),
ntohs(nc->sa.sin.sin_port)));
if (n > 0) {
mg_if_recv_udp_cb(nc, buf, n, &sa, sa_len);
} else {
MG_FREE(buf);
}
}
#define _MG_F_FD_CAN_READ 1 #define _MG_F_FD_CAN_READ 1
#define _MG_F_FD_CAN_WRITE 1 << 1 #define _MG_F_FD_CAN_WRITE 1 << 1
#define _MG_F_FD_ERROR 1 << 2 #define _MG_F_FD_ERROR 1 << 2
void mg_mgr_handle_conn(struct mg_connection *nc, int fd_flags, double now) { void mg_mgr_handle_conn(struct mg_connection *nc, int fd_flags, double now) {
DBG(("%p fd=%d fd_flags=%d nc_flags=%lu rmbl=%d smbl=%d", nc, nc->sock, DBG(("%p fd=%d fd_flags=%d nc_flags=0x%lx rmbl=%d smbl=%d", nc, nc->sock,
fd_flags, nc->flags, (int) nc->recv_mbuf.len, (int) nc->send_mbuf.len)); fd_flags, nc->flags, (int) nc->recv_mbuf.len, (int) nc->send_mbuf.len));
if (!mg_if_poll(nc, now)) return;
if (nc->flags & MG_F_CONNECTING) { if (nc->flags & MG_F_CONNECTING) {
if (nc->flags & MG_F_UDP || nc->err != SL_ERROR_BSD_EALREADY) { if ((nc->flags & MG_F_UDP) || nc->err != SL_ERROR_BSD_EALREADY) {
mg_if_connect_cb(nc, nc->err); mg_if_connect_cb(nc, nc->err);
} else { } else {
/* In SimpleLink, to get status of non-blocking connect() we need to wait /* In SimpleLink, to get status of non-blocking connect() we need to wait
@@ -252,9 +221,6 @@ void mg_mgr_handle_conn(struct mg_connection *nc, int fd_flags, double now) {
) { ) {
nc->err = 0; nc->err = 0;
} }
if (nc->flags & MG_F_SSL && nc->err == 0) {
nc->flags |= MG_F_SSL_HANDSHAKE_DONE;
}
mg_if_connect_cb(nc, nc->err); mg_if_connect_cb(nc, nc->err);
} }
} }
@@ -264,28 +230,21 @@ void mg_mgr_handle_conn(struct mg_connection *nc, int fd_flags, double now) {
if (fd_flags & _MG_F_FD_CAN_READ) { if (fd_flags & _MG_F_FD_CAN_READ) {
if (nc->flags & MG_F_UDP) { if (nc->flags & MG_F_UDP) {
mg_handle_udp_read(nc); mg_if_can_recv_cb(nc);
} else { } else {
if (nc->flags & MG_F_LISTENING) { if (nc->flags & MG_F_LISTENING) {
mg_accept_conn(nc); mg_accept_conn(nc);
} else { } else {
mg_handle_tcp_read(nc); mg_if_can_recv_cb(nc);
} }
} }
} }
if (!(nc->flags & MG_F_CLOSE_IMMEDIATELY)) { if (fd_flags & _MG_F_FD_CAN_WRITE) {
if ((fd_flags & _MG_F_FD_CAN_WRITE) && nc->send_mbuf.len > 0) { mg_if_can_send_cb(nc);
mg_write_to_socket(nc);
}
if (!(fd_flags & (_MG_F_FD_CAN_READ | _MG_F_FD_CAN_WRITE))) {
mg_if_poll(nc, now);
}
mg_if_timer(nc, now);
} }
DBG(("%p after fd=%d nc_flags=%lu rmbl=%d smbl=%d", nc, nc->sock, nc->flags, DBG(("%p after fd=%d nc_flags=0x%lx rmbl=%d smbl=%d", nc, nc->sock, nc->flags,
(int) nc->recv_mbuf.len, (int) nc->send_mbuf.len)); (int) nc->recv_mbuf.len, (int) nc->send_mbuf.len));
} }
@@ -406,14 +365,6 @@ time_t mg_sl_if_poll(struct mg_iface *iface, int timeout_ms) {
mg_mgr_handle_conn(nc, fd_flags, now); mg_mgr_handle_conn(nc, fd_flags, now);
} }
for (nc = mgr->active_connections; nc != NULL; nc = tmp) {
tmp = nc->next;
if ((nc->flags & MG_F_CLOSE_IMMEDIATELY) ||
(nc->send_mbuf.len == 0 && (nc->flags & MG_F_SEND_AND_CLOSE))) {
mg_close_conn(nc);
}
}
return now; return now;
} }
@@ -464,7 +415,8 @@ void sl_restart_cb(struct mg_mgr *mgr) {
mg_sl_if_connect_udp, \ mg_sl_if_connect_udp, \
mg_sl_if_tcp_send, \ mg_sl_if_tcp_send, \
mg_sl_if_udp_send, \ mg_sl_if_udp_send, \
mg_sl_if_recved, \ mg_sl_if_tcp_recv, \
mg_sl_if_udp_recv, \
mg_sl_if_create_conn, \ mg_sl_if_create_conn, \
mg_sl_if_destroy_conn, \ mg_sl_if_destroy_conn, \
mg_sl_if_sock_set, \ mg_sl_if_sock_set, \
+13 -1
View File
@@ -1,6 +1,18 @@
/* /*
* Copyright (c) 2014-2016 Cesanta Software Limited * Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved * All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
#ifndef CS_COMMON_PLATFORMS_SIMPLELINK_SL_NET_IF_H_ #ifndef CS_COMMON_PLATFORMS_SIMPLELINK_SL_NET_IF_H_
+13 -1
View File
@@ -1,6 +1,18 @@
/* /*
* Copyright (c) 2014-2016 Cesanta Software Limited * Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved * All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
#if MG_NET_IF == MG_NET_IF_SIMPLELINK #if MG_NET_IF == MG_NET_IF_SIMPLELINK
+85 -45
View File
@@ -1,6 +1,18 @@
/* /*
* Copyright (c) 2014-2016 Cesanta Software Limited * Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved * All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
#if MG_ENABLE_SSL && MG_SSL_IF == MG_SSL_IF_SIMPLELINK #if MG_ENABLE_SSL && MG_SSL_IF == MG_SSL_IF_SIMPLELINK
@@ -54,6 +66,31 @@ enum mg_ssl_if_result mg_ssl_if_conn_init(
return MG_SSL_OK; return MG_SSL_OK;
} }
enum mg_ssl_if_result mg_ssl_if_conn_accept(struct mg_connection *nc,
struct mg_connection *lc) {
/* SimpleLink does everything for us, nothing for us to do. */
(void) nc;
(void) lc;
return MG_SSL_OK;
}
enum mg_ssl_if_result mg_ssl_if_handshake(struct mg_connection *nc) {
/* SimpleLink has already performed the handshake, nothing to do. */
return MG_SSL_OK;
}
int mg_ssl_if_read(struct mg_connection *nc, void *buf, size_t len) {
/* SimpelLink handles TLS, so this is just a pass-through. */
int n = nc->iface->vtable->tcp_recv(nc, buf, len);
if (n == 0) nc->flags |= MG_F_WANT_READ;
return n;
}
int mg_ssl_if_write(struct mg_connection *nc, const void *buf, size_t len) {
/* SimpelLink handles TLS, so this is just a pass-through. */
return nc->iface->vtable->tcp_send(nc, buf, len);
}
void mg_ssl_if_conn_close_notify(struct mg_connection *nc) { void mg_ssl_if_conn_close_notify(struct mg_connection *nc) {
/* Nothing to do */ /* Nothing to do */
(void) nc; (void) nc;
@@ -78,9 +115,9 @@ bool pem_to_der(const char *pem_file, const char *der_file) {
pf = fopen(pem_file, "r"); pf = fopen(pem_file, "r");
if (pf == NULL) goto clean; if (pf == NULL) goto clean;
remove(der_file); remove(der_file);
fs_slfs_set_new_file_size(der_file + MG_SSL_IF_SIMPLELINK_SLFS_PREFIX_LEN, fs_slfs_set_file_size(der_file + MG_SSL_IF_SIMPLELINK_SLFS_PREFIX_LEN, 2048);
2048);
df = fopen(der_file, "w"); df = fopen(der_file, "w");
fs_slfs_unset_file_flags(der_file + MG_SSL_IF_SIMPLELINK_SLFS_PREFIX_LEN);
if (df == NULL) goto clean; if (df == NULL) goto clean;
while (1) { while (1) {
char pem_buf[70]; char pem_buf[70];
@@ -154,56 +191,59 @@ int sl_set_ssl_opts(int sock, struct mg_connection *nc) {
const struct mg_ssl_if_ctx *ctx = (struct mg_ssl_if_ctx *) nc->ssl_if_data; const struct mg_ssl_if_ctx *ctx = (struct mg_ssl_if_ctx *) nc->ssl_if_data;
DBG(("%p ssl ctx: %p", nc, ctx)); DBG(("%p ssl ctx: %p", nc, ctx));
if (ctx != NULL) { if (ctx == NULL) return 0;
DBG(("%p %s,%s,%s,%s", nc, (ctx->ssl_cert ? ctx->ssl_cert : "-"), DBG(("%p %s,%s,%s,%s", nc, (ctx->ssl_cert ? ctx->ssl_cert : "-"),
(ctx->ssl_key ? ctx->ssl_cert : "-"), (ctx->ssl_key ? ctx->ssl_cert : "-"),
(ctx->ssl_ca_cert ? ctx->ssl_ca_cert : "-"), (ctx->ssl_ca_cert ? ctx->ssl_ca_cert : "-"),
(ctx->ssl_server_name ? ctx->ssl_server_name : "-"))); (ctx->ssl_server_name ? ctx->ssl_server_name : "-")));
if (ctx->ssl_cert != NULL && ctx->ssl_key != NULL) { if (ctx->ssl_cert != NULL && ctx->ssl_key != NULL) {
char *ssl_cert = sl_pem2der(ctx->ssl_cert); char *ssl_cert = sl_pem2der(ctx->ssl_cert), *ssl_key = NULL;
char *ssl_key = sl_pem2der(ctx->ssl_key); if (ssl_cert != NULL) {
if (ssl_cert != NULL && ssl_key != NULL) { err = sl_SetSockOpt(sock, SL_SOL_SOCKET,
err = sl_SetSockOpt(sock, SL_SOL_SOCKET, SL_SO_SECURE_FILES_CERTIFICATE_FILE_NAME, ssl_cert,
SL_SO_SECURE_FILES_CERTIFICATE_FILE_NAME, ssl_cert, strlen(ssl_cert));
strlen(ssl_cert)); MG_FREE(ssl_cert);
LOG(LL_INFO, ("CERTIFICATE_FILE_NAME %s -> %d", ssl_cert, err)); LOG(LL_DEBUG, ("CERTIFICATE_FILE_NAME %s -> %d", ssl_cert, err));
ssl_key = sl_pem2der(ctx->ssl_key);
if (ssl_key != NULL) {
err = sl_SetSockOpt(sock, SL_SOL_SOCKET, err = sl_SetSockOpt(sock, SL_SOL_SOCKET,
SL_SO_SECURE_FILES_PRIVATE_KEY_FILE_NAME, ssl_key, SL_SO_SECURE_FILES_PRIVATE_KEY_FILE_NAME, ssl_key,
strlen(ssl_key)); strlen(ssl_key));
LOG(LL_INFO, ("PRIVATE_KEY_FILE_NAME %s -> %d", ssl_key, err)); MG_FREE(ssl_key);
LOG(LL_DEBUG, ("PRIVATE_KEY_FILE_NAME %s -> %d", ssl_key, err));
} else { } else {
err = -1; err = -1;
} }
MG_FREE(ssl_cert); } else {
MG_FREE(ssl_key); err = -1;
}
if (err != 0) return err;
}
if (ctx->ssl_ca_cert != NULL) {
if (ctx->ssl_ca_cert[0] != '\0') {
char *ssl_ca_cert = sl_pem2der(ctx->ssl_ca_cert);
if (ssl_ca_cert != NULL) {
err =
sl_SetSockOpt(sock, SL_SOL_SOCKET, SL_SO_SECURE_FILES_CA_FILE_NAME,
ssl_ca_cert, strlen(ssl_ca_cert));
LOG(LL_DEBUG, ("CA_FILE_NAME %s -> %d", ssl_ca_cert, err));
} else {
err = -1;
}
MG_FREE(ssl_ca_cert);
if (err != 0) return err; if (err != 0) return err;
} }
if (ctx->ssl_ca_cert != NULL) { }
if (ctx->ssl_ca_cert[0] != '\0') { if (ctx->ssl_server_name != NULL) {
char *ssl_ca_cert = sl_pem2der(ctx->ssl_ca_cert); err = sl_SetSockOpt(sock, SL_SOL_SOCKET,
if (ssl_ca_cert != NULL) { SL_SO_SECURE_DOMAIN_NAME_VERIFICATION,
err = sl_SetSockOpt(sock, SL_SOL_SOCKET, ctx->ssl_server_name, strlen(ctx->ssl_server_name));
SL_SO_SECURE_FILES_CA_FILE_NAME, ssl_ca_cert, DBG(("DOMAIN_NAME_VERIFICATION %s -> %d", ctx->ssl_server_name, err));
strlen(ssl_ca_cert)); /* Domain name verificationw as added in a NWP service pack, older
LOG(LL_INFO, ("CA_FILE_NAME %s -> %d", ssl_ca_cert, err)); * versions return SL_ERROR_BSD_ENOPROTOOPT. There isn't much we can do
} else { * about it,
err = -1; * so we ignore the error. */
} if (err != 0 && err != SL_ERROR_BSD_ENOPROTOOPT) return err;
MG_FREE(ssl_ca_cert);
if (err != 0) return err;
}
}
if (ctx->ssl_server_name != NULL) {
err = sl_SetSockOpt(sock, SL_SOL_SOCKET,
SL_SO_SECURE_DOMAIN_NAME_VERIFICATION,
ctx->ssl_server_name, strlen(ctx->ssl_server_name));
DBG(("DOMAIN_NAME_VERIFICATION %s -> %d", ctx->ssl_server_name, err));
/* Domain name verificationw as added in a NWP service pack, older
* versions return SL_ERROR_BSD_ENOPROTOOPT. There isn't much we can do
* about it,
* so we ignore the error. */
if (err != 0 && err != SL_ERROR_BSD_ENOPROTOOPT) return err;
}
} }
return 0; return 0;
} }
+2 -2
View File
@@ -11,7 +11,7 @@ import (
"time" "time"
"unsafe" "unsafe"
"cesanta.com/mos/flash/common" "cesanta.com/common/go/fwbundle"
"github.com/cesanta/errors" "github.com/cesanta/errors"
) )
@@ -20,7 +20,7 @@ type FlashOpts struct {
Timeout time.Duration Timeout time.Duration
} }
func Flash(fw *common.FirmwareBundle, opts *FlashOpts) error { func Flash(fw *fwbundle.FirmwareBundle, opts *FlashOpts) error {
data, err := fw.GetPartData("boot") data, err := fw.GetPartData("boot")
if err != nil { if err != nil {
return errors.Annotatef(err, "invalid manifest") return errors.Annotatef(err, "invalid manifest")
+13 -1
View File
@@ -1,6 +1,18 @@
/* /*
* Copyright (c) 2016 Cesanta Software Limited * Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved * All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
#ifdef WINCE #ifdef WINCE
+13 -1
View File
@@ -1,6 +1,18 @@
/* /*
* Copyright (c) 2017 Cesanta Software Limited * Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved * All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
#ifdef _WIN32 #ifdef _WIN32
+83
View File
@@ -0,0 +1,83 @@
/*
* Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "common/cs_dbg.h"
#include "common/test_main.h"
#include "common/test_util.h"
#if defined(_MSC_VER) && _MSC_VER >= 1900
#include <crtdbg.h>
int __cdecl CrtDbgHook(int nReportType, char *szMsg, int *pnRet) {
(void) nReportType;
(void) szMsg;
(void) pnRet;
fprintf(stderr, "CRT debug hook: type: %d, msg: %s\n", nReportType, szMsg);
/* Return true - Abort,Retry,Ignore dialog will *not* be displayed */
return 1;
}
#endif
#ifndef __cdecl
#define __cdecl
#endif
int g_num_tests = 0;
int g_num_checks = 0;
const char *g_argv_0 = NULL;
int __cdecl main(int argc, char *argv[]) {
const char *fail_msg;
const char *filter = argc > 1 ? argv[1] : "";
char *seed_str = getenv("TEST_SEED");
double started;
int seed = 0;
if (seed_str != NULL) {
seed = atoi(seed_str);
} else {
seed = (int) time(NULL);
}
printf("seed: %d\n", seed);
srand(seed);
setvbuf(stdout, NULL, _IONBF, 0);
setvbuf(stderr, NULL, _IONBF, 0);
#if defined(_MSC_VER) && _MSC_VER >= 1900
/* NOTE: not available on wine/vc6 */
_CrtSetReportHook2(_CRT_RPTHOOK_INSTALL, CrtDbgHook);
#endif
g_argv_0 = argv[0];
tests_setup();
started = cs_time();
fail_msg = tests_run(filter);
printf("%s, ran %d tests (%d checks) in %.3lfs\n", fail_msg ? "FAIL" : "PASS",
g_num_tests, g_num_checks, cs_time() - started);
tests_teardown();
if (fail_msg != NULL) {
/* Prevent leak analyzer from running: there will be "leaks" because of
* premature return from the test, and in this case we don't care. */
_exit(EXIT_FAILURE);
}
return EXIT_SUCCESS;
}
+34
View File
@@ -0,0 +1,34 @@
/*
* Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CS_COMMON_TEST_MAIN_H_
#define CS_COMMON_TEST_MAIN_H_
#ifdef __cplusplus
extern "C" {
#endif
void tests_setup(void);
const char *tests_run(const char *filter);
void tests_teardown(void);
extern const char *g_argv_0;
#ifdef __cplusplus
}
#endif
#endif /* CS_COMMON_TEST_MAIN_H_ */
+13 -1
View File
@@ -1,6 +1,18 @@
/* /*
* Copyright (c) 2014-2016 Cesanta Software Limited * Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved * All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
#include "common/test_util.h" #include "common/test_util.h"
+110 -52
View File
@@ -1,18 +1,18 @@
/* /*
* Copyright (c) 2015 Cesanta Software Limited * Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved * All rights reserved
* This software is dual-licensed: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation. For the terms of this
* license, see <http://www.gnu.org/licenses/>.
* *
* You are free to use this software under the terms of the GNU General * Licensed under the Apache License, Version 2.0 (the ""License"");
* Public License, but WITHOUT ANY WARRANTY; without even the implied * you may not use this file except in compliance with the License.
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * You may obtain a copy of the License at
* See the GNU General Public License for more details.
* *
* Alternatively, you can license this software under a commercial * http://www.apache.org/licenses/LICENSE-2.0
* license, as set out in <https://www.cesanta.com/license>. *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
#ifndef CS_COMMON_TEST_UTIL_H_ #ifndef CS_COMMON_TEST_UTIL_H_
@@ -28,6 +28,7 @@ extern "C" {
#endif #endif
extern int g_num_tests; extern int g_num_tests;
extern int g_num_checks;
#ifdef MG_TEST_ABORT_ON_FAIL #ifdef MG_TEST_ABORT_ON_FAIL
#define MG_TEST_ABORT abort() #define MG_TEST_ABORT abort()
@@ -48,7 +49,7 @@ void _strfail(const char *a, const char *e, int len);
#define ASSERT(expr) \ #define ASSERT(expr) \
do { \ do { \
g_num_tests++; \ g_num_checks++; \
if (!(expr)) FAIL(#expr, __LINE__); \ if (!(expr)) FAIL(#expr, __LINE__); \
} while (0) } while (0)
#define ASSERT_TRUE(expr) ASSERT(expr) #define ASSERT_TRUE(expr) ASSERT(expr)
@@ -71,55 +72,108 @@ void _strfail(const char *a, const char *e, int len);
elapsed = cs_time() - elapsed; \ elapsed = cs_time() - elapsed; \
printf(" [%.3f] %s\n", elapsed, test_name); \ printf(" [%.3f] %s\n", elapsed, test_name); \
fflush(stdout); \ fflush(stdout); \
g_num_tests++; \
} \ } \
if (msg) return msg; \ if (msg) return msg; \
} while (0) } while (0)
/* VC6 doesn't know how to cast an unsigned 64-bit int to double */ /* VC6 doesn't have long long. */
#if (defined(_MSC_VER) && _MSC_VER <= 1200) #if (defined(_MSC_VER) && _MSC_VER <= 1200)
#define AS_DOUBLE(d) (double)(int64_t)(d) #define LONG_TYPE int64_t
#else #else
#define AS_DOUBLE(d) (double)(d) #define LONG_TYPE long long
#endif #endif
#define AS_DOUBLE(d) (double)(d)
#define RANGE_CHECK(x) (fabs(x) > 4503599627370496.0 /* 2 << 51 */)
/* /*
* Numeric equality assertion. Comparison is made in native types but for * Numeric equality assertion.
* printing both are convetrted to double. * Args are cast to double to ensure aruemnts are only evaluated once.
* This will work fine for all integer types except large 64-bit values.
*/ */
#define ASSERT_EQ(actual, expected) \ #define ASSERT_EQ(actual, expected) \
do { \ do { \
g_num_tests++; \ const double ad = AS_DOUBLE(actual); \
if (!((actual) == (expected))) { \ const double ed = AS_DOUBLE(expected); \
printf("%f != %f\n", AS_DOUBLE(actual), AS_DOUBLE(expected)); \ if (RANGE_CHECK(ad) || RANGE_CHECK(ed)) { \
FAIL(#actual " == " #expected, __LINE__); \ FAIL("loss of precision, use ASSERT_EQ64", __LINE__); \
} \ } \
g_num_checks++; \
if (!(ad == ed)) { \
printf("%lf != %lf\n", ad, ed); \
FAIL(#actual " != " #expected, __LINE__); \
} \
} while (0)
#define ASSERT_EQ64(actual, expected) \
do { \
const LONG_TYPE a64 = (LONG_TYPE)(actual); \
const LONG_TYPE e64 = (LONG_TYPE)(expected); \
g_num_checks++; \
if (!(a64 == e64)) { \
printf("%lld != %lld\n", a64, e64); \
FAIL(#actual " != " #expected, __LINE__); \
} \
} while (0)
#define ASSERT_NE(actual, expected) \
do { \
const double ad = AS_DOUBLE(actual); \
const double ed = AS_DOUBLE(expected); \
g_num_checks++; \
if (RANGE_CHECK(ad) || RANGE_CHECK(ed)) { \
FAIL("loss of precision, use ASSERT_NE64", __LINE__); \
} \
if (!(ad != ed)) { \
printf("%lf == %lf\n", ad, ed); \
FAIL(#actual " == " #expected, __LINE__); \
} \
} while (0)
#define ASSERT_NE64(actual, expected) \
do { \
const LONG_TYPE a64 = (LONG_TYPE)(actual); \
const LONG_TYPE e64 = (LONG_TYPE)(expected); \
g_num_checks++; \
if (!(a64 != e64)) { \
printf("%lld == %lld\n", a64, e64); \
FAIL(#actual " == " #expected, __LINE__); \
} \
} while (0) } while (0)
/* "Less than" assertion. */ /* "Less than" assertion. */
#define ASSERT_LT(a, b) \ #define ASSERT_LT(a, b) \
do { \ do { \
g_num_tests++; \ const double ad = AS_DOUBLE(a); \
if (!((a) < (b))) { \ const double bd = AS_DOUBLE(b); \
printf("%f >= %f\n", AS_DOUBLE(a), AS_DOUBLE(b)); \ g_num_checks++; \
FAIL(#a " < " #b, __LINE__); \ if (RANGE_CHECK(ad) || RANGE_CHECK(bd)) { \
} \ FAIL("loss of precision in comparison", __LINE__); \
} \
if (!(ad < bd)) { \
printf("%lf >= %lf\n", ad, bd); \
FAIL(#a " < " #b, __LINE__); \
} \
} while (0) } while (0)
/* "Greater than" assertion. */ /* "Greater than" assertion. */
#define ASSERT_GT(a, b) \ #define ASSERT_GT(a, b) \
do { \ do { \
g_num_tests++; \ const double ad = AS_DOUBLE(a); \
if (!((a) > (b))) { \ const double bd = AS_DOUBLE(b); \
printf("%f <= %f\n", AS_DOUBLE(a), AS_DOUBLE(b)); \ g_num_checks++; \
FAIL(#a " > " #b, __LINE__); \ if (!(ad > bd)) { \
} \ printf("%lf <= %lf\n", ad, bd); \
FAIL(#a " > " #b, __LINE__); \
} \
} while (0) } while (0)
/* Assert that actual == expected, where both are NUL-terminated. */ /* Assert that actual == expected, where both are NUL-terminated. */
#define ASSERT_STREQ(actual, expected) \ #define ASSERT_STREQ(actual, expected) \
do { \ do { \
g_num_tests++; \ g_num_checks++; \
if (!_assert_streq(actual, expected)) { \ if (!_assert_streq((actual), (expected))) { \
FAIL("ASSERT_STREQ(" #actual ", " #expected ")", __LINE__); \ FAIL("ASSERT_STREQ(" #actual ", " #expected ")", __LINE__); \
} \ } \
} while (0) } while (0)
@@ -127,27 +181,31 @@ void _strfail(const char *a, const char *e, int len);
/* Assert that actual == expected, where both are pointers */ /* Assert that actual == expected, where both are pointers */
#define ASSERT_PTREQ(actual, expected) \ #define ASSERT_PTREQ(actual, expected) \
do { \ do { \
g_num_tests++; \ const void *ap = (const void *) (actual); \
if (actual != expected) { \ const void *ep = (const void *) (expected); \
printf("%p != %p\n", actual, expected); \ g_num_checks++; \
if (!(ap == ep)) { \
printf("%p != %p\n", ap, ep); \
FAIL("ASSERT_PTREQ(" #actual ", " #expected ")", __LINE__); \ FAIL("ASSERT_PTREQ(" #actual ", " #expected ")", __LINE__); \
} \ } \
} while (0) } while (0)
/* Assert that actual != expected, where both are pointers */ /* Assert that actual != expected, where both are pointers */
#define ASSERT_PTRNEQ(actual, expected) \ #define ASSERT_PTRNE(actual, expected) \
do { \ do { \
g_num_tests++; \ const void *ap = (const void *) (actual); \
if (actual == expected) { \ const void *ep = (const void *) (expected); \
printf("%p == %p\n", actual, expected); \ g_num_checks++; \
FAIL("ASSERT_PTRNEQ(" #actual ", " #expected ")", __LINE__); \ if (!(ap != ep)) { \
} \ printf("%p == %p\n", ap, ep); \
FAIL("ASSERT_PTRNE(" #actual ", " #expected ")", __LINE__); \
} \
} while (0) } while (0)
/* Same as STREQ, but only expected is NUL-terminated. */ /* Same as STREQ, but only expected is NUL-terminated. */
#define ASSERT_STREQ_NZ(actual, expected) \ #define ASSERT_STREQ_NZ(actual, expected) \
do { \ do { \
g_num_tests++; \ g_num_checks++; \
if (!_assert_streq_nz(actual, expected)) { \ if (!_assert_streq_nz(actual, expected)) { \
FAIL("ASSERT_STREQ_NZ(" #actual ", " #expected ")", __LINE__); \ FAIL("ASSERT_STREQ_NZ(" #actual ", " #expected ")", __LINE__); \
} \ } \
@@ -155,7 +213,7 @@ void _strfail(const char *a, const char *e, int len);
#define ASSERT_MG_STREQ(actual, expected) \ #define ASSERT_MG_STREQ(actual, expected) \
do { \ do { \
g_num_tests++; \ g_num_checks++; \
if ((actual).len != strlen(expected) || \ if ((actual).len != strlen(expected) || \
memcmp((actual).p, expected, (actual).len) != 0) { \ memcmp((actual).p, expected, (actual).len) != 0) { \
printf("'%.*s' (%d) != '%s'\n", (int)(actual).len, (actual).p, \ printf("'%.*s' (%d) != '%s'\n", (int)(actual).len, (actual).p, \
Loaded 100 of 125 files, more files were not shown because too many files have changed in this diff. Show more