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 + -
显示快捷键?