174 lines
4.4 KiB
C
174 lines
4.4 KiB
C
#include <string.h>
|
|
|
|
#include "esp_log.h"
|
|
#include "esp32-lora.h"
|
|
#include "lorcomm.h"
|
|
#include "main.h"
|
|
|
|
#define TAG "lorcomm"
|
|
|
|
#define MSG_ID_TRACK (16)
|
|
|
|
typedef struct {
|
|
uint8_t mac[3];
|
|
uint8_t ids[MSG_ID_TRACK];
|
|
} id_cache_t;
|
|
|
|
uint8_t mac[6] = {0};
|
|
static uint8_t msg_id = 1;
|
|
|
|
id_cache_t id_cache[MSG_ID_TRACK] = { 0 };
|
|
|
|
uint8_t acmp(uint8_t a[], uint8_t b[], uint8_t len) {
|
|
for(uint8_t i = 0; i < len; i++) {
|
|
if(a[i] != b[i]) return 0;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
void lorcomm_handle_receive(uint8_t size) {
|
|
printf("packet size: %d\n", size);
|
|
|
|
uint8_t *buf = malloc(size);
|
|
lora_packet *packet = malloc(sizeof(lora_packet));
|
|
|
|
// get data from the lora driver
|
|
lora32_read_data(&lora, buf);
|
|
|
|
// copy buffer onto message headers
|
|
memcpy(packet, buf, LORA_PACKET_HEADER_SIZE);
|
|
ESP_LOGI(TAG, "[%02X:%02X:%02X] id: %02d type: %02X", packet->src[0], packet->src[1], packet->src[2], packet->id, packet->type);
|
|
|
|
for(uint8_t i = 0; i < MSG_ID_TRACK; i++) {
|
|
if(id_cache[i].mac[0]+id_cache[i].mac[1]+id_cache[i].mac[2] == 0) {
|
|
memcpy(id_cache[i].mac, &packet->src, 3);
|
|
|
|
// this is assumed to be empty
|
|
id_cache[i].ids[0] = packet->id;
|
|
ESP_LOGI(TAG, "adding new tracking entity");
|
|
|
|
break;
|
|
}
|
|
|
|
for(uint8_t j = 0; j < MSG_ID_TRACK; j++) {
|
|
if(id_cache[i].ids[j] == packet->id) {
|
|
ESP_LOGI(TAG, "already seen packet, not relaying");
|
|
goto receive_cleanup;
|
|
} else if(id_cache[i].ids[j] == 0) {
|
|
ESP_LOGI(TAG, "adding id to tracking");
|
|
|
|
// add id to array
|
|
id_cache[i].ids[i] = packet->id;
|
|
// set next in queue to zero, rolling over as needed
|
|
id_cache[i].ids[(i + 1) % MSG_ID_TRACK] = 0;
|
|
|
|
goto break_outer;
|
|
}
|
|
}
|
|
}
|
|
|
|
break_outer:
|
|
|
|
// update local msg id to incoming +1
|
|
// this will give a rolling local area id
|
|
if(packet->id < msg_id) {
|
|
msg_id = packet->id + 1;
|
|
|
|
// 0 is an invalid id
|
|
if(msg_id == 0) msg_id = 1;
|
|
}
|
|
|
|
if(memcmp(packet->src, &mac[3], 3) == 0) {
|
|
ESP_LOGI(TAG, "received own packet, done");
|
|
goto receive_cleanup;
|
|
}
|
|
|
|
if(packet->type == TEXT) {
|
|
lora_msg *msg = malloc(sizeof(lora_msg));
|
|
memcpy(msg, buf + LORA_PACKET_HEADER_SIZE, LORA_MSG_HEADER_SIZE);
|
|
|
|
// allocate memory for message payload
|
|
msg->msg = malloc(msg->length);
|
|
|
|
memcpy(msg->msg, buf + LORA_PACKET_HEADER_SIZE + LORA_MSG_HEADER_SIZE, msg->length);
|
|
|
|
// if the msg doesnt end in NULL it's probably already corrupt
|
|
// just go ahead and terminate it
|
|
//if(msg->msg[msg->length] != '\0')
|
|
//msg->msg[msg->length] = '\0';
|
|
|
|
ESP_LOGI(TAG, "msg (len: %d): %s", msg->length, msg->msg);
|
|
|
|
free(msg->msg);
|
|
msg->msg = NULL;
|
|
free(msg);
|
|
} else if(packet->type == ROUTING) {
|
|
// future stuff
|
|
} else {
|
|
ESP_LOGW(TAG, "Unknown packet type: %02X", packet->type);
|
|
ESP_LOGW(TAG, "msg: %s", (char*)packet);
|
|
|
|
goto receive_cleanup;
|
|
}
|
|
|
|
vTaskDelay(3000/portTICK_PERIOD_MS);
|
|
ESP_LOGI(TAG, "relaying message");
|
|
|
|
lora32_send(&lora, buf, size);
|
|
|
|
receive_cleanup:
|
|
free(buf);
|
|
|
|
lora32_enable_continuous_rx(&lora);
|
|
}
|
|
|
|
void lorcomm_send_message(lora32_cfg_t *lora, char *text) {
|
|
// allocate and zero out packet and msg payload
|
|
uint8_t len = strlen(text) + 1;
|
|
lora_packet packet = { 0 };
|
|
lora_msg msg = { 0 };
|
|
|
|
// set packet tracking id
|
|
packet.id = msg_id;
|
|
|
|
msg_id = msg_id + 1;
|
|
if(msg_id == 0) msg_id = 1;
|
|
|
|
// set src and dest (broadcast) addresses
|
|
memcpy(packet.src, &mac[3], 3);
|
|
memset(packet.dst, 0xFF, 3);
|
|
|
|
// indicate message payload
|
|
packet.type = TEXT;
|
|
packet.payload = malloc(LORA_PACKET_HEADER_SIZE + len);
|
|
|
|
msg.length = len;
|
|
msg.msg = malloc(LORA_MSG_HEADER_SIZE + len);
|
|
memcpy(msg.msg, text, len);
|
|
|
|
uint8_t buf_len = LORA_PACKET_HEADER_SIZE + LORA_MSG_HEADER_SIZE + len;
|
|
uint8_t *send_buf = malloc(buf_len);
|
|
ESP_LOGI(TAG, "packet length: %d", buf_len);
|
|
|
|
// set src, dst, length
|
|
memcpy(send_buf, (uint8_t*)&packet, LORA_PACKET_HEADER_SIZE);
|
|
memcpy((uint8_t*)(send_buf + LORA_PACKET_HEADER_SIZE), (void*)&msg, LORA_MSG_HEADER_SIZE);
|
|
memcpy((uint8_t*)(send_buf + LORA_PACKET_HEADER_SIZE + LORA_MSG_HEADER_SIZE), (void*)msg.msg, len);
|
|
|
|
ESP_LOGI(TAG, "id: %02d", packet.id);
|
|
ESP_LOGI(TAG, "src: [%02X:%02X:%02X]", packet.src[0], packet.src[1], packet.src[2]);
|
|
ESP_LOGI(TAG, "dst: [%02X:%02X:%02X]", packet.dst[0], packet.dst[1], packet.dst[2]);
|
|
|
|
lora32_send(lora, send_buf, buf_len);
|
|
|
|
free(packet.payload);
|
|
packet.payload = NULL;
|
|
|
|
free(msg.msg);
|
|
msg.msg = NULL;
|
|
|
|
free(send_buf);
|
|
}
|
|
|