260 lines
No EOL
6.5 KiB
C++
260 lines
No EOL
6.5 KiB
C++
#include "stdlib.h"
|
|
|
|
#include "Arduino.h"
|
|
#include "nvs_flash.h"
|
|
#include <mutex>
|
|
|
|
#include "mpack.h"
|
|
#include "ESP32epdx.h"
|
|
#include "EPD.h"
|
|
#include "mesh_netif.h"
|
|
#include "esp_mesh.h"
|
|
#include "main.h"
|
|
|
|
#include "sha256.h"
|
|
|
|
std::mutex epd_mtx;
|
|
|
|
/*
|
|
SPI: SCK = 6 ; MISO = 2 ; MOSI = 7 ; SS = 16
|
|
EPD: RES = 22 ; DC = 23 ; CS = 1 ; BUSY = 0
|
|
*/
|
|
|
|
uint8_t *image_buf = nullptr;
|
|
|
|
#if CONFIG_MESH_ROOT == 0
|
|
extern "C" void req_release(request_t *req) {
|
|
free(req->command);
|
|
req->command = 0;
|
|
free(req->data);
|
|
req->data = 0;
|
|
|
|
free(req);
|
|
|
|
return;
|
|
}
|
|
|
|
extern "C" int command_update_image(uint64_t index, char *buf, size_t len) {
|
|
// check
|
|
if (!buf) {
|
|
return -2;
|
|
}
|
|
|
|
// main
|
|
if (!epd_mtx.try_lock()) {
|
|
return -3; // locked
|
|
}
|
|
|
|
if (
|
|
index < 0 || index >= CONFIG_IMAGE_BUF_SIZE ||
|
|
len < 0 || len > CONFIG_IMAGE_BUF_SIZE ||
|
|
(index+len) < 0 || (index+len) > CONFIG_IMAGE_BUF_SIZE
|
|
)
|
|
{
|
|
epd_mtx.unlock();
|
|
return -2;
|
|
}
|
|
|
|
memcpy(image_buf + index, buf, len);
|
|
|
|
epd_mtx.unlock();
|
|
return 0;
|
|
}
|
|
|
|
extern "C" int command_push_image() {
|
|
#if DEBUG == 1
|
|
printf("sha256 of image_buf: ");
|
|
show_sha256((char *)image_buf, CONFIG_IMAGE_BUF_SIZE);
|
|
#endif
|
|
|
|
if (epd_mtx.try_lock()) {
|
|
EPD_HW_Init_Fast();
|
|
EPD_Display((unsigned char *)(image_buf));
|
|
EPD_DeepSleep();
|
|
|
|
epd_mtx.unlock();
|
|
return 0;
|
|
} else {
|
|
return -3;
|
|
}
|
|
}
|
|
|
|
extern "C" int mesh_client_callback(char *buf, size_t len) {
|
|
request_t *req = client_parse_data(buf, len);
|
|
if (!req) { // error -> invalid data
|
|
return -2;
|
|
}
|
|
|
|
int ret = 0;
|
|
|
|
// execute command
|
|
if (strcmp(req->command, "ping") == 0)
|
|
{
|
|
goto mesh_client_callback_ret;
|
|
}
|
|
else if (strcmp(req->command, "update_image") == 0)
|
|
{
|
|
ret = command_update_image(req->index, req->data, req->data_len);
|
|
goto mesh_client_callback_ret;
|
|
}
|
|
else if (strcmp(req->command, "push_image") == 0)
|
|
{
|
|
ret = command_push_image();
|
|
goto mesh_client_callback_ret;
|
|
}
|
|
else
|
|
{
|
|
ret = -2;
|
|
goto mesh_client_callback_ret;
|
|
}
|
|
|
|
mesh_client_callback_ret:
|
|
req_release(req);
|
|
return ret;
|
|
}
|
|
#else // root -> 送測試資料
|
|
#define PAYLOAD_SIZE 1024
|
|
#include "IMAGE.h"
|
|
void mesh_server_send_test_data() {
|
|
/*
|
|
mpack_writer_t *writer = (mpack_writer_t *)malloc(sizeof(mpack_writer_t));
|
|
char *payload = (char *)malloc(PAYLOAD_SIZE);
|
|
if (!writer || !payload) {
|
|
printf("failed to allocate memory\n");
|
|
return;
|
|
}
|
|
|
|
const unsigned char *image_start = &gImage_1[0];
|
|
const unsigned char *image_end = image_start + sizeof(gImage_1);
|
|
|
|
printf("sha256 of gImage_1: ");
|
|
show_sha256((char *)image_start, sizeof(gImage_1));
|
|
|
|
uint32_t counter = 0;
|
|
for (const unsigned char *image = image_start; image < image_end; image += 950) {
|
|
vTaskDelay(2000 / portTICK_PERIOD_MS);
|
|
|
|
memset(writer, 0, sizeof(mpack_writer_t));
|
|
memset(payload, 0, PAYLOAD_SIZE);
|
|
|
|
mpack_writer_init(writer, payload, PAYLOAD_SIZE);
|
|
mpack_start_map(writer, 3);
|
|
|
|
mpack_write_cstr(writer,"command");
|
|
mpack_write_cstr(writer,"update_image");
|
|
mpack_write_cstr(writer,"index");
|
|
printf("index -> %d\n", image - image_start);
|
|
mpack_write_u64(writer, image - image_start);
|
|
|
|
//mpack_write_cstr(writer,"data");
|
|
//size_t count = 950;
|
|
//if (image + 950 > image_end)
|
|
// count = image_end - image;
|
|
//mpack_start_bin(writer, count);
|
|
//mpack_write_bin(writer, (const char *)image, count);
|
|
//mpack_finish_bin(writer);
|
|
|
|
char testdata[64];
|
|
memset(testdata, 0, sizeof(testdata));
|
|
snprintf(testdata, sizeof(testdata), "Hello, World! -> %lu", counter++);
|
|
mpack_start_bin(writer, sizeof(testdata));
|
|
mpack_write_bin(writer, testdata, sizeof(testdata));
|
|
mpack_finish_bin(writer);
|
|
|
|
mpack_finish_map(writer);
|
|
|
|
if (mpack_writer_destroy(writer) != mpack_ok) {
|
|
printf("error!\n");
|
|
continue;
|
|
}
|
|
|
|
//fwrite("payload: ", 1, 9, stdout);
|
|
//fwrite(payload, 1, PAYLOAD_SIZE, stdout);
|
|
//fwrite("\n", 1, 1, stdout);
|
|
|
|
esp_err_t err = esp_mesh_boardcast_to_nodes((uint8_t *)payload, PAYLOAD_SIZE);
|
|
printf("mesh_server_send_test_data result -> %d\n", err);
|
|
}
|
|
|
|
|
|
vTaskDelay(1500 / portTICK_PERIOD_MS);
|
|
|
|
memset(writer, 0, sizeof(mpack_writer_t));
|
|
memset(payload, 0, PAYLOAD_SIZE);
|
|
|
|
mpack_writer_init(writer, payload, PAYLOAD_SIZE);
|
|
mpack_start_map(writer, 1);
|
|
mpack_write_cstr(writer,"command");
|
|
mpack_write_cstr(writer,"push_image");
|
|
mpack_finish_map(writer);
|
|
|
|
if (mpack_writer_destroy(writer) != mpack_ok) {
|
|
printf("error!\n");
|
|
} else {
|
|
esp_err_t err = esp_mesh_boardcast_to_nodes((uint8_t *)payload, PAYLOAD_SIZE);
|
|
printf("mesh_server_send_test_data result -> %d\n", err);
|
|
}
|
|
|
|
free(writer);
|
|
free(payload);
|
|
*/
|
|
|
|
char payload[64] = {0};
|
|
|
|
for (int i = 0; i < 6; i++) {
|
|
memset(payload, 0, sizeof(payload));
|
|
snprintf(payload, sizeof(payload), "Hello, World! -> %d", i);
|
|
esp_err_t err = esp_mesh_boardcast_to_nodes((uint8_t *)payload, sizeof(payload));
|
|
printf("[i=%d] result -> %d\n", i, err);
|
|
vTaskDelay(1000 / portTICK_PERIOD_MS);
|
|
}
|
|
|
|
return;
|
|
}
|
|
#endif
|
|
|
|
extern "C" void app_main() {
|
|
initArduino();
|
|
|
|
// init image_buf
|
|
image_buf = (uint8_t *)malloc(CONFIG_IMAGE_BUF_SIZE);
|
|
if (!image_buf) {
|
|
return;
|
|
}
|
|
memset(image_buf, 0, CONFIG_IMAGE_BUF_SIZE);
|
|
|
|
// initialize NVS
|
|
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);
|
|
|
|
// Initialize EPD
|
|
EPD_Pin_Init(6, 2, 7, 16,
|
|
22, 23, 1, 0);
|
|
|
|
// start mesh network
|
|
mesh_main();
|
|
xTaskCreate(esp_mesh_p2p_rx_main, "MPRX", 3072, NULL, 5, NULL);
|
|
|
|
// Arduino-like setup()
|
|
|
|
// Arduino-like loop()
|
|
int32_t counter = 6;
|
|
while (true)
|
|
{
|
|
#if CONFIG_MESH_ROOT == 1
|
|
printf("counter -> %ld\n", counter);
|
|
if (counter == 0)
|
|
mesh_server_send_test_data();
|
|
if (counter >= 0)
|
|
counter--;
|
|
#endif
|
|
printf("Am I root? -> %d\n", esp_mesh_is_root());
|
|
vTaskDelay(5 * 1000 / portTICK_PERIOD_MS);
|
|
}
|
|
|
|
// WARNING: if program reaches end of function app_main() the MCU will restart.
|
|
} |