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

📄 igmpcon_main.c

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

		count++;
		total_count++;
		if (count == max_packet_group)
		{
			*phead = groupcfgmsg;
			*(phead + 1) = count;
			*(phead + 2) = pn;
			*(phead + 3) = total_count / max_packet_group;
			count = 0;
		}
		ptmp = ptmp->pNext;
	}

	if (count)
	{
		*phead = groupcfgmsg;
		*(phead + 1) = count;
		*(phead + 2) = pn;
		*(phead + 3) = pn;
		count = 0;
	}

	p = sendPkt;
	for (i = 1; i <= pn; i++)
	{
		count = *(unsigned char *) (p + 1);
		len = 4 + 16 * count;
		dm_send_igmp (islot, p, len);
		p = p + len;
	}
	free (sendPkt);
}

/*************************************************
  Function:       SendCfgPkt
  Description:   向线卡发送控制消息
  Input:            type:类型,slot:槽位号,port:端口号,当
  			  帧不指定特定端口时,port可用于命令
  			  例如crossvlanmsg. start 1:上电时的发包,0:非初始时发包
  Output:          
  Return:         正确返回0,失败返回-1
  Others:         
*************************************************/
int SendCfgPkt (UCHAR type, UCHAR slot, UCHAR onu, UCHAR onuPort, char start)
{
	UCHAR *p;
	USHORT gcount, count;
	UCHAR *sendPkt;
	Cfgen *cfgenPkt;
	GroupCfg *configPkt;
	GroupAuth *ptmp;
	int len = 0;
	int i;
	int tmpno;
	int size;

	switch (type)
	{
			/*发组配置使能帧 */
		case groupcfgmsg:
#ifdef _AN5116_06A_
			return send_groupcfgmsg_06a (slot);
#endif
			size = 16 * Totalauthgroup + 4;
			sendPkt = (char *) malloc (size);
			p = sendPkt;
			if (NULL == sendPkt)
			{
				if (bConDebug)
				{
					printf ("Error, Can't send a cfgEnable Packet!!\n");
				}
				return ERROR;
			}
			ptmp = authlist;
			*p = groupcfgmsg;
			p++;
			*p = Totalauthgroup;
			p = p + 3;
			while (ptmp)
			{
				*(UINT *) p = ptmp->groupaddress;
				p = p + 4;
				*p = ptmp->preCount;
				p = p + 1;
				*p = ptmp->preTime;
				p = p + 1;
				*p = ptmp->preInterval;
				p = p + 1;
				*p = ptmp->preReset;
				p = p + 1;
				*p = ptmp->pretotaltime;
				p = p + 4;
				*(USHORT *) p = ptmp->vlanid;
				p += 2;
				*(USHORT *) p = ptmp->bandwidth;
				p += 2;
				ptmp = ptmp->pNext;
			}
			len = size;
			break;

			/*发端口绑定组帧 */
		case port2groupmsg:
			tmpno = portstatlist[slot][onu][onuPort].tmpno;

			/*初次发配置不发配置为空的包 */
			if (!tmpno)
			{
				if (start)
				{
					return OK;
				}
				else
				{
					gcount = 0;
				}
			}

			gcount = 0;
			ptmp = authlist;
			while (ptmp)
			{
				if (ptmp->profile[tmpno])
				{
					gcount++;
				}
				ptmp = ptmp->pNext;
			}

			len = 4 + gcount * 8;
			sendPkt = (char *) malloc (len);
			p = sendPkt;
			if (NULL == sendPkt)
			{
				if (bConDebug)
				{
					printf ("Error, Can't send a cfgEnable Packet!!\n");
				}
				return ERROR;
			}
			*p = port2groupmsg;
			p++;
			*p = onu;
			p++;
			*p = onuPort;
			p++;
			*p = gcount;
			p++;

			if (tmpno != 0)
			{
				ptmp = authlist;
				while (ptmp && gcount)
				{
					if (ptmp->profile[tmpno])
					{
						*(UINT *) p = ptmp->groupaddress;
						p += 4;
						*p = ptmp->profile[tmpno];
						p += 4;
						gcount--;
					}
					ptmp = ptmp->pNext;

				}
			}
			else
			{
				len = 4;
			}
			break;

			/*发送端口配置帧 */
			/*初始发送的帧,如果参数均为缺省参数,则不发送 */
		case portcfgmsg:
			if (start && !portstatlist[slot][onu][onuPort].control &&
				!portstatlist[slot][onu][onuPort].bandwidth &&
				portstatlist[slot][onu][onuPort].gouplimit == 32 &&
				!portstatlist[slot][onu][onuPort].vlanpeer)
			{
				return OK;
			}

			len = 13;
			sendPkt = (UCHAR *) malloc (len);
			if (NULL == sendPkt)
			{
				if (bConDebug)
				{
					printf ("Error, Can't send a cfgEnable Packet!!\n");
				}
				return ERROR;
			}
			p = sendPkt;
			*p = portcfgmsg;
			p++;
			*p = onu;
			p++;
			*p = onuPort;
			p++;
			*p = portstatlist[slot][onu][onuPort].control;
			p++;
			*(UINT *) p = portstatlist[slot][onu][onuPort].bandwidth;
			p += 4;
			*(USHORT *) p = portstatlist[slot][onu][onuPort].gouplimit;
			p += 2;
			*p = portstatlist[slot][onu][onuPort].vlanpeer;
			p++;
			*p = portstatlist[slot][onu][onuPort].fast_leave_state;
			p++;
			len = p - sendPkt;
			break;

			/*发送跨VLAN帧,onu=1表示跨VLAN,port=0表示不跨 */
		case zcrossvlanmsg:
			{
				sendPkt = (UCHAR *) malloc (4);
				if (NULL == sendPkt)
					return ERROR;
				p = sendPkt;
				*p = zcrossvlanmsg;
				p++;
				*(USHORT *) p = global_vlan;
				p = p + 2;
				*p = (UCHAR) gEnableCrossVlan;
				len = 4;
			}
			break;

			/*发送快速离开帧 */
		case instantleavemsg:
			{
				sendPkt = (UCHAR *) malloc (4);
				if (NULL == sendPkt)
					return ERROR;
				p = sendPkt;
				*p = instantleavemsg;
				p++;
				*p = (UCHAR) bEnableInstantLeave;
				p++;
				len = 4;
			}
			break;

			/*发清理配置帧,onu代表清理id,0:组配置,1,端口配置 */
		case clearcfgmsg:
			sendPkt = (UCHAR *) malloc (4);
			if (NULL == sendPkt)
				return ERROR;

			p = sendPkt;
			*p = clearcfgmsg;
			p++;
			*p = onu;
			len = 4;
			break;

			/*用户配置查询帧 */
		case portcfgquerymsg:
			len = 4;
			sendPkt = (UCHAR *) malloc (len);
			if (NULL == sendPkt)
			{
				if (bConDebug)
				{
					printf ("Error, Can't send a cfgEnable Packet!!\n");
				}
				return ERROR;
			}
			p = sendPkt;
			*p = portcfgquerymsg;
			p++;
			*p = onu;
			p++;
			*p = onuPort;
			p++;
			break;
		case igmpmodemsg:
			len = 4;
			sendPkt = (char *) malloc (len);
			if (NULL == sendPkt)
				return ERROR;

			p = sendPkt;
			*p = igmpmodemsg;
			p++;
			*p = gIGMPMODE;
			p++;
			break;

		case igmpparametersmsg:
			len = 8;
			sendPkt = (char *) malloc (len);
			if (NULL == sendPkt)
				return ERROR;

			p = sendPkt;
			*p = igmpparametersmsg;
			p++;
			*p = ucRobustness;
			p++;
			*p = usQueryResponseInterval;
			p++;
			*p = usLastMemberQueryInterval;
			p++;
			*p = ucLastMemberQueryCount;
			p++;
			*p = usQueryInterval;
			p++;
			*(short *) p = usGroupMembershipInterval;
			p += 2;
			break;

		default:
			return ERROR;
	}

	if (len >= 4500)
	{
		printf ("\r\n Error!! Control Packet is too large to send \r\n");
		free (sendPkt);
		sendPkt = NULL;
		return ERROR;
	}

	if (contest == FALSE && SlotType (slot) == -1)
	{
		if (0)
		{
			printf ("It's not right slot, can't send control packets\r\n");
		}
		free (sendPkt);
		sendPkt = NULL;
		return ERROR;
	}

	dm_send_igmp (slot, (char *) sendPkt, len);
	free (sendPkt);
	sendPkt = NULL;
	return OK;
}

/*由外部模块调用,当有线卡变动时,调用此函数向消息列队发消息*/
void SendSlotChangeMsg (UCHAR slot, UCHAR slottype, UCHAR act)
{
	ConMsg msg;

	msg.type = Slothangemsg;
	msg.slot = slot;
	msg.cmd = act;

	/*return;  aibin for ec2 unsolved reboot error 20080111 */

	if (bConDebug)
		printf ("SendSlotChangeMsg slot:%d, act:%d\r\n", slot, act);

	msgQSend (ConMsgQId, (char *) &msg, sizeof (msg), NO_WAIT, MSG_PRI_NORMAL);
}

/*发送强迫下线帧, cmd=1,表示手动加入端口,留做今后功能升级用*/
int SendForceLeaveMsg (UCHAR slot, UCHAR onu, UCHAR onuPort, UCHAR cmd,
	UINT groupaddress)
{
	char *p;
	char *sendpkt;
	int len, i;
	GroupInfo *curgroup;

	sendpkt = (char *) malloc (8);
	if (NULL == sendpkt)
		return ERROR;

	p = sendpkt;
	*p = forceleavemsg;
	p++;
	*p = onu;
	p++;
	*p = onuPort;
	p++;
	*p = cmd;
	p++;
	*(UINT *) p = groupaddress;
	len = 8;

	if (bConDebug)
	{
		printf ("\n\rSend to Slot %d:\r\n", slot);
		typePkt (sendpkt, len);
	}

	/*发送该包,底层提供接口函数 */
	if (sendpktcount[slot] > 300)
	{
		taskDelay (20);
		sendpktcount[slot] = 0;
	}
	dm_MakeCmdPkt_IGMP (slot, 0x9001, (char *) sendpkt, len);
	sendpktcount[slot]++;
	free (sendpkt);
	sendpkt = NULL;
	return OK;

}

/*************************************************
  Function:       GetCurPortBd
  Description:   calculate port total current bandwidth
  Input:         	 char slot, UCHAR onu, char port
  Output:         无
  Return:         succes 0, error -1;
  Others:         // 其它说明
*************************************************/
int GetCurPortBd (char slot, UCHAR onu, char port)
{
	GroupInfo *ptmp;
	GroupAuth *pauth;
	groupMember *pMember;
	int bandwidth;
	int total;

	total = 0;
	ptmp = infolist;
	while (ptmp)
	{
		pMember = ptmp->member;
		while (pMember)
		{
			if (pMember->slot == slot && pMember->onu == onu &&
				pMember->onuPort == port)
			{
				pauth = (GroupAuth *) GetAuthGroup (ptmp->groupaddress);
				if (NULL == pauth)
				{
					bandwidth = 0;
				}
				else
				{
					bandwidth = pauth->bandwidth;
				}
				total = total + bandwidth;
				break;
			}
			pMember = pMember->pNext;
		}
		ptmp = ptmp->pNext;
	}
	return total;
}

/*************************************************
  Function:      AddRecord
  Description:  记录日志,用一个环形链表记录,当超过最大记录条数时,
  			删除最早的那条记录
  Input:         	msg
  Output:         无
  Return:         succes 0, error -1;
  Others:         // 其它说明
*************************************************/
int AddRecord (ConMsg msg)
{
	PortRecord *ptmp, *p;
	int semlog;
	UINT curtime;
	int count;

	/*printf ("%d:%d, act=%d, stat= %d, group=%x, preview=%d\r\n", msg.slot, port, act, state, groupaddress, preview); */

	/*重复的错误日志丢弃 */
	curtime = tickGet ();
	count = recordcount;
	ptmp = recordlist;
	while (count)
	{
		if (curtime - ptmp->ctime > 1000)
			break;

		if (ptmp && msg.slot == ptmp->slot && msg.onu == ptmp->onu &&
			msg.onuPort == ptmp->onuPort && msg.cmd == ptmp->cmd &&
			msg.state == ptmp->state && msg.group == ptmp->groupaddress &&
			msg.preview == ptmp->preview)
		{
			return ERROR;
		}
		ptmp = ptmp->pNext;
		count--;
	}

	semlog = semTake (semConLog, 1);
	if (ERROR == semlog)
	{
		printf ("Take semConLog error!\r\n");
		semtakeerror++;
		return ERROR;
	}
	/*已经到了日志条数的最大值 */
	if (recordcount == MaxRecord)
	{
		recordlist->pPrv->cmd = msg.cmd;
		recordlist->pPrv->state = msg.state;
		recordlist->pPrv->groupaddress = msg.group;
		recordlist->pPrv->slot = msg.slot;
		recordlist->pPrv->onu = msg.onu;
		recordlist->pPrv->onuPort = msg.onuPort;
		recordlist->pPrv->preview = msg.preview;
		recordlist->pPrv->staying = RecordHolding;
		getTime (recordlist->pPrv->time);
		recordlist->pPrv->ctime = tickGet ();
		recordlist = recordlist->pPrv;
		semGive (semConLog);
		return OK;
	}

	ptmp = (PortRecord *) malloc (sizeof (PortRecord));
	if (NULL == ptmp)
	{
		if (bConDebug)
		{
			printf ("Error!!, can't creat a record!\n");
		}
		semGive (semConLog);
		return ERROR;
	}
	ptmp->slot = msg.slot;
	ptmp->onu = msg.onu;
	ptmp->onuPort = msg.onuPort;
	ptmp->cmd = msg.cmd;
	ptmp->state = msg.state;
	if (msg.cmd == 2)
	{
		ptmp->staying = RecordHolding;
	}
	else
	{
		ptmp->staying = 0xffff;
	}
	ptmp->preview = msg.preview;
	ptmp->ctime = tickGet ();
	/*由底层提供接口函数 */
	getTime (ptmp->time);
	ptmp->groupaddress = msg.group;
	recordcount++;

	/*第一条记录 */
	if (recordcount == 1)
	{
		ptmp->pNext = NULL;
		ptmp->pPrv = NULL;
		recordlist = ptmp;
	}

	/*第二条记录 */
	if (recordcount == 2)
	{
		ptmp->pNext = recordlist;
		ptmp->pPrv = recordlist;
		recordlist->pNext = ptmp;
		recordlist->pPrv = ptmp;
		recordlist = ptmp;
	}

	/*第三条记录 */
	if (recordcount >= 3)
	{
		ptmp->pNext = recordlist;
		ptmp->pPrv = recordlist->pPrv;
		recordlist->pPrv->pNext = ptmp;
		recordlist->pPrv = ptmp;
		recordlist = ptmp;
	}
	semGive (semConLog);
	return OK;
}

/*************************************************
  Function:       UpRecordBuf
  Description:   传送日志的存储的缓冲区,返回值为缓冲的长度
  Input:         	 buf
  Output:          无
  Return:          success 0, error -1;
  Others:         // 其它说明
*************************************************/
int UpRecordBuf (char *buf)
{
	int len;
	int count;

⌨️ 快捷键说明

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