📄 tskprot.c
字号:
//Protocol process tasks.
//The transmission stack work like this:
//The lowest layer----tskDEBUG, function:packet/depacket and check ACK frame out
//The second layer----tskRxProtocol & tskTxProtocol
// function: segment and reasamble MCNM data blocks, and deal with
// such operations like retransmission, timeout, resync, etc
//The highest layer---tskMCNM
// function: save parameters according to bitmap in received data block
// and answer with the polled domain
//This file containing tskTxProtocol and tskRxProtocol
#include "includes.h"
extern OS_EVENT *rom peventTxProtocol;
extern OS_EVENT *rom peventRxProtocol;
extern OS_EVENT *rom peventMCNM;
extern OS_EVENT *rom peventDEBUG;
extern OS_EVENT *rom peventWICCmd;
extern OS_EVENT *rom peventTimer;
extern OS_MEM *pMemSml;
extern OS_MEM *pMemLge;
extern OS_MEM *pMemHug;
extern unsigned char DebugContent[48];
extern rom unsigned char *DebugReadAddr;
#define PROT_TIME_OUT_ID 0x0001
#define LONG_TIMEOUT 50 //unit:second
#define SHORT_TIMEOUT 10 //unit:second
#define MAX_TX_FRAME_LEN 138
#define MAX_RX_FRAME_LEN 256
//Service type word in frame
#define FT_PAYPHONE 0x04
#define FT_SYS 0x00
//Subtype
#define FC_DATA 0x00
#define FC_ACK 0x01
#define FC_MON 0x02
#define BIT_SYN 0b01000000
#define BIT_TOBECONTINUE 0b10000000
//link status
#define LS_IDLE 0 //idle state
#define LS_WAITANS 1 //waiting answer
#define LS_WAITFOLLOW 2 //waiting following frames
extern void Func_Clear_Msg(INT8U rom * pMsg);
INT8U TestNR(INT8U rom *ptrF);
INT8U TestNT(INT8U rom *ptrF);
INT8U TestACK(INT8U rom *ptrF);
INT8U TestToBeContinue(INT8U rom *ptrF);
INT8U Data_Rx_Proc(INT8U rom * ptrF, INT8U port);
void Data_Tx_Proc(INT8U rom * ptrF, INT16U Len, INT8U port);
void SendACK(INT8U port);
void SendFrame(INT8U rom * ptrD, INT16U len, INT8U port, INT8U option);
#pragma romdata EXTRAM
INT8U rom CurNT;
INT8U rom CurNR;
INT8U rom ActivePort;
INT8U rom * rom ptrRxBuf;
INT8U rom * rom ptrRxBufBase;
OS_MEM * rom ptrRxBufMem;
INT16U rom CurTimeOut;
INT8U rom Syn_Needed;
#pragma code MYCODE
void tskRxProtocol(void * data){
void rom * pMsg;
INT8U err;
INT8U rom * pSml;
CurNT = 0;
CurNR = 0;
ActivePort = PT_NONE;
CurTimeOut = LONG_TIMEOUT;
ptrRxBuf = NULL_PTR;
ptrRxBufBase = NULL_PTR;
for(;;){
pMsg = OSQPend(peventRxProtocol, 0, &err); //Wait for the messages
if(err == OS_NO_ERR){
if((INT24U)pMsg >= PTR_MAX){ //If is a direct message--just a value
switch ((INT24U)pMsg){
}
}
else{ //If it's a undirect message--a pointer
switch (((MSG_HEAD *)pMsg)->Msg_ID){
case MSG_PROT_RECEIVE:
if(((MSG_HEAD *)pMsg)->Origin == peventDEBUG){
ActivePort = PT_HDLC;
CurTimeOut = SHORT_TIMEOUT;
}
else{
ActivePort = PT_SM;
CurTimeOut = LONG_TIMEOUT;
}
if(Data_Rx_Proc(((MSG_HEAD *)pMsg)->pMem,ActivePort) == 1){
//open or clear the timer
pSml=OSMemGet(pMemSml,&err);
if(err == OS_NO_ERR){
((MSG_HEAD *)pSml)->Msg_ID=MSG_TIMER_START;
((MSG_HEAD *)pSml)->Origin=peventRxProtocol;
((MSG_HEAD *)pSml)->pmemME=pMemSml;
((MSG_HEAD *)pSml)->Attached=FALSE;
((MSG_HEAD *)pSml)->LenOfBody=4;
((TIMER_MESSAGE *)pSml)->TID=PROT_TIME_OUT_ID;
((TIMER_MESSAGE *)pSml)->Val=OS_TICKS_PER_SEC * CurTimeOut;
OSQPost(peventTimer,pSml);
}
}
break;
case MSG_TIMER_EXPIRE:
if(ptrRxBufBase != NULL_PTR){//if a rx buffer has been applied
OSMemPut(ptrRxBufMem, ptrRxBufBase);
ptrRxBufBase = NULL_PTR;
}
break;
}
Func_Clear_Msg(pMsg);
//if(((MSG_HEAD *)pMsg)->Attached == TRUE){
// OSMemPut(((MSG_HEAD *)pMsg)->pmemATT, ((MSG_HEAD *)pMsg)->pMem);
//}
//OSMemPut(((MSG_HEAD *)pMsg)->pmemME, pMsg);
}
}
}
}
//if return "0" means current data block is completed, "1" means further frames expected
INT8U Data_Rx_Proc(INT8U rom * ptrF, INT8U port){
INT8U Type, SubType, SubNet;
INT8U Temp,err;
INT16U i;
OS_MEM * pSml;
Temp = TestNR(ptrF);
if(Temp == 2){//do not match
//if a frame with error NT(not agree with CurNR), current and former frames shall be discarded
if(ptrRxBufBase != NULL_PTR){
OSMemPut(ptrRxBufMem, ptrRxBufBase);
ptrRxBufBase = NULL_PTR;
return(0);
}
}
else if(Temp == 1){//resync needed
if(ptrRxBufBase != NULL_PTR){
ptrRxBuf = ptrRxBufBase;//clear the buffer
}
}
if(TestNT(ptrF)== FALSE) Syn_Needed = TRUE; //if the NR in information frame does not agree with local NT,
//resynchronization is needed
//if it's a correct frame
if(TestToBeContinue(ptrF)==TRUE){
if(ptrRxBufBase == NULL_PTR){
ptrRxBuf=OSMemGet(pMemHug,&err);
if(err != OS_NO_ERR) return(0);
ptrRxBufBase = ptrRxBuf;
ptrRxBufMem = pMemHug;
}
Temp = *ptrF; //the length fo frame
ptrF +=5;
for(i=0; i<Temp-5; i++){
*ptrRxBuf = *ptrF;
ptrRxBuf++;
ptrF++;
}
SendACK(port);//no wait here
return (1);
}
else{
if(ptrRxBufBase == NULL_PTR){
ptrRxBuf=OSMemGet(pMemLge,&err);
if(err != OS_NO_ERR) return(0);
ptrRxBufBase = ptrRxBuf;
ptrRxBufMem = pMemLge;
}
Temp = *ptrF;
ptrF +=3;
Type = *ptrF & 0x07;
SubType = (*ptrF & 0xf0)>>4;
ptrF++;
SubNet = *ptrF;
ptrF++;
for(i=0; i<Temp-5; i++){
*ptrRxBuf = *ptrF;
//DebugContent[i] = *ptrF;
ptrRxBuf++;
ptrF++;
}
DebugReadAddr = ptrRxBuf;
pSml = OSMemGet(pMemSml,&err);
if(err == OS_NO_ERR){
((MSG_HEAD *)pSml)->Msg_ID = MSG_MCNM_RECEIVE;
((MSG_HEAD *)pSml)->Origin = peventRxProtocol;
((MSG_HEAD *)pSml)->pmemME = pMemSml;
((MSG_HEAD *)pSml)->Attached = TRUE;
((MSG_HEAD *)pSml)->LenOfAttach = (INT16U)(((INT24U)ptrRxBuf) - ((INT24U)ptrRxBufBase));
((MSG_HEAD *)pSml)->pMem = ptrRxBufBase;
((MSG_HEAD *)pSml)->pmemATT = ptrRxBufMem;
((MSG_HEAD *)pSml)->LenOfBody = 3;
((MSG_PROTOCOL *)pSml)->Type = Type;
((MSG_PROTOCOL *)pSml)->SubType = SubType;
((MSG_PROTOCOL *)pSml)->SubNet = SubNet;
OSQPost(peventMCNM, pSml);
ptrRxBufBase = NULL_PTR; //mark that no mem. block is applied
//OSTimeDly(((MSG_HEAD *)pSml)->LenOfAttach /32+1);
//note: the worst situation is to write "len" bytes in MCNM, so cost about len/32 *10 ms
SendACK(port);
return(0);
}
}
}
void tskTxProtocol(void * data){
void rom * pMsg; //The pointer of message, it has to be a pointer point to the "rom: region
INT8U err; //Used to return the error value. It must be a variable in data region
for(;;){ //The main loop
pMsg = OSQPend(peventTxProtocol, 0, &err); //Wait for the messages
if(err == OS_NO_ERR){
if((INT24U)pMsg >= PTR_MAX){ //If is a direct message--just a value
switch ((INT24U)pMsg){
}
}
else{ //If it's a undirect message--a pointer
switch (((MSG_HEAD *)pMsg)->Msg_ID){
case MSG_MCNM_TRANSMIT:
if(ActivePort != PT_NONE){
Data_Tx_Proc(((MSG_HEAD *)pMsg)->pMem, ((MSG_HEAD *)pMsg)->LenOfAttach,ActivePort);
}
else{
OSQPost(peventMCNM, (OS_EVENT *)MSG_MCNM_TXNOPORT);
}
break;
case MSG_MCNM_SETPORT:
if(((MSG_PROTOCOL *)pMsg)->Port != ActivePort){
ActivePort = ((MSG_PROTOCOL *)pMsg)->Port;
if(ActivePort == PT_HDLC){
//to dialup or something
}
}
break;
}
Func_Clear_Msg(pMsg);
//if(((MSG_HEAD *)pMsg)->Attached == TRUE){
// OSMemPut(((MSG_HEAD *)pMsg)->pmemATT, ((MSG_HEAD *)pMsg)->pMem);
//}
//OSMemPut(((MSG_HEAD *)pMsg)->pmemME, pMsg);
}
}
}
}
//This level deal with frame
void Data_Tx_Proc(INT8U rom * ptrF, INT16U Len, INT8U port){
INT8U rom * pMsg;
INT8U err,SendEn;
//INT16U TimeOut;
INT8U Option,Err_Cnt;
//decide if the syn bit of NT byte shall be set
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -