⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cs.c

📁 包括EPA协议栈
💻 C
字号:
#include "list.h"
#include "tcpip.h"
#define CS_GLOBALS
#include "cs.h"
#undef CS_GLOBALS
#include "epa.h"
#include "ctimer.h"
#include <string.h>

#define CS_NO_NPKT          (0)

#define PTP_EVENT_PORT      (319)
#define PTP_GERNERAL_PORT   (320)
#define NODE_AMOUNT_ALL     (0x20)

static OS_STK    CSendStack[STACK_SIZE_CSEND];
static void*     CSendMsgQTbl[MSG_AMOUNT_CSEND];
static OS_EVENT* gpNodeSem;
static OS_MEM*   gpNodeMCB;

static Foo       gFooPool[NODE_AMOUNT_ALL];
static Foo       gPrdList;
static Foo       gNonPrdList;
static Foo       gGlbNonPrdList;
static uint8     gAnnedNPkt;

static void CSendTask(void* pdata);

/*-----------------------------------------------------------------------*
 *- Template of EndAnn pkt
 *----------------------------
 *- Destination MAC address(0) :               FF FF FF FF FF FF
 *- Source MAC address(6) :                    CD CD CD CD CD CD
 *- Frame type(12) :                           08 00
 *- Destination IP address(26) :               CD CD CD CD
 *- Source IP address(30) :                    CD CD CD CD
 *- Destination port(34) :                     88 BC
 *- Source port(36) :                          88 BC
 *- Annanciation Tag(42) :                     CD
 *- Priority(43) :                             CD
 *-----------------------------------------------------------------------*/
static uint8 gCSAnn[CSANN_LEN] = {
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 
	0xCD, 0xCD, 0xCD, 0xCD, 0xCD, 0xCD,
	0x08, 0x00,
	0x45, 0x00, 0x00, 0x4A, 0x04, 0x57, 0x00, 0x00, 0x20, 0x11,	0xED, 0x2F, 
	0xCD, 0xCD, 0xCD, 0xCD, 
	0xCD, 0xCD, 0xCD, 0xCD,
	0x88, 0xBC, 0x88, 0xBC, 0x00, 0x1A, 0x00, 0x00,
	0xCD,
	0xCD,
	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
	0x20, 0x20, 0x20, 0x20
};

__inline PFoo GetNode(void) {
	CpuSr sr;
	uint8 err;
	PFoo  pnode;

	SpinLock(sr);
	OSSemPend(gpNodeSem, 0, &err);
	pnode = (PFoo)OSMemGet(gpNodeMCB, &err);
	SpinUnLock(sr);
	return (pnode);
}

__inline void PutNode(PFoo pnode) {
	CpuSr sr;
	
	SpinLock(sr);
	OSSemPost(gpNodeSem);
	OSMemPut(gpNodeMCB, (void*)pnode);
	SpinUnLock(sr);
}

void CSInit(void) {
	uint8 err;

	gAtcPrdOff = 0;
	gNonPrdOff = 0;
	gMacroCyc = 0;
	LIST_INIT(gPrdList);
	LIST_INIT(gNonPrdList);
	LIST_INIT(gGlbNonPrdList);
	gpCSendMsgQ = OSQCreate(CSendMsgQTbl, MSG_AMOUNT_CSEND);
	OSTaskCreate(CSendTask, (void*)0, (void*)(&CSendStack[STACK_SIZE_CSEND]), TASK_PRIORITY_CSEND);
	gpNodeSem = OSSemCreate(NODE_AMOUNT_ALL);
	gpNodeMCB = OSMemCreate(gFooPool, NODE_AMOUNT_ALL, sizeof(Foo), &err);
}

void CSStart(PNetIF pni) {
	
	CSTimerStart();
	pni->output = CSend;
}

void CSStop(void) {
	CSTimerStop();
}

uint8 CSend(PSock psock) {
	CpuSr  sr;
	PNetIF pni;
	uint8  srvid, protocol;
	uint16 frmtype, dstport;
	uint32 tag;

	pni = psock->pni;
	n2h16(psock->payload + 12, &frmtype);
	if(frmtype == IP_TYPE){
		protocol = psock->payload[23];
		n2h16(psock->payload + 34, &dstport);
		if(protocol == UDP_PROTOCOL && dstport == EPA_PORT) {
			srvid = psock->payload[42];
			if(srvid == EVS_DISTRIBUTE) {
				tag = (0 | (pni->ip & ~pni->mask));
				Push(&gPrdList, &(psock->node), tag);
				return EPA_NO_ERR;
			}
			else if(srvid & EPA_SERVICEID_MASK <=  EES_ALTER_MONITOR &&
					srvid & EPA_SERVICEID_MASK >= EES_ACK_NOTI) {
					tag = ((1 << 24) | (pni->ip & ~pni->mask));
			}
			else {
				tag = ((2 << 24) | (pni->ip & ~pni->mask));
			}
		}
		else if(protocol == UDP_PROTOCOL 
			&& (dstport == PTP_EVENT_PORT || dstport == PTP_GERNERAL_PORT)) {
			tag = ((3 << 24) | (pni->ip & ~pni->mask));;
		}
		else {
			tag = ((4 << 24) | (pni->ip & ~pni->mask));;
		}
	}
	else {
		tag = ((1 << 24) | (pni->ip & ~pni->mask));;
	}		
	SpinLock(sr);
	InsertByTag(&gNonPrdList, &(psock->node), tag);
	SpinUnLock(sr);
	return SYS_NO_ERR;
}

void CSAnnInput(PSock psock, uint8 com_type, uint16 msg_id) {
	PFoo pnode;

	if(psock->payload[1] != 0xFF) {
		pnode = GetNode();
		InsertByTag(&gGlbNonPrdList, pnode, ((uint32)(psock->payload[1]) << 24) | (psock->src_ip & ~psock->pni->mask));
	}
	PutSock(psock);
}

void CSEndAnnInput(PSock psock, uint8 com_type, uint16 msg_id) {
	uint32 idx;
	PFoo   pnode;

	if(gCStatus == CS_NONPRDTIME) {
		if(gNonPrdList.tag > 0) {
			pnode = LIST_HEAD(gGlbNonPrdList);
			if(((pnode->tag) & ~psock->pni->mask) == (psock->src_ip & ~psock->pni->mask)) {
				PutNode(Pop(&gGlbNonPrdList));
			}
			else {
				idx = 0;
				do {
					if((pnode->tag & ~psock->pni->mask) == (psock->src_ip & ~psock->pni->mask)) {
						PutNode(DeleteAt(&gGlbNonPrdList, idx));
						break;
					}
					pnode = pnode->next;
					idx += 1;
				} while(idx < gGlbNonPrdList.tag);
			}
			if(psock->payload[1] != 0xFF) {
				pnode = GetNode();
				InsertByTag(&gGlbNonPrdList, pnode, ((uint32)(psock->payload[1]) << 24) | (psock->src_ip & ~psock->pni->mask));
			}
			if(gAnnedNPkt != CS_NO_NPKT) {
				while(gNonPrdList.tag > 0 && (gGlbNonPrdList.tag == 0 || LIST_HEAD(gNonPrdList)->tag < LIST_HEAD(gGlbNonPrdList)->tag)) {
					pnode = Pop(&gNonPrdList);
					LLOutput(LIST_ENTRY(pnode, Sock, node));
					PutNode(pnode);
				}
				if(gNonPrdList.tag > 0) {
					CSEndAnnOutput((uint8)(LIST_HEAD(gNonPrdList)->tag >> 24), psock->pni);
				}
				else {
					CSEndAnnOutput(0xFF, psock->pni);
				}
			}
		}
	}
	PutSock(psock);
}

void CSAnnOutput(uint8 prio, PNetIF pni) {
	PSock psock;

	psock = GetSock(PROTOCOL_ETHER, CSANN_LEN, 0, BCInetAddr(pni), pni);
	memcpy(psock->payload, gCSAnn, 60);
	memcpy(psock->payload + 6, pni->mac, 6);
	h2n32(pni->ip, psock->payload + 26);
	h2n32(BCInetAddr(pni), psock->payload + 30);
	psock->payload[42] = NPMA_TAG;
	psock->payload[43] = prio;
	psock->blank = 0;
	LLOutput(psock);
}

void CSEndAnnOutput(uint8 prio, PNetIF pni) {
	PSock psock;

	psock = GetSock(PROTOCOL_ETHER, CSANN_LEN, 0, BCInetAddr(pni), pni);
	memcpy(psock->payload, gCSAnn, 60);
	memcpy(psock->payload + 6, pni->mac, 6);
	h2n32(pni->ip, psock->payload + 26);
	h2n32(BCInetAddr(pni), psock->payload + 30);
	psock->payload[42] = ENPMA_TAG;
	psock->payload[43] = prio;
	psock->blank = 0;
	LLOutput(psock);
}

static void CSendTask(void* pdata) {
	uint8  err;
	PNetIF pni;
	PFoo   pnode;
	
	while(1) {
		pni = (PNetIF)OSQPend(gpCSendMsgQ, TASK_TIMEOUT_CSEND, &err);
		if(gCStatus & CS_CYCSTART) {
			while(gGlbNonPrdList.tag > 0) {
				PutNode(Pop(&gGlbNonPrdList));
			}
		}
		if(gCStatus & CS_ACTIVETIME) {
			while(gPrdList.tag) {
				pnode = Pop(&gPrdList);
				pni->output(LIST_ENTRY(pnode, Sock, node));
			}
			if(gNonPrdList.tag > 0) {
				CSAnnOutput((uint8)(LIST_HEAD(gNonPrdList)->tag >> 24), pni);
				gAnnedNPkt = gNonPrdList.tag;
			}
			else {
				CSAnnOutput(0xFF, pni);
				gAnnedNPkt = CS_NO_NPKT;
			}
		}
		else if((gCStatus == CS_NONPRDTIME) && (gNonPrdList.tag > 0) && (gAnnedNPkt != CS_NO_NPKT)) {
			while(gNonPrdList.tag > 0 && (gGlbNonPrdList.tag == 0 || LIST_HEAD(gNonPrdList)->tag < LIST_HEAD(gGlbNonPrdList)->tag)) {
				pnode = Pop(&gNonPrdList);
				LLOutput(LIST_ENTRY(pnode, Sock, node));
			}
			if(gNonPrdList.tag > 0) {
				CSEndAnnOutput((uint8)(LIST_HEAD(gNonPrdList)->tag >> 24), pni);
			}
			else {
				CSEndAnnOutput(0xFF, pni);
			}
		}
	}	// while(1)
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -