<commit_before>/*******************************************************************************
 * Copyright (c) 2016 <NAME>
 *
 * Permission is hereby granted, free of charge, to anyone
 * obtaining a copy of this document and accompanying files,
 * to do whatever they want with them without any restriction,
 * including, but not limited to, copying, modification and redistribution.
 * NO WARRANTY OF ANY KIND IS PROVIDED.
 *
 *******************************************************************************/

 #if 1 // Defining ABP parameters statically
 #define APPSKEY { 0x43, 0x0D, 0x53, 0xB2, 0x72, 0xA6, 0x47, 0xAF, 0x5D, 0xFF, 0x6A, 0x16, 0x7A, 0xB7, <KEY> }
 #define NWKSKEY { 0x80, 0x42, 0x43, 0x64, 0x2C, 0x1E, 0x3B, 0x04, 0x36, 0x6D, 0x36, 0xC3, 0x90, 0x9F, 0xCA, 0xA2 }
 #define DEVADDR { 0xDE, 0xAD, 0xAA, 0xAA }
 #endif
 #if 0 // Defining OTAA parameters statically
 #define APPKEY { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
 #define APPEUI { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
 #define DEVEUI { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
 #endif

#include "Lora.h"
#include "Bluetooth.h"
#include "Adafruit_BLE.h" // Define TimeoutTimer
#include "Logging.h"

#define offset(s, field) ((u1_t *)(&s.field) - (u1_t *)&s)

typedef struct {
#define PERSISTENT_FORMAT_UNINITIALIZED 0
#define PERSISTENT_FORMAT_V1 1
  uint32_t format;
  uint32_t flags; // Bit flags indicating what values in structure are set

  uint32_t seq_no;

#define FLAG_SESSION_VARS_SET (1 << 0) // Set of DevAddr, NwkSKey, and AppSKey set.
  u1_t DevAddr[4];
  u1_t NwkSKey[16];
  u1_t AppSKey[16];

// Separate set flags because BLE can't send all at once
#define FLAG_APP_KEY_SET (1 << 1)
  u1_t AppKey[16];
#define FLAG_APP_EUI_SET (1 << 2)
  u1_t AppEUI[8];
#define FLAG_DEV_EUI_SET (1 << 3)
  u1_t DevEUI[8];
} PersistentSettings;

PersistentSettings settings;

// Otherwise, this value connects a sendPacket request with tx result notification
static struct {
  bool active;
  u1_t bleSeq;
} CurrentTx = {false, 0};

extern "C" {
  void debugPrint(const char *msg) {
    Log.Debug(msg);
    Log.Debug(CR);
  }

  void debugLog(const char *msg, uint32_t value) {
    Log.Debug("%s %x" CR, msg, value);
  }

  void debugLogData(const char *msg, uint8_t data[], uint16_t len) {
    char buffer[200+1];
    Log.Debug("%s: " CR, msg);
    Log.Debug("Length: %d" CR, len);
    for(int i=0; i<min(len, sizeof(buffer)/2); ++i) {
      snprintf(buffer+2*i, sizeof(buffer)-2*i, "%02x", data[i]);
    }
    Log.Debug("%s" CR, buffer);
  }
} // extern "C".

#define CMD_DISCONNECT 1

void sendCommandCallback(uint8_t data[], uint16_t len) {
  uint16_t command = *(uint16_t *)data;
  Log.Debug("sendCommand: %d" CR, command);
  switch (command) {
    case CMD_DISCONNECT:
      bluetoothDisconnect();
      break;
  }
}

void enqueuePacket(uint8_t bleSeq, uint8_t data[], uint16_t len) {
  debugLog("sendPacket with BLE seq: ", bleSeq);
  debugLogData("sendPacket: ", data, len);
  if (!CurrentTx.active) {
    CurrentTx.active = true;
    CurrentTx.bleSeq = bleSeq;
    loraSendBytes(data, len);
  }
  else {
    debugPrint("Send ignored - active transmission not completed");
  }
}
void sendPacketCallback(uint8_t data[], uint16_t len) {
  enqueuePacket(0, data, len);
}

void sendPacketWithAckCallback(uint8_t data[], uint16_t len) {
  // Includes ble seq as first byte of packet. Don't send that out.
  enqueuePacket(data[0], data+1, len-1);
}

void assignDevAddrCallback(uint8_t data[], uint16_t len) {
  debugLogData("assignDevAddr", data, len);
  if (len==sizeof(settings.DevAddr)) {
    memcpy(settings.DevAddr, data, sizeof(settings.DevAddr));
    writeNVBytes(offset(settings, DevAddr), settings.DevAddr, sizeof(settings.DevAddr));
    loraSetSessionKeys(settings.seq_no, settings.AppSKey, settings.NwkSKey, settings.DevAddr);
  }
}

void assignNwkSKeyCallback(uint8_t data[], uint16_t len) {
  debugLogData("assignNwkSKey", data, len);
  if (len==sizeof(settings.NwkSKey)) {
    memcpy(settings.NwkSKey, data, sizeof(settings.NwkSKey));
    writeNVBytes(offset(settings, NwkSKey), settings.NwkSKey, sizeof(settings.NwkSKey));
    loraSetSessionKeys(settings.seq_no, settings.AppSKey, settings.NwkSKey, settings.DevAddr);
  }
}

void assignAppSKeyCallback(uint8_t data[], uint16_t len) {
  debugLogData("assignAppSKey", data, len);
  if (len==sizeof(settings.AppSKey)) {
    memcpy(settings.AppSKey, data, sizeof(settings.AppSKey));
    writeNVBytes(offset(settings, AppSKey), settings.AppSKey, sizeof(settings.AppSKey));
    loraSetSessionKeys(settings.seq_no, settings.AppSKey, settings.NwkSKey, settings.DevAddr);
  }
}

void assignSpreadingFactorCallback(uint8_t data[], uint16_t len) {
  if (len==1) {
    uint sf = data[0];
    Log.Debug("assignSpreadingFactor: %d" CR, sf);
    loraSetSF(sf);
  }
}

CharacteristicConfigType charConfigs[] = {
{
  UNINITIALIZED,
  // 0x08 write to device only, datatype 3 is int
  "AT+GATTADDCHAR=UUID=0x2AD0,PROPERTIES=0x08,MIN_LEN=2,MAX_LEN=2,DATATYPE=3,DESCRIPTION=Command",<commit_msg>Use some macros to reduce code noise<commit_after>/*******************************************************************************
 * Copyright (c) 2016 <NAME>
 *
 * Permission is hereby granted, free of charge, to anyone
 * obtaining a copy of this document and accompanying files,
 * to do whatever they want with them without any restriction,
 * including, but not limited to, copying, modification and redistribution.
 * NO WARRANTY OF ANY KIND IS PROVIDED.
 *
 *******************************************************************************/

 #if 1 // Defining ABP parameters statically
 #define APPSKEY { <KEY> }
 #define NWKSKEY { 0x80, 0x42, 0x43, 0x64, 0x2C, 0x1E, 0x3B, 0x04, 0x36, 0x6D, 0x36, 0xC3, 0x90, 0x9F, 0xCA, 0xA2 }
 #define DEVADDR { 0xDE, 0xAD, 0xAA, 0xAA }
 #endif
 #if 0 // Defining OTAA parameters statically
 #define APPKEY { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
 #define APPEUI { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
 #define DEVEUI { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
 #endif

#include "Lora.h"
#include "Bluetooth.h"
#include "Adafruit_BLE.h" // Define TimeoutTimer
#include "Logging.h"

#define offset(s, field) ((u1_t *)(&s.field) - (u1_t *)&s)

typedef struct {
#define PERSISTENT_FORMAT_UNINITIALIZED 0
#define PERSISTENT_FORMAT_V1 1
  uint32_t format;
  uint32_t flags; // Bit flags indicating what values in structure are set

  uint32_t seq_no;

#define FLAG_SESSION_VARS_SET (1 << 0) // Set of DevAddr, NwkSKey, and AppSKey set.
  u1_t DevAddr[4];
  u1_t NwkSKey[16];
  u1_t AppSKey[16];

// Separate set flags because BLE can't send all at once
#define FLAG_APP_KEY_SET (1 << 1)
  u1_t AppKey[16];
#define FLAG_APP_EUI_SET (1 << 2)
  u1_t AppEUI[8];
#define FLAG_DEV_EUI_SET (1 << 3)
  u1_t DevEUI[8];
} PersistentSettings;

PersistentSettings settings;

// Otherwise, this value connects a sendPacket request with tx result notification
static struct {
  bool active;
  u1_t bleSeq;
} CurrentTx = {false, 0};

extern "C" {
  void debugPrint(const char *msg) {
    Log.Debug(msg);
    Log.Debug(CR);
  }

  void debugLog(const char *msg, uint32_t value) {
    Log.Debug("%s %x" CR, msg, value);
  }

  void debugLogData(const char *msg, uint8_t data[], uint16_t len) {
    char buffer[200+1];
    Log.Debug("%s: " CR, msg);
    Log.Debug("Length: %d" CR, len);
    for(int i=0; i<min(len, sizeof(buffer)/2); ++i) {
      snprintf(buffer+2*i, sizeof(buffer)-2*i, "%02x", data[i]);
    }
    Log.Debug("%s" CR, buffer);
  }
} // extern "C".

#define CMD_DISCONNECT 1

void sendCommandCallback(uint8_t data[], uint16_t len) {
  uint16_t command = *(uint16_t *)data;
  Log.Debug("sendCommand: %d" CR, command);
  switch (command) {
    case CMD_DISCONNECT:
      bluetoothDisconnect();
      break;
  }
}

void enqueuePacket(uint8_t bleSeq, uint8_t data[], uint16_t len) {
  debugLog("sendPacket with BLE seq: ", bleSeq);
  debugLogData("sendPacket: ", data, len);
  if (!CurrentTx.active) {
    CurrentTx.active = true;
    CurrentTx.bleSeq = bleSeq;
    loraSendBytes(data, len);
  }
  else {
    debugPrint("Send ignored - active transmission not completed");
  }
}
void sendPacketCallback(uint8_t data[], uint16_t len) {
  enqueuePacket(0, data, len);
}

void sendPacketWithAckCallback(uint8_t data[], uint16_t len) {
  // Includes ble seq as first byte of packet. Don't send that out.
  enqueuePacket(data[0], data+1, len-1);
}

#define AssignSessionCallback(key) \
void assign##key##Callback(uint8_t data[], uint16_t len) { \
  debugLogData("assign" #key, data, len); \
  if (len==sizeof(settings.key)) {        \
    memcpy(settings.key, data, sizeof(settings.key)); \
    writeNVBytes(offset(settings, key), settings.key, sizeof(settings.key)); \
    loraSetSessionKeys(settings.seq_no, settings.AppSKey, settings.NwkSKey, settings.DevAddr); \
  } \
}

AssignSessionCallback(DevAddr)
AssignSessionCallback(NwkSKey)
AssignSessionCallback(AppSKey)

#define AssignAppCallback(key) \
void assign##key##Callback(uint8_t data[], uint16_t len) { \
  debugLogData("assign" #key, data, len); \
  if (len==sizeof(settings.key)) {        \
    memcpy(settings.key, data, sizeof(settings.key)); \
    writeNVBytes(offset(settings, key), settings.key, sizeof(settings.key)); \
  } \
}

AssignAppCallback(AppKey)
AssignAppCallback(AppEUI)
AssignAppCallback(DevEUI)

// void assignDevAddrCallback(uint8_t data[], uint16_t len) {
//   debugLogData("assignDevAddr", data, len);
//   if (len==sizeof(settings.DevAddr)) {
//     memcpy(settings.DevAddr, data, sizeof(settings.DevAddr));
//     writeNVBytes(offset(settings, DevAddr), settings.DevAddr, sizeof(settings.DevAddr));
//     loraSetSessionKeys(settings.seq_no, settings.AppSKey, settings.NwkSKey, settings.DevAddr);
//   }
// }
//
// void assignNwkSKeyCallback(uint8_t data[], uint16_t len) {
//   debugLogData("assignNwkSKey", data, len);
//   if (len==sizeof(settings.NwkSKey)) {
//     memcpy(settings.NwkSKey, data, sizeof(settings.NwkSKey));
//     writeNVBytes(offset(settings, NwkSKey), settings.NwkSKey, sizeof(settings.NwkSKey));
//     loraSetSessionKeys(settings.seq_no, settings.AppSKey, settings.NwkSKey, settings.DevAddr);
//   }
// }
//
// void assignAppSKeyCallback(uint8_t data[], uint16_t len) {
//   debugLogData("assignAppSKey", data, len);
//   if (len==sizeof(settings.AppSKey)) {
//     memcpy(settings.AppSKey, data, sizeof(settings.AppSKey));
//     writeNVBytes(offset(settings, AppSKey), settings.AppSKey, sizeof(settings.AppSKey));
//     loraSetSessionKeys(settings.seq_no, settings.AppSKey, settings.NwkSKey, settings.DevAddr);
//   }
// }
//
// void assignAppKeyCallback(uint8_t data[], uint16_t len) {
//   debugLogData("assignAppKey", data, len);
//   if (len==sizeof(settings.AppKey)) {
//     memcpy(settings.AppKey, data, sizeof(settings.AppKey));
//     writeNVBytes(offset(settings, AppKey), settings.AppKey, sizeof(settings.AppKey));
//   }
// }
//
// void assignAppEUICallback(uint8_t data[], uint16_t len) {
//   debugLogData("assignAppEUI", data, len);
//   if (len==sizeof(settings.AppEUI)) {
//     memcpy(settings.AppEUI, data, sizeof(settings.AppEUI));
//     writeNVBytes(offset(settings, AppEUI), settings.AppEUI, sizeof(settings.AppEUI));
//   }
// }
//
// void assignDevEUICallback(uint8_t data[], uint16_t len) {
//   debugLogData("assignDevEUI", data, len);
//   if (len==sizeof(settings.DevEUI)) {
//     memcpy(settings.DevEUI, data, sizeof(settings.DevEUI));
//     writeNVBytes(offset(settings, DevEUI), settings.DevEUI, sizeof(settings.DevEUI));
//   }
// }

void assignSpreadingFactorCallback(uint8_t data[], uint16_t len) {
  if (len==1) {
    uint sf = data[0];
    Log.Debug("assignSpreadingFactor: %d" CR, sf);
    loraSetSF(sf);
  }
}

CharacteristicConfigType charConfigs[] = {
{
  UNINITIALIZED,
  // 0x08 write to device only, datatype 3 is int
  "AT+GATTADDCHAR=UUID=0x2AD0,PROPERTIES=0x08,MIN_LEN=2,MAX_LEN=2,DATATYPE=3,DESCRIPTION=Command",
{'fraction_non_alphanumeric': 0.1648997846612556, 'fraction_numerical': 0.04439291038595329, 'mean_word_length': 4.516217450890818, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1681364', 'n_tokens_mistral': 4810, 'n_tokens_neox': 4449, 'n_words': 1034}