webguiapp/src/LoRaWAN.c

195 lines
5.6 KiB
C

/* Copyright 2022 Bogdan Pilyugin
*
* 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.
*
* File name: LoRaWANTransport.c
* Project: MStation2Firmware
* Created on: 2022-12-17
* Author: bogd
* Description:
*/
#include "ttn.h"
#include "driver/spi_common.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#include "Helpers.h"
#include "NetTransport.h"
#include "webguiapp.h"
#include "LoRaWAN.h"
#include "../include/WebGUIAppMain.h"
// Pins and other resources
/*Defined in global configuration*/
#ifdef CONFIG_WEBGUIAPP_LORAWAN_ENABLE
#define TTN_SPI_HOST CONFIG_SPI_HOST
#define TTN_PIN_NSS CONFIG_LORA_SPI_CS_GPIO
#define TTN_PIN_RXTX TTN_NOT_CONNECTED
#define TTN_PIN_RST TTN_NOT_CONNECTED
#define TTN_PIN_DIO0 CONFIG_LORA_DIO0_GPIO
#define TTN_PIN_DIO1 CONFIG_LORA_DIO1_GPIO
#define LORAWAN_DELIVERY_RETRY_PERIOD 10
#define MESSAGE_LENGTH 32
#define TAG "LoRaWANApp"
#define LORAWAN_APP_LOG_ENABLED 1
#define LORAWAN_MESSAGE_BUFER_LENTH 5
QueueHandle_t LORAMessagesQueueHandle;
static StaticQueue_t xStaticLoRaMessagesQueue;
uint8_t LoRaMessagesQueueStorageArea[LORAWAN_MESSAGE_BUFER_LENTH
* sizeof(LORA_DATA_SEND_STRUCT)];
void (*LoRaUserReceiveHandler)(const char *message, int length, int port);
void regLoRaUserReceiveHandler(
void (*user_handler)(const char *message, int length, int port))
{
LoRaUserReceiveHandler = user_handler;
}
esp_err_t LORASendData(LORA_DATA_SEND_STRUCT *pdss)
{
char *ptr = (char*) malloc(MESSAGE_LENGTH);
if (ptr)
{
memcpy(ptr, pdss->raw_data_ptr, MESSAGE_LENGTH);
LORA_DATA_SEND_STRUCT DSS;
DSS.raw_data_ptr = ptr;
DSS.data_length = MESSAGE_LENGTH;
if (xQueueSend(LORAMessagesQueueHandle, &DSS,
pdMS_TO_TICKS(1000)) == pdPASS)
return ESP_OK;
else
{
free(ptr);
return ESP_ERR_TIMEOUT;
}
}
else
return ESP_ERR_NO_MEM;
}
void messageReceived(const uint8_t *message, size_t length, ttn_port_t port)
{
#if LORAWAN_APP_LOG_ENABLED == 1
if (length == MESSAGE_LENGTH && port == 1)
{
char P[MESSAGE_LENGTH * 2 + 1];
P[MESSAGE_LENGTH * 2] = 0x00;
BytesToStr((unsigned char*) message, (unsigned char*) P, length);
ESP_LOGI(TAG, "Received=%s", P);
}
#endif
if(LoRaUserReceiveHandler != NULL)
LoRaUserReceiveHandler((char*)message, length, (int)port);
}
void LoRaWANTransportTask(void *pvParameter)
{
LORA_DATA_SEND_STRUCT DSS;
while (!LORAMessagesQueueHandle)
vTaskDelay(pdMS_TO_TICKS(300)); //wait for LORA queue ready
while (1)
{
while (!ttn_is_connected())
vTaskDelay(pdMS_TO_TICKS(300));
if (ttn_is_provisioned())
{
xQueueReceive(LORAMessagesQueueHandle, &DSS, portMAX_DELAY);
#if LORAWAN_APP_LOG_ENABLED == 1
char P[MESSAGE_LENGTH * 2 + 1];
BytesToStr((unsigned char*) DSS.raw_data_ptr, (unsigned char*) P, MESSAGE_LENGTH);
P[MESSAGE_LENGTH * 2] = 0x00;
ESP_LOGI(TAG, "Send=%s", P);
#endif
ttn_transmit_message((const uint8_t*) DSS.raw_data_ptr, MESSAGE_LENGTH, 1, true);
free(DSS.raw_data_ptr);
}
else
{
#if LORAWAN_APP_LOG_ENABLED == 1
ESP_LOGW(TAG, "Transmit fail, transport not ready");
#endif
}
}
}
void LoRaWANRejoin(void)
{
ttn_rejoin();
}
void LoRaWANInitJoinTask(void *pvParameter)
{
LORAMessagesQueueHandle = NULL;
if (GetSysConf()->lorawanSettings.Flags1.bIsLoRaWANEnabled)
LORAMessagesQueueHandle = xQueueCreateStatic(LORAWAN_MESSAGE_BUFER_LENTH,
sizeof(LORA_DATA_SEND_STRUCT),
LoRaMessagesQueueStorageArea,
&xStaticLoRaMessagesQueue);
ttn_init();
// Configure the SX127x pins
ttn_configure_pins(TTN_SPI_HOST, TTN_PIN_NSS, TTN_PIN_RXTX, -1,
TTN_PIN_DIO0,
TTN_PIN_DIO1);
char devEui[17], appEui[17], appKey[33];
BytesToStr((unsigned char*) &GetSysConf()->lorawanSettings.DevEui,
(unsigned char*) devEui,
8);
BytesToStr((unsigned char*) &GetSysConf()->lorawanSettings.AppEui,
(unsigned char*) appEui,
8);
BytesToStr((unsigned char*) &GetSysConf()->lorawanSettings.AppKey,
(unsigned char*) appKey,
16);
// Register callback for received messages
ttn_on_message(messageReceived);
while (!ttn_join(devEui, appEui, appKey))
{
};
xTaskCreate(LoRaWANTransportTask, "LoRaWANTransportTask", 1024 * 4,
(void*) 0,
3,
NULL);
vTaskDelete(NULL);
}
#endif
void LoRaWANStart(void)
{
#ifdef CONFIG_WEBGUIAPP_LORAWAN_ENABLE
xTaskCreate(LoRaWANInitJoinTask, "LoRaWANInitJoinTask", 1024 * 4, (void*) 0,
3,
NULL);
#endif
}
bool isLORAConnected(void)
{
#ifdef CONFIG_WEBGUIAPP_LORAWAN_ENABLE
return ttn_is_connected();
#else
return false;
#endif
}