ESP8266 examples
This page captures our experience reading and executing the examples provided with standard esp8266 RTOS SDK.
3. SPI: generic is strange, one with OLED is understandable but can't really test without an oled
- 802.11 - PHY, MAC, bands speed
- IP - IP address, fragmentation, re-assembly, MTU
- TCP - sequence, ACK, error check, port, window size
- UDP - checksum, port, multi/broadcast
- HTTP - request-response, connection reuse
Example wifi->getting started folder
4. Station example
Connecting esp8266 as station to iPhone hotspot
Connecting as in blue line appears on iPhone but no IP displayed on terminal
Seems to be a problem with iPhone
Links read:
https://osxdaily.com/2013/01/11/get-new-ip-address-ios-renew-dhcp-lease/
https://serverfault.com/questions/278567/dealing-with-ipad-dhcp-issue
https://discussions.apple.com/thread/8599697
https://www.iphonehacks.com/2018/08/fix-wifi-problems-ios-12.html
https://www.saintlad.com/fix-personal-hotspot-issues-in-ios-13/#method7
Tried:
- iPhone switched OFF and ON, connected to power, different iPhone
- DHCP timeout 2->10 minutes
- Auto IP works with iPhone, assigns IP 169.254.27.79. At same time, MacBook connects via wifi to same iPhone, gets IP 172.20.10.3, can ping esp
- Android phones (tried 2) works, esp gets IP 192.168.43.118, MacBook gets 192.168.43.5, can ping esp
- AutoIP with android phone, assigns DHCP IP 192.168.43.118 but after 2-6 failed tries, still does not use autoIP
How to switch AutoIP ON: make menuconfig: component—>LWIP—>enable IPV4 link local addressing
How to change DHCP timeout: make menuconfig: component—>config—>tcpip adapter—>IP address lost timer interval
Final approach for now: #3
Autoip approach did not work for further examples that required connection with internet
Bought new SIM to put in an android phone. That is working fine.
nvs, tcp-adapter, wifi ON
5. softAP example: worked without any problem
Protocols folder
Using protcol_examples_common.h and connect.c (example_connect/disconnect) for all examples in this folder
6. httprequest example
in addition to nvs, tcp-adapter, wifi ON, creating a socket connection using 'addressinfo', then send a GET request and receive response (full page from example.com)
main functions: get_task(), getaddreinfo()
7. httpserver example - simple
- esp connected to android phone in station mode with IP 192.168.43.118 and becomes a server
- laptop connected to same phone with IP 192.168.43.5 and becomes a client
- Tried GET, PUT and POST
- Chrome browser can
- send GET request in URL
- send query string in URL
- show response body in main page
- show request/response headers in browser (view->developer->inspect elements->network, re-send request)
- Curl can
- send GET, PUT and POST (and probably others)
- can even send a file with POST and receive response in another file
- may be able to send/show all request / response parameters
- https://curl.haxx.se/docs/httpscripting.html
- Modheader can (chrome plugin)
- Add request / response headers to a particular URL
- Restman can (chrome plugin)
- send GET, PUT and POST with parameters
- show response along with headers etc.
- not sure how to send file in POST
- http_req_t structure in esp_http_server.h
- use of user_ctx to maintain and show visitor count
- use of sess_ctx to send any number and accumulate it
- use of local pointers to update value stored in global pointers like user_ctx and sess_ctx
- All 3 (GET, PUT and POST) add 1 to visitor count & start a session if sess_ctx is NULL
- Once sess_ctx is not NULL, the session can only be terminated by calling 'free' function. In this case, it gets called when webserver and hence the socket is closed
- POST allows user to send a number that is added to sess_ctx
- GET shows the current value of sess_ctx
- PUT allows user to send a number, sess_ctx value is reset to that value
- read esp_http_server.h (to understand get/set sess_ctx, get/set transport_ctx, get_global_user_ctx, get_global_transport_ctx, sess_trigger_close, sess_update_lru_counter)
- 8 handlers doing simple things
- printing remaining heap
- using httpd_queue_work
- async_get_handler not working properly
- read esp_http_client.h
- additional methods PATCH, DELETE, HEAD
- EAGAIN message/error
- Authentication types: basic v digest
- Certification: SSL (confirms identity of server & encrypts data), PEM file
- Redirection requests: absolute v relative (not full path but only page), make source relative, not destination
- httpbin.org
- basically to establish a secure connection SSL/TLS
- esp_tls.h
- simply using the wrapper API in file above
- https_mbedtls_example_main: using esp_tls_mbedtls.h, complex API, lots of functions
12. openssl demo example
- ssl.h
- hosting structure with in-addr = 32 bit int to store IP address
- get host by name
- create ssl context (v1.1)
- verify ssl context (verify none)
- create socket
- bind socket to local port (9999)
- connect socket to remote server (IP, port 443)
- create SSL
- connect SSL to socket
- check heap size / stack depth
- send request to SSL (write)
- read response
13. openssl client example (different points from demo)
- extra certificates (ca, server, client - pem files and keys)
- different version while creating context (v1.2)
- load certificates and keys to context
- verify ssl context (verify peer)
- when run, client-server connected, server (laptop) showed request received but client could not get a response back
14. open ssl server example (different points)
- after create context and socket, listen (instead of connect)
- create ssl, then accept (server socket accept client)
- connect ssl with new (client) socket
- ssl accept (ssl server accept client)
- write/read
- same as client example, server could not get a response back from client (laptop)
- using standard sockets.h
- using python script to create server/client (on the other end of esp)
- port is important, 50000 did not work, 3333 worked
- BCD socket (link)
- destinationAddress = server’s
- create socket with SOCK_DGRAM (datagram)
- another while (1)
- sendto (sock, payload, destAddr)
- recvfrom (sock, buf, sourceAddr (blank)): you get data & sourceAddr
- no 3 way handshake
- destAddr: INADDR_ANY (same as tcp)
- create socket
- bind socket and destAddr
- another while(1)
- recvfrom(sock, buf, sourceAddr (blank)): you get data & sourceAddr
- sendto (sock, buf, sourceAddr)
- client, server
- machine to machine
- UDP based
- methods similar to http
- resolves hostname to IP address within small (local) network that does not have a dedicated DNS
- designed to enable simple, constrained devices to join the IoT even through constrained networks with low bandwidth and low availability
- generally used for machine-to-machine (M2M) applications such as smart energy and building automation
- app_main
- mdns example task
- generate hostname
- initialise mdns
- mdns print results
- query mdns service
- query mdns host
- initialise button
- while (1) check button, mdns example task
- synchronizes system time with official world time / coordinated universal time
- simpler (needs fewer algorithms) than NTP (network time protocol) but less accurate
- not used much if processing power enough to run NTP
- UDP port 123, TZ for India is Asia/Kolkata (not working), UTC-5:30 worked
- app_main
- sntp example task
- initialise sntp
- obtain time
- Useful links: internetofthingsagenda, espressif
- Light weight IOT messaging, publish-subscribe architecture
- client (pub) --> broker --> client (sub)
- you subscribe to topics, if you publish topic gets created (if does not exist)
- if broker->pub is broken, cached msg sent to all subs
- if broker->sub is broken, values buffered & sent when back online
- port 1883 (non encrypted), 8883 (encrypted)
- client side certificates are also verified during handshake
- connection-->authentication-->communication-->termination
- 2 byte fixed header+variable length optional header+256MB payload+QoS level
- BLOBs - binary large objects
- mqtt://mqtt.eclipse.org
- graceful shutdown, easy reconnect
- MQTT tcp client example
- events: connected, published, subscribed, unsubscribed, disconnected
- if data present with broker, no subscribe event called, direct data event
- make erase_flash to get rid of prev data
- test1: subscribe to qos0 only: print event_sub
- test2: subscribe to qos1 only: event sub+event data (previously kept with broker, end less loop, msg id different every time). topic+event: unique msg id; topic / event change: msg id change
- test3: qos0 sub & unsub: event_sub (diff msg ids)
- test4: qos1 sub & unsub: event_sub, event_data, event_unsub (all diff msg ids)
- test 5: qos0 sub, publish within event sub body; event_sub, event_data
- test6: no prev data stored with broker in case of qos0
- test7: qos0-sub, publish, unsub: event_sub, event_unsub (no data event!) unsub happens before data!
- test8: qos0 pub-sub, qos1 sub-unsub: no data for qos0 unless you publish 'within sub event'. event_sub for qos0, event_data for qos1, event_unsub for qos1
- test9: qos0 sub (publish within sub), qos1 sub-unsub: event_sub qos0, event_data qos1, event_unsub qos1, event_data qos0 (comes last event when published much earlier! priority less than qos1?)
- MQTT webserver example
- same code, only config for WS instead of TCP
- MQTT webserver secure example
- certificate of broker procured and added in config
- MQTT on SSL example
- same as WSS
- MQTT SSL mutual auth example
- additional client certificate with pem file & key
- url hardcoded in config struct
- used eclipse's mosquitto
Tested with Increased storage partition to (almost) maximum memory available in esp flash. partition tables
About creating ‘provision’ (like electrical/plumbing) to update something (like wifi ssid/pwd in this case) while device is active (doing it’s main job)
Components
- protocomm: manages secure session (app_prov.h/.c): can work over wifi (softap+httpd), BLE and console
- protobuf: google’s protocol for serialised data transfer of structures
- wifi provisoning: exchange of userid/pwd (wifi_init_sta/connect/mode)
Flow
- app_main
- tcp adapter init, loop create default, nvs init, security 0 or 1
- is provisioned? if yes, wifi_init_sta (register events, wifi start, mode)
- if no, read esp softap ssid from config & send to app_prov_start_softap_provisioning
- app_prov.h
- app_prov_get_wifi_state, disconnect reason
- event handler
- is provisioned
- configure sta
- start softap provisioning
- app_prov_data: protocol handler, security, pop, timer, wifi state, disconnect reason
Running experience
- install google’s protobuf
- copied 1 missing file (wifi_scan.py) in sdk\tools\esp_prov\prov\
- updated 1 outdated file (security1.py) in sdk\tools\esp_prov\security\
- laptop and esp connect to each other and are also able to exchange data but does not work beyond a point
- keeps saying ‘connecting’, does not say ‘connected’ and does not proceed to close softap etc.
- system_events are not happening, no way to trigger system events from user code
- latest SDK/example code available on GitHub seems to be different from ours (downloaded 2 months ago)
Custom config: extra config / end-point in protocomm
Console
- components
- linenoise lib
- argtable2 lib
- esp_console.h, esp_vfs_dev.h
- cmdwifi.c, cmdsystem.c
- app_main
- nvs init
- console init
- esp console register help command
- register system
- register wifi
- linenoiseprobe
- linenoise
- esp console run
- Runs fine
- Reading: VFS
wrapper on top of file systems like FAT, SPIFFS etc. Skimmed through link, review when needed
- OTA
- Reading: partition tables (link)
- single factory app, no OTA: nvs, phy-init, factory (bootloader will run this by default)
- nvs, otadata, phy_init, ota_0, ota_1 (bootloader will read otadata to know which app to run; if empty, will run 1st 'app' partition (ota_0/factory/test_app)
- nvs (size 0x4000 or 0x2000) is for working data, can create extra 'data' partitions for storage like SPIFFS
- 1st app partition is starting at 0x10000 (64kB) in both default cases
- app should be in integrated 1M partition - not clear
- Reading: bootloader (link)
- Bootloader is at 0x1000
- it can update newer SDK code but not older
- With old code, keep bootloader copy also!!
- so don't upload (flash) ESP-IDF unless the code (forumware) is also updated and tested and can be uploaded (flashed) along with
- ESP-IDF versions link
- OTA links: main link having esp_ota_ops.h, link related to https
- App rollback needs some thinking specially related to versioning & inability of bootloader to update older versions
- simple_ota_example
- read_me & ota_workflow.png is good
- Running experience
- Error1: hostname / common name not valid, certificate cannot be verified. While creating cert pem key, give hostname = IP address of server (laptop).
- Error2: E (3220) esp-tls-mbedtls: mbedtls_ssl_handshake returned -0x2700
I (3223) esp-tls-mbedtls: Failed to verify peer certificate!
I (3226) esp-tls-mbedtls: verification info: ! The certificate Common Name (CN) does not match with the expected CN
! The certificate is not
E (3247) esp-tls: Failed to open new connection
E (3255) TRANS_SSL: Failed to open a new connection
E (3267) HTTP_CLIENT: Connection failed, sock < 0
E (3272) esp_https_ota: Failed to open HTTP connection: 28674
E (3281) simple_ota_example: Firmware Upgrades Failed
- Sometimes returned 0x4c (instead of 0x2700)
- Links studied: link1, link2
- Worked when retried, working but still this error appears
E (13687) TRANS_SSL: esp_tls_conn_read error, errno=Socket is not connected
No comments:
Post a Comment