cmppapi.c

来自「用c/c++实现的一个CMPP API」· C语言 代码 · 共 2,167 行 · 第 1/5 页

C
2,167
字号
    *创建连接发送线程    *创建发送缓冲区    *创建MO、回执缓冲区    *创建sequence缓冲区    */    nRet = nInitAConnBufferAndThread( FD );    if( nRet != API_OK )    {        Trace( "Init Buffer And Thread Failed \n" );        nInitRet = nRet;        goto ERR_RETURN;    }        nMutexInit( &g_HConnDesc[FD].rMutex );    /*    *通过配置得到connect的包内容    */    nGetConnectDataByCfg( &g_HConnDesc[FD].rCfgPara,                          &rCmppConnect  );        /*    *登陆MTBS服务器    */    nRet = nLogin( FD, &rCmppConnect, &rCmppConnectResp, TRUE );    if( nRet != API_OK  )    {        vSetErrorDetail("Error when Login Server\n");        /*        *释放线程和内存资源        */        nExitInterface( FD );        nInitRet = nRet;        goto ERR_RETURN;            }    Trace( "Init Interface Login Success\n" );    if( rCmppConnectResp.unStatus != 0 )    {        vSetErrorDetail("Error: Connect Failed, status of response = [%d]\n",                             rCmppConnectResp.unStatus );        Trace( "Connect Failed, status of response = [%d]\n",                             rCmppConnectResp.unStatus );                                    /*        *释放线程和内存资源        */        nExitInterface( FD );        nInitRet = API_ERR_OTHER;        goto ERR_RETURN;          }    g_HConnDesc[FD].eLoginStatus  = Logined;    return API_OK;    ERR_RETURN:    g_HConnDesc[ FD ].nInitFlag = NO_INIT;    return nInitRet;            }/* *描述:(1) 连接MTBS服务器        (2) 创建连接接收线程        (3) 创建连接发送线程        (4) 创建接收缓冲区        (5) 创建发送缓冲区        (6) 创建MO、回执缓冲区 *输入:const char* sIniFile *输出:CONNFD* pCONNFD 连接句柄 *返回值:API_OK 成功          其它 失败 */int ASPAPI nInitInterface(                    const char* sIniFile,                    CONNFD* pCONNFD                   ){    int nRet ;    CONNFD FD;  // 连接句柄                Trace( "Call nInitInterface \n" );    if( sIniFile == NULL || pCONNFD == NULL )    {        vSetErrorDetail("Error: Invalid input parameter\n" );        return  API_ERR_INVALID;    }        /*    *查找空闲的连接资源    */    nRet = nSearchFreeConn( );    if( nRet == -1 ) // fail     {        vSetErrorDetail("Error: no free connection resource\n" );        return  API_ERR_OTHER;    }    Trace( "Success in find a free connection resource, is [%d]\n", nRet );    FD = nRet;        *pCONNFD = FD;            return nInitByFD( sIniFile, FD );       }                                      /* *描述:(1)释放API资源        (2)关闭同MTBS的连接  注意:系统退出时必须调用nExitInterface,释放线程资源 *输入:CONNFD connDesc 连接句柄 *输出:无 *返回值:API_OK 成功 *        其它 失败 */int ASPAPI nExitInterface( CONNFD connDesc ){    Trace( "call ExitInterface\n" );    if( API_OK != nValidConnFD( connDesc ) )    {        return API_ERR_INVALID;    }            /*    *退出线程    */    /*    *因为WINDOWS的CANCEL线程问题,    *用一个状态通知线程退出    */    g_HConnDesc[connDesc].bThreadExit = TRUE;    // 清零    vFreeConnFD( &g_HConnDesc[connDesc] );        /*    *因为WINDOWS的CANCEL线程问题,    *用一个状态通知线程退出    */    vAPIJointhread( &g_HConnDesc[connDesc].SendThreadHandle );    vAPIJointhread( &g_HConnDesc[connDesc].RecvThreadHandle );    g_HConnDesc[connDesc].bThreadExit = FALSE;        /*    *释放内存BUFFER    */    nLockRemoveQueue( &g_HConnDesc[connDesc].rSendBufFd );    nLockRemoveQueue( &g_HConnDesc[connDesc].rDeliverBufFd);    nLockRemoveMemHT( &g_HConnDesc[connDesc].rSeqBufFd );    /*    *释放互斥锁    */    nMutexDestroy( &g_HConnDesc[connDesc].rMutex );    /*    nRet = nAPICancelThread(  &g_HConnDesc[connDesc].SendThreadHandle );    if( nRet != THREAD_OK )    {        vSetErrorDetail( "error when cancel send thread\n" );    }    nRet = nAPICancelThread(  &g_HConnDesc[connDesc].RecvThreadHandle );    if( nRet != THREAD_OK )    {        vSetErrorDetail( "error when cancel send thread\n" );    }    */    return API_OK;}/**检查连接和LOGIN状态*/static  int nCheckSocketAndLogin( CONNFD FD ){    CONNFD connDesc  = FD;             /*    *判断连接状态    */    if( g_HConnDesc[ connDesc ].eSocketStatus != ConnectOpen )    {        vSetErrorDetail( "Error: Socket is closed\n" );        return    API_ERR_NETWORK;       }    if( g_HConnDesc[ connDesc ].eLoginStatus == ReLoginFail )    {        vSetErrorDetail( "Error: Reconnect server failed\n" );        return    API_ERR_NETWORK;       }        if( g_HConnDesc[ connDesc ].eLoginStatus != Logined )    {        vSetErrorDetail( "Error: No login server\n" );        return    API_ERR_OTHER;       }       return API_OK;    }/**sequence++*/static int nAddSequence( CONNFD FD ){    CONNFD connDesc  = FD;    int nSeq;       /*    *考虑多线程的安全问题    */    nMutexLock( &g_HConnDesc[ connDesc ].rMutex );    g_HConnDesc[ connDesc ].nSequence++;    if( g_HConnDesc[ connDesc ].nSequence >= MAXSEQUENCE )    {        g_HConnDesc[ connDesc ].nSequence = 0;       }    nSeq = g_HConnDesc[ connDesc ].nSequence;    nMutexUnlock( &g_HConnDesc[ connDesc ].rMutex );        return nSeq;}/**发送CMPPPCK,等待响应消息*/static int nSendCmppAndGetResp( CONNFD connDesc,                                 recCmppPck* prCmppPck,                                recCmppPck* prRespCmppPck,                                EBool       bSocket,                                int         nTimeOut                            ){    int nRet;    recCmppPck rCmppPck;    recEvent   rEvent;    recSeqCell rSeqCell;    int nSeq;        if( prCmppPck == NULL ||        prRespCmppPck == NULL )    {            return API_ERR_INVALID;    }    // init                memcpy( &rCmppPck, prCmppPck, sizeof( recCmppPck ) );    memset( &rSeqCell, 0, sizeof( recSeqCell ) );    /*    *生成等待事件    */    nRet = nInitEvent( &rEvent);    if( nRet != 0 )    {        vSetErrorDetail( "Error when init event\n" );        return API_ERR_OTHER;    }    rSeqCell.prEvent = &rEvent;    nSeq = rCmppPck.rHead.unSequenceId;     /*    *放入等待RESP HASH 表    */    nRet = nLockAddACell(   &(g_HConnDesc[ connDesc ].rSeqBufFd),                            (void*)&nSeq,                             sizeof( nSeq ),                             (void*)&rSeqCell,                             sizeof( recSeqCell ) );    if( nRet != SHMHT_OK )    {        if( nRet == SHMHT_NOSPACE )        {            vSetErrorDetail( "Error when add response table, no enough space\n" );        }        else        {            vSetErrorDetail( "Error when add response table\n" );        }        nDestroyEvent( &rEvent);        return API_ERR_OTHER;    }    //Trace( "add a Sequence[%d] in HT \n", nSeq );        if( bSocket == FALSE ) //通过写队列出去    {        /*        *写队列        */        printf("MyLink to Queue=%s\n",rCmppPck.body.rCmppSubmit.chLinkId);                nRet = nLockWriteQueue( &(g_HConnDesc[ connDesc ].rSendBufFd),                                 (void*)&rCmppPck, sizeof( recCmppPck) );        if( nRet != QUEUE_OK )        {            if( nRet == QUEUE_FULL )            {                vSetErrorDetail( "Error: send buffer is full\n" );                /*                *将seq 清除                */                nLockDelACell( &(g_HConnDesc[ connDesc ].rSeqBufFd),                            (void*)&nSeq,                            sizeof( nSeq ),                            (void*)&rSeqCell,                            sizeof( recSeqCell )                           );                }            else            {                   vSetErrorDetail( "Error: send buffer error\n" );                /*                *将seq 清除                */                nLockDelACell( &(g_HConnDesc[ connDesc ].rSeqBufFd),                            (void*)&nSeq,                            sizeof( nSeq ),                            (void*)&rSeqCell,                            sizeof( recSeqCell )                           );                }            nDestroyEvent( &rEvent);            return API_ERR_OTHER;        }                /** Added by YXJ (2003-12-18) ***/        vPrintCellNums( (void *) (g_HConnDesc[ connDesc ].rSendBufFd.pvBufPtr), 1 );        /*** End by YXJ ****/     }     else   // 通过写SOCKET出去     {        /*        *写SOCKET        */                nRet = nCmppSendSocket( g_HConnDesc[ connDesc ].nConnFd,                                 (void*)&rCmppPck );        if( nRet != API_OK )        {            vSetErrorDetail( "Error: Send a package to server error\n" );            /*            *将seq 清除            */            nLockDelACell( &(g_HConnDesc[ connDesc ].rSeqBufFd),                            (void*)&nSeq,                            sizeof( nSeq ),                            (void*)&rSeqCell,                            sizeof( recSeqCell )                           );            nDestroyEvent( &rEvent);            return API_ERR_PROTOCOL;        }     }            /*    *超时的等待事件    */    //Trace( "TimedWaitEvent, timeout [%d] second\n", MAC_TIMEOUT );    //Trace( " bef TimeWaitEvnet , rEvent = %x, bSended = %d",    //                           &rEvent, *rEvent.pbSended );                                   nRet = nTimedWaitEvent( &rEvent, nTimeOut );    if(  nRet == EVENT_TIMEOUT )    {         vSetErrorDetail( "Error: Timeout when wait for response\n" );         /*         *清除         */         nDestroyEvent( &rEvent);                  nLockDelACell( &(g_HConnDesc[ connDesc ].rSeqBufFd),                          (void*)&nSeq,                           sizeof( nSeq ),                           (void*)&rSeqCell,                           sizeof( recSeqCell )                          );                  return API_ERR_TIMEOUT;     }	if( nRet == EVENT_FAIL )	{	     vSetErrorDetail( "Error: Timeout when wait for response\n" );	     return API_ERR_TIMEOUT;	}    Trace( "Event be notified , seq = [%d]\n", nSeq );    /*    *通过SEQUENCE得到RESP的内容    */    nRet = nLockDelACell( &(g_HConnDesc[ connDesc ].rSeqBufFd),                          (void*)&nSeq,                           sizeof( nSeq ),                           (void*)&rSeqCell,                           sizeof( recSeqCell )                          );    if( nRet != SHMHT_OK )    {        vSetErrorDetail( "Error: can't found sequence in HT\n" );        nDestroyEvent( &rEvent);        return API_ERR_OTHER;    }    memcpy( prRespCmppPck, &rSeqCell.rCmppPck, sizeof( recCmppPck ) );    nDestroyEvent( &rEvent);    return API_OK;    }                            static  int nCmppSendSocket( int nSocket, recCmppPck* prCmppPck ){    int     nRet;    char    sSendBuffer[ sizeof( recCmppPck) +1 ];    int     nLen;        if( nSocket < 0 || prCmppPck == NULL )    {        Trace("nSocket < 0 || prCmppPck == NULL, nCmppSendSocket Return Error");        return API_ERR_INVALID;    }                             /*    Trace( "Ready to Send [%x] package to outside\n",             prCmppPck->rHead.unCommandId );            */    nRet = nCmppEncode( prCmppPck,                         sSendBuffer,                        &nLen );    if( nRet != 0 )    {        Trace("Encode Failed,  nRet = %d", nRet);        return API_ERR_OTHER;

⌨️ 快捷键说明

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