Basic MAC data interface for LoRa transceiver
Dependents: LoRaBaseStation LoRaTerminal
Diff: AlohaTransceiver.cpp
- Revision:
- 31:a0454fda1538
- Parent:
- 30:bccad60351ac
- Child:
- 32:b7d87c5f647c
--- a/AlohaTransceiver.cpp Sat Sep 03 03:15:52 2016 +0000 +++ b/AlohaTransceiver.cpp Sat Sep 03 04:41:48 2016 +0000 @@ -63,7 +63,7 @@ */ AlohaTransceiver::AlohaTransceiver(uint8_t id): - AlohaTxQueue(10) + AlohaTxQueue(32) { // store unique device id deviceId = id; @@ -71,8 +71,11 @@ // initialize sequenceid memset(seqid, 0x0, sizeof(seqid)); - // clear flags - flags = 0xff; + // clear tx done state + isTxDone = true; + + // assume all station is clear to transmit + isAcked = 0xffff; // configure properties #if USE_MODEM_LORA == 1 @@ -191,6 +194,18 @@ #ifdef DEBUG_ALOHA printf("\r\nRXACK::SRC_ADDR:0x%x,SEQID:0x%x\r\n", frame->getSourceAddress(), frame->getSequenceID()); #endif + // clear the ack state + uint8_t src_addr = frame->getSourceAddress(); + uint8_t foreign_seqid = frame->getSequenceID(); + + // compare the local sequence id and foreign sequence id for specific host + // if same then set the flag + if (seqid[src_addr] == foreign_seqid) + { + setAckedFlag(src_addr); + } + printf("frame_seqid: %d, local_seqid: %d\r\n", frame->getSequenceID(), seqid[frame->getSourceAddress()]); + } // check registered callback function @@ -253,26 +268,56 @@ case LOWPOWER: { // transmit packet when the radio is free - if (getTxDoneFlag() && AlohaTxQueue.getCounter() > 0) + if (getTxDoneFlag()) { - AlohaFrame *frame = AlohaTxQueue.dequeue(); - - // create a buffer for transmit - uint8_t frame_length = frame->getPayloadLength() + FIXED_BYTE; - uint8_t buffer[frame_length]; // 4 fix fields - memset(buffer, 0x0, sizeof(buffer)); - - // copy content to buffer - frame->serialize(buffer); - - // send to radio - Radio.Send(buffer, frame_length); - - // block the next transmission until previous transmission is done - clearTxDoneFlag(); - - // free memory - delete frame; + // find next available packet to transmit + for (size_t i = 0; i < AlohaTxQueue.getCounter(); i++) + { + AlohaFrame *frame = AlohaTxQueue.dequeue(); + uint8_t type = frame->getType(); + + // determined by the type of the frame, only data frame need to be cleared before transmitting + switch (type) + { + // ack frame can transmit directly + case AlohaFrame::Aloha_ACK: + { + sendFrame(frame); + break; + } + case AlohaFrame::Aloha_Data: + { + uint8_t dest_addr = frame->getDestinationAddress(); + + // depending on the availability of the destination host, + // the radio will on transmit the packet when acked + if (getAckedFlag(dest_addr)) + { + sendFrame(frame); + + // block the next transmission until previous transmission is done + clearTxDoneFlag(); + + // block the next transmission of the same host until an acked packet + // is received + clearAckedFlag(dest_addr); + + // free memory + delete frame; + } + + // otherwise put the packet back to the end of queue and wait for its being acked + else + { + AlohaTxQueue.enqueue(frame); + } + break; + } + + default: + break; + } + } } break; } @@ -284,6 +329,20 @@ } } +void AlohaTransceiver::sendFrame(AlohaFrame *frame) +{ + // create a buffer for transmit + uint8_t frame_length = frame->getPayloadLength() + FIXED_BYTE; + uint8_t buffer[frame_length]; // 4 fix fields + memset(buffer, 0x0, sizeof(buffer)); + + // copy content to buffer + frame->serialize(buffer); + + // send to radio + Radio.Send(buffer, frame_length); +} + bool AlohaTransceiver::send(BasicPacket *packet) { // for the reason that we only transmit basic packet format, the @@ -384,17 +443,32 @@ bool AlohaTransceiver::getTxDoneFlag() { - return CHECK_FLAG(flags, 0); + return isTxDone; } void AlohaTransceiver::setTxDoneFlag() { - SET_FLAG(flags, 0); + isTxDone = true; } void AlohaTransceiver::clearTxDoneFlag() { - CLEAR_FLAG(flags, 0); + isTxDone = false; +} + +bool AlohaTransceiver::getAckedFlag(uint8_t addr) +{ + return CHECK_FLAG(isAcked, addr); +} + +void AlohaTransceiver::setAckedFlag(uint8_t addr) +{ + SET_FLAG(isAcked, addr); +} + +void AlohaTransceiver::clearAckedFlag(uint8_t addr) +{ + CLEAR_FLAG(isAcked, addr); } void AlohaTransceiver::registerType(AlohaFrame::AlohaType_t type, aloha_callback_func f)