1
0
This repository has been archived on 2024-09-17. You can view files and clone it, but cannot push or open issues or pull requests.
tor-heredero-tokenring/mac_sender.c

346 lines
10 KiB
C
Raw Normal View History

2024-04-15 14:26:40 +00:00
#include "main.h"
2024-04-21 19:23:15 +00:00
#include <cstdio>
2024-04-22 11:51:45 +00:00
#include <stdbool.h>
#include <stdint.h>
2024-04-20 10:40:44 +00:00
#include <string.h>
2024-04-22 11:51:45 +00:00
#include <cassert>
2024-04-20 10:40:44 +00:00
2024-05-01 14:09:03 +00:00
uint8_t* lastToken; // Pointer to last token
uint8_t* lastSentMsgPtr; // Pointer to last sent message (for retransmission)
2024-05-01 14:09:03 +00:00
// Queue for messages to be sent when token is received
2024-04-20 10:40:44 +00:00
osMessageQueueId_t queue_macData_id;
const osMessageQueueAttr_t queue_macData_attr = {
.name = "MAC_DATA"
};
2024-05-01 14:09:03 +00:00
/**
* @brief Send token to the next station
*/
2024-04-24 13:25:06 +00:00
void sendToken() {
2024-05-01 14:09:03 +00:00
// Create queueMsg struct with new memory
2024-04-24 13:25:06 +00:00
struct queueMsg_t queueMsg;
2024-04-26 11:15:48 +00:00
queueMsg.anyPtr = osMemoryPoolAlloc(memPool,osWaitForever);
2024-04-24 13:25:06 +00:00
queueMsg.type = TO_PHY;
2024-05-01 14:09:03 +00:00
// Copy token
memcpy(queueMsg.anyPtr, lastToken, TOKENSIZE-2);
// Send token to PHY
2024-04-24 13:25:06 +00:00
osStatus_t retCode = osMessageQueuePut(
queue_phyS_id,
&queueMsg,
osPriorityNormal,
0);
CheckRetCode(retCode, __LINE__, __FILE__, CONTINUE);
}
2024-05-01 14:09:03 +00:00
/**
* @brief MAC sender task
*/
2024-04-20 10:40:44 +00:00
void MacSender(void *argument) {
2024-04-15 14:26:40 +00:00
struct queueMsg_t queueMsg; // queue message
2024-05-01 14:09:03 +00:00
uint8_t* msg; // pointer to message
Adresse src; // source Address
Adresse dst; // destination Address
uint8_t length; // length of message
Status status; // status of message
osStatus_t retCode; // return error code
char* strPtr; // pointer to string message
SapiToken stationStatus; // Status of one station
2024-04-20 10:40:44 +00:00
2024-05-01 14:09:03 +00:00
// Allocate memory for last token
2024-04-20 10:40:44 +00:00
lastToken = osMemoryPoolAlloc(memPool, osWaitForever);
2024-05-01 14:09:03 +00:00
// Create queue for messages to be sent when token is received
2024-04-20 10:40:44 +00:00
queue_macData_id = osMessageQueueNew(4, sizeof(struct queueMsg_t), &queue_macData_attr);
2024-04-15 14:26:40 +00:00
for(;;) {
2024-04-20 16:44:37 +00:00
//--------------------------------------------------------------------------
2024-04-15 14:26:40 +00:00
// QUEUE READ
2024-04-20 16:44:37 +00:00
//--------------------------------------------------------------------------
2024-05-01 14:09:03 +00:00
{
// Get message from queue, test retCode and get msg
2024-04-15 14:26:40 +00:00
retCode = osMessageQueueGet(
queue_macS_id,
&queueMsg,
NULL,
osWaitForever);
CheckRetCode(retCode, __LINE__, __FILE__, CONTINUE);
2024-04-20 10:40:44 +00:00
2024-04-17 15:09:48 +00:00
msg = queueMsg.anyPtr;
2024-05-01 14:09:03 +00:00
}
2024-04-15 14:26:40 +00:00
switch(queueMsg.type) {
2024-04-20 16:44:37 +00:00
//----------------------------------------------------------------------
// TOKEN MESSAGE
//----------------------------------------------------------------------
2024-04-20 10:40:44 +00:00
case TOKEN: {
// Get token and save it
memcpy(lastToken, msg, TOKENSIZE-2);
// update token
lastToken[gTokenInterface.myAddress+1] = (0x1 << TIME_SAPI) + (gTokenInterface.connected << CHAT_SAPI);
for(uint8_t i = 1; i < sizeof(gTokenInterface.station_list); i++) {
gTokenInterface.station_list[i-1] = lastToken[i];
}
// send to lcd
queueMsg.type = TOKEN_LIST;
2024-04-26 11:15:48 +00:00
memcpy(queueMsg.anyPtr , lastToken, TOKENSIZE-2);
2024-04-20 10:40:44 +00:00
retCode = osMessageQueuePut(
queue_lcd_id,
&queueMsg,
osPriorityNormal,
osWaitForever);
CheckRetCode(retCode, __LINE__, __FILE__, CONTINUE);
2024-04-26 14:19:18 +00:00
2024-05-01 14:09:03 +00:00
// Free memory
2024-04-26 14:19:18 +00:00
retCode = osMemoryPoolFree(memPool, queueMsg.anyPtr);
CheckRetCode(retCode, __LINE__, __FILE__, CONTINUE);
2024-04-20 10:40:44 +00:00
// Send one msg from internal queue if exist
2024-04-24 18:54:35 +00:00
retCode = osMessageQueueGet(queue_macData_id, &queueMsg, NULL, 0);
if(retCode == 0){
2024-04-20 10:40:44 +00:00
queueMsg.type = TO_PHY;
retCode = osMessageQueuePut(
queue_phyS_id,
&queueMsg,
osPriorityNormal,
2024-04-21 19:23:15 +00:00
0);
2024-04-20 10:40:44 +00:00
CheckRetCode(retCode, __LINE__, __FILE__, CONTINUE);
2024-04-24 13:25:06 +00:00
} else {
sendToken();
2024-04-17 15:09:48 +00:00
}
2024-04-15 14:26:40 +00:00
break;
2024-04-20 10:40:44 +00:00
}
2024-04-15 14:26:40 +00:00
2024-04-20 16:44:37 +00:00
//----------------------------------------------------------------------
// DATABACK MESSAGE
//----------------------------------------------------------------------
2024-04-20 10:40:44 +00:00
case DATABACK: {
2024-05-01 14:09:03 +00:00
// Get source Addresse, destination Addresse, length and status
src.raw = msg[0];
dst.raw = msg[1];
length = msg[2];
status.raw = msg[3+length];
2024-04-20 10:40:44 +00:00
2024-04-24 18:54:35 +00:00
if (dst.addr == BROADCAST_ADDRESS) {
2024-05-01 14:09:03 +00:00
// Broadcast message -> free memory
2024-04-21 19:23:15 +00:00
retCode = osMemoryPoolFree(memPool, queueMsg.anyPtr);
CheckRetCode(retCode, __LINE__, __FILE__, CONTINUE);
2024-05-01 14:09:03 +00:00
// Send token
2024-04-24 13:25:06 +00:00
sendToken();
2024-05-01 14:09:03 +00:00
} else if(src.addr != gTokenInterface.myAddress) {
2024-05-01 14:09:03 +00:00
// Not from me -> to PHY
queueMsg.type = TO_PHY;
retCode = osMessageQueuePut(
queue_phyS_id,
&queueMsg,
osPriorityNormal,
0);
CheckRetCode(retCode, __LINE__, __FILE__, CONTINUE);
2024-04-22 11:51:45 +00:00
} else if(status.read == 1) {
if(status.ack == 1) {
2024-05-01 14:09:03 +00:00
// Read + ack => Everything is fine -> free memory and send token
retCode = osMemoryPoolFree(memPool, queueMsg.anyPtr);
CheckRetCode(retCode, __LINE__, __FILE__, CONTINUE);
2024-04-24 18:54:35 +00:00
retCode = osMemoryPoolFree(memPool, lastSentMsgPtr);
CheckRetCode(retCode, __LINE__, __FILE__, CONTINUE);
2024-04-24 13:25:06 +00:00
sendToken();
} else {
2024-05-01 14:09:03 +00:00
// Read but checksum error, send original message again
2024-04-24 13:25:06 +00:00
if(lastSentMsgPtr != NULL) {
2024-04-24 18:54:35 +00:00
memcpy(queueMsg.anyPtr, lastSentMsgPtr, lastSentMsgPtr[2]+4);
queueMsg.type = TO_PHY;
//queueMsg.anyPtr = lastSentMsgPtr;
retCode = osMessageQueuePut(
2024-04-24 13:25:06 +00:00
queue_phyS_id,
&queueMsg,
osPriorityNormal,
0);
CheckRetCode(retCode, __LINE__, __FILE__, CONTINUE);
} else {
// Error, no original message found
strPtr = osMemoryPoolAlloc(memPool, osWaitForever);
2024-04-24 13:25:06 +00:00
sprintf(strPtr, "%d did shit on the ring #1\0", dst.addr);
queueMsg.type = MAC_ERROR;
queueMsg.addr = src.addr;
queueMsg.sapi = src.sapi;
queueMsg.anyPtr = strPtr;
retCode = osMessageQueuePut(
queue_lcd_id,
&queueMsg,
osPriorityNormal,
0);
CheckRetCode(retCode, __LINE__, __FILE__, CONTINUE);
}
}
} else {
2024-05-01 14:09:03 +00:00
// Not read => Station not connected -> free backup message
2024-04-24 13:25:06 +00:00
retCode = osMemoryPoolFree(memPool, queueMsg.anyPtr);
2024-04-21 19:23:15 +00:00
CheckRetCode(retCode, __LINE__, __FILE__, CONTINUE);
// Send error message to LCD
strPtr = osMemoryPoolAlloc(memPool, osWaitForever);
2024-04-21 19:23:15 +00:00
sprintf(strPtr, "Dest. %d couldn't read message from %d\0", dst.addr+1, src.addr+1);
queueMsg.type = MAC_ERROR;
queueMsg.addr = src.addr;
queueMsg.sapi = src.sapi;
queueMsg.anyPtr = strPtr;
retCode = osMessageQueuePut(
queue_lcd_id,
&queueMsg,
osPriorityNormal,
2024-04-21 19:23:15 +00:00
0);
CheckRetCode(retCode, __LINE__, __FILE__, CONTINUE);
2024-04-24 13:25:06 +00:00
2024-05-01 14:09:03 +00:00
// Send token
2024-04-24 13:25:06 +00:00
sendToken();
}
2024-04-22 11:51:45 +00:00
2024-04-15 14:26:40 +00:00
break;
2024-04-20 10:40:44 +00:00
}
2024-04-15 14:26:40 +00:00
2024-04-20 16:44:37 +00:00
//----------------------------------------------------------------------
// NEW TOKEN MESSAGE
//----------------------------------------------------------------------
2024-04-20 10:40:44 +00:00
case NEW_TOKEN: {
2024-05-01 14:09:03 +00:00
// Create new token
2024-04-20 10:40:44 +00:00
lastToken[0] = TOKEN_TAG;
2024-04-17 15:09:48 +00:00
2024-05-01 14:09:03 +00:00
// Set all station status to 0
memset(lastToken, 0, sizeof(TOKENSIZE-2));
// Set my station status on station list and lastToken
2024-04-17 15:09:48 +00:00
gTokenInterface.station_list[gTokenInterface.myAddress] = (0x1 << TIME_SAPI) + (gTokenInterface.connected << CHAT_SAPI);
2024-04-20 10:40:44 +00:00
lastToken[gTokenInterface.myAddress+1] = gTokenInterface.station_list[gTokenInterface.myAddress];
2024-05-01 14:09:03 +00:00
// Send token
2024-04-26 11:15:48 +00:00
sendToken();
2024-04-15 14:26:40 +00:00
break;
2024-04-20 10:40:44 +00:00
}
2024-04-15 14:26:40 +00:00
2024-04-20 16:44:37 +00:00
//----------------------------------------------------------------------
// START MESSAGE
//----------------------------------------------------------------------
2024-04-20 10:40:44 +00:00
case START: {
2024-04-20 16:44:37 +00:00
gTokenInterface.connected = true;
2024-04-15 14:26:40 +00:00
break;
2024-04-20 10:40:44 +00:00
}
2024-04-15 14:26:40 +00:00
2024-04-20 16:44:37 +00:00
//----------------------------------------------------------------------
// STOP MESSAGE
//----------------------------------------------------------------------
2024-04-20 10:40:44 +00:00
case STOP: {
2024-04-20 16:44:37 +00:00
gTokenInterface.connected = false;
2024-04-15 14:26:40 +00:00
break;
2024-04-20 10:40:44 +00:00
}
2024-04-15 14:26:40 +00:00
2024-04-20 16:44:37 +00:00
//----------------------------------------------------------------------
// DATA MESSAGE
//----------------------------------------------------------------------
2024-04-20 10:40:44 +00:00
case DATA_IND: {
2024-05-01 14:09:03 +00:00
// Set source Addresse, destination Addresse and length
dst.addr = queueMsg.addr;
dst.sapi = queueMsg.sapi;
dst.nothing = 0;
src.addr = gTokenInterface.myAddress;
src.sapi = queueMsg.sapi;
src.nothing = 0;
length = strlen(queueMsg.anyPtr);
2024-04-20 10:40:44 +00:00
2024-05-01 14:09:03 +00:00
// Set station status
2024-04-26 14:19:18 +00:00
if(dst.addr == BROADCAST_ADDRESS) {
status.read = 1;
status.ack = 1;
stationStatus.raw = 0;
} else {
status.read = 0;
status.ack = 0;
2024-04-25 12:59:15 +00:00
stationStatus.raw = gTokenInterface.station_list[dst.addr];
}
2024-05-01 14:09:03 +00:00
// Check if destination is online
2024-04-26 14:19:18 +00:00
if( (dst.addr == BROADCAST_ADDRESS) || (stationStatus.chat == 1)) {
2024-05-01 14:09:03 +00:00
// Allocate memory for message and check if allocation was successful
2024-04-25 12:59:15 +00:00
msg = osMemoryPoolAlloc(memPool, 0);
if(msg == NULL) {
printf("Memory allocation failed #1\r\n");
assert(false);
}
2024-05-01 14:09:03 +00:00
// Set message
2024-04-25 12:59:15 +00:00
msg[0] = src.raw;
msg[1] = dst.raw;
msg[2] = length;
2024-05-01 14:09:03 +00:00
// Copy message to memory
2024-04-25 12:59:15 +00:00
memcpy(&msg[3], queueMsg.anyPtr, length);
2024-05-01 14:09:03 +00:00
// Set status
2024-04-25 12:59:15 +00:00
status.checksum = Checksum(msg);
msg[3+length] = status.raw;
2024-04-24 13:25:06 +00:00
2024-05-01 14:09:03 +00:00
// Free memory
2024-04-25 12:59:15 +00:00
retCode = osMemoryPoolFree(memPool, queueMsg.anyPtr);
CheckRetCode(retCode, __LINE__, __FILE__, CONTINUE);
2024-04-24 18:54:35 +00:00
2024-05-01 14:09:03 +00:00
// Backup message if destination is chat station and isn't a broadcast message
2024-04-25 12:59:15 +00:00
if( (dst.addr != BROADCAST_ADDRESS) && (dst.sapi == CHAT_SAPI) ) {
lastSentMsgPtr = osMemoryPoolAlloc(memPool, 0);
if(lastSentMsgPtr == NULL) {
printf("Memory allocation failed #2\r\n");
assert(false);
}
memcpy(lastSentMsgPtr, msg, length+4);
}
2024-04-24 13:25:06 +00:00
2024-05-01 14:09:03 +00:00
// Send message to PHY
2024-04-25 12:59:15 +00:00
queueMsg.anyPtr = msg;
queueMsg.type = TO_PHY;
retCode = osMessageQueuePut(
queue_macData_id,
&queueMsg,
osPriorityNormal,
0);
CheckRetCode(retCode, __LINE__, __FILE__, CONTINUE);
2024-04-24 18:54:35 +00:00
} else {
2024-05-01 14:09:03 +00:00
// Destination is not online
2024-04-24 18:54:35 +00:00
strPtr = queueMsg.anyPtr;
sprintf(strPtr, "%d is not online\0", dst.addr+1);
queueMsg.type = MAC_ERROR;
queueMsg.addr = src.addr;
queueMsg.anyPtr = strPtr;
retCode = osMessageQueuePut(
queue_lcd_id,
&queueMsg,
osPriorityNormal,
0);
CheckRetCode(retCode, __LINE__, __FILE__, CONTINUE);
}
2024-04-15 14:26:40 +00:00
break;
2024-04-20 10:40:44 +00:00
}
2024-04-20 16:44:37 +00:00
//----------------------------------------------------------------------
// DEFAULT - TBD
//----------------------------------------------------------------------
2024-04-20 10:40:44 +00:00
default: {
2024-04-15 14:26:40 +00:00
break;
2024-04-20 10:40:44 +00:00
}
2024-04-15 14:26:40 +00:00
}
}
2024-04-10 17:17:57 +00:00
}