99 lines
3.0 KiB
C
99 lines
3.0 KiB
C
/**
|
|
* \file
|
|
* \brief This is the implementation of the Radio MAC part.
|
|
* \author (c) 2013-2014 Erich Styger, http://mcuoneclipse.com/
|
|
* \note MIT License (http://opensource.org/licenses/mit-license.html), see 'RNet_License.txt'
|
|
*
|
|
* This module encapsulates the Media Access of network stack.
|
|
*/
|
|
|
|
#include "McuRNetConfig.h"
|
|
#if McuRNET_CONFIG_IS_ENABLED
|
|
#include "RMAC.h"
|
|
#include "RPHY.h"
|
|
#include "RNWK.h"
|
|
#include "McuUtility.h"
|
|
|
|
static uint8_t RMAC_SeqNr = 0;
|
|
static uint8_t RMAC_ExpectedAckSeqNr;
|
|
|
|
uint8_t RMAC_PutPayload(uint8_t *buf, size_t bufSize, uint8_t payloadSize, RPHY_FlagsType flags) {
|
|
if (flags&RPHY_PACKET_FLAGS_REQ_ACK) {
|
|
RMAC_BUF_TYPE(buf) = (uint8_t)((uint8_t)RMAC_MSG_TYPE_DATA|(uint8_t)RMAC_MSG_TYPE_REQ_ACK);
|
|
} else {
|
|
RMAC_BUF_TYPE(buf) = (uint8_t)RMAC_MSG_TYPE_DATA;
|
|
}
|
|
RMAC_ExpectedAckSeqNr = RMAC_SeqNr;
|
|
RMAC_BUF_SEQN(buf) = RMAC_SeqNr++;
|
|
return RPHY_PutPayload(buf, bufSize, payloadSize+RMAC_HEADER_SIZE, flags);
|
|
}
|
|
|
|
uint8_t RMAC_OnPacketRx(RPHY_PacketDesc *packet) {
|
|
return RNWK_OnPacketRx(packet); /* pass data packet up the stack */
|
|
}
|
|
|
|
uint8_t RMAC_SendACK(RPHY_PacketDesc *rxPacket, RPHY_PacketDesc *ackPacket) {
|
|
RMAC_BUF_TYPE(ackPacket->phyData) = (uint8_t)RMAC_MSG_TYPE_ACK; /* set type to ack */
|
|
RMAC_BUF_SEQN(ackPacket->phyData) = RMAC_BUF_SEQN(rxPacket->phyData);
|
|
/* use same sequence number as in the received package, so no change */
|
|
return RPHY_PutPayload(ackPacket->phyData, ackPacket->phySize, RMAC_HEADER_SIZE+RNWK_HEADER_SIZE, RPHY_PACKET_FLAGS_NONE);
|
|
}
|
|
|
|
RMAC_MsgType RMAC_GetType(uint8_t *buf, size_t bufSize) {
|
|
(void)bufSize; /* not used */
|
|
return (RMAC_MsgType)RMAC_BUF_TYPE(buf);
|
|
}
|
|
|
|
bool RMAC_IsExpectedACK(uint8_t *buf, size_t bufSize) {
|
|
(void)bufSize; /* not used */
|
|
return RMAC_BUF_SEQN(buf)==RMAC_ExpectedAckSeqNr;
|
|
}
|
|
|
|
void RMAC_SniffPacket(RPHY_PacketDesc *packet, bool isTx) {
|
|
RNWK_SniffPacket(packet, isTx);
|
|
}
|
|
|
|
void RMAC_DecodeType(uint8_t *buf, size_t bufSize, RPHY_PacketDesc *packet) {
|
|
RMAC_MsgType type;
|
|
bool first = TRUE;
|
|
|
|
type = (RMAC_MsgType)RMAC_BUF_TYPE(packet->phyData);
|
|
buf[0] = '\0';
|
|
McuUtility_chcat(buf, bufSize, '(');
|
|
if ((uint8_t)type&(uint8_t)RMAC_MSG_TYPE_REQ_ACK) {
|
|
McuUtility_strcat(buf, bufSize, (unsigned char*)"RACK");
|
|
first = FALSE;
|
|
} else {
|
|
McuUtility_strcat(buf, bufSize, (unsigned char*)"NACK");
|
|
first = FALSE;
|
|
}
|
|
if ((uint8_t)type&(uint8_t)RMAC_MSG_TYPE_DATA) {
|
|
if (!first) {
|
|
McuUtility_chcat(buf, bufSize, '|');
|
|
}
|
|
McuUtility_strcat(buf, bufSize, (unsigned char*)"DATA");
|
|
first = FALSE;
|
|
}
|
|
if ((uint8_t)type&(uint8_t)RMAC_MSG_TYPE_ACK) {
|
|
if (!first) {
|
|
McuUtility_chcat(buf, bufSize, '|');
|
|
}
|
|
McuUtility_strcat(buf, bufSize, (unsigned char*)"ACK");
|
|
}
|
|
if ((uint8_t)type&(uint8_t)RMAC_MSG_TYPE_CMD) {
|
|
McuUtility_strcat(buf, bufSize, (unsigned char*)"CMD");
|
|
}
|
|
McuUtility_chcat(buf, bufSize, ')');
|
|
}
|
|
|
|
void RMAC_Deinit(void) {
|
|
/* nothing needed */
|
|
}
|
|
|
|
void RMAC_Init(void) {
|
|
RMAC_SeqNr = 0;
|
|
RMAC_ExpectedAckSeqNr = 0;
|
|
}
|
|
|
|
#endif /* McuRNET_CONFIG_IS_ENABLED */
|