void cpix_Error_report(cpix_Error * thisError, wchar_t * target, size_t targetLength) { if (thisError != NULL) { const wchar_t * errorTypeName = GetErrorTypeName(thisError->type_); const wchar_t * detail = thisError->msg_; if (detail == NULL) { detail = L"No details"; } snwprintf(target, targetLength, L"Error type: %S. %S\n", errorTypeName, detail); } else { *target = 0; } }
void PrintDataFrameHeader(ENDI_DATA_FRAME *pFrame, int nLength) { XDEBUG(" DATA (ACCESS=%s, FLOW=%s, TYPE=%s[0x%02X], LENGTH=%d)\r\n", (pFrame->hdr.ctrl & CODI_FRAMEFLOW_READ) > 0 ? "Read" : "Write", (pFrame->hdr.ctrl & CODI_FRAMEFLOW_RESPONSE) > 0 ? "Response" : "Request", GetDataTypeName(pFrame->hdr.type), pFrame->hdr.type, pFrame->hdr.len-sizeof(EUI64)); // Link frame중 Write response이면 에러 코드를 찍는다. if (pFrame->hdr.type == ENDI_DATATYPE_LINK) { if (((pFrame->hdr.ctrl & CODI_FRAMEFLOW_READ) == 0) && ((pFrame->hdr.ctrl & CODI_FRAMEFLOW_RESPONSE) > 0)) { // 에러인 경우만 로그를 찍는다. if ((pFrame->payload[0] & 0xff) != 0) { XDEBUG(" \033[1;40;31mWrite Result = 0x%02X %s\033[0m\r\n", pFrame->payload[0] & 0xff, GetErrorTypeName(pFrame->payload[0] & 0xff)); } } } }
BOOL CEndDevicePool::EndDeviceRecvCallback(COORDINATOR *codi, ENDI_DATA_FRAME *pFrame, int nLength, int nTLength, BYTE LQI, signed char RSSI) { ENDDEVICE *pEndDevice; ENDI_LINK_PAYLOAD *pLink; ENDI_NAN_PAYLOAD *pNan; ENDI_ROM_PAYLOAD *pRead; ENDI_ERROR_FRAME *pError; EUI64 id; BYTE flow, mode; char szGUID[17]; //BOOL bAccept; mode = GET_FRAME_MODE(pFrame->hdr.ctrl); flow = GET_FRAME_FLOW(pFrame->hdr.ctrl); ReverseEUI64(&pFrame->id, &id); eui64toa(&id, szGUID); m_lockerPool.Lock(); pEndDevice = FindEndDeviceByID(&id); if (pEndDevice) LockEndDevice(pEndDevice); m_lockerPool.Unlock(); if (pEndDevice == NULL) { switch(pFrame->hdr.type) { case ENDI_DATATYPE_ROM_READ : if (((mode == CODI_ACCESS_READ) && (flow == CODI_FLOW_RESPONSE)) || ((mode == CODI_ACCESS_WRITE) && (flow == CODI_FLOW_REQUEST))) { pRead = (ENDI_ROM_PAYLOAD *)&pFrame->payload; endiOnRead((HANDLE)codi, &id, pFrame->hdr.seq, ntoshort(pRead->addr), (pRead->typelen & 0x3F), LQI, RSSI); } break; #ifndef __NETWORK_NODE__ case ENDI_DATATYPE_BYPASS : if (((mode == CODI_ACCESS_READ) && (flow == CODI_FLOW_RESPONSE)) || ((mode == CODI_ACCESS_WRITE) && (flow == CODI_FLOW_REQUEST))) { endiOnData((HANDLE)codi, &id, pFrame->hdr.seq, (BYTE *)&pFrame->payload, nLength, LQI, RSSI); } break; #endif case ENDI_DATATYPE_LINK : if (((mode == CODI_ACCESS_READ) && (flow == CODI_FLOW_RESPONSE)) || ((mode == CODI_ACCESS_WRITE) && (flow == CODI_FLOW_REQUEST))) { pLink = (ENDI_LINK_PAYLOAD *)&pFrame->payload; #ifndef __NETWORK_NODE__ if (pLink->type & ENDI_LINKSRC_PDA) #endif endiOnLink((HANDLE)codi, &id, (pLink->type & 0x0F), LQI, RSSI); } break; #ifndef __NETWORK_NODE__ case ENDI_DATATYPE_AMR : endiOnKeepAlive((HANDLE)codi, &id, pFrame->hdr.ctrl, (ENDI_AMR_PAYLOAD *)&pFrame->payload, nLength, LQI, RSSI); break; #endif case ENDI_DATATYPE_NAN : if (((mode == CODI_ACCESS_READ) && (flow == CODI_FLOW_RESPONSE)) || ((mode == CODI_ACCESS_WRITE) && (flow == CODI_FLOW_REQUEST))) { pNan = (ENDI_NAN_PAYLOAD *)&pFrame->payload; endiOnNanData((HANDLE)codi, &id, pNan->trid, (pNan->ctrl & 0x80) ? 1 : 0, (pNan->ctrl & 0x40) ? 1 : 0, pNan->ctrl & 0x3F, pNan->data, nLength - 2, LQI, RSSI); } break; } return TRUE; } #ifdef __NETWORK_NODE__ else { switch(pFrame->hdr.type) { case ENDI_DATATYPE_LINK : if (((mode == CODI_ACCESS_READ) && (flow == CODI_FLOW_RESPONSE)) || ((mode == CODI_ACCESS_WRITE) && (flow == CODI_FLOW_REQUEST))) { pLink = (ENDI_LINK_PAYLOAD *)&pFrame->payload; endiOnLink((HANDLE)codi, &id, (pLink->type & 0x0F), LQI, RSSI); } return TRUE; } } #endif if ((mode == CODI_ACCESS_WRITE) && (flow == CODI_FLOW_RESPONSE)) { pError = (ENDI_ERROR_FRAME *)pFrame; // Save last error code codi->nLastError = pError->payload.code; if (pError->payload.code != CODI_SUCCESS) { XDEBUG(" \033[1;40;31m***** WRITE RESPONSE ERROR (0x%02X): %s\033[0m\r\n", pError->payload.code, GetErrorTypeName(pError->payload.code)); endiOnError((HANDLE)codi, (HANDLE)pEndDevice, pFrame->hdr.ctrl, pFrame->hdr.type, pError->payload.code); } UnlockEndDevice(pEndDevice); return TRUE; } if((mode == CODI_ACCESS_READ) && (flow == CODI_FLOW_RESPONSE)) { /** Endi에서 올라오는 Keepalive Event는 Seq 처리를 하지 않는다 */ if(pFrame->hdr.type == ENDI_DATATYPE_AMR && !pFrame->hdr.seq) { pEndDevice->nTotalRecv += nLength; ceTime(&pEndDevice->tmLastReceive); endiOnAmrData((HANDLE)codi, (HANDLE)pEndDevice, pFrame->hdr.ctrl, (ENDI_AMR_PAYLOAD *)&pFrame->payload, nLength, LQI, RSSI); // 총수신량 합산 = 중복 프레임 제외 UnlockEndDevice(pEndDevice); return TRUE; } } // 중복 프레임 및 시퀀스 오류 버리기 if (pEndDevice->nLastRecvSeq == pFrame->hdr.seq) { XDEBUG(" \033[1;40;31m-------------------- DUPLICATE ERROR ------------------\033[0m\r\n"); XDEBUG(" \033[1;40;31m***** DUPLICATE FRAME PREV=%d, SEQ=%d, LENGTH=%d *****\033[0m\r\n", pEndDevice->nLastRecvSeq, pFrame->hdr.seq, nTLength); XDUMP((char *)pFrame, nTLength, TRUE); UnlockEndDevice(pEndDevice); return FALSE; } // 처음이 아니면서 시퀀스를 검사해야 하는 경우 if ((pEndDevice->nLastRecvSeq != -1) && (pEndDevice->nOptions & ENDIOPT_SEQUENCE)) { if(!IsValidSeq((BYTE)pEndDevice->nLastRecvSeq, pFrame->hdr.seq)) { XDEBUG(" \033[1;40;31m---------------------- SEQ ERROR --------------------\033[0m\r\n"); XDEBUG(" \033[1;40;31m***** SEQUENCE CHECK FRAME PREV=%d, CUR=%d *****\033[0m\r\n", pEndDevice->nLastRecvSeq, pFrame->hdr.seq); // 연속적으로 시퀀스 에러가 발생되는것을 누적하기 위하여 사용 pEndDevice->nSeqError++; if(IsPossibleSeq((BYTE)pEndDevice->nLastRecvSeq, pFrame->hdr.seq)) { /** 내부 버퍼에 내용을 집어 넣는다. * 내부 버퍼는 Binding을 Open 할 때 할당 되고 * Close 할 때 Free 한다 */ // 내부에 등록 XDEBUG(" AddDataBuffer -- ID=%s, LAST=%d, SEQ=%d\r\n", pEndDevice->szGUID, (BYTE)pEndDevice->nLastRecvSeq, pFrame->hdr.seq); AddDataBuffer(pEndDevice, pFrame, nLength, nTLength, LQI, RSSI); } UnlockEndDevice(pEndDevice); return FALSE; } } // 총수신량 합산 = 중복 프레임 제외 pEndDevice->nTotalRecv += nLength; // 정상 프레임이 수신되면 누적된 Count를 초기화 한다. pEndDevice->nSeqError = 0; // 수신한 시퀀스를 저장한다. pEndDevice->nLastRecvSeq = pFrame->hdr.seq; ceTime(&pEndDevice->tmLastReceive); // Thread Debugging __PTHREAD_INFO__; switch(pFrame->hdr.type) { case ENDI_DATATYPE_BYPASS : pEndDevice->nTotalDataRecv += nLength; endiOnBypass((HANDLE)codi, (HANDLE)pEndDevice, pFrame->hdr.ctrl, pFrame->hdr.seq, (BYTE *)&pFrame->payload, nLength, LQI, RSSI); break; case ENDI_DATATYPE_AMR : endiOnAmrData((HANDLE)codi, (HANDLE)pEndDevice, pFrame->hdr.ctrl, (ENDI_AMR_PAYLOAD *)&pFrame->payload, nLength, LQI, RSSI); break; case ENDI_DATATYPE_NETWORK_LEAVE : endiOnNetworkLeave((HANDLE)codi, (HANDLE)pEndDevice, pFrame->hdr.ctrl, (ENDI_LEAVE_PAYLOAD *)&pFrame->payload, nLength, LQI, RSSI); break; case ENDI_DATATYPE_ROM_READ : #ifdef __NETWORK_NODE__ pRead = (ENDI_ROM_PAYLOAD *)&pFrame->payload; endiOnRead((HANDLE)codi, &id, pFrame->hdr.seq, ntoshort(pRead->addr), (pRead->typelen & 0x3F), LQI, RSSI); #else endiOnRomRead((HANDLE)codi, (HANDLE)pEndDevice, pFrame->hdr.ctrl, (ENDI_ROM_PAYLOAD *)&pFrame->payload, nLength, LQI, RSSI); #endif break; case ENDI_DATATYPE_LONG_ROM_READ : endiOnLongRomRead((HANDLE)codi, (HANDLE)pEndDevice, pFrame->hdr.ctrl, (ENDI_LONG_ROM_PAYLOAD *)&pFrame->payload, nLength, LQI, RSSI); break; case ENDI_DATATYPE_MCCB : endiOnMccbData((HANDLE)codi, (HANDLE)pEndDevice, pFrame->hdr.ctrl, (ENDI_MCCB_PAYLOAD *)&pFrame->payload, nLength, LQI, RSSI); break; case ENDI_DATATYPE_COMMAND : endiOnCommand((HANDLE)codi, (HANDLE)pEndDevice, pFrame->hdr.ctrl, (ENDI_COMMAND_PAYLOAD *)&pFrame->payload, nLength, LQI, RSSI); break; case ENDI_DATATYPE_NAN : pNan = (ENDI_NAN_PAYLOAD *)&pFrame->payload; endiOnNanData((HANDLE)codi, &id, pNan->trid, (pNan->ctrl & 0x80) ? 1 : 0, (pNan->ctrl & 0x40) ? 1 : 0, pNan->ctrl & 0x3F, pNan->data, nLength - 2, LQI, RSSI); break; } UnlockEndDevice(pEndDevice); return TRUE; }