MAC command decoder (experimental)

This commit is contained in:
Verkehrsrot 2019-08-31 18:36:49 +02:00
parent 80a24f10ab
commit 1d2c79133f
2 changed files with 92 additions and 6 deletions

View File

@ -23,6 +23,13 @@
extern QueueHandle_t LoraSendQueue; extern QueueHandle_t LoraSendQueue;
extern TaskHandle_t lmicTask, lorasendTask; extern TaskHandle_t lmicTask, lorasendTask;
// table of LORAWAN MAC commands
typedef struct {
const uint8_t opcode;
const char cmdname[20];
const uint8_t params;
} mac_t;
esp_err_t lora_stack_init(); esp_err_t lora_stack_init();
void lmictask(void *pvParameters); void lmictask(void *pvParameters);
void onEvent(ev_t ev); void onEvent(ev_t ev);
@ -40,6 +47,8 @@ void lora_queuereset(void);
void myRxCallback(void *pUserData, uint8_t port, const uint8_t *pMsg, void myRxCallback(void *pUserData, uint8_t port, const uint8_t *pMsg,
size_t nMsg); size_t nMsg);
void myTxCallback(void *pUserData, int fSuccess); void myTxCallback(void *pUserData, int fSuccess);
void mac_decode(const uint8_t cmd[], const uint8_t cmdlength);
#if (TIME_SYNC_LORAWAN) #if (TIME_SYNC_LORAWAN)
void user_request_network_time_callback(void *pVoidUserUTCTime, void user_request_network_time_callback(void *pVoidUserUTCTime,
int flagSuccess); int flagSuccess);

View File

@ -375,10 +375,10 @@ void lora_send(void *pvParameters) {
(cfg.countermode & 0x02), myTxCallback, NULL)) { (cfg.countermode & 0x02), myTxCallback, NULL)) {
case 0: case 0:
ESP_LOGI(TAG, "%d byte(s) delivered to LMIC", SendBuffer.MessageSize); ESP_LOGI(TAG, "%d byte(s) sent to LORA", SendBuffer.MessageSize);
break; break;
case -1: // LMIC already has a tx message pending case -1: // LMIC already has a tx message pending
ESP_LOGD(TAG, "LMIC busy, message re-enqueued"); // ESP_LOGD(TAG, "LMIC busy, message re-enqueued");
vTaskDelay(pdMS_TO_TICKS(1000 + random(500))); // wait a while vTaskDelay(pdMS_TO_TICKS(1000 + random(500))); // wait a while
lora_enqueuedata(&SendBuffer); // re-enqueue the undeliverd message lora_enqueuedata(&SendBuffer); // re-enqueue the undeliverd message
break; break;
@ -545,9 +545,27 @@ void lmictask(void *pvParameters) {
void myRxCallback(void *pUserData, uint8_t port, const uint8_t *pMsg, void myRxCallback(void *pUserData, uint8_t port, const uint8_t *pMsg,
size_t nMsg) { size_t nMsg) {
// did we receive payload data -> display info // tell the compiler that pUserData is required by the API, but we don't
// happen to use it.
LMIC_API_PARAMETER(pUserData);
// display type of received data
if (nMsg) if (nMsg)
ESP_LOGI(TAG, "Received %d bytes of payload on port %d", nMsg, port); ESP_LOGI(TAG, "Received %u bytes of payload on port %u", nMsg, port);
else if (port)
ESP_LOGI(TAG, "Received empty message on port %u", port);
// list MAC messages, if any
uint8_t nMac = pMsg - &LMIC.frame[0];
if (port != MACPORT)
--nMac;
if (nMac) {
ESP_LOGI(TAG, "Received %u MAC messages:", nMac);
// NOT WORKING YET
// whe need to strip some protocol overhead from LMIC.frame to unwrap the
// MAC command
mac_decode(LMIC.frame, nMac);
}
switch (port) { switch (port) {
@ -570,12 +588,71 @@ void myRxCallback(void *pUserData, uint8_t port, const uint8_t *pMsg,
#endif #endif
// unknown port -> display info // unknown port -> display info
ESP_LOGI(TAG, "Received data on unsupported port %d", port); ESP_LOGI(TAG, "Received data on unsupported port %u", port);
break; break;
} // switch } // switch
} }
// transmit complete message handler // transmit complete message handler
void myTxCallback(void *pUserData, int fSuccess) { /* currently unused */ } void myTxCallback(void *pUserData, int fSuccess) {
/* currently no code here */
// tell the compiler that pUserData is required by the API, but we don't
// happen to use it.
LMIC_API_PARAMETER(pUserData);
}
// LORAWAN MAC interpreter
// table of LORAWAN MAC messages sent by the network to the device
// format: opcode, cmdname (max 19 chars), #bytes params
// source: LoRaWAN 1.1 Specification (October 11, 2017)
static mac_t table[] = {
{0x01, "ResetConf", 1}, {0x02, "LinkCheckAns", 2},
{0x03, "LinkADRReq", 4}, {0x04, "DutyCycleReq", 1},
{0x05, "RXParamSetupReq", 4}, {0x06, "DevStatusReq", 0},
{0x07, "NewChannelReq", 5}, {0x08, "RxTimingSetupReq", 1},
{0x09, "TxParamSetupReq", 1}, {0x0A, "DlChannelReq", 4},
{0x0B, "RekeyConf", 1}, {0x0C, "ADRParamSetupReq", 1},
{0x0D, "DeviceTimeAns", 5}, {0x0E, "ForceRejoinReq", 2},
{0x0F, "RejoinParamSetupReq", 1}};
static const uint8_t cmdtablesize =
sizeof(table) / sizeof(table[0]); // number of commands in command table
// decode mac message
void mac_decode(const uint8_t cmd[], const uint8_t cmdlength) {
if (!cmdlength)
return;
uint8_t foundcmd[cmdlength], cursor = 0;
while (cursor < cmdlength) {
int i = cmdtablesize;
while (i--) {
if (cmd[cursor] == table[i].opcode) { // lookup command in opcode table
cursor++; // strip 1 byte opcode
if ((cursor + table[i].params) <= cmdlength) {
memmove(foundcmd, cmd + cursor,
table[i].params); // strip opcode from cmd array
cursor += table[i].params;
ESP_LOGI(TAG, "Network command %s", table[i].cmdname);
} else
ESP_LOGI(TAG, "MAC message 0x%02X with missing parameter(s)",
table[i].opcode);
break; // command found -> exit table lookup loop
} // end of command validation
} // end of command table lookup loop
if (i < 0) { // command not found -> skip it
ESP_LOGI(TAG, "Unknown MAC message 0x%02X", cmd[cursor]);
cursor++;
}
} // command parsing loop
} // mac_decode()
#endif // HAS_LORA #endif // HAS_LORA