1 // *********************************************************************
    2 //   Custom DPA Handler code example - Peer-to-peer receiver           *
    3 // *********************************************************************
    4 // Copyright (c) MICRORISC s.r.o.
    5 //
    6 // File:    $RCSfile: CustomDpaHandler-Peer-to-Peer.c,v $
    7 // Version: $Revision: 1.30 $
    8 // Date:    $Date: 2022/02/25 09:41:25 $
    9 //
   10 // Revision history:
   11 //   2022/02/24  Release for DPA 4.17
   12 //   2019/01/10  Release for DPA 4.00
   13 //   2017/03/13  Release for DPA 3.00
   14 //   2015/08/05  Release for DPA 2.20
   15 //
   16 // *********************************************************************
   17 
   18 // Online DPA documentation https://doc.iqrf.org/DpaTechGuide/
   19 
   20 // Default IQRF include (modify the path according to your setup)
   21 #include "IQRF.h"
   22 
   23 // Default DPA header (modify the path according to your setup)
   24 #include "DPA.h"
   25 // Default Custom DPA Handler header (modify the path according to your setup)
   26 #include "DPAcustomHandler.h"
   27 
   28 // This example receives peer-to-peer packets sent from Peer-to-Peer-Transmitter.c example using build-in DPA support of peer-to-peer packets (event DpaEvent_PeerToPeer).
   29 // The example also shows fully user programmed implementation of peer-to-peer packet at the different channel (event DpaEvent_Idle). This approach requires more code but avoids radio jamming of the main network traffic.
   30 // User peer-to-peer must be enabled in the configuration.
   31 // !!! It is highly recommended to use additional security techniques (e.g. encryption, rolling code, checksum, CRC) against packet sniffing, spoofing and eavesdropping.
   32 // !!! It is also recommended to use listen-before-talk technique to minimize the risk of RF collision that might cause the main network RF traffic to fail.
   33 
   34 void HandlerPeer2PeerPacket();
   35 
   36 // Must be the 1st defined function in the source code in order to be placed at the correct FLASH location!
   37 //############################################################################################
   38 bit CustomDpaHandler()
   39 //############################################################################################
   40 {
   41   // Handler presence mark
   42   clrwdt();
   43 
   44   // Detect DPA event to handle
   45   switch ( GetDpaEvent() )
   46   {
   47 #ifdef  DpaEvent_Interrupt
   48     // -------------------------------------------------
   49     case DpaEvent_Interrupt:
   50       // Do an extra quick background interrupt work
   51 
   52       return Carry;
   53 #endif
   54       // -------------------------------------------------
   55     case DpaEvent_PeerToPeer:
   56       // Called when peer-to-peer (non-networking) packet is received
   57 
   58       // Handle peer-to-peer packet received by the build-in DPA support. Those packets are sent at the same channel the main network work at.
   59       HandlerPeer2PeerPacket();
   60       break;
   61 
   62       // -------------------------------------------------
   63     case DpaEvent_Idle:
   64     {
   65       // Do a quick background work when RF packet is not received
   66 
   67       // Try to receive peer-to-peer packets at the secondary main network channel. This avoids RF jamming of the main network but it is not 100% reliable as 2 channels must be scanned.
   68 
   69       // Save state of the filtering.
   70       bit saveFiltering = _filterCurrentNetwork;
   71       // Packet not received yet
   72       bit handlePacket = FALSE;
   73       // Change the channel
   74       uns8 saveRFchannel = RFchannel;
   75       setRFchannel( DpaApiReadConfigByte( CFGIND_CHANNEL_B ) );
   76       // Disable filtering to allow receiving of peer-to-peer packets
   77       setNetworkFilteringOff();
   78 
   79       // Try to receive packet
   80       if ( checkRF( DpaApiReadConfigByte( CFGIND_RXFILTER ) ) && RFRXpacket() )
   81         // Some packet received!
   82         handlePacket = TRUE;
   83 
   84       // Before handling the packet restore RF settings (there might be needed for the correct DPA command, that is stored in the packet, execution)
   85       // Restore channel
   86       setRFchannel( saveRFchannel );
   87       // Restore network filtering
   88       if ( saveFiltering )
   89         setNetworkFilteringOn();
   90 
   91       // If packet was received, handle it
   92       if ( handlePacket )
   93         HandlerPeer2PeerPacket();
   94 
   95       break;
   96     }
   97   }
   98 
   99   return FALSE;
  100 }
  101 
  102 //############################################################################################
  103 void HandlerPeer2PeerPacket()
  104 //############################################################################################
  105 {
  106   // Peer-to-peer "DPA" packet?
  107   if ( _DPAF )
  108   {
  109     // Is my local address matched?
  110     if ( _DpaParams == ntwADDR )
  111     {
  112       // Just execute the DPA request
  113       DpaApiLocalRequest();
  114       // Make sure LED is visible at LP mode
  115       waitMS( 20 );
  116     }
  117   }
  118   else
  119   {
  120     // Pure peer-to-peer packet
  121 
  122     // Is my peer-to-peer packet (check length and content)
  123     if ( DLEN == 2 && bufferRF[0] == 'P' && bufferRF[1] == ntwADDR )
  124     {
  125       // Pulse red LED
  126       pulseLEDR();
  127       // Make sure LED is visible at LP mode
  128       waitMS( 20 );
  129     }
  130   }
  131 }
  132 //############################################################################################
  133 // Default Custom DPA Handler header; 2nd include implementing a Code bumper to detect too long code of the Custom DPA Handler (modify the path according to your setup)
  134 #include "DPAcustomHandler.h"
  135 //############################################################################################