📄 iannerw.c
字号:
RV_FALSE,
fSendNow
);
}
void
send_nack5(tNode* pNode,RvUint32 seqn, int oid_length, RvUint8* poid, RvBool fSendNow) {
/* send NACK REASON_5:"ObjectID-payload not supported!" */
IAnnexET00NAckHeader header[sizeof_IAnnexET00NAckHeader];
IAnnexENAckReason reason[sizeof_IAnnexENAckReason_ND];
RvLogInfo(&pNode->pAnnexE->log,
(&pNode->pAnnexE->log, "Send NAck5(ObjectID-payload not supported, SEQN=%i) to Host(%08x:%i)",
seqn, pNode->RemoteHost.nIP, pNode->RemoteHost.nPort));
header[IAnnexET00NAckHeader_Header+IAnnexET00Header_PFLAGS] = 0;
/*
header.Header.T = 0;
header.Header.A = 0;
header.Header.S = 0;
header.Header.RES = 0;
*/
header[IAnnexET00NAckHeader_Header+IAnnexET00Header_TRANSPORT_TYPE] = AEPT00_NAck;
hton16(1, &header[IAnnexET00NAckHeader_NACK_COUNT]);
hton24(seqn, &reason[IAnnexENAckReason_SEQNUM]);
reason[IAnnexENAckReason_DATA_LENGTH] = (RvUint8)(oid_length & 0xff);
hton16(5, &reason[IAnnexENAckReason_REASON]);
send_payload(
pNode,
header,
sizeof_IAnnexET00NAckHeader,
reason,
sizeof_IAnnexENAckReason_ND,
poid,
oid_length,
RV_FALSE,
RV_FALSE,
fSendNow
);
}
void
send_nack6(tNode* pNode, RvUint32 seqn, int nPayload, RvBool fSendNow) {
/* send NACK REASON_6:"Payload Corrupted" */
IAnnexET00NAckHeader header[sizeof_IAnnexET00NAckHeader];
IAnnexENAckReason6 reason[sizeof_IAnnexENAckReason6];
RvLogInfo(&pNode->pAnnexE->log,
(&pNode->pAnnexE->log, "Send NAck6(Payload corrupted, Id=%i, SEQN=%i) to Host(%08x:%i)", nPayload,
seqn, pNode->RemoteHost.nIP, pNode->RemoteHost.nPort));
header[IAnnexET00NAckHeader_Header+IAnnexET00Header_PFLAGS] = 0;
/*
header.Header.T = 0;
header.Header.A = 0;
header.Header.S = 0;
header.Header.RES = 0;
*/
header[IAnnexET00NAckHeader_Header+IAnnexET00Header_TRANSPORT_TYPE] = AEPT00_NAck;
hton16(1, &header[IAnnexET00NAckHeader_NACK_COUNT]);
hton24(seqn, &reason[IAnnexENAckReason6_SEQNUM]);
reason[IAnnexENAckReason6_DATA_LENGTH] = 1;
hton16(6, &reason[IAnnexENAckReason6_REASON]);
reason[IAnnexENAckReason6_PAYLOAD_NUMBER] = (RvUint8)nPayload;
send_payload(
pNode,
header,
sizeof_IAnnexET00NAckHeader,
reason,
sizeof_IAnnexENAckReason6,
NULL,
0,
RV_FALSE,
RV_FALSE,
fSendNow
);
}
void
ack_received(tNode* pNode) {
tPDU* pPDU = pNode->pWaitingForAckPDU;
pNode->pWaitingForAckPDU = NULL;
/* notify user that the node is no longer waiting for ack */
if (pNode->pAnnexE->events.AnnexEEvWriteable != NULL) {
pNode->nRef++; /* protect node */
pNode->pAnnexE->events.AnnexEEvWriteable(
AsHANNEXE(pNode->pAnnexE),
pNode->pAnnexE->hAppAnnexE,
pNode->RemoteHost.nIP,
pNode->RemoteHost.nPort
);
if (pNode->nRef == 1) {
del_node(pNode);
}
pNode->nRef--; /* unprotect node */
}
/* start IMA timer */
pNode->nRetry = 0;
start_retransmit_or_ima_timer(pNode);
/* free PDU! */
free_pdu(pNode->pAnnexE, pPDU);
}
#define MoveToNextPayload(payload, payload_size) \
((IAnnexEPayloadHeader*)(((RvUint8*)(payload)) + (payload_size)))
#define MoveToNextReason(reason, reason_size) \
((IAnnexENAckReason*)(((RvUint8*)(reason)) + (reason_size)))
void process_pdu(IN tNode* pNode, IN tpPDU pPDU)
{
IAnnexEPayloadHeader* pPayload;
RvBool fError = RV_FALSE;
int nCurPayload = 0;
int nBytesAvail = pPDU->nSize;
int i, cnt, nSz;
RvBool fResendForced = RV_FALSE;
RvUint32 seqn;
remote_host_is_alive(pNode);
seqn = ntoh24(&pPDU->PDU[IAnnexEHeader_SEQN]);
/* Check for duplicated PDU's. That check is posible only for PDU's with set A-flag!*/
if (AEHGet_A(pPDU->PDU) != 0)
{
if (is_old_seqn(seqn, pNode->nLast_Ack_SEQ))
{
/* duplicate!
An Ack is sent immediately in order to unblock remote annexe module */
RvLogInfo(&pNode->pAnnexE->log, (&pNode->pAnnexE->log, "Duplicate PDU received! send Ack immediately."));
send_ack(pNode, seqn, RV_TRUE);
return;
}
if (check_pdu(pNode, pPDU))
{
pNode->nLast_Ack_SEQ = seqn;
if (pNode->pWaitingForAckPDU != NULL)
send_ack(pNode, seqn, RV_TRUE);
else
send_ack(pNode, seqn, RV_FALSE);
}
}
/* get first payload! */
if (AEHGet_L(pPDU->PDU) != 0)
{
/* this is valid only for Annex E over TCP, but it is possible that
the host implementation of Annex E to not understand it.*/
pPayload = (IAnnexEPayloadHeader*)(&pPDU->PDU[4 + 4]);
}
else
{
pPayload = (IAnnexEPayloadHeader*)(&pPDU->PDU[4]);
nBytesAvail -= 4;
}
/* a cycle to walk through all payloads in the PDU */
while ((void*)pPayload < (void*)(&pPDU->PDU[pPDU->nSize]))
{
switch (AEPGet_T(*pPayload))
{
case AEPT_TransportMessage: {
/***************************************************************/
/* T == 00 * Annex E Transport Messages */
/***************************************************************/
IAnnexET00Header* pTrPayload = (IAnnexET00Header*)(pPayload);
/* check 'Source/Dest' and 'Session' flags in payload header */
if ((AEPGet_A(*pPayload) != 0) || (AEPGet_S(*pPayload) != 0))
{
/* this is not a valid Annex E Transport message!
send NACK REASON_6:"Payload Corrupted" */
send_nack6(pNode, seqn, nCurPayload, RV_TRUE);
/* break the processing of the rest payloads as there is no
guarantee that the size of packet may be found correctly. */
fError = RV_TRUE;
break;
}
switch (pTrPayload[IAnnexET00Header_TRANSPORT_TYPE])
{
case AEPT00_IAmAlive:
/* check size of payload! */
nSz = sizeof_IAmAlive(pTrPayload);
nBytesAvail -= nSz;
if (nBytesAvail < 0) {
/* incorrect payload size! payload corrupted! */
send_nack6(pNode, seqn, nCurPayload, RV_TRUE);
fError = RV_TRUE;
break;
}
if (IMAGet_P(AsIAmAlive(pTrPayload)))
{
/* I_Am_Alive message from remote AnnexE module, return
the same payload, with 'P' flag cleared!*/
i_am_alive_request_received(pNode, AsIAmAlive(pTrPayload));
}
else
{
/* answer to our I-Am-Alive payload! */
i_am_alive_response_received(pNode, AsIAmAlive(pTrPayload));
}
pPayload = MoveToNextPayload(pPayload, sizeof_IAmAlive(pTrPayload));
break;
case AEPT00_Ack:
/* check size of payload! */
nSz = sizeof_Ack(pTrPayload);
nBytesAvail -= nSz;
if (nBytesAvail < 0)
{
/* incorrect payload size! payload corrupted! */
send_nack6(pNode, seqn, nCurPayload, RV_TRUE);
fError = RV_TRUE;
break;
}
/* as the current implementation of Annex E fulfills only the
'Serial' model, we are interested only of ACK.SEQN equal to
that waiting for acknowledge.*/
if (pNode->pWaitingForAckPDU != NULL)
{
RvUint32 waiting_seqn = ntoh24(&pNode->pWaitingForAckPDU->PDU[IAnnexEHeader_SEQN]);
cnt = countof_AckData(pTrPayload);
for (i = 0; i < cnt; i++)
{
RvUint32 ack_seqn = ntoh24(&(AsAck(pTrPayload)[IAnnexET00Ack_ACK+
i*sizeof_IAnnexEAckData+
IAnnexEAckData_SEQNUM]));
if (ack_seqn == waiting_seqn)
{
ack_received(pNode);
break;
}
}
}
pPayload = MoveToNextPayload(pPayload, nSz);
break;
case AEPT00_NAck:
{
IAnnexENAckReason* pReason = AsNAckReason(GetNAckReasonPtr(pTrPayload));
/* check size of payload! */
nSz = sizeof_IAnnexET00NAckHeader;
nBytesAvail -= nSz;
if (nBytesAvail < 0)
{
/* incorrect payload size! payload corrupted! */
send_nack6(pNode, seqn, nCurPayload, RV_TRUE);
fError = RV_TRUE;
break;
}
cnt = countof_NAckReasons(pTrPayload);
for (i = 0; i < cnt; i++)
{
RvUint16 nReason;
RvUint32 reason_seqn;
/* check size of reason */
nSz = sizeof_NAckReason(pReason);
nBytesAvail -= nSz;
if (nBytesAvail < 0)
{
/* incorrect payload size! payload corrupted! */
send_nack6(pNode, seqn, nCurPayload, RV_TRUE);
fError = RV_TRUE;
break;
}
/* process pReason */
nReason = ntoh16(&pReason[IAnnexENAckReason_REASON]);
reason_seqn = ntoh24(&pReason[IAnnexENAckReason_SEQNUM]);
switch (nReason)
{
case 0:
/* NAck.REASON = Non-Standart Reason
not supported by this implementation of Annex E! Skipped!*/
break;
case 1:
/* NAck.REASON = Request the sender to use an alternate port
for the specified static payload type. That Nack is of
interest only if static type == 0 => (H.225) payload!*/
if (AsNAckReason1(pReason)[IAnnexENAckReason1_STATIC_TYPE] == 0)
{
use_alternate_port(pNode,
ntoh32(&AsNAckReason1(pReason)[IAnnexENAckReason1_ALTERNATE_IP]),
ntoh16(&AsNAckReason1(pReason)[IAnnexENAckReason1_ALTERNATE_PORT]));
}
break;
case 2:
/* NAck.REASON = Request the sender to use an alternate port
for the specified ObjectID payload type
not supported in that implementation of Annex E => it is not possible
for us to have sent such payload. Possible line error.
No reaction currently. It is possible that the next payload is
corrupted and the if the Nack is for the PDU with set A flag it
should be retransmitted.*/
break;
case 3:
/* NAck.REASON = Transport-payload not supported
Supporting only types to 3 including ('Restart Message'), their
implementation is necessary. Do not pay attention to that Nack!*/
break;
case 4:
/* NAck.REASON = Static-payload type not supported
the NAck is of interest only if it is a static type == 0 => (H.225) payload!*/
if (AsNAckReason4(pReason)[IAnnexENAckReason4_STATIC_TYPE] == 0)
{
static_type0_is_not_supported(pNode);
}
break;
case 5:
/* NAck.REASON = OID-payload not supported
Do not pay attention to that Nack!*/
break;
case 6:
/* NAck.REASON = Payload Corrupted
The NAck is of interest only if it is about a PDU waiting for pWaitingForAckPDU!*/
if (!fResendForced && (pNode->pWaitingForAckPDU != NULL) && (reason_seqn == ntoh24(&pNode->pWaitingForAckPDU->PDU[IAnnexEHeader_SEQN])))
{
fResendForced = RV_TRUE;
RvH323TimerCancel(pNode->pAnnexE->hTimers, &pNode->hResendAndIMATimer);
pNode->nRetry--;
retransmit_or_ima_timer_event(pNode);
}
default:
/* reserved for future use => skipped! */
break;
}
/* goto next reason */
pReason = MoveToNextReason(pReason, nSz);
}
pPayload = (IAnnexEPayloadHeader*)pReason;
}
break;
case AEPT00_Restart:
/* check size of payload! */
nSz = sizeof_IAnnexET00Restart;
nBytesAvail -= nSz;
if (nBytesAvail < 0)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -