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

📄 iannerw.c

📁 基于h323协议的软phone
💻 C
📖 第 1 页 / 共 4 页
字号:
            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 + -