195 lines
5.6 KiB
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
|
|
}
|