PCRetCode ReaderRecvHead(PacketConnection* pPacketConnection, AMUInt8* pHead, AMInt32 headLen) { AMInt32 length = 0; memset(pHead, 0, headLen); //get byte stream from socket recv. length = pPacketConnection->pProtocolEngine->pPCContext->recv( pPacketConnection->pProtocolEngine->pPCCore->socketFd, pHead, headLen); if(length != headLen) { #ifdef AMOS_DEBUG AMPrintf("noble:recv head length error.\n"); #endif if(ReaderRecvExceptionHandler(pPacketConnection,headLen,length) == eContinue) return eContinue; else return eJumpWhile; } else { #ifdef AMOS_DEBUG AMPrintf("noble:recv head ok.\n"); #endif } return eOK; }
static AMInt32 _AMRunTask(_AMTaskMgr* _taskMgr, AMBool isUseThisThread) { if(_taskMgr == AMNULL) return -1; else { AMInt32 index = 0; _AMTask* task = AMNULL; _AMTask* nextRunTask = AMNULL; AMThreadMutexLock(&_taskMgr->mMutex); //find a unrun task. task = _taskMgr->mTasks; while(task != AMNULL) { if(task->mStatus == 0) { nextRunTask = task; break; } task = task->mNext; } if(nextRunTask != AMNULL && isUseThisThread == AMFALSE) { //find a empty thread. for(index = 0; index < _taskMgr->mConcurNum; index++) { if(_taskMgr->mThreadsFlag[index] == 1) { AMThreadWait(_taskMgr->mThreads[index], AMNULL); _taskMgr->mThreads[index] = AMNULL; _taskMgr->mThreadsFlag[index] = 0; } if(_taskMgr->mThreadsFlag[index] == 0) { nextRunTask->mStatus = 1; _taskMgr->mThreadsFlag[index] = 2; nextRunTask->mThreadIndex = index; AMPrintf("Create Thread\n"); AMThreadCreate(&_taskMgr->mThreads[index], AMNULL, _AMRunTaskThreadRun, nextRunTask); break; } } } else if(nextRunTask != AMNULL && isUseThisThread == AMTRUE) { nextRunTask->mStatus = 1; AMThreadMutexUnlock(&_taskMgr->mMutex); AMPrintf("Re use Thread\n"); task->mProc(task->mProcArg); AMThreadMutexLock(&_taskMgr->mMutex); task->mStatus = 2; AMThreadMutexUnlock(&_taskMgr->mMutex); AMTaskMgrRemove((AMTaskMgr*)_taskMgr, (AMTask*)task); return 1; } AMThreadMutexUnlock(&_taskMgr->mMutex); return 0; } }
void PCCoreStop(struct ST_ProtocolEngine* pProtocolEngine) { pProtocolEngine->pPCCore->coreStatus = eIMnetCoreStop; #ifdef AMOS_DEBUG AMPrintf("noble:PCCoreStop <<<<< reader\n"); #endif //close looper. LoopStop(pProtocolEngine->pPCCore->pReaderQueue, &pProtocolEngine->pPCCore->pReaderLooper->semaphore); #ifdef AMOS_DEBUG AMPrintf("noble:PCCoreStop <<<<< sender\n"); #endif LoopStop(pProtocolEngine->pPCCore->pSenderQueue, &pProtocolEngine->pPCCore->pSenderLooper->semaphore); #ifdef AMOS_DEBUG AMPrintf("noble:PCCoreStop <<<<< callback\n"); #endif LoopStop(pProtocolEngine->pPCCore->pCallbackQueue, &pProtocolEngine->pPCCore->pCallbackLooper->semaphore); #ifdef AMOS_DEBUG AMPrintf("noble:PCCoreStop <<<<< quit\n"); #endif }
PCRetCode ReaderRecvBody(PacketConnection* pPacketConnection, AMUInt8* pHead, AMUInt8** ppBodyBuffer, AMInt32* pBodyLength) { AMInt32 length = 0; #ifdef AMOS_DEBUG AMPrintf("noble:ReaderRecvBody <<<<.\n"); #endif *pBodyLength = getIntValue(pHead, 12); if(*pBodyLength <0 /*|| *pBodyLength > PC_MAX_PROTOCOL_LEN */) { #ifdef AMOS_DEBUG AMPrintf("noble:reader: bodyLength exceed limited(0~20000) = %d\n", *pBodyLength); #endif //send a body exceed exception to up-layer. ReaderExceedExceptionHandler(pPacketConnection->pProtocolEngine, *pBodyLength); return eContinue; } // 分配Body空间并填充 *ppBodyBuffer = (AMUInt8*)AMMalloc(*pBodyLength); if(*ppBodyBuffer == NULL) { #ifdef AMOS_DEBUG AMPrintf("noble:malloc pBodyBuffer error = %d.\n", *pBodyLength); AMAssert(0); #endif return eJumpWhile; } memset(*ppBodyBuffer, 0, *pBodyLength); length = PCContextGetInstance()->recv( pPacketConnection->pProtocolEngine->pPCCore->socketFd, *ppBodyBuffer, *pBodyLength); if( length != *pBodyLength) { #ifdef AMOS_DEBUG AMPrintf("noble:recv = %d != bodyLength = %d\n", length, *pBodyLength); #endif //first free memory AMFree(*ppBodyBuffer); *ppBodyBuffer = NULL; //send exception to up. if(ReaderRecvExceptionHandler(pPacketConnection,*pBodyLength,length) == eContinue) return eContinue; else return eJumpWhile; } #ifdef AMOS_DEBUG AMPrintf("noble:ReaderRecvBody >>>>>.\n"); #endif return eOK; }
PCRetCode ReaderUnpackPacketBuffer(PacketConnection* pPacketConnection, AMUInt8* pPacketBuffer, AMInt32 length) { PCRetCode retCode = eOK; AMInt32 cmd = 0; Event* pEvent = NULL; #ifdef AMOS_DEBUG AMPrintf("noble:ReaderUnpackPacketBuffer <<<<.\n"); #endif cmd = getIntValue(pPacketBuffer, 16); //denx:这里如果收到了心跳包的回复,则心跳包计数+1 if(cmd == 0x01000001 /*IM_HEALTH_CHECK_ACK*/) ++pPacketConnection->pNetwork->maxHealthCheckMiss; if(pPacketConnection->pUnpacker) { retCode = pPacketConnection->pUnpacker( (PCHandle)pPacketConnection, &pEvent, (EventId)cmd, pPacketBuffer, length, pPacketConnection->pReference); } else retCode = eInalidUnpacker; if(retCode != eOK ) { #ifdef AMOS_DEBUG AMPrintf("noble:unpack procedure error. PCRetCode=%d. cmd=0x%08x\n", retCode, cmd); #endif //send a unpack exception to up-layer. PacketExceptionHandler(pPacketConnection, retCode, PC_UNPACK_EXCEPTION_IND); } else { //被踢下线,关闭socket. //if(cmd == PC_NTF_FORCEDISCONNECT) // pProtocolEngine->pPCContext->socketClose((AMUInt32*)&pProtocolEngine->pPCCore->socketFd); } //send to Callback Queue. if(pEvent) { PCPostMessage(pEvent, pPacketConnection->pProtocolEngine->pPCCore->pCallbackQueue); } #ifdef AMOS_DEBUG AMPrintf("noble:ReaderUnpackPacketBuffer >>>>>>.\n"); #endif return eOK; }
void PCCoreClear(ST_PacketConnection* pPacketConnection, Semaphore* pSemaphore, PCClearType type) { Event* pEvent1 = NULL; Event* pEvent2 = NULL; Event* pEvent3 = NULL; PcClearVarInd request; ProtocolEngine* pProtocolEngine = pPacketConnection->pProtocolEngine; #ifdef AMOS_DEBUG AMPrintf("noble:PCCoreClear <<<<< PCClearType = %d start...\n", type); #endif memset(&request, 0, sizeof(request)); //denx add for sync pProtocolEngine->pPCContext->semaphoreCreate(pSemaphore, 0, 2); request.pSemaphore = pSemaphore; EventCreate(pPacketConnection, &pEvent1, PC_CLEAR_VAR_IND, (void*)&request, sizeof(request)); EventCreate(pPacketConnection, &pEvent2, PC_CLEAR_VAR_IND, (void*)&request, sizeof(request)); PCPostMessage(pEvent1, pProtocolEngine->pPCCore->pReaderQueue); PCPostMessage(pEvent2, pProtocolEngine->pPCCore->pSenderQueue); PCContextGetInstance()->semaphoreWait(pSemaphore); PCContextGetInstance()->semaphoreWait(pSemaphore); PCContextGetInstance()->semaphoreDestory(pSemaphore); if(type == ePCClearPCHandle) { #ifdef AMOS_DEBUG AMPrintf("noble:PCCoreClear <<<<< ePCClearPCHandle...\n"); #endif pProtocolEngine->pPCContext->semaphoreCreate(pSemaphore, 0, 1); request.pSemaphore = pSemaphore; EventCreate(pPacketConnection, &pEvent3, PC_CLEAR_VAR_IND, (void*)&request, sizeof(request)); PCPostMessage(pEvent3, pProtocolEngine->pPCCore->pCallbackQueue); #ifdef AMOS_DEBUG AMPrintf("noble:PCCoreClear <<<<< ePCClearPCHandle before wait..\n"); #endif PCContextGetInstance()->semaphoreWait(pSemaphore); PCContextGetInstance()->semaphoreDestory(pSemaphore); } #ifdef AMOS_DEBUG AMPrintf("noble:PCCoreClear >>>>> end...\n"); #endif }
void SocketSenderCallback(AMInt32 reference, AMInt32 socket, SocketStatus status) { IMnet* pIMnet = (IMnet*)reference; switch(status) { case eSocketSendOK: break; case eSocketSendFail: #ifdef AMOS_DEBUG AMPrintf("noble:SocketSenderCallback: Send Fail."); #endif break; default: #ifdef AMOS_DEBUG AMPrintf("noble:SocketSenderCallback: default."); #endif break; } }
void PCCoreRun(struct ST_PacketConnection* pPacketConnection) { PCCore* pPCCore = pPacketConnection->pProtocolEngine->pPCCore; #ifdef AMOS_DEBUG AMPrintf("noble:create reader thread.\n"); #endif LooperCreate(pPacketConnection, &pPCCore->pReaderLooper, ReaderRunner, 0, 0, 0); #ifdef AMOS_DEBUG AMPrintf("noble:create sender thread.\n"); #endif LooperCreate(pPacketConnection, &pPCCore->pSenderLooper, SenderRunner, 0, 0, 0); #ifdef AMOS_DEBUG AMPrintf("noble:create callback thread.\n"); #endif LooperCreate(pPacketConnection, &pPCCore->pCallbackLooper, CallbackRunner, 0, 0, 0); pPCCore->coreStatus = eIMnetCoreStart; }
AIM_RESULT OnNtfNeedAuth(AMVoid *pvArg, AIM_NTF_NEED_AUTH *pNtfNeedAuth) { if(pNtfNeedAuth) { AMPrintf("%s >>>>>> autId: %d\n", __FUNCTION__, pNtfNeedAuth->iAuthId); if(pNtfNeedAuth->pvData && pNtfNeedAuth->iDataLen) { AMFILE *pFile = AMFopen("checkImg.jpg", "wb"); AMFwrite(pNtfNeedAuth->pvData, 1, pNtfNeedAuth->iDataLen, pFile); AMFclose(pFile); } } return eAIM_RESULT_OK; }
void SkipPropertyNum(AMUInt8** ppbuffer, AMInt32 n) { AMInt32 i; AMInt32 strLen; AMInt8 type; for(i=0; i<n; i++) { getByte((*ppbuffer), type); switch(type) { case FT_INT8: case FT_UINT8: (*ppbuffer) += 1; break; case FT_INT16: case FT_UINT16: (*ppbuffer) += 2; break; case FT_INT32: case FT_UINT32: (*ppbuffer) += 4; break; case FT_INT64: case FT_UINT64: (*ppbuffer) += 8; break; case FT_STRING: getInt((*ppbuffer), strLen); (*ppbuffer) += strLen; break; default: #ifdef AMOS_DEBUG AMPrintf("unspported SkipPropertyNum."); #endif break; } } }
PCRetCode ReaderMergeToPacketBuffer(AMUInt8** ppPacketBuffer, AMUInt8* pHead, AMInt32 headLength, AMUInt8* pBodyBuffer, AMInt32 bodyLength) { // 分配包大小并填充 *ppPacketBuffer = (AMUInt8*)AMMalloc(headLength+bodyLength); if(*ppPacketBuffer == NULL) { #ifdef AMOS_DEBUG AMPrintf("noble:malloc pPacketBuffer error.\n"); AMAssert(0); #endif return eJumpWhile; } memset(*ppPacketBuffer, 0, headLength+bodyLength); memcpy(*ppPacketBuffer, pHead, headLength); memcpy((*ppPacketBuffer)+headLength, pBodyBuffer, bodyLength); return eOK; }
AMInt32 AMLooperLoop(struct AMLooper* looper) { //AMLogForDebug("AMLooper", "AMLooperLoop"); if(NULL == looper) return AME_LOOPER_LOOPER_NULL; if(LOOPER_END_TRUE == looper->end_run_flag) return AME_LOOPER_LOOPER_INVALID; looper->start_run_falg = LOOPER_RUNNING_TRUE; do { struct AMMessage message; AMInt32 left_time; AMInt32 err_code = 0; AMInt32 is_cond_time_set = 0; //处理完所有的一般消息 do { if(LOOPER_END_TRUE == looper->end_run_flag) { looper->start_run_falg = LOOPER_RUNNING_FALSE; _AMLooperDestory(looper); return AME_LOOPER_SCUESS; } if(_AMLooperGetMessage(looper, &message) == AME_LOOPER_SCUESS) { message.handler->callback(&message, message.handler->cbArgs); if(message.cleanUp != NULL) message.cleanUp(&message); } else { break; } }while(1); //处理所有定时消息 do { if(LOOPER_END_TRUE == looper->end_run_flag) { looper->start_run_falg = LOOPER_RUNNING_FALSE; _AMLooperDestory(looper); return AME_LOOPER_SCUESS; } err_code = _AMLooperGetTimeMessage(looper, &message, &left_time); if(err_code == AME_LOOPER_SCUESS) { if(message.type == AM_MESSAGE_TIMER) ((AMVoid(*)(AMPVoid* pArg))message.ref1.ptr)(message.ref2.ptr); else { message.handler->callback(&message, message.handler->cbArgs); if(message.cleanUp != NULL) message.cleanUp(&message); } } else if(left_time > 0) { is_cond_time_set = 1; break; } else { is_cond_time_set = 0; break; } }while(1); //用athread_cond来处理. AMThreadMutexLock(&looper->loop_cond_mutex); while(looper->isHasRecord == 0) { if(is_cond_time_set == 0) { AMPrintf("AMThreadCondWait Start\n"); AMThreadCondWait(&looper->loop_cond, &looper->loop_cond_mutex); AMPrintf("AMThreadCondWait End\n"); } else { //还要加上当前的时间 struct AMTimeval tm; AMGetUTCTimeEx(&tm); tm.tv_sec += (left_time + tm.tv_usec / 1000) / 1000; tm.tv_usec = (((left_time + tm.tv_usec /1000)) % 1000) * 1000; AMThreadCondTimewait(&looper->loop_cond, &looper->loop_cond_mutex, &tm); } } looper->isHasRecord = 0; AMThreadMutexUnlock(&looper->loop_cond_mutex); }while(1); return AME_LOOPER_SCUESS; }
AMUInt32 SenderRunner(void* lpParam) #endif #endif { Event* pEvent = NULL; AMInt32 isExit = 0; PcNetworkConfig* pConfig = NULL; ProtocolEngine* pProtocolEngine = ((PacketConnection*)lpParam)->pProtocolEngine; PacketConnection* pPacketConnection; AMInt32 iBarkTime = 0, iNowTime = 0, iMissCount = 0; PcHealthCheckConfig hcConfig = {0, NULL}; Event* pHealthCheckEvent = NULL; Event* pHealthCheckSelfEvent = NULL; PcClearVarInd* pClearVarInd = NULL; while(1) { //get Request EVENT from sender queue. PullQueue(pProtocolEngine->pPCCore->pSenderQueue, &pEvent, 1); if(pEvent != NULL) { pPacketConnection = (PacketConnection*)pEvent->hPCHandle; switch(pEvent->id) { case PC_SHUTDOWN_IND: //关闭当前模块 #ifdef AMOS_DEBUG AMPrintf("noble:exit sender thread....\n"); #endif isExit = 1; break; case PC_CLEAR_VAR_IND: #ifdef AMOS_DEBUG AMPrintf("noble:sender PC_CLEAR_VAR_IND....\n"); #endif //network need to close if(pPacketConnection && pPacketConnection->pNetwork && pPacketConnection->pNetwork->fd>0) PCContextGetInstance()->socketClose(&pPacketConnection->pNetwork->fd); pClearVarInd = (PcClearVarInd*)pEvent->pContent; pProtocolEngine->pPCContext->semaphoreSignal(pClearVarInd->pSemaphore); break; case PC_SET_HEALTH_CHECK_CONFIG: if(iBarkTime == 0) memcpy(&hcConfig, (PcHealthCheckConfig*)pEvent->pContent, sizeof(hcConfig)); if( IsPCNetworkReady(pProtocolEngine->pPCCore) > 0 && IsPCNeedHealthCheck(pProtocolEngine->pPCCore) > 0 ) { iNowTime = AMGetUTCTime(AMNULL); if( iBarkTime+hcConfig.second < iNowTime || iNowTime < iBarkTime) { if(hcConfig.pMaker != NULL) { hcConfig.pMaker(pEvent->hPCHandle, &pHealthCheckEvent, pPacketConnection->pReference); SenderPacket(pHealthCheckEvent); EventDestory(&pHealthCheckEvent); iBarkTime = iNowTime; } iMissCount = 0; } } //send PC_SET_HEALTH_CHECK_CONFIG to self. EventCreate(pEvent->hPCHandle, &pHealthCheckSelfEvent, PC_SET_HEALTH_CHECK_CONFIG, (void*)&hcConfig, sizeof(hcConfig)); PCPostMessage(pHealthCheckSelfEvent, pProtocolEngine->pPCCore->pSenderQueue); pProtocolEngine->pPCContext->sleep(HEALTH_CHECK_SLEEP_TIME); break; case PC_SET_NETWORK_CONFIG: //预处理网络连接 pConfig = (PcNetworkConfig*)pEvent->pContent; if(pConfig->nCount <= 1) { #ifdef AMOS_DEBUG AMPrintf("noble:sender socket create. ip = %s:%d\n", pConfig->ip, pConfig->port); #endif pProtocolEngine->pPCCore->socketFd = pProtocolEngine->pPCContext->socketCreate( pConfig->ip, pConfig->port #ifdef AMOS #ifdef SOCKET_ASYNC , (AMInt32)pIMnet, AMSocketIAPGet(), SocketConnectionCallback, SocketSenderCallback, SocketReaderCallback #endif #endif ); #ifdef AMOS_DEBUG AMPrintf("noble:sender socket create over %d \n", pProtocolEngine->pPCCore->socketFd); #endif } if(pPacketConnection->pNetwork != NULL) pPacketConnection->pNetwork->fd = pProtocolEngine->pPCCore->socketFd; if(pConfig->sync) { //tell pcmgr PacketConnectionOpen pPacketConnection->pProtocolEngine->pPCContext->semaphoreSignal(&(pPacketConnection->semaphore)); } else { #ifdef SOCKET_ASYNC if(pProtocolEngine->pPCCore->socketFd <= 0) #endif { SendNetworkConnectedMsg(pPacketConnection, pProtocolEngine->pPCCore->socketFd); } } break; default: SenderPacket(pEvent); break; } } //destory EVENT if(pEvent != NULL) EventDestory(&pEvent); if(isExit == 1) goto SenderEnd; } SenderEnd: pProtocolEngine->pPCContext->semaphoreSignal(&pProtocolEngine->pPCCore->pSenderLooper->semaphore); #ifdef AMOS return (AMPVoid)isExit; #else #ifdef WIN32 return isExit; #endif #endif }
void SenderPacket(Event* pEvent) { AMChar* pBuffer = NULL; AMInt32 length = 0; AMInt32 sd = 0; PCRetCode retCode = eOK; PacketConnection* pPacketConnection; pPacketConnection = (PacketConnection*)pEvent->hPCHandle; pBuffer = NULL; length = 0; //pack EVENT #ifdef AMOS_DEBUG AMPrintf("noble:SenderPacket. <<<<< \n"); #endif if(pPacketConnection->pPacker) retCode = pPacketConnection->pPacker(pPacketConnection, pEvent, (AMUInt8**)&pBuffer, &length, pPacketConnection->pReference); else retCode = eInvalidPacker; //send to socket if(retCode == eOK) { #ifdef AMOS_DEBUG AMPrintf("noble:SenderPacket. before network check. \n"); #endif if(IsPCNetworkReady(pPacketConnection->pProtocolEngine->pPCCore) > 0) { #ifdef AMOS_DEBUG AMPrintf("noble:SenderPacket. before send. \n"); #endif sd = pPacketConnection->pProtocolEngine->pPCContext->send( pPacketConnection->pProtocolEngine->pPCCore->socketFd, (AMUInt8*)pBuffer, length); if(sd <= 0) { #ifdef AMOS_DEBUG AMPrintf("noble:send error. sd=%d, cmd=0x%x\n", sd, pEvent->id); #endif // send exception to uplayer. SenderSendExceptionHandler(pPacketConnection, sd, pEvent->id); } else { if(pEvent->id == 0x01000001 /*IM_HEALTH_CHECK*/&& (--pPacketConnection->pNetwork->maxHealthCheckMiss) <= 0 ) { //denx:发出的心跳包未得到回馈的次数已经超过了设置的maxHealthCheckMiss //close network #ifdef AMOS_DEBUG AMPrintf("noble:SenderPacket. .....................Uncheck Exceeded! Close Socket!\n"); #endif // AMOS_DEBUG PCContextGetInstance()->socketClose((AMUInt32*)&pPacketConnection->pProtocolEngine->pPCCore->socketFd); } #ifdef AMOS_DEBUG AMPrintf("noble:SenderPacket. send ok. \n"); #endif } } else { #ifdef AMOS_DEBUG AMPrintf("noble:socket isn't ready.. socket = %d\n", pPacketConnection->pProtocolEngine->pPCCore->socketFd); #endif } #ifdef AMOS_DEBUG AMPrintf("noble:SenderPacket. before packfree. \n"); #endif if(pPacketConnection->pPackerFree) { #ifdef AMOS_DEBUG AMPrintf("noble:SenderPacket. packfree 1111"); #endif pPacketConnection->pPackerFree((AMInt8*)pBuffer, pPacketConnection->pReference); #ifdef AMOS_DEBUG AMPrintf("noble:SenderPacket. packfree 2222"); #endif } else { #ifdef AMOS_DEBUG AMPrintf("noble:SenderPacket. packfree 3333"); #endif retCode = eInvalidPackerFree; } #ifdef AMOS_DEBUG AMPrintf("noble:SenderPacket. packfree OK."); #endif pBuffer = NULL; } //dengxiang: don't use "else" to link "if(retCode == eOK)" if(retCode != eOK) { #ifdef AMOS_DEBUG AMPrintf("noble:pack procedure has error. PCRetCode=%d.\n", retCode); #endif // send exception to uplayer. PacketExceptionHandler(pPacketConnection, retCode, PC_PACK_EXCEPTION_IND); } #ifdef AMOS_DEBUG AMPrintf("noble:SenderPacket..>>>>>> \n"); #endif }
static AMVoid _AMLooperMessagePrint(const AMPVoid u) { //AMLogForDebug("AMLooper", "_AMLooperMessagePrint"); struct AMMessage* msg = (struct AMMessage*)u; AMPrintf("Msg: t = [%d, %d]\n", msg->run_tm.tv_sec, msg->run_tm.tv_usec); }
PCRetCode ReaderRecvExceptionHandler(PacketConnection* pPacketConnection, AMInt32 desireLen, AMInt32 realLen) { PCRetCode retCode = eOK; Event* pExceptionEvent = NULL; PcRecvExceptionInd exceptionInd; #ifdef SOCKET_ASYNC AMInt32 indType = 0; #endif AMAssert(NULL != pPacketConnection && NULL != pPacketConnection->pProtocolEngine ); AMAssert(NULL != pPacketConnection->pProtocolEngine->pPCCore); //shutdown health check PCCoreSwitchHealthCheck(pPacketConnection->pProtocolEngine->pPCCore, 0); //close network PCContextGetInstance()->socketClose((AMUInt32*)&pPacketConnection->pProtocolEngine->pPCCore->socketFd); if(pPacketConnection->pProtocolEngine->pPCCore->coreStatus == eIMnetCoreStart) { //send a exception to up-layer. pExceptionEvent = NULL; exceptionInd.desireLength = desireLen; exceptionInd.realLength = realLen; #ifdef AMOS_DEBUG AMPrintf("noble: reader send PC_RECV_EXCEPTION_IND\n"); #endif retCode = EventCreate(pPacketConnection, &pExceptionEvent, PC_RECV_EXCEPTION_IND, (void*)&exceptionInd, sizeof(exceptionInd)); if(retCode == eOK) PCPostMessage(pExceptionEvent, pPacketConnection->pProtocolEngine->pPCCore->pCallbackQueue); else { #ifdef AMOS_DEBUG AMAssert(0); #endif return eJumpWhile; } } else { #ifdef AMOS_DEBUG AMPrintf("noble: reader do not send PC_RECV_EXCEPTION_IND\n"); #endif } #ifdef AMOS_DEBUG AMPrintf("noble: reader wait for ...\n"); #endif //等待上层重新建立连接,或者退出程序 while(IsPCNetworkReady(pPacketConnection->pProtocolEngine->pPCCore) <= 0) { if( ReaderEventHandler(pPacketConnection->pProtocolEngine, 0 #ifdef SOCKET_ASYNC , &indType #endif ) == eJumpWhile ) return eJumpWhile; PCContextGetInstance()->sleep(100); } #ifdef AMOS_DEBUG AMPrintf("noble: reader out wait for....\n"); #endif return eContinue; }
PCRetCode ReaderEventHandler(ProtocolEngine* pProtocolEngine, AMInt32 sync #ifdef SOCKET_ASYNC , AMInt32* pIndType #endif ) { PCRetCode retCode = eOK; Event* pEvent = NULL; PcClearVarInd* pClearVarInd = NULL; PacketConnection* pPacketConnection = NULL; AMAssert(NULL != pProtocolEngine && NULL != pProtocolEngine->pPCCore); //get Request EVENT from reader queue. PullQueue(pProtocolEngine->pPCCore->pReaderQueue, &pEvent, sync); if(pEvent != NULL) { switch(pEvent->id) { case PC_SHUTDOWN_IND: #ifdef AMOS_DEBUG AMPrintf("noble:exit reader thread....\n"); #endif retCode = eJumpWhile; break; #ifdef SOCKET_ASYNC case PC_SOCKET_IND: *pIndType = ((ImSocketInd*)pEvent->pContent)->indType; break; #endif case PC_CLEAR_VAR_IND: #ifdef AMOS_DEBUG AMPrintf("noble:ReaderEventHandler PC_CLEAR_VAR_IND.\n"); #endif pPacketConnection = (PacketConnection*)pEvent->hPCHandle; //network need to close if(pPacketConnection && pPacketConnection->pNetwork && pPacketConnection->pNetwork->fd>0) PCContextGetInstance()->socketClose(&pPacketConnection->pNetwork->fd); pClearVarInd = (PcClearVarInd*)pEvent->pContent; PCContextGetInstance()->semaphoreSignal(pClearVarInd->pSemaphore); break; default: #ifdef AMOS_DEBUG AMPrintf("noble:ReaderEventHandler default.\n"); #endif break; } //destory EVENT EventDestory(&pEvent); #ifdef AMOS_DEBUG AMPrintf("noble:ReaderEventHandler after EventDestory.\n"); #endif } return retCode; }
AMUInt32 CallbackRunner(void* lpParam) #endif #endif { Event* pEvent = NULL; AMInt32 isExit = 0; ProtocolEngine* pProtocolEngine = ((PacketConnection*)lpParam)->pProtocolEngine; PacketConnection* pPacketConnection; PcClearVarInd* pClearVarInd = NULL; while(1) { //get Request EVENT from callback queue. PullQueue(pProtocolEngine->pPCCore->pCallbackQueue, &pEvent, 1); if(pEvent != NULL) { pPacketConnection = (PacketConnection*)pEvent->hPCHandle; switch(pEvent->id) { case PC_SHUTDOWN_IND: #ifdef AMOS_DEBUG AMPrintf("noble:exit callback thread....\n"); #endif isExit = 1; break; case PC_CLEAR_VAR_IND: #ifdef AMOS_DEBUG AMPrintf("noble:callback PC_CLEAR_VAR_IND....\n"); #endif //network need to close if(pPacketConnection && pPacketConnection->pNetwork && pPacketConnection->pNetwork->fd>0) PCContextGetInstance()->socketClose(&pPacketConnection->pNetwork->fd); pClearVarInd = (PcClearVarInd*)pEvent->pContent; PCContextGetInstance()->semaphoreSignal(pClearVarInd->pSemaphore); break; default: #ifdef AMOS_DEBUG AMPrintf("noble:callback event <<<<< 0x%x... start\n", pEvent->id); #endif if(pEvent->id == PC_RECV_EXCEPTION_IND) ProtocolNetworkDestory(pEvent->hPCHandle, 1); if(pPacketConnection && pPacketConnection->pReceiver) pPacketConnection->pReceiver(pPacketConnection, pEvent, pPacketConnection->pReference); #ifdef AMOS_DEBUG AMPrintf("noble:callback event >>>>> 0x%x end \n", pEvent->id); #endif break; } //destory EVENT EventDestory(&pEvent); if(isExit == 1) goto CallbackEnd; } } CallbackEnd: PCContextGetInstance()->semaphoreSignal(&pProtocolEngine->pPCCore->pCallbackLooper->semaphore); #ifdef AMOS return (AMPVoid)isExit; #else #ifdef WIN32 return isExit; #endif #endif }