Compare commits

...

16 Commits

Author SHA1 Message Date
9ce79aef85 change station to monitor 2025-01-07 02:58:29 +01:00
3a5c9abe34 change font of character '1'
could be better, but i like it for now
2025-01-07 02:57:31 +01:00
83fd0e8a8b dont write out of bounds 2025-01-07 02:56:30 +01:00
0e8b867323 changes ive found here 2025-01-07 02:54:19 +01:00
6a9ee38a99 utf8 2023-12-18 01:25:39 +01:00
b781dc0d1b manual parsing kind of works 2023-12-11 04:45:58 +01:00
0b25ceb40d lwjson also does not work, parsing manualy 2023-12-11 00:35:17 +01:00
1ab009feef try use cjson, too much heap usage 2023-12-10 21:47:36 +01:00
f062b492fc get bsvg string 2023-12-07 05:22:55 +01:00
23eb8d5bce add https from example 2023-12-07 04:05:33 +01:00
28410daead add http read 2023-12-06 03:17:28 +01:00
9faf03daf0 wifi task to core 1 2023-12-05 03:58:15 +01:00
7dd9ed7d0f improve 'f' font 2023-12-05 03:50:20 +01:00
17e2480102 add wifi 2023-12-05 03:49:14 +01:00
22a02d1d66 use timer 2023-12-05 02:29:15 +01:00
2699d85193 bump to new idf version 2023-12-02 02:26:27 +01:00
18 changed files with 3074 additions and 841 deletions

View File

@@ -1,6 +1,6 @@
# The following lines of boilerplate have to be in your project's
# CMakeLists in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.5)
cmake_minimum_required(VERSION 3.16)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(hello-world)
project(hello_world)

View File

@@ -1,2 +1,3 @@
idf_component_register(SRCS "hello_world_main.c"
INCLUDE_DIRS "")
idf_component_register(SRCS "main.c" "font.c" "display.c" "text.c" "wlan.c" "https.c" "lwjson/lwjson/src/lwjson/lwjson.c"
REQUIRES esp_driver_gpio esp_wifi nvs_flash esp_timer esp-tls
INCLUDE_DIRS "." "lwjson/lwjson/src/include")

67
main/Kconfig.projbuild Normal file
View File

@@ -0,0 +1,67 @@
menu "WiFi Credentials"
config ESP_WIFI_SSID
string "WiFi SSID"
default "myssid"
help
SSID (network name) for the example to connect to.
config ESP_WIFI_PASSWORD
string "WiFi Password"
default "mypassword"
help
WiFi password (WPA or WPA2) for the example to use.
choice ESP_WIFI_SAE_MODE
prompt "WPA3 SAE mode selection"
default ESP_WPA3_SAE_PWE_BOTH
help
Select mode for SAE as Hunt and Peck, H2E or both.
config ESP_WPA3_SAE_PWE_HUNT_AND_PECK
bool "HUNT AND PECK"
config ESP_WPA3_SAE_PWE_HASH_TO_ELEMENT
bool "H2E"
config ESP_WPA3_SAE_PWE_BOTH
bool "BOTH"
endchoice
config ESP_WIFI_PW_ID
string "PASSWORD IDENTIFIER"
depends on ESP_WPA3_SAE_PWE_HASH_TO_ELEMENT|| ESP_WPA3_SAE_PWE_BOTH
default ""
help
password identifier for SAE H2E
config ESP_MAXIMUM_RETRY
int "Maximum retry"
default 5
help
Set the Maximum retry to avoid station reconnecting to the AP unlimited when the AP is really inexistent.
choice ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD
prompt "WiFi Scan auth mode threshold"
default ESP_WIFI_AUTH_WPA2_PSK
help
The weakest authmode to accept in the scan mode.
This value defaults to ESP_WIFI_AUTH_WPA2_PSK incase password is present and ESP_WIFI_AUTH_OPEN is used.
Please select ESP_WIFI_AUTH_WEP/ESP_WIFI_AUTH_WPA_PSK incase AP is operating in WEP/WPA mode.
config ESP_WIFI_AUTH_OPEN
bool "OPEN"
config ESP_WIFI_AUTH_WEP
bool "WEP"
config ESP_WIFI_AUTH_WPA_PSK
bool "WPA PSK"
config ESP_WIFI_AUTH_WPA2_PSK
bool "WPA2 PSK"
config ESP_WIFI_AUTH_WPA_WPA2_PSK
bool "WPA/WPA2 PSK"
config ESP_WIFI_AUTH_WPA3_PSK
bool "WPA3 PSK"
config ESP_WIFI_AUTH_WPA2_WPA3_PSK
bool "WPA2/WPA3 PSK"
config ESP_WIFI_AUTH_WAPI_PSK
bool "WAPI PSK"
endchoice
endmenu

1
main/cJSON Submodule

Submodule main/cJSON added at cb8693b058

View File

@@ -25,7 +25,7 @@ void latch(){
gpio_set_level(GPIO_LAT, 1);
}
void clock(){
static void clock(){
gpio_set_level(GPIO_CLK, 1);
gpio_set_level(GPIO_CLK, 0);
}
@@ -59,7 +59,7 @@ void display_init(){
gpio_set_level(GPIO_OE, 0);
}
void display_cycle(){
void display_cycle(void* arg){
static uint8_t line = 0;
for(uint8_t i=0;i<128;i++){

View File

@@ -29,8 +29,7 @@ extern uint8_t fb[64][128][3];
void write_bits(uint8_t r1, uint8_t g1, uint8_t b1, uint8_t r2, uint8_t g2, uint8_t b2);
void write_address(uint8_t addr);
void latch(void);
void clock(void);
void display_init(void);
void display_cycle(void);
void display_cycle(void* arg);
#endif

View File

@@ -1,6 +1,6 @@
#include <stdint.h>
const uint8_t font[96][7] = {
const uint8_t font[256][7] = {
{0x00,0x00,0x00,0x00,0x00,0x00,0x00}, //
{0x5f,0x00,0x00,0x00,0x00,0x00,0x00}, // !
{0x03,0x00,0x03,0x00,0x00,0x00,0x00}, // "
@@ -18,7 +18,7 @@ const uint8_t font[96][7] = {
{0x40,0x00,0x00,0x00,0x00,0x00,0x00}, // .
{0x60,0x10,0x08,0x04,0x03,0x00,0x00}, // /
{0x7f,0x41,0x41,0x7f,0x00,0x00,0x00}, // 0
{0x01,0x7f,0x00,0x00,0x00,0x00,0x00}, // 1
{0x02,0x03,0x7f,0x00,0x00,0x00,0x00}, // 1
{0x7b,0x49,0x49,0x6f,0x00,0x00,0x00}, // 2
{0x63,0x49,0x49,0x7f,0x00,0x00,0x00}, // 3
{0x0f,0x08,0x08,0x7f,0x00,0x00,0x00}, // 4
@@ -71,7 +71,7 @@ const uint8_t font[96][7] = {
{0x7c,0x44,0x44,0x6c,0x00,0x00,0x00}, // c
{0x7c,0x44,0x44,0x7f,0x00,0x00,0x00}, // d
{0x7c,0x54,0x54,0x5c,0x00,0x00,0x00}, // e
{0x7f,0x05,0x05,0x01,0x00,0x00,0x00}, // f
{0x04,0x7e,0x05,0x01,0x00,0x00,0x00}, // f
{0xbc,0xa4,0xa4,0xfc,0x00,0x00,0x00}, // g
{0x7f,0x04,0x04,0x7c,0x00,0x00,0x00}, // h
{0x7d,0x00,0x00,0x00,0x00,0x00,0x00}, // i
@@ -96,6 +96,161 @@ const uint8_t font[96][7] = {
{0xff,0x00,0x00,0x00,0x00,0x00,0x00}, // |
{0x41,0x3e,0x08,0x00,0x00,0x00,0x00}, // }
{0x1c,0x04,0x1c,0x10,0x1c,0x00,0x00}, // ~
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x7d,0x44,0x44,0x7d,0x00,0x00,0x00}, // o
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00}
};

81
main/http.c Normal file
View File

@@ -0,0 +1,81 @@
#include "http.h"
#include "esp_err.h"
#include "esp_log.h"
#include "lwip/err.h"
#include "lwip/sockets.h"
#include "lwip/sys.h"
#include "lwip/netdb.h"
#include "lwip/dns.h"
static const char *TAG = "http";
static const char *REQUEST = "GET " WEB_PATH " HTTP/1.0\r\n"
"Host: "WEB_SERVER":"WEB_PORT"\r\n"
"User-Agent: esp-idf/1.0 esp32\r\n"
"\r\n";
esp_err_t http_request(char* buf)
{
const struct addrinfo hints = {
.ai_family = AF_INET,
.ai_socktype = SOCK_STREAM,
};
struct addrinfo *res;
struct in_addr *addr;
int s, r;
int err = getaddrinfo(WEB_SERVER, WEB_PORT, &hints, &res);
if(err != 0 || res == NULL) {
ESP_LOGE(TAG, "DNS lookup failed err=%d res=%p", err, res);
return ESP_ERR_NOT_FOUND;
}
/* Code to print the resolved IP.
* Note: inet_ntoa is non-reentrant, look at ipaddr_ntoa_r for "real" code */
addr = &((struct sockaddr_in *)res->ai_addr)->sin_addr;
ESP_LOGI(TAG, "DNS lookup succeeded. IP=%s", inet_ntoa(*addr));
s = socket(res->ai_family, res->ai_socktype, 0);
if(s < 0) {
ESP_LOGE(TAG, "... Failed to allocate socket.");
freeaddrinfo(res);
return -1;
}
ESP_LOGI(TAG, "... allocated socket");
if(connect(s, res->ai_addr, res->ai_addrlen) != 0) {
ESP_LOGE(TAG, "... socket connect failed errno=%d", errno);
close(s);
freeaddrinfo(res);
return -1;
}
ESP_LOGI(TAG, "... connected");
freeaddrinfo(res);
if (write(s, REQUEST, strlen(REQUEST)) < 0) {
ESP_LOGE(TAG, "... socket send failed");
close(s);
return -1;
}
ESP_LOGI(TAG, "... socket send success");
struct timeval receiving_timeout;
receiving_timeout.tv_sec = 5;
receiving_timeout.tv_usec = 0;
if (setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &receiving_timeout,
sizeof(receiving_timeout)) < 0) {
ESP_LOGE(TAG, "... failed to set socket receiving timeout");
close(s);
return -1;
}
ESP_LOGI(TAG, "... set socket receiving timeout success");
/* Read HTTP response */
r = read(s, buf, RCV_BUFSIZE);
if(r >= RCV_BUFSIZE)
return -1;
return 0;
}

10
main/http.h Normal file
View File

@@ -0,0 +1,10 @@
#include "esp_system.h"
/* Constants that aren't configurable in menuconfig */
#define WEB_SERVER "mustbehax.de"
#define WEB_PORT "80"
#define WEB_PATH "/test"
#define RCV_BUFSIZE 8000
esp_err_t http_request(char* buf);

124
main/https.c Normal file
View File

@@ -0,0 +1,124 @@
#include "esp_tls.h"
#include "esp_log.h"
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "esp_crt_bundle.h"
static const char *TAG = "https";
#define WEB_SERVER "bsvg.efa.de"
#define WEB_PORT "443"
#define WEB_URL "/bsvagstd/XML_DM_REQUEST?outputFormat=JSON&stateless=1&locationServerActive=1&type_dm=stop&name_dm=\"Kaiserstr,Braunschweig\"&mode=direct&ptOptionsActive=1&useRealtime=1"
//#define WEB_SERVER "mustbehax.de"
//#define WEB_PORT "443"
//#define WEB_URL "/web/reduced.json"
static const char REQUEST[] = "GET " WEB_URL " HTTP/1.1\r\n"
"Host: "WEB_SERVER"\r\n"
"User-Agent: esp-idf/1.0 esp32\r\n"
"\r\n";
esp_err_t https_get_request_using_crt_bundle(char* buf, size_t bufsize)
{
memset(buf, 0, bufsize);
ESP_LOGI(TAG, "https_request using crt bundle");
esp_tls_cfg_t cfg = {
.crt_bundle_attach = esp_crt_bundle_attach,
};
//https_get_request(cfg, "https://"WEB_SERVER""WEB_URL, HOWSMYSSL_REQUEST);
//char buf[47000];
int ret, len;
esp_tls_t *tls = esp_tls_init();
if (!tls) {
ESP_LOGE(TAG, "Failed to allocate esp_tls handle!");
return -1;
}
if (esp_tls_conn_http_new_sync("https://"WEB_SERVER""WEB_URL, &cfg, tls) == 1) {
ESP_LOGI(TAG, "Connection established...");
} else {
ESP_LOGE(TAG, "Connection failed...");
int esp_tls_code = 0, esp_tls_flags = 0;
esp_tls_error_handle_t tls_e = NULL;
esp_tls_get_error_handle(tls, &tls_e);
/* Try to get TLS stack level error and certificate failure flags, if any */
ret = esp_tls_get_and_clear_last_error(tls_e, &esp_tls_code, &esp_tls_flags);
if (ret == ESP_OK) {
ESP_LOGE(TAG, "TLS error = -0x%x, TLS flags = -0x%x", esp_tls_code, esp_tls_flags);
}
esp_tls_conn_destroy(tls);
return -2;
}
#ifdef CONFIG_EXAMPLE_CLIENT_SESSION_TICKETS
/* The TLS session is successfully established, now saving the session ctx for reuse */
if (save_client_session) {
esp_tls_free_client_session(tls_client_session);
tls_client_session = esp_tls_get_client_session(tls);
}
#endif
size_t written_bytes = 0;
do {
ret = esp_tls_conn_write(tls,
REQUEST + written_bytes,
strlen(REQUEST) - written_bytes);
if (ret >= 0) {
ESP_LOGI(TAG, "%d bytes written", ret);
written_bytes += ret;
} else if (ret != ESP_TLS_ERR_SSL_WANT_READ && ret != ESP_TLS_ERR_SSL_WANT_WRITE) {
ESP_LOGE(TAG, "esp_tls_conn_write returned: [0x%02X](%s)", ret, esp_err_to_name(ret));
esp_tls_conn_destroy(tls);
return -3;
}
} while (written_bytes < strlen(REQUEST));
uint32_t write_offset = 0;
memset(buf, 0x00, bufsize);
ESP_LOGI(TAG, "Reading HTTP response...");
do {
len = bufsize - write_offset - 1;
if(len > 6000)
len = 6000;
ret = esp_tls_conn_read(tls, &buf[write_offset], len);
if (ret == ESP_TLS_ERR_SSL_WANT_WRITE || ret == ESP_TLS_ERR_SSL_WANT_READ) {
continue;
} else if (ret < 0) {
ESP_LOGE(TAG, "esp_tls_conn_read returned [-0x%02X](%s)", -ret, esp_err_to_name(ret));
break;
} else if (ret == 0) {
ESP_LOGI(TAG, "connection closed");
break;
}
write_offset += ret;
len = ret;
ESP_LOGI(TAG, "%d bytes read", len);
//if(!strstr(buf, "departureList")){
// ESP_LOGI(TAG,"tossing ... strstr: %ld", (uint32_t)strstr(buf, "departureList"));
// write_offset=0;
//}else
// ESP_LOGI(TAG,"keeping ... strstr: %ld", (uint32_t)strstr(buf, "departureList"));
} while (1);
buf[write_offset+len+1] = 0;
esp_tls_conn_destroy(tls);
return 0;
///* Print response directly to stdout as it is read */
//for (int i = 0; i < sizeof(buf); i++) {
// putchar(buf[i]);
// if(i%100 == 0)
// vTaskDelay(1);
//}
//putchar('\n'); // JSON output doesn't have a newline at end
}

4
main/https.h Normal file
View File

@@ -0,0 +1,4 @@
#include <stddef.h>
#include "esp_err.h"
esp_err_t https_get_request_using_crt_bundle(char* buf, size_t bufsize);

View File

@@ -6,17 +6,26 @@
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <strings.h>
#include <sys/types.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "esp_spi_flash.h"
#include "driver/gpio.h"
#include "esp_timer.h"
#include "esp_log.h"
#include "display.h"
#include "text.h"
#include "wlan.h"
#include "https.h"
#include "esp_heap_caps.h"
#include "lwjson/lwjson.h"
#ifdef CONFIG_IDF_TARGET_ESP32
#define CHIP_NAME "ESP32"
@@ -27,13 +36,186 @@
#endif
const esp_timer_create_args_t periodic_timer_args = {
.callback = &display_cycle,
};
uint8_t buf_ok = 0;
char bsvg_buf[40000];
static void https_request_task(void *pvparameters){
while(https_get_request_using_crt_bundle(bsvg_buf, sizeof(bsvg_buf)) != 0){
ESP_LOGE("bsvg", "Failed to get data from server. Retrying...");
vTaskDelay(1);
}
buf_ok = 1;
vTaskDelete(NULL);
}
void get_json_string(char* buf, char* name, char* dest){
char* element = strstr(buf, name);
char *ptr= element;
while(*ptr != ':' && *ptr != 0) ptr++;
while(*ptr != '"' && *ptr != 0) ptr++;
ptr++;
char *end=ptr;
while(*end != '"') end++;
strncpy(dest, ptr, end-ptr);
dest[end-ptr]=0;
}
uint8_t json_ok = 0;
static void json_parse_task(void *pvparameters){
//uint16_t start_ptr = 0;
//while(buf[start_ptr] != '{' && start_ptr < sizeof(buf))
// start_ptr++;
char *start = strstr(bsvg_buf, "\"departureList\"") + 17;
//char *start = strstr(bsvg_buf, "{");
ESP_LOGI("bsvg", "start at %ld: \"%.10s\"", (uint32_t)start, start);
//departureList = cJSON_Parse(start);
uint8_t line = 0;
char *item = start;
char txt[6][50];
while((item = strstr(item+1, "{ \"stopID\":")) != 0){
char symbol[10];
get_json_string(item, "symbol", symbol);
char direction[50];
get_json_string(item, "direction", direction);
char countdown[10] ;
get_json_string(item, "countdown", countdown);
if(atoi(countdown)>=60){
uint8_t h = atoi(countdown) / 60;
uint8_t m = atoi(countdown) % 60;
sprintf(countdown, "%d:%02d", h, m);
}
if(line < 6){
sprintf(txt[line], " %.4s", countdown);
put_line(fb, line, txt[line], 1, 1);
sprintf(txt[line], " %.20s", direction);
put_line(fb, line, txt[line], 1, 1);
sprintf(txt[line], "%.3s", symbol);
put_line(fb, line, txt[line], 1, 1);
}
//sprintf(txt[line], "%.3s\t%.20s\t%.4s", symbol, direction, countdown);
printf("line = %d: %s\n", line, txt[line]);
printf("\n");
line++;
}
//lwjson_init(&lwjson, tokens, LWJSON_ARRAYSIZE(tokens));
//if (lwjson_parse(&lwjson, start) == lwjsonOK) {
// const lwjson_token_t* t;
// printf("JSON parsed..\r\n");
// /* Find custom key in JSON */
// if ((t = lwjson_find(&lwjson, "stopID")) != NULL) {
// printf("Key found with data type: %d\r\n", (int)t->type);
// }
// /* Call this when not used anymore */
// lwjson_free(&lwjson);
//}
//else{
// ESP_LOGI("bsvg", "parse fail");
//}
json_ok = 1;
vTaskDelete(NULL);
}
void app_main(void)
{
printf("Hello world!\n");
printf("free heap: %d\n", heap_caps_get_free_size( MALLOC_CAP_DEFAULT) );
ESP_LOGI("bsvg", "display init");
display_init();
put_line(fb, 2, "429 Amalienplatz", 1, 1);
printf("free heap: %d\n", heap_caps_get_free_size( MALLOC_CAP_DEFAULT) );
esp_timer_handle_t periodic_timer;
ESP_ERROR_CHECK(esp_timer_create(&periodic_timer_args, &periodic_timer));
ESP_ERROR_CHECK(esp_timer_start_periodic(periodic_timer, 500));
put_line(fb, 1, "Moin", 1, 1);
wlan_init();
put_line(fb, 2, "wifi", 1, 1);
for (;;) {
display_cycle();
printf("free heap: %d\n", heap_caps_get_free_size( MALLOC_CAP_DEFAULT) );
xTaskCreate(&https_request_task, "https_get_task", 8192, NULL, 5, NULL);
while (!buf_ok) {
vTaskDelay(1);
}
printf("free heap: %d\n", heap_caps_get_free_size( MALLOC_CAP_DEFAULT) );
ESP_LOGI("bsvg", "got from https server:");
for(uint32_t i=0; i<sizeof(bsvg_buf); i++){
putchar(bsvg_buf[i]);
if(i%1000==0)
vTaskDelay(1);
}
putchar('\n');
printf("free heap: %d\n", heap_caps_get_free_size( MALLOC_CAP_DEFAULT) );
put_line(fb, 3, "https", 1, 1);
xTaskCreate(&json_parse_task, "json_parse_task", 8192, NULL, 5, NULL);
ESP_LOGI("bsvg", "Parsing JSON...");
while (!json_ok) {
printf("free heap: %d\n", heap_caps_get_free_size( MALLOC_CAP_DEFAULT) );
vTaskDelay(1);
}
ESP_LOGI("bsvg", "Done");
//if (departureList == NULL)
//{
// ESP_LOGI("bsvg", "did not get list");
// const char *error_ptr = cJSON_GetErrorPtr();
// heap_caps_print_heap_info(MALLOC_CAP_DEFAULT);
// if (error_ptr != NULL)
// {
// fprintf(stderr, "Error at %ld: %.10s\n", (uint32_t)error_ptr-(uint32_t)bsvg_buf, error_ptr);
// fprintf(stderr, "%.100s%.100s\n", error_ptr-100, error_ptr);
// fprintf(stderr, " ^\n");
// }
// else {
// fprintf(stderr, "did not get err ptr\n");
// }
//}else{
// ESP_LOGI("bsvg", "got list");
// printf("free heap: %d\n", heap_caps_get_free_size( MALLOC_CAP_DEFAULT) );
// ESP_LOGI("bsvg", "type: %d", departureList->type);
// ESP_LOGI("bsvg", "child: %ld", (uint32_t)departureList->child);
// if(cJSON_IsArray(departureList)){
// ESP_LOGI("bsvg", "is Array");
// const cJSON *departure = NULL;
// cJSON_ArrayForEach(departure, departureList){
// cJSON *number = cJSON_GetObjectItemCaseSensitive(cJSON_GetObjectItemCaseSensitive(departure, "servingLine"), "number");;
// if(number == NULL)
// ESP_LOGI("bsvg", "cant get number");
// else if(cJSON_IsNumber(number))
// ESP_LOGI("bsvg", "number (int): %d\n", number->valueint);
// else if(cJSON_IsString(number))
// ESP_LOGI("bsvg", "number (str): %.3s\n", number->valuestring);
// else
// ESP_LOGI("bsvg", "cant get number value");
// }
// }
//}
vTaskDelay(6000);
}
}

View File

@@ -1,4 +1,5 @@
#include <stdint.h>
#include <stdio.h>
#include "text.h"
uint8_t check_chr_width(const uint8_t chr[]){
@@ -22,8 +23,17 @@ void put_line(uint8_t framebuffer[DISPLAY_HEIGHT][DISPLAY_WIDTH][3], uint8_t lin
uint8_t pos = 0;
uint8_t disp_pos = 0;
while(str[pos] != 0){
put_chr(framebuffer, line, disp_pos, font[str[pos]-0x20], size);
disp_pos += (check_chr_width(font[str[pos]-0x20]) + 1 + spacing)*size;
uint16_t code = 0;
if((str[pos]&0xE0) == 0xC0 && (str[pos+1]&0xC0) == 0x80){
code = (str[pos] & 0x1F) << 6;
code |= (str[pos+1] & 0x3F);
printf("mbc: %x\n", font[code][0]);
pos++;
}else{
code = str[pos];
}
put_chr(framebuffer, line, disp_pos, font[code-0x20], size);
disp_pos += (check_chr_width(font[code-0x20]) + 1 + spacing)*size;
pos++;
}
}

115
main/wlan.c Normal file
View File

@@ -0,0 +1,115 @@
#include "sdkconfig.h"
#include "esp_system.h"
#include "esp_event.h"
#include "nvs_flash.h"
#include "esp_log.h"
#include "esp_wifi.h"
static const char *TAG = "wlan";
/* The event group allows multiple bits for each event, but we only care about two events:
* - we are connected to the AP with an IP
* - we failed to connect after the maximum amount of retries */
#define WIFI_CONNECTED_BIT BIT0
#define WIFI_FAIL_BIT BIT1
/* FreeRTOS event group to signal when we are connected*/
static EventGroupHandle_t s_wifi_event_group;
static int s_retry_num = 0;
static void event_handler(void* arg, esp_event_base_t event_base,
int32_t event_id, void* event_data)
{
if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) {
esp_wifi_connect();
} else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {
if (s_retry_num < CONFIG_ESP_MAXIMUM_RETRY) {
esp_wifi_connect();
s_retry_num++;
ESP_LOGI(TAG, "retry to connect to the AP");
} else {
xEventGroupSetBits(s_wifi_event_group, WIFI_FAIL_BIT);
}
ESP_LOGI(TAG,"connect to the AP fail");
} else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
ip_event_got_ip_t* event = (ip_event_got_ip_t*) event_data;
ESP_LOGI(TAG, "got ip:" IPSTR, IP2STR(&event->ip_info.ip));
s_retry_num = 0;
xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT);
}
}
void wifi_init_sta(void)
{
s_wifi_event_group = xEventGroupCreate();
ESP_ERROR_CHECK(esp_netif_init());
ESP_ERROR_CHECK(esp_event_loop_create_default());
esp_netif_create_default_wifi_sta();
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
esp_event_handler_instance_t instance_any_id;
esp_event_handler_instance_t instance_got_ip;
ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,
ESP_EVENT_ANY_ID,
&event_handler,
NULL,
&instance_any_id));
ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT,
IP_EVENT_STA_GOT_IP,
&event_handler,
NULL,
&instance_got_ip));
wifi_config_t wifi_config = {
.sta = {
.ssid = CONFIG_ESP_WIFI_SSID,
.password = CONFIG_ESP_WIFI_PASSWORD,
///* Authmode threshold resets to WPA2 as default if password matches WPA2 standards (pasword len => 8).
// * If you want to connect the device to deprecated WEP/WPA networks, Please set the threshold value
// * to WIFI_AUTH_WEP/WIFI_AUTH_WPA_PSK and set the password with length and format matching to
// * WIFI_AUTH_WEP/WIFI_AUTH_WPA_PSK standards.
// */
//.threshold.authmode = ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD,
//.sae_pwe_h2e = ESP_WIFI_SAE_MODE,
//.sae_h2e_identifier = EXAMPLE_H2E_IDENTIFIER,
},
};
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA) );
ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config) );
ESP_ERROR_CHECK(esp_wifi_start() );
ESP_LOGI(TAG, "wifi_init_sta finished.");
/* Waiting until either the connection is established (WIFI_CONNECTED_BIT) or connection failed for the maximum
* number of re-tries (WIFI_FAIL_BIT). The bits are set by event_handler() (see above) */
EventBits_t bits = xEventGroupWaitBits(s_wifi_event_group,
WIFI_CONNECTED_BIT | WIFI_FAIL_BIT,
pdFALSE,
pdFALSE,
portMAX_DELAY);
/* xEventGroupWaitBits() returns the bits before the call returned, hence we can test which event actually
* happened. */
if (bits & WIFI_CONNECTED_BIT) {
ESP_LOGI(TAG, "connected to ap SSID:%s password:%s",
CONFIG_ESP_WIFI_SSID, CONFIG_ESP_WIFI_PASSWORD);
} else if (bits & WIFI_FAIL_BIT) {
ESP_LOGI(TAG, "Failed to connect to SSID:%s, password:%s",
CONFIG_ESP_WIFI_SSID, CONFIG_ESP_WIFI_PASSWORD);
} else {
ESP_LOGE(TAG, "UNEXPECTED EVENT");
}
}
void wlan_init(){
esp_err_t ret = nvs_flash_init();
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
ESP_ERROR_CHECK(nvs_flash_erase());
ret = nvs_flash_init();
}
ESP_ERROR_CHECK(ret);
wifi_init_sta();
}

1
main/wlan.h Normal file
View File

@@ -0,0 +1 @@
void wlan_init(void);

1609
sdkconfig

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +0,0 @@
CONFIG_APP_BUILD_TYPE_ELF_RAM=y
CONFIG_VFS_SUPPORT_TERMIOS=
CONFIG_NEWLIB_NANO_FORMAT=y
CONFIG_ESP32_PANIC_PRINT_HALT=y
CONFIG_ESP32_DEBUG_STUBS_ENABLE=
CONFIG_ESP_ERR_TO_NAME_LOOKUP=

File diff suppressed because it is too large Load Diff