#include <stdio.h>
#include "mfifo.h"
+int Q921SendRR(L2TRUNK trunk, int Sapi, int cr, int Tei, int pf);
+
/*****************************************************************************
Function: Q921_InitTrunk
trunk->PrivateData21 = priv21;
trunk->PrivateData23 = priv23;
trunk->Q921HeaderSpace = hsize;
+ trunk->T200 = 0;
+ trunk->T203 = 0;
+ trunk->T200Timeout = 1000;
+ trunk->T203Timeout = 10000;
}
static int Q921Tx21Proc(L2TRUNK trunk, L2UCHAR *Msg, L2INT size)
return trunk->Q921Tx23Proc(trunk->PrivateData23, Msg, size);
}
+\r
+/*****************************************************************************\r
+\r
+ Function: Q921TimeTick\r
+\r
+ Description: Called periodically from an external source to allow the \r
+ stack to process and maintain it's own timers.\r
+\r
+ Return Value: none\r
+\r
+*****************************************************************************/\r
+L2ULONG (*Q921GetTimeProc) ()=NULL; /* callback for func reading time in ms */\r
+static L2ULONG tLast={0};\r
+\r
+L2ULONG Q921GetTime()\r
+{\r
+ L2ULONG tNow = 0;\r
+ if(Q921GetTimeProc != NULL)\r
+ {\r
+ tNow = Q921GetTimeProc();\r
+ if(tNow < tLast) /* wrapped */\r
+ {\r
+ /* TODO */\r
+ }\r
+ tLast = tNow;\r
+ }\r
+ return tNow;\r
+}\r
+\r
+void Q921T200TimerStart(L2TRUNK trunk)\r
+{\r
+ if (!trunk->T200) {\r
+ trunk->T200 = Q921GetTime() + trunk->T200Timeout;\r
+ }\r
+}\r
+\r
+void Q921T200TimerStop(L2TRUNK trunk)\r
+{\r
+ trunk->T200 = 0;\r
+}\r
+\r
+void Q921T200TimerReset(L2TRUNK trunk)\r
+{\r
+ Q921T200TimerStop(trunk);\r
+ Q921T200TimerStart(trunk);\r
+}\r
+
+void Q921T203TimerStart(L2TRUNK trunk)\r
+{\r
+ if (!trunk->T203) {\r
+ trunk->T203 = Q921GetTime() + trunk->T203Timeout;\r
+ }\r
+}\r
+\r
+void Q921T203TimerStop(L2TRUNK trunk)\r
+{\r
+ trunk->T203 = 0;\r
+}\r
+\r
+void Q921T203TimerReset(L2TRUNK trunk)\r
+{\r
+ Q921T203TimerStop(trunk);\r
+ Q921T203TimerStart(trunk);\r
+}\r
+\r
+void Q921T200TimerExpire(L2TRUNK trunk)\r
+{\r
+ (void)trunk;\r
+}\r
+\r
+void Q921T203TimerExpire(L2TRUNK trunk)\r
+{\r
+ Q921T203TimerReset(trunk);\r
+ Q921SendRR(trunk, trunk->sapi, trunk->NetUser == Q921_TE ? 0 : 1, trunk->tei, 1);\r
+}\r
+\r
+void Q921TimerTick(L2TRUNK trunk)\r
+{\r
+ L2ULONG tNow = Q921GetTime();\r
+ if (trunk->T200 && tNow > trunk->T200) {\r
+ Q921T200TimerExpire(trunk);\r
+ }\r
+ if (trunk->T203 && tNow > trunk->T203) {\r
+ Q921T203TimerExpire(trunk); \r
+ }\r
+}\r
+\r
+\r
+void Q921SetGetTimeCB(L2ULONG (*callback)())\r
+{\r
+ Q921GetTimeProc = callback;\r
+}\r
/*****************************************************************************
if(smes != NULL)
{
+ rs = size - trunk->Q921HeaderSpace;
+ mes = &smes[trunk->Q921HeaderSpace];
+
if ((mes[2] & 3) != 3) {
/* we have an S or I frame */
/* if nr is between va and vs, update our va counter */
}
}
- rs = size - trunk->Q921HeaderSpace;
- mes = &smes[trunk->Q921HeaderSpace];
-
/* check for I frame */
if((mes[2] & 0x01) == 0)
{
if(Q921Tx23Proc(trunk, smes, size-2) >= 0) /* -2 to clip away CRC */
{
if (vs == trunk->vs) {
- Q921SendRR(trunk, (mes[0]&0xfc)>>2, (mes[0]>>1)&0x01,mes[1]>>1, mes[3]&0x01);
+ Q921SendRR(trunk, (mes[0]&0xfc)>>2, (mes[0]>>1)&0x01, mes[1]>>1, mes[3]&0x01);
}
}
else
/* todo: we probably should schedule to send RR at timeout here */
/* todo: check if RR is responce to I */
- Q921SendRR(trunk, (mes[0]&0xfc)>>2, (mes[0]>>1)&0x01,mes[1]>>1, mes[2]&0x01);
+ Q921T203TimerStart(trunk);
}
/* check for RNR */