📄 vmac.c
字号:
#include "vmac.h"
#include "hardware_proc.h"
#include "pid.h"
#include <stdbool.h>
#include "malloc.h"
#include <string.h>
#include "cul.h"
#include "sos_timer.h"
#include "sos_module_types.h"
#include "sched.h"
#include "message.h"
#include "message_queue.h"
#include "random.h"
#include "net_stack.h"
/*************************************************************************
* define the maximum number retry times for sending a packet *
*************************************************************************/
#define MAX_RETRIES 7
/*************************************************************************
* define the maximum number of messages in the MAC queue *
*************************************************************************/
#define MAX_MSGS_IN_QUEUE 30
/*************************************************************************
* define the timer ID *
*************************************************************************/
#define WAKEUP_TIMER_TID 0 //!< Wakeup Timer TID
/*************************************************************************
* declare the timer *
*************************************************************************/
static sos_timer_t wakeup_timer;// = TIMER_INITIALIZER(RADIO_PID, WAKEUP_TIMER_TID, TIMER_ONE_SHOT);
/*
declare global sending buffer
*/
#define SEND_BUFFER_LEN 122
static uint8_t send_buffer[SEND_BUFFER_LEN];
extern volatile BYTE sppRxStatus;
extern volatile BYTE sppTxStatus;
extern __no_init SPP_RX_STRUCT rxData @ "PM0_XDATA"; //defined in radio.c
extern __no_init SPP_TX_STRUCT txData @ "PM0_XDATA"; //defined in radio.c
/*************************************************************************
* declare the message handler *
*************************************************************************/
static int8_t vmac_handler(void *state, Message *e);
static void backoff_timeout();
static uint8_t getMsgNumOfQueue();
static int16_t MacBackoff_congestionBackoff(int8_t retries);
/*************************************************************************
* define the MAC module header *
*************************************************************************/
static mod_header_t SOS_MODULE_HEADER mod_header ={
.mod_id = RADIO_PID,
.state_size = 0,
.num_timers = 0,
.num_sub_func = 0,
.num_prov_func = 0,
.module_handler= vmac_handler,
};
/*************************************************************************
* declare the MAC module *
*************************************************************************/
static sos_module_t vmac_module;
/*************************************************************************
* declare the queue used for MAC *
*************************************************************************/
static mq_t vmac_pq;
/*************************************************************************
* declare the sequence number variable *
*************************************************************************/
static uint16_t seq_count;
/*************************************************************************
* define the retry times variable *
*************************************************************************/
static uint8_t retry_count;
static uint16_t getSeq()
{
uint16_t ret;
HAS_CRITICAL_SECTION;
ENTER_CRITICAL_SECTION();
ret = seq_count;
LEAVE_CRITICAL_SECTION();
return ret;
}
/*************************************************************************
* increase sequence number *
*************************************************************************/
static uint16_t incSeq()
{
uint16_t ret;
HAS_CRITICAL_SECTION;
ENTER_CRITICAL_SECTION();
ret = seq_count++;
LEAVE_CRITICAL_SECTION();
return ret;
}
/*************************************************************************
* set sequence number to 0 *
*************************************************************************/
static void resetSeq()
{
HAS_CRITICAL_SECTION;
ENTER_CRITICAL_SECTION();
seq_count = 0;
LEAVE_CRITICAL_SECTION();
}
/*************************************************************************
* get retry times *
*************************************************************************/
static uint8_t getRetries()
{
uint8_t ret;
HAS_CRITICAL_SECTION;
ENTER_CRITICAL_SECTION();
ret = retry_count;
LEAVE_CRITICAL_SECTION();
return ret;
}
/*************************************************************************
* increase retry times *
*************************************************************************/
static uint8_t incRetries()
{
uint8_t ret;
HAS_CRITICAL_SECTION;
ENTER_CRITICAL_SECTION();
ret = retry_count++;
LEAVE_CRITICAL_SECTION();
return ret;
}
/*************************************************************************
* set retry times to 0 *
*************************************************************************/
static void resetRetries()
{
HAS_CRITICAL_SECTION;
ENTER_CRITICAL_SECTION();
retry_count = 0;
LEAVE_CRITICAL_SECTION();
}
/*************************************************************************
* message dispatch function for backoff mechanism for Collision *
* Avoidance implementation *
*************************************************************************/
static int8_t vmac_handler(void *state, Message *e)
{
// MsgParam *p = (MsgParam*)(e->data);
switch(e->type){
case MSG_TIMER_TIMEOUT:
backoff_timeout();
break;
default:
break;
}
return SOS_OK;
}
static void msg_to_sendbuffer(Message *msg,uint8_t *send_buffer)
{
uint16_t packet_seq;
uint8_t offset;
uint8_t len;
uint8_t *msg_data;
//uint8_t *send_buffer;
if(flag_msg_release(msg->flag)) {
len=msg->len;
msg_data=msg->data;
}
else
{
len=SOS_MSG_PAYLOAD_LENGTH;
msg_data=msg->payload;
}
offset=0;
memcpy(send_buffer+offset,&(msg->did),sizeof(msg->did));
offset += sizeof(msg->did);
memcpy(send_buffer+offset,&(msg->sid),sizeof(msg->sid));
offset += sizeof(msg->sid);
memcpy(send_buffer+offset,&(msg->daddr),sizeof(msg->daddr));
offset += sizeof(msg->daddr);
memcpy(send_buffer+offset,&(msg->saddr),sizeof(msg->saddr));
offset += sizeof(msg->saddr);
memcpy(send_buffer+offset,&(msg->type),sizeof(msg->type));
offset += sizeof(msg->type);
memcpy(send_buffer+offset,&len,sizeof(len));
offset += sizeof(len);
memcpy(send_buffer+offset,&(msg->flag),sizeof(msg->flag));
offset += sizeof(msg->flag);
//packet_seq=getSeq();
//memcpy(send_buffer+offset,&(packet_seq),sizeof(packet_seq));
//offset += sizeof(packet_seq);
//copy data
memcpy(send_buffer+offset,msg_data,len);
//printf("%d\n",(uint8_t)len);
if (msg->type==MSG_PKT_SENDDONE)
{
packet_seq++;
}
}
static int8_t radio_msg_send(Message *msg_in)
{
//uint8_t * send_buffer;
uint8_t len;
//uint8_t *msg_data;
Message *msg; //!< message we will be taking data out
/* if(msg_in->type == MSG_PKT_SENDDONE) {
msg = (Message*) (msg_in->data);
} else {
msg = msg_in;
}*/
msg=msg_in;
if(flag_msg_release(msg->flag)) {
len=msg->len;
//msg_data=msg->data;
}
else
{
len=SOS_MSG_PAYLOAD_LENGTH;
/// msg_data=msg->payload;
}
//first we need to malloc a buffer for message
/* send_buffer=ker_malloc(len+MESSAGE_RADIO_PAYLOAD_HEADER_LEN,RADIO_PID);
if( send_buffer == NULL ) {
return FALSE;
}
*/
if (len>SEND_BUFFER_LEN)
return FALSE;
msg_to_sendbuffer(msg_in,send_buffer);
uint8_t ret;
ret=radioSend(send_buffer, len+MESSAGE_RADIO_PAYLOAD_HEADER_LEN, msg->daddr, DO_ACK);
if (ret==TRUE)
{
//ker_free(send_buffer);
//printf("success %d\n",i1);
return TRUE;
}
else
{
//ker_free(send_buffer);
//printf("failed %d\n",i2);
return FALSE;
}
}
/*************************************************************************
* will be called by post_net, etc functions to send message *
*************************************************************************/
void radio_msg_alloc(Message *msg)
{
uint16_t sleeptime = 0;
incSeq();
if (radio_msg_send(msg)) //success
msg_send_senddone(msg, 1, RADIO_PID);
else
{
if( getMsgNumOfQueue() < MAX_MSGS_IN_QUEUE ) //queue is full?
{
mq_enqueue(&vmac_pq, msg);
//printf("enter in queeu\n");
}
else
msg_send_senddone(msg, 0, RADIO_PID); //release the memory for the msg
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -