arm studio build

Dependencies:   libxDot-mbed5

src/multicast.cpp

Committer:
alan1974
Date:
2020-07-29
Revision:
31:4539c212ecaa
Parent:
18:d95e1a2c4303

File content as of revision 31:4539c212ecaa:

#include "mbed.h"
#include "dot_util.h"
#include "mDot.h"
#include "RadioEvent.h"
#include "ChannelPlans.h"
#include "Lora.h"
#include "commI2C.h"
#include "multicast.h"

extern bool bListen4Multicast;         
 extern uint8_t nodeState;
// extern uint8_t buf_xmt[BUFFER_SIZE_I2C];  //outgoing data
 
 //OTAA keys
extern uint8_t app_eui[];
extern uint8_t app_key[];

//arrays to hold OTAA keys
std::vector<uint8_t> netwrk_address_OTAA;
std::vector<uint8_t> netwrk_session_key_OTAA;
std::vector<uint8_t> data_session_key_OTAA;
uint32_t downcounter_OTAA;
uint32_t upcounter_OTAA;

//local
//uint8_t frags_old_nmb = 0;
//uint8_t frags_missing_cnts = 0;   
//uint8_t frags_nmb_sending = 0;   //# of frags to be send
//uint8_t frags_size = 0;          //size of each frag to be sent
//uint32_t frag_missd = 0;
//========================================================================================================
// save_OTAA_session session parameters
//========================================================================================================
void save_OTAA_session_keys()
{
    printf("\r\n saving OTAA session keys --------------------------------- \r\n"); 
    netwrk_address_OTAA = dot->getNetworkAddress();
    logInfo(" OTAA devAddr %s", mts::Text::bin2hexString(netwrk_address_OTAA).c_str());      
    netwrk_session_key_OTAA = dot->getNetworkSessionKey();
    logInfo(" OTAA network session key %s", mts::Text::bin2hexString(netwrk_session_key_OTAA).c_str());      
    data_session_key_OTAA = dot->getDataSessionKey();
    logInfo(" OTAA app session key %s", mts::Text::bin2hexString(data_session_key_OTAA).c_str());      
}
//========================================================================================================
//change radio back to class to class A, //change back to OTAA
// returns true if class change OK
//========================================================================================================
bool multicast_change_classA() 
{   
    printf("\r\n switching to class A \r\n"); 
    printf("\r\nchanging network address to OTAA device address %s\r\n", mts::Text::bin2hexString(netwrk_address_OTAA).c_str());
    if (dot->setNetworkAddress(netwrk_address_OTAA) != mDot::MDOT_OK) {
    printf("\r\nfailed to set network device address to %s", mts::Text::bin2hexString(netwrk_address_OTAA).c_str());
    } 
    printf("\r\nchanging network session key  to OTAA device key %s", mts::Text::bin2hexString(netwrk_session_key_OTAA).c_str());
    if (dot->setNetworkSessionKey(netwrk_session_key_OTAA) != mDot::MDOT_OK) {
            printf("\r\nfailed to set network session key to %s", mts::Text::bin2hexString(netwrk_session_key_OTAA).c_str());
    }      
    printf("\r\nchanging data session key to OTAA device data key %s", mts::Text::bin2hexString(data_session_key_OTAA).c_str());
    if (dot->setDataSessionKey(data_session_key_OTAA) != mDot::MDOT_OK) {
        printf("\r\nfailed to set data session key to %s", mts::Text::bin2hexString(data_session_key_OTAA).c_str());
     }
     dot->setDownLinkCounter(downcounter_OTAA); //restore frame counters before switching
     dot->setUpLinkCounter(upcounter_OTAA);
     
     if (dot->setClass("A") == mDot::MDOT_OK){
          printf("\r\nset network mode to class A");
          bListen4Multicast = false;   //exit radio rcv only mode
          return true;
    }      
    else{
         printf("\r\n FAILED set network mode to class A");
         return false;
    }     
 }
//========================================================================================================
//change radio class to class C or class A
// bClass_C:true => change class C credentials
//         :false=> change class A credentials
// sClass contains class C credentials
// returns true if class change OK
//========================================================================================================
bool multicast_change_class(class_switch *sClass)
{
  if (sClass->bClassC)
  {   
    uint8_t joined = dot->getNetworkJoinStatus();   //are we joined to Lorawan?
    if (!joined){
         printf("\r\n cannot change radio class unless already joined");
         return false;  //don't switch if not joined
     }    
    printf("\r\n switching to class C \r\n"); 
    downcounter_OTAA = dot->getDownLinkCounter(); //save frame counters before switching
    upcounter_OTAA = dot->getUpLinkCounter();
    
    dot->setUpLinkCounter(0);  
    dot->setDownLinkCounter(0);
    
//load ABP keys into arrays    
    std::vector<uint8_t> dev_adr;
    std::vector<uint8_t> nwky;
    std::vector<uint8_t> dataky;
    bool bKeyOk = true;
    uint8_t indx;
       
//set ABP keys
    for (indx =0; indx < sizeof(sClass->devAdr);indx++)      dev_adr.push_back(sClass->devAdr[indx]);   
    for (indx =0; indx < sizeof(sClass->key_nsk);indx++)     nwky.push_back(sClass->key_nsk[indx]);         
    for (indx =0; indx < sizeof(sClass->key_aps);indx++)     dataky.push_back(sClass->key_aps[indx]);              
//set ABP keys
    printf("\r\nsetting ABP network address %s\r\n", mts::Text::bin2hexString(dev_adr).c_str());    
    if (dot->setNetworkAddress(dev_adr) != mDot::MDOT_OK){
         printf(" failed to set key\r\n");
         bKeyOk = false;
    }     
    printf("\r\nsetting ABP network session key %sr\n", mts::Text::bin2hexString(nwky).c_str());
    if (dot->setNetworkSessionKey(nwky) != mDot::MDOT_OK){
         printf(" failed to set key\r\n");
         bKeyOk = false;
    }         
    printf("\r\nsettomg ABP data session key %sr\n", mts::Text::bin2hexString(dataky).c_str());
    if (dot->setDataSessionKey(dataky) != mDot::MDOT_OK){
         printf(" failed to set key\r\n");
         bKeyOk = false;
    }     
    if (!bKeyOk) return false;
            
    if (dot->setClass("C") == mDot::MDOT_OK){
          printf("\r\n set network mode to class C\r\n");
          return true;
    }      
    else{
         printf("\r\n  FAILED to set network mode to class C\r\n");
         return false;
    }        
 } //if Class C
 else{           
    multicast_change_classA();  //change back to OTAA
  } 
  return true;        
}
//========================================================================================================
//multicast_data_process()            
//transfer incoming  rx mcast code frag pkt to proc via I2C
//- I2C xfr pkt: always xfr size = BUFFER_SIZE_MCAST to proc, must match same size as used in proc, else proc will fault on i2c comm
//- end of multicast session:
//   - first 2 bytes in mcast pkt = flash rowNmb
//   - if rowNmb = 0xffff => end of mcast session, return to normal ClassA mode
//========================================================================================================
void multicast_data_process(std::vector<uint8_t> rx_packet){            
    uint8_t i;                                    
    uint8_t buf_xmt[BUFFER_SIZE_MCAST] = {0};
    uint8_t rxLen = rx_packet.size();     

    printf("\n\rmulticast frag rcvd, len: %d",rxLen);         
    printf("\r\nmcast data: ");            
    for (i=1; i< rxLen;i++)printf(" %x",rx_packet[i]);            
    printf("\r\n");   
//transfer to output buffer... is this needed?
    for (i=0; i< rxLen;i++) buf_xmt[i] = rx_packet[i];  
//xfr to proc   
    i2c_pulse_wake();
    i2c_proc_comm(buf_xmt,buf_xmt,BUFFER_SIZE_MCAST); 
//check for end of mcast session
    if ((rx_packet[0] == 0xff) && (rx_packet[1] == 0xff)){
        multicast_change_classA();       
    }
}