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

📄 transstates.c

📁 基于h323协议的软phone
💻 C
📖 第 1 页 / 共 5 页
字号:

                    /* check if the above message caused a startH245 facility message, if so send it */
                    if (!emaWasDeleted((EMAElement)session))
                        sendStartH245Facility(transGlobals, session);
                }
            }

            /* if we don't have yet an H.245 host (and also no remote address)
               create such a host and start a listen on it */
            if (!session->H245Connection)
            {
                TRANSERR err;
                cmTransportAddress h245LocalAddr;

                /* get a local address for the listenning host */
                h245LocalAddr.type = cmTransportTypeIP;
                h245LocalAddr.ip   = 0;
                getGoodAddress(transGlobals,
                               0,
                               session->Q931Connection,
                               cmTransH245Conn,
                               &h245LocalAddr);
                h245LocalAddr.port  = 0;

                /* this will allocate the H.245 host and allocate a listenning port */
                err = cmTransSetAddress((HSTRANSSESSION)session,
                                         &h245LocalAddr,
                                         NULL,
                                         NULL,
                                         NULL,
                                         cmTransH245Conn,
                                         RV_TRUE);
                if (err != cmTransOK)
                {
                    RvLogError(&transGlobals->hLog,
                        (&transGlobals->hLog, "determineIfToOpenH245 failed to create a H.245 host"));
                    return RV_FALSE;
                }
                else
                /* we have a new host, lock it */
                if (!emaLock((EMAElement)session->H245Connection))
                    return RV_FALSE;
            }

            /* If the host is still closed and we don't have a remote address,
               that means that we need to start a listenning process on it */
            if ( (session->H245Connection->state == hostIdle) &&
                 (session->H245Connection->remoteAddress.ip == 0) )
            {
                TRANSERR    reply = cmTransOK;

                /* Call the call back that we are about to start listenning */
                if (transGlobals->hostEventHandlers.cmEvTransHostListen)
                {
                    int         numOfLocks;
                    HATRANSHOST haTransHost =
                                 (HATRANSHOST)emaGetApplicationHandle(((EMAElement)session->H245Connection));

                    RvLogInfo(&transGlobals->hLog,
                        (&transGlobals->hLog, "cmEvTransHostListen(hsHost = %d(%x), haHost=%x, type=cmTransH245Conn, address = (ip:%x,port:%d))",
                            emaGetIndex((EMAElement)session->H245Connection),session->H245Connection,
                            haTransHost, session->H245Connection->localAddress.ip, session->H245Connection->localAddress.port));

                    numOfLocks = emaPrepareForCallback((EMAElement)session->H245Connection);
                    reply = transGlobals->hostEventHandlers.cmEvTransHostListen(
                                            (HSTRANSHOST)session->H245Connection,
                                            haTransHost,
                                            cmTransH245Conn,
                                            &session->H245Connection->localAddress);
                    emaReturnFromCallback((EMAElement)session->H245Connection, numOfLocks);
                    session->H245Connection->reported = RV_TRUE;
                }

                if (reply == cmTransOK)
                    /* actual listenning initiation */
                    session->H245Connection->h245Listen =
                            tpktOpen(transGlobals->tpktCntrl,
                                     &session->H245Connection->localAddress,
                                     RvH323ConnectionH245,
                                     tpktServer,
                                     transH245AcceptHandler,
                                     (void *)session->H245Connection);
                else
                    session->H245Connection->h245Listen = NULL;


                /* get the allocated full local address (IP and port) */
                getGoodAddress(transGlobals,
                               session->H245Connection->h245Listen,
                               session->Q931Connection,
                               cmTransH245Conn,
                               &session->H245Connection->localAddress);

                /* call the call back that listenning has initiated */
                if (transGlobals->hostEventHandlers.cmEvTransHostListening)
                {
                    int         numOfLocks;
                    HATRANSHOST haTransHost =
                                 (HATRANSHOST)emaGetApplicationHandle(((EMAElement)session->H245Connection));

                    RvLogInfo(&transGlobals->hLog,
                        (&transGlobals->hLog, "cmEvTransHostListening(hsHost = %d(%x), haHost=%x, type=cmTransH245Conn, address = (ip:%x,port:%d) error = %d)",
                            emaGetIndex((EMAElement)session->H245Connection),session->H245Connection,
                            haTransHost, session->H245Connection->localAddress.ip, session->H245Connection->localAddress.port,
                            (session->H245Connection->h245Listen == NULL)));

                    numOfLocks = emaPrepareForCallback((EMAElement)session->H245Connection);
                    transGlobals->hostEventHandlers.cmEvTransHostListening(
                                            (HSTRANSHOST)session->H245Connection,
                                            haTransHost,
                                            cmTransH245Conn,
                                            &session->H245Connection->localAddress,
                                            (session->H245Connection->h245Listen == NULL));
                    emaReturnFromCallback((EMAElement)session->H245Connection, numOfLocks);
                    session->H245Connection->reported = RV_TRUE;
                }

                /* in case of failure or user abortion report to log,
                   upon real error exit */
                if ( (!session->H245Connection->h245Listen) && (reply != cmTransIgnoreMessage) )
                {
                    RvLogError(&transGlobals->hLog,
                        (&transGlobals->hLog, "determineIfToOpenH245 failed to initiate listen on H.245 TPKT"));
                    emaUnlock((EMAElement)session->H245Connection);
                    return RV_FALSE;
                }
                else
                if (reply == cmTransIgnoreMessage)
                {
                    RvLogInfo(&transGlobals->hLog,
                        (&transGlobals->hLog, "determineIfToOpenH245 listen on H.245 TPKT refused by user"));
                }
                else
                {
                    /* mark that the h245 host is in listenning mode */
                    session->H245Connection->state = hostListenning;
                }
            }

            /* for listenning hosts we need to insert the address to the outgoing
               message so do it */
            if ( (session->H245Connection->state == hostListenning) ||
                 (session->H245Connection->state == hostListenningConnecting) )
            {
                __pvtBuildByFieldIds(addressNode,
                                     transGlobals->hPvt,
                                     messageBodyNode,
                                    {   _q931(h323_message_body)
                                        _anyField
                                        _q931(h245Address)
                                        LAST_TOKEN
                                    },
                                    0, NULL);

                res = -1;
                if (addressNode >= 0)
                    res = cmTAToVt(transGlobals->hPvt,
                                   addressNode,
                                   &session->H245Connection->localAddress);
                if (res < 0)
                {
                    /* if we can't transfer the address to the other side there
                       is no much use in leaving the poor connection listenning,
                       so kill it */
                    if (session->H245Connection->h245Listen)
                    {
                        tpktClose(session->H245Connection->h245Listen);
                        session->H245Connection->h245Listen = NULL;
                    }
                    RvLogError(&transGlobals->hLog,
                        (&transGlobals->hLog, "determineIfToOpenH245 failed on building h245Address"));
                    emaUnlock((EMAElement)session->H245Connection);
                    return RV_FALSE;
                }
            }
        }
        else
        /* this section is done for incoming messages */
        {
            int  addressNode = -1;
            RvBool ok = RV_FALSE;

            /* if we don't have the remote H245 address yet let's try and get one */
            if ( (!session->H245Connection) ||
                 ( (session->H245Connection) && (session->H245Connection->remoteAddress.ip == 0)) )
            {
                /* check if the incoming message has H245 address */
                __pvtGetNodeIdByFieldIds(addressNode,
                                         transGlobals->hPvt,
                                         messageBodyNode,
                                        {   _q931(h323_message_body)
                                            _anyField
                                            _q931(h245Address)
                                            LAST_TOKEN
                                        });

                /* if we got a remote address (or if it's a CONNECT message, which
                   means that we won't have another chance to get the address) try
                   to connect the H.245 to it */
                if ( (addressNode >= 0) || (msgType == cmQ931connect) )
                {
                    /* we have the remote address, do we have a H245 host at all? */
                    if (!session->H245Connection)
                    {
                        /* just create a non-listenning host */
                        res = createHostByType(transGlobals,
                                              (HSTRANSSESSION)session,
                                              (HSTRANSHOST *)&session->H245Connection,
                                              cmTransH245Conn,
                                              NULL,
                                              cmTransNoAnnexE);
                        if (res != cmTransOK)
                        {
                            RvLogError(&transGlobals->hLog,
                                (&transGlobals->hLog, "determineIfToOpenH245 failed on allocating host element"));
                            return RV_FALSE;
                        }
                        else
                        {
                            /* create h245 local host address */
                            cmTransportAddress h245LocalAddr;

                            h245LocalAddr.ip = 0;
                            h245LocalAddr.type = cmTransportTypeIP;
                            getGoodAddress(transGlobals,
                                           0,
                                           session->Q931Connection,
                                           cmTransH245Conn,
                                           &h245LocalAddr);
                            h245LocalAddr.port  = 0;

                            session->H245Connection->localAddress = h245LocalAddr;
                        }

                       /* this is a new host, lock it */
                       if (!emaLock((EMAElement)session->H245Connection))
                            return RV_FALSE;
                    }

                    /* Now we surly have a host, if we have a remote address,
                       put the address into the host */
                    if (addressNode >= 0)
                        cmVtToTA(transGlobals->hPvt,
                                 addressNode,
                                 &session->H245Connection->remoteAddress);

                    /* if we receive a start H.245 message while already listening, we should be careful not
                    to create an H.245 conflict. */
                    if (forceOpen && (session->H245Connection->h245Listen != NULL))
                    {
                        /* first see if the listening connection is an "old" one or an initiated one: */
                        if ((!session->openControlWasAsked) && (!session->switchToSeparateWasAsked))
                        {
                            /* connection was not initiated - this is an "old" listening connection.
                            close it, for the sake of interoperability */
                            tpktClose(session->H245Connection->h245Listen);
                            session->H245Connection->h245Listen = NULL;
                        }
                        else
                        {
                            /* this is an "initiated" listening connection, so there might be a conflict */
                            HOSTSTATE state = session->H245Connection->state;

                            /* see in advance who would win the H.245 conflict, and act acordingly */
                            session->H245Connection->state = hostListenningConnecting;
                            solveH245Conflict(session->H245Connection);
                            if (session->H245Connection->state == hostListenning)
                            {
                                /* abort connecting */
                                needToOpen = RV_FALSE;
                            }
                            else
                                session->H245Connection->state = state;
                        }
                    }

                    /* we have a new host and a remote address */
                    ok = RV_TRUE;
                }
                else
                    /* we didn't manage to get an address but it's not CONNECT yet so maybe in the next message*/
                    ok = RV_FALSE;
            }
            else
                /* we have a host & a remote address */
                ok = RV_TRUE;

            /* if we need to open an H.245 connection and can do it, just do it, except for setup, in which we
            delay until after ACF */
            if (needToOpen && ok && (msgType != cmQ931setup))
            {
                /* if we put a remote address into the host the connection will
                   happen, if we didn't, i.e. this is a CONNECT message and we don't
                   have a remote address yet, it will initiate a facility with startH245 */

⌨️ 快捷键说明

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