ENEL400
/
Aloha
Aloha implementation of LoRa technology
Fork of SX1276PingPong by
Diff: main.cpp
- 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; } }