Aloha implementation of LoRa technology

Dependencies:   SX1276Lib mbed

Fork of SX1276PingPong by Semtech

Revision:
16:c3c6b13c3c42
Parent:
15:f790f35839db
--- a/main.cpp	Tue May 31 09:52:21 2016 +0000
+++ b/main.cpp	Wed Jun 08 22:15:29 2016 +0000
@@ -74,6 +74,49 @@
 // aloha protocol
 Aloha aloha;
 
+// user button
+InterruptIn UserButton(USER_BUTTON);
+static int seqid = 0;
+
+void sendMessage()
+{
+    HeaderStruct header;
+    DataStruct data;
+    
+    memset(&header, 0, sizeof(header));
+    memset(&data, 0, sizeof(data));
+    
+    header.fid = 0x0;
+    header.no = (uint8_t) seqid;
+    data.pd0 = 0xff;
+    data.pd1 = 0xff;
+    
+    uint8_t buffer[4];
+    createAlohaPacket(buffer, &header, &data);
+    
+    Radio.Send(buffer, 4);
+}
+
+void sendAck(int id)
+{
+    HeaderStruct header;
+    DataStruct data;
+    
+    memset(&header, 0, sizeof(header));
+    memset(&data, 0, sizeof(data));
+    
+    header.fid = 0x1;
+    header.no = (uint8_t) id;
+    data.pd0 = 0x00;
+    data.pd1 = 0x00;
+    
+    uint8_t buffer[4];
+    createAlohaPacket(buffer, &header, &data);
+    
+    Radio.Send(buffer, 4);
+}
+
+
 void setExpire()
 {
     if (aloha.attempts >= ALOHA_MAX_ATTEMPT)
@@ -83,10 +126,15 @@
     else
     {
         aloha.state = Aloha::RETRANSMIT;
-        aloha.delay = aloha.delay * aloha.delay;
     }
 }
 
+void userButtonHandler()
+{
+    seqid += 1;
+    sendMessage();
+}
+
 void RadioInit()
 {
     // Initialize Radio driver
@@ -126,7 +174,9 @@
 int main() 
 {  
     RadioInit();
+    UserButton.rise(userButtonHandler);
     
+    Radio.Rx( RX_TIMEOUT_VALUE );
     while (1)
     {
         switch( State )
@@ -135,36 +185,104 @@
             // if the receive frame is an ack, then cancel the timer
             // otherwise process the frame
             HeaderStruct header;
+            DataStruct data;
+            
             memset(&header, 0, sizeof(header));
+            memset(&data, 0, sizeof(data));
             
+            // decode data
+            dissectAlohaPacket(Buffer, &header, &data);
+            
+            // process packet
+            switch (header.fid)
+            {
+                case 0x0: // data packet
+                    sendAck(header.no);
+                    break;
+                    
+                case 0x1: // ack received
+                    aloha.AlohaAckTimeout.detach();
+                    aloha.state = Aloha::IDLE;
+                    break;
+                
+                default:
+                    break;
+            }
+                
             if (header.fid == 0x01)
             {
                 aloha.AlohaAckTimeout.detach();
             }
             
             // TODO: process the frame
+            
+            
+            printf("RECV::fid=0x%x, seqid=0x%x, pd0=0x%x, pd1=0x%x\r\n", header.fid, header.no, data.pd0, data.pd1);
+            
+            // enter listening mode
+            Radio.Rx( RX_TIMEOUT_VALUE );
+            
+            State = LOWPOWER;
             break;
         case TX:
             // transmit done
-            // then set state to aloha pending and start the timer
+            // set the state to pending and attach the timer with random delay
+            
+            // we dont need ack for ack
+            if (aloha.state == Aloha::ACK_RESP)
+            {
+                aloha.state =  Aloha::IDLE;
+                break;
+            }
+            
+            // set delay time
+            if (aloha.state == Aloha::IDLE)
+            {
+                aloha.delay = (Radio.Random() % 1000) / 1000.0f;
+            }
+            else if (aloha.state == Aloha::RETRANSMIT)
+            {
+                aloha.delay *= 2;
+            }
+            
+            aloha.AlohaAckTimeout.detach();
+            aloha.AlohaAckTimeout.attach(&setExpire, aloha.delay);
+            
+            // increase the attempt counter
+            aloha.attempts += 1;
+            
+            // enter listening mode
+            Radio.Rx( RX_TIMEOUT_VALUE );
+            
+            // state transition
             aloha.state = Aloha::PENDING;
-            aloha.delay = Radio.Random();
-            aloha.AlohaAckTimeout.detach();
-            aloha.AlohaAckTimeout.attach_us(&setExpire, aloha.delay);
-            aloha.attempts += 1;
+                    
+            State = LOWPOWER;
             break;
         case RX_TIMEOUT:
             // enter listening mode
+            Radio.Rx( RX_TIMEOUT_VALUE );
+            
+            State = LOWPOWER;
             break;
         case RX_ERROR:
             // we don't handle crc failed situation
+            // enter listening mode
+            Radio.Rx( RX_TIMEOUT_VALUE );
+            
+            State = LOWPOWER;
             break;
         case TX_TIMEOUT:
             // we don't handle hardware error
+            // enter listening mode
+            Radio.Rx( RX_TIMEOUT_VALUE );
+            
+            State = LOWPOWER;
             break;
         case LOWPOWER:
             break;
         default:
+            State = LOWPOWER;
             break;
         }
         
@@ -172,22 +290,31 @@
         {
         case Aloha::IDLE:
             // transmit packet if any
+            // printf("Aloha::IDLE\r\n");
             break;
         
         case Aloha::PENDING:
             // set rx time
+            // printf("Aloha::PENDING, delay=%f, attempt=%d\r\n", aloha.delay, aloha.attempts);
             break;
             
         case Aloha::RETRANSMIT:
             // send the packet again
-            // and setup the timer with new backoff delay
-            aloha.AlohaAckTimeout.attach(&setExpire, aloha.delay);
-            aloha.state = Aloha::PENDING;
+            sendMessage();
+            
+            // printf("Aloha::RETRANSMIT\r\n");
             break;
         case Aloha::EXPIRED:
             // give up the transmission
             // back to idle
+            aloha.attempts = 0;
+            
             aloha.state = Aloha::IDLE;
+            // printf("Aloha::EXPIRED\r\n");
+            break;
+        case Aloha::ACK_RESP:
+            break;
+        default:
             break;
         }
     }