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

📄 igmpcon_main.c

📁 igmp for switch in vxworks
💻 C
📖 第 1 页 / 共 5 页
字号:

/************************************************************
  Copyright (C), 1988-2002, Fiberhome Tech. Co., Ltd.
  文件名: igmpcon_main.c
  作者:	aibin
  日期:	2006-12-19
  文件描述:    可控组播主函数,负责接收和处理
  				 可控组播私有协议报文
  版本:         // 版本信息
  
***********************************************************/

#include "igmpcon.h"
#define OK 0
#define MaxRecord 200			/*最大日志条数 */
#define MaxGroupStat 255		/*最大组统计条数 */
#define SAVE_CHECK  124			/*存储读取标志检查 */
#define MODULE_IGMPCON 1		/*可控组播模块号 */
#define defalut_igmp_port 1		/*iptv默认端口 */

MSG_Q_ID ConMsgQId = 0;
int ConTaskId;

#ifdef TEST
BOOL bConDebug = FALSE;
#else
BOOL bConDebug = FALSE;
#endif
BOOL bConDebugSnmp = FALSE;

BOOL gEnableCrossVlan = FALSE;	/*TRUE 表示跨VLAN ,可有多个组播VLAN, FALSE表示不跨VLAN,只能和单播共用一个VLAN */

SEM_ID semConinfo = 0;
SEM_ID semConauth = 0;
SEM_ID semConLog = 0;
SEM_ID semConStat = 0;
SEM_ID semBandwidth = 0;

UINT tConRecordTmer;			/*日志查询时间 */
UINT tConQueryTimer;			/*控制查询时间 */
UINT tStartUpQuery = 0;			/*启动时的查询 */
short gConOld = 300;

UINT MaxUpBandwidth;			/*上传带宽上限 */
UINT CurrentUpBandwidth;		/*当前总共上传带宽 */

USHORT Totaluser;				/*总用户数 */
USHORT Totalgroup;				/*总组播组数 */
USHORT Totalauthgroup;			/*配置的认证组个数 */
USHORT sendpktcount[MAX_DOWN_SLOT + 1];	/*发送指定槽位线卡控制包计数 */

UCHAR previewtime = 10;			/*预览持续时间 */
UCHAR previewinterval = 20;		/*预览间隔 */
UCHAR previewresettime = 24;	/*预览复位时间 */
UCHAR previewcount = 4;			/*预览次数 */
UCHAR previewTotalTime = 254;	/*总预览时间,min */

struct Group_auth *authlist = NULL;	/*认证表 */
struct Group_info *infolist = NULL;	/*当前信息表 */
struct Port_Record *recordlist = NULL;	/*日志表 */
struct Group_Stat *groupstatlist = NULL;	/*组用户统计表 */
struct Port_stat portstatlist[MAX_DOWN_SLOT + 1][MaxOnu + 1][MaxOnuPort + 1];	/*端口信息统计 */
struct Profile_Data profile[MaxTemp + 1];
struct igmp_onu onulist[MAX_DOWN_SLOT + 1][MaxOnu + 1];

USHORT groupstatcount;			/*组统计个数 */
USHORT recordcount;				/*日志的计数 */
UCHAR RecordHolding;			/*日志轮询时间 */
UCHAR RecordIgnore;				/*日志忽略时间 */
UCHAR aSlotType[MAX_DOWN_SLOT + 1];	/*线卡的类型 */

UINT semtakeerror;
BOOL bUpLinkPortEnable = TRUE;	/*上联口使能,为0不能级联 */
int gPortCfgResponse = 0;		/*端口信息查询响应 */
int gIGMPMODE = MODE_PROXY;

/*************************************************
  Function:       ProcessInfoMsg
  Description:   process an infor message
  Input:         	 msg
  Output:         无
  Return:         无
  Others:         // 其它说明
*************************************************/
extern int auto_upload_igmplog_flag;
int ProcessInfoMsg (ConMsg msg)
{
	if (msg.onu < 1 || msg.onuPort < 1 || msg.cmd > 1 || msg.state > leaveforce
		|| msg.preview < 1)
	{
		return ERROR;
	}

	/*防止线卡传来预览位为0的消息 */
	if (msg.preview == 0)
	{
		msg.preview = MEMBER_NORMAL;
	}

	/*加入的情况 */
	if (msg.cmd == 1)
	{
		if (processJoinMsg (msg) != OK)
		{
			return ERROR;
		}
	}

	/*离开的情况 */
	else
	{
		if (processLeaveMsg (msg) != OK)
		{
			return ERROR;
		}
	}

	/*记录日志 */
	AddRecord (msg);

	/*加入统计 ,只在离开时统计 */
	if (msg.cmd == 0)
	{
		AddStatistic (msg);
	}

	/*在日志自动上传使能时,如果日志达到最大数时自动上传 */
	if (auto_upload_igmplog_flag && recordcount >= MaxRecord)
	{
		upload_igmp_log ();
	}
	return OK;
}

int typedebug = 0;

/*************************************************
  Function:       processJoinMsg
  Description:   process a join message
  Input:         	 msg
  Output:         无
  Return:         正确返回0,错误返回-1
  Others:         // 其它说明
*************************************************/
int processJoinMsg (ConMsg msg)
{
	int prestat;
	int find, i, seek;

	int port;
	GroupInfo *ptmp;
	groupMember *pMember;
	GroupAuth *authgroup;

	/*if it's failed join, return ok */
	if (msg.state != 0)
	{
		return OK;
	}

	/*find such port in online group list, if exist,flush the oldtimer and return error, else continue */
	ptmp = (GroupInfo *) GetCurGroup (msg.group);
	if (ptmp && ptmp->member)
	{
		pMember = ptmp->member;
		while (pMember)
		{
			if (pMember->slot == msg.slot && pMember->onu == msg.onu &&
				pMember->onuPort == msg.onuPort)
			{
				pMember->old = 0;
				return ERROR;
			}
			pMember = pMember->pNext;
		}
	}

	/*check the port whether have right join the group */
	/*exceed the group limit of gsw? */
	if (NULL == ptmp && Totalgroup == MaxGroup)
	{
		msg.state = failmaxgroup;
		SendForceLeaveMsg (msg.slot, msg.onu, msg.onuPort, 0, msg.group);
		AddRecord (msg);
		return ERROR;
	}

	authgroup = (GroupAuth *) GetAuthGroup (msg.group);

	/*exceed the port bandwidth? */
	if (portstatlist[msg.slot][msg.onu][msg.onuPort].bandwidth)
	{
		if (authgroup && authgroup->bandwidth)
		{
			if (GetCurPortBd (msg.slot, msg.onu,
					msg.onuPort) + authgroup->bandwidth >
				portstatlist[msg.slot][msg.onu][msg.onuPort].bandwidth)
			{
				/*printf ("currb =%d, gband=%d, portband=%d\r\n", GetCurPortBd(msg.slot, msg.onu, msg.onuPort), authgroup->bandwidth, portstatlist[msg.slot][msg.onu][msg.onuPort].bandwidth ); */
				msg.state = failupbd;
				SendForceLeaveMsg (msg.slot, msg.onu, msg.onuPort, 0,
					msg.group);
				AddRecord (msg);
				return ERROR;
			}

		}

		/*if (authgroup && authgroup->bandwidth
		   && (portstatlist[msg.slot][msg.onu][msg.onuPort].curbd +
		   authgroup->bandwidth >
		   portstatlist[msg.slot][msg.onu][msg.onuPort].bandwidth))
		   {
		   printf ("currb =%d, gband=%d, portband=%d\r\n", portstatlist[msg.slot][msg.onu][msg.onuPort].curbd,authgroup->bandwidth, portstatlist[msg.slot][msg.onu][msg.onuPort].bandwidth );
		   msg.state = failupbd;
		   SendForceLeaveMsg (msg.slot, msg.onu, msg.onuPort, 0, msg.group);
		   AddRecord (msg);
		   return ERROR;
		   } */
	}

	/*exceed the group bandwidth? */
	if (NULL == ptmp && MaxUpBandwidth)
	{
		if (authgroup && authgroup->bandwidth &&
			(CurrentUpBandwidth + authgroup->bandwidth > MaxUpBandwidth))
		{
			msg.state = failupbd;
			SendForceLeaveMsg (msg.slot, msg.onu, msg.onuPort, 0, msg.group);
			AddRecord (msg);
			return ERROR;
		}
	}

/*****************************add such port to group********************************************/

	/*在线组不存在 */
	if (NULL == ptmp)
	{
		ptmp = (GroupInfo *) malloc (sizeof (GroupInfo));
		if (NULL == ptmp)
		{
			if (bConDebug)
			{
				printf ("malloc GroupInfo failed!\r\n");
			}
			return ERROR;
		}

		memset (ptmp, 0, sizeof (GroupInfo));
		ptmp->groupaddress = msg.group;
		ptmp->member = NULL;
		ptmp->pNext = NULL;
		ptmp->pPrv = NULL;
		ptmp->totaluser = 1;
		if (NULL == authgroup)
		{
			ptmp->auth = FALSE;
		}
		else
		{
			ptmp->auth = TRUE;
		}

		pMember = (groupMember *) malloc (sizeof (groupMember));
		if (NULL == pMember)
		{
			if (bConDebug)
			{
				printf ("malloc pMember failed!\r\n");
			}
			return ERROR;
		}
		memset (pMember, 0, sizeof (groupMember));
		pMember->slot = msg.slot;
		pMember->onu = msg.onu;
		pMember->onuPort = msg.onuPort;
		pMember->state = msg.preview;
		pMember->pNext = NULL;
		pMember->pPrv = NULL;
		pMember->onlinetime = 0;
		pMember->old = 0;

		ptmp->member = pMember;

		ptmp->pNext = infolist;
		if (NULL == infolist)
		{
			infolist = ptmp;
		}
		else
		{
			infolist->pPrv = ptmp;
			infolist = ptmp;
		}

		Totalgroup++;
		if (authgroup)
		{
			CurrentUpBandwidth += authgroup->bandwidth;
		}
	}

	/*在线组已经存在 */
	else
	{
		pMember = (groupMember *) malloc (sizeof (groupMember));
		if (NULL == pMember)
		{
			if (bConDebug)
			{
				printf ("malloc pMember failed!\r\n");
			}
			return ERROR;
		}
		memset (pMember, 0, sizeof (groupMember));
		pMember->slot = msg.slot;
		pMember->onu = msg.onu;
		pMember->onuPort = msg.onuPort;
		pMember->state = msg.preview;
		pMember->pNext = NULL;
		pMember->pPrv = NULL;
		pMember->onlinetime = 0;
		pMember->old = 0;

		pMember->pNext = ptmp->member;
		ptmp->member->pPrv = pMember;
		ptmp->member = pMember;
		ptmp->totaluser++;
	}

	if (authgroup)
	{
		portstatlist[msg.slot][msg.onu][msg.onuPort].curbd +=
			authgroup->bandwidth;
	}

	pMember = infolist->member;
	return OK;
}

void free1 (groupMember * member)
{
	if (member != NULL)
		free (member);
	return;
}

void free2 (groupMember * member)
{
	if (member != NULL)
		free (member);
	return;
}

void free3 (groupMember * member)
{
	if (member != NULL)
		free (member);
	return;
}

void free4 (groupMember * member)
{
	if (member != NULL)
		free (member);
	return;
}

/*************************************************
  Function:       processLeaveMsg
  Description:   process a leave message
  Input:         	 msg
  Output:         无
  Return:         正确返回0,错误返回-1
  Others:         // 其它说明
*************************************************/
int processLeaveMsg (ConMsg msg)
{
	int prestat;
	int find = 0, i, seek;
	int port;
	GroupInfo *ptmp, *groupdel;
	groupMember *pMember = NULL, *memdel, *pMember1;
	GroupAuth *authgroup;

	/*find such port in online group list, if dosn't exist, return ERROR, else break */
	ptmp = (GroupInfo *) GetCurGroup (msg.group);
	if (ptmp && ptmp->member)
	{
		pMember = ptmp->member;
		while (pMember)
		{
			if (pMember->slot == msg.slot && pMember->onu == msg.onu &&
				pMember->onuPort == msg.onuPort)
			{
				find = 1;
				break;
			}
			pMember = pMember->pNext;
		}
	}

	if (!find)
	{
		return ERROR;
	}

	pMember1 = infolist->member;
	if (typedebug)
		printf ("\r\ndelete find %x(%d:%d)\r\n", pMember, pMember->slot,
			pMember->onu);
	while (typedebug && pMember1)
	{
		printf ("---%x<-%x->%x(%d:%d)", pMember1->pPrv, pMember1,
			pMember1->pNext, pMember1->slot, pMember1->onu);
		pMember1 = pMember1->pNext;
	}

	/*del port from online group */
	memdel = pMember;
	authgroup = (GroupAuth *) GetAuthGroup (msg.group);

	if (authgroup)
		portstatlist[msg.slot][msg.onu][msg.onuPort].curbd -=
			authgroup->bandwidth;

	/*case single port */
	if (pMember->pPrv == NULL && NULL == pMember->pNext)
	{

		if (authgroup)
		{
			authgroup->active = FALSE;
		}
		taskLock ();
		delGroupFromOnlineList (ptmp);
		taskUnlock ();

	}
	/*case first */
	else if (pMember->pPrv == NULL && NULL != pMember->pNext)
	{
		ptmp->member = pMember->pNext;
		ptmp->member->pPrv = NULL;
		free2 (memdel);
		ptmp->totaluser--;
	}
	/*case last */
	else if (pMember->pPrv != NULL && NULL == pMember->pNext)
	{
		/*  printf ("lastr\n"); */
		pMember->pPrv->pNext = NULL;
		free3 (memdel);
		ptmp->totaluser--;
	}
	/*case middle */
	else
	{
		/*  printf ("middler\n"); */
		pMember->pPrv->pNext = pMember->pNext;
		pMember->pNext->pPrv = pMember->pPrv;
		free4 (memdel);
		ptmp->totaluser--;
	}
	return OK;
}

/*************************************************
  Function:       delGroupFromOnlineList
  Description:   del group node from online group list
  Input:         	 onlinegroup
  Output:         n/a
  Return:         n/a
  Others:         // 其它说明
*************************************************/
void delGroupFromOnlineList (GroupInfo * onlinegroup)
{
	GroupAuth *authgroup;

	authgroup = (GroupAuth *) GetAuthGroup (onlinegroup->groupaddress);

	if (onlinegroup->member)
	{
		free1 (onlinegroup->member);
	}

	Totalgroup--;
	if (authgroup)
	{
		if (CurrentUpBandwidth >= authgroup->bandwidth)
			CurrentUpBandwidth -= authgroup->bandwidth;
		else
			CurrentUpBandwidth = 0;
	}

	/*case single port */
	if (onlinegroup->pPrv == NULL && NULL == onlinegroup->pNext)
	{
		free (onlinegroup);
		infolist = NULL;
	}
	/*case first */
	else if (onlinegroup->pPrv == NULL && NULL != onlinegroup->pNext)
	{
		infolist = onlinegroup->pNext;
		infolist->pPrv = NULL;
		free (onlinegroup);
	}
	/*case last */
	else if (onlinegroup->pPrv != NULL && NULL == onlinegroup->pNext)
	{
		onlinegroup->pPrv->pNext = NULL;
		free (onlinegroup);
	}
	/*case middle */
	else
	{
		onlinegroup->pPrv->pNext = onlinegroup->pNext;
		onlinegroup->pNext->pPrv = onlinegroup->pPrv;
		free (onlinegroup);
	}
}

/*************************************************
  Function:       ProcessSlotChangeMsg
  Description:   process a slotchange message
  Input:         	 msg
  Output:         无
  Return:         无
  Others:         // 其它说明
*************************************************/
void ProcessSlotChangeMsg (ConMsg msg)
{
	int i;
	GroupInfo *ptmp;
	groupMember *pMember;
	int sem;

	ptmp = infolist;

	if (bConDebug)
	{
		if (msg.cmd == 0)
			printf ("\r\n processslotchagemsg: slot %d down\r\n", msg.slot);
		else
			printf ("\r\n processslotchagemsg: slot %d up\r\n", msg.slot);
	}

	/*线卡拔出 */
	if (msg.cmd == 0)
	{

		/*将该线卡上所有端口的信息清除 */
		while (ptmp)
		{
			pMember = ptmp->member;
			while (pMember)
			{
				if (pMember->slot == msg.slot)
				{
					SendIgmpPktbyCmd (23, ptmp->groupaddress, 0x11111, msg.slot,
						1);
					pMember->old = 1;
				}
				pMember = pMember->pNext;
			}
			ptmp = ptmp->pNext;
		}
	}

	/*线卡被插上的情况 */
	else
	{
		SendCfg2Slot (msg.slot);
	}
	return;
}

/*************************************************
  Function:       sendInfoMsgbyCmd
  Description:   send an info msg by cmd
  Input:         	 
  Output:         无
  Return:         success return 0, else return -1
  Others:         // 其它说明
*************************************************/

⌨️ 快捷键说明

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