📄 igmpcon_main.c
字号:
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 + -