int CCAN232Obj::writeMsg(PCANALMSG pCanalMsg) { int rv = 0; // Must be room for the message if (m_can232obj.m_sndList.nCount < CAN232_MAX_SNDMSG) { if (NULL != pCanalMsg) { dllnode *pNode = new dllnode; if (NULL != pNode) { canalMsg *pnewMsg = new canalMsg; pNode->pObject = pnewMsg; pNode->pKey = NULL; pNode->pstrKey = NULL; if (NULL != pnewMsg) { memcpy(pnewMsg, pCanalMsg, sizeof( canalMsg)); } LOCK_MUTEX(m_can232ObjMutex); dll_addNode(&m_can232obj.m_sndList, pNode); UNLOCK_MUTEX(m_can232ObjMutex); rv = true; } } } return rv; }
bool CIxxObj::writeMsg( canalMsg *pMsg ) { bool rv = false; if ( NULL != pMsg ) { // VCI2 only allow sending of message with the same // mode as the i/f is opended with. So extended id's in // standard mode shoud be disregareded and vice versa. if ( VCI_29B & m_initFlag ) { if ( !( pMsg->flags & CANAL_IDFLAG_EXTENDED ) ) return false; } else { if ( pMsg->flags & CANAL_IDFLAG_EXTENDED ) return false; } // Must be room for the message if ( m_transmitList.nCount < IXXATVCI_MAX_SNDMSG ) { dllnode *pNode = new dllnode; if ( NULL != pNode ) { canalMsg *pcanalMsg = new canalMsg; pNode->pObject = pcanalMsg; pNode->pKey = NULL; pNode->pstrKey = NULL; if ( NULL != pcanalMsg ) { memcpy( pcanalMsg, pMsg, sizeof( canalMsg ) ); } LOCK_MUTEX( m_transmitMutex ); dll_addNode( &m_transmitList, pNode ); UNLOCK_MUTEX( m_transmitMutex ); rv = true; } else { delete pMsg; } } } return rv; }
int CCAN232Obj::writeMsg( bool bExtended, unsigned long id, unsigned char dlc, unsigned char * pdata ) { int rv = 0; // Must be room for the message if ( m_can232obj.m_sndList.nCount < CAN232_MAX_SNDMSG ) { PCANALMSG pMsg = new canalMsg; pMsg->flags = 0; if ( bExtended ) pMsg->flags = CANAL_IDFLAG_EXTENDED; pMsg->id =id; pMsg->sizeData = dlc; if ( dlc > 0 ) { for ( int i = 0; i < pMsg->sizeData; i++ ) { pMsg->data[i ] = pdata[ i ]; } } if ( NULL != pMsg ) { dllnode *pNode = new dllnode; if ( NULL != pNode ) { pNode->pObject = pMsg; WaitForSingleObject( m_can232ObjMutex, INFINITE ); dll_addNode( &m_can232obj.m_sndList, pNode ); ReleaseMutex( m_can232ObjMutex ); rv = true; } else { delete pMsg; } } } return rv; }
bool CClientList::addClient( CClientItem *pClientItem ) { char buf[32]; pClientItem->m_clientID = m_clientIDCounter++; dllnode *pNode = new dllnode; if ( NULL != pNode ) { pNode->pKey = &pClientItem->m_clientID; pNode->pObject = pClientItem; sprintf( buf, "%s%i", VSCPD_CLIENT_MUTEX, pClientItem->m_clientID ); #ifdef WIN32 pClientItem->m_hclientMutex = CreateMutex( NULL, false, buf ); #endif dll_addNode( &m_clientList, pNode ); } return true; }
bool CPeakObj::writeMsg( canalMsg *pMsg ) { bool rv = false; if ( NULL != pMsg ) { // Must be room for the message if ( m_transmitList.nCount < PEAKDRV_MAX_SNDMSG ) { dllnode *pNode = new dllnode; if ( NULL != pNode ) { canalMsg *pcanalMsg = new canalMsg; pNode->pObject = pcanalMsg; pNode->pKey = NULL; pNode->pstrKey = NULL; if ( NULL != pcanalMsg ) { memcpy( pcanalMsg, pMsg, sizeof( canalMsg ) ); } LOCK_MUTEX( m_transmitMutex ); dll_addNode( &m_transmitList, pNode ); UNLOCK_MUTEX( m_transmitMutex ); rv = true; } else { delete pMsg; } } } return rv; }
void *workThread(void *pObject) { int rv = 0; int cnt; bool bActivity = true; short nPollCnt = 0; char szResponse[ 32 ]; printf("can232obj in workThread\n"); CCAN232Obj * pcan232obj = (CCAN232Obj *) pObject; if (NULL == pcan232obj) { pthread_exit(&rv); } while (pcan232obj->m_can232obj.m_bRun) { /////////////////////////////////////////////////////////////////////// // Receive /////////////////////////////////////////////////////////////////////// LOCK_MUTEX(pcan232obj->m_can232ObjMutex); // Noting to do if we should end... if (!pcan232obj->m_can232obj.m_bRun) continue; int cnt; unsigned char c; //printf("workThread - Receive\n"); c = pcan232obj->m_can232obj.m_comm.readChar(&cnt); while (-1 != cnt) { bActivity = true; if (CAN232_STATE_NONE == pcan232obj->m_can232obj.m_state) { if (('t' == c) || ('T' == c) || ('r' == c) || ('R' == c)) { pcan232obj->m_can232obj.m_state = CAN232_STATE_MSG; pcan232obj->m_can232obj.m_receiveBuf[ 0 ] = c; pcan232obj->m_can232obj.m_cntRcv = 1; } } else if (CAN232_STATE_MSG == pcan232obj->m_can232obj.m_state) { pcan232obj->m_can232obj.m_receiveBuf[ pcan232obj->m_can232obj.m_cntRcv++ ] = c; if (0x0d == c) { // One full message received If there is place in the queue // add message to it if (pcan232obj->m_can232obj.m_rcvList.nCount < CAN232_MAX_RCVMSG) { PCANALMSG pMsg = new canalMsg; pMsg->flags = 0; if (NULL != pMsg) { dllnode *pNode = new dllnode; if (NULL != pNode) { printf("workThread R - m_receiveBuf = [%s]\n", pcan232obj->m_can232obj.m_receiveBuf); int cnt = pcan232obj->m_can232obj.m_cntRcv; printf("workThread R - m_receiveBuf ["); for (int i = 0; i < cnt; i++) { printf("%02X ", pcan232obj->m_can232obj.m_receiveBuf[i]); } printf("]\n"); if (!can232ToCanal(pcan232obj->m_can232obj.m_receiveBuf, pMsg)) { pNode->pObject = pMsg; dll_addNode(&pcan232obj->m_can232obj.m_rcvList, pNode); // Update statistics pcan232obj->m_can232obj.m_stat.cntReceiveData += pMsg->sizeData; pcan232obj->m_can232obj.m_stat.cntReceiveFrames += 1; printf("workThread R - RcvFrames = [%ld]\n\n", pcan232obj->m_can232obj.m_stat.cntReceiveFrames); } else { // Failed to translate message printf("workThread R - Receive Failed to translate message\n"); delete pMsg; delete pNode; } } else { delete pMsg; } } } pcan232obj->m_can232obj.m_state = CAN232_STATE_NONE; } if (pcan232obj->m_can232obj.m_cntRcv > sizeof( pcan232obj->m_can232obj.m_receiveBuf)) { // Problems start all over again pcan232obj->m_can232obj.m_state = CAN232_STATE_NONE; } } c = pcan232obj->m_can232obj.m_comm.readChar(&cnt); } // while ( 0 != cnt ) UNLOCK_MUTEX(pcan232obj->m_can232ObjMutex); /////////////////////////////////////////////////////////////////////// // Transmit /////////////////////////////////////////////////////////////////////// //printf("workThread - Transmit\n"); LOCK_MUTEX(pcan232obj->m_can232ObjMutex); // Is there something to transmit // while ( ( NULL != pcan232obj->m_can232obj.m_sndList.pHead ) && // ( NULL != pcan232obj->m_can232obj.m_sndList.pHead->pObject ) ) { if ((NULL != pcan232obj->m_can232obj.m_sndList.pHead) && (NULL != pcan232obj->m_can232obj.m_sndList.pHead->pObject)) { char buf[ 80 ]; canalMsg msg; bActivity = true; memcpy(&msg, pcan232obj->m_can232obj.m_sndList.pHead->pObject, sizeof( canalMsg)); dll_removeNode(&pcan232obj->m_can232obj.m_sndList, pcan232obj->m_can232obj.m_sndList.pHead); // Must be a valid standard id if (!(msg.flags & CANAL_IDFLAG_EXTENDED) && (msg.id > 0x7ff)) { msg.id &= 0x7ff; }; // Must be a valid extended id if ((msg.flags & CANAL_IDFLAG_EXTENDED) && (msg.id > 0x1fffffff)) { msg.id &= 0x1fffffff; } // Currently there is a bug in ice old asm can232 tranceiver, and allow only small hex digits if (msg.flags & CANAL_IDFLAG_EXTENDED) { sprintf(buf, "T%8.8lx%i", msg.id, msg.sizeData); } else { sprintf(buf, "t%3.3lx%i", msg.id, msg.sizeData); } if (msg.sizeData) { char hex[5]; for (int i = 0; i < msg.sizeData; i++) { sprintf(hex, "%2.2X", msg.data[i]); //sprintf( hex, "%02.2x", msg.data[i] ); strcat(buf, hex); } strcat(buf, "\r"); } // Send the data pcan232obj->m_can232obj.m_comm.comm_puts(buf, strlen(buf), true); printf("workThread T - Write ["); for (int i = 0; i < strlen(buf); i++) { if (buf[i] == 0x0D) { printf("[CR]"); } else { printf("%c", buf[i]); } } printf("]\n"); pcan232obj->m_can232obj.m_comm.comm_gets(szResponse, sizeof( szResponse), 10000); printf("workThread T - Read ["); for (int i = 0; i < strlen(szResponse); i++) { if (szResponse[i] == 0x0D) { printf("[CR]"); } else { printf("%c", szResponse[i]); } } printf("]\n\n"); // needed !! At least at 19200 baud SLEEP(100); // Update statistics pcan232obj->m_can232obj.m_stat.cntTransmitData += msg.sizeData; pcan232obj->m_can232obj.m_stat.cntTransmitFrames += 1; //} // while there is something to transmit } // if there is something to transmit // If not in autopoll mode we do a poll for all frames first nPollCnt++; if (!pcan232obj->m_can232obj.m_bAuto && (nPollCnt > 5)) { char szCmd[5]; sprintf(szCmd, "A\r"); pcan232obj->m_can232obj.m_comm.comm_puts(szCmd, strlen(szCmd), true); nPollCnt = 0; } UNLOCK_MUTEX(pcan232obj->m_can232ObjMutex); if (!bActivity) SLEEP(100); bActivity = false; } // while( pcan232obj->m_can232obj.m_bRun ) pthread_exit(&rv); }
void clientThreadLevel2( void *pThreadObject ) { char *p; char buf[ MAX_PATH ]; vscpEvent *pEvent; dllnode *pNode; CControlObject *pctrlObject = NULL; HANDLE hMap; // http://msdn.microsoft.com/msdnmag/issues/0300/security/default.aspx // here we use a SECURITY_DESCRIPTOR to say // that we don't want *any DACL at all* SECURITY_DESCRIPTOR sd; InitializeSecurityDescriptor( &sd, SECURITY_DESCRIPTOR_REVISION); SetSecurityDescriptorDacl(&sd, TRUE, 0, FALSE); SECURITY_ATTRIBUTES sa = { sizeof sa, &sd, TRUE }; _clientstruct clientInfo; memcpy( &clientInfo, (_clientstruct *)pThreadObject, sizeof( _clientstruct ) ); pctrlObject = clientInfo.m_pctrlObject; // We need to create a clientobject and add this object to the list CClientItem *pClientItem = new CClientItem; if ( NULL == pClientItem ) { delete (_clientstruct *)pThreadObject; // Delete the client structure ExitThread( -1 ); } // This is a Level II Client pClientItem->m_ClientLevel = CLIENT_ITEM_LEVEL2; // We need to get the shared memory sprintf( buf, CANAL_LISTEN_CLIENT_SHM_TEMPLATE, clientInfo.m_shmid ); if ( NULL == ( hMap = ::OpenFileMapping( FILE_MAP_WRITE, TRUE, buf ) ) ) { delete (_clientstruct *)pThreadObject; // Delete the client structure ExitThread( -1 ); } struct __shmCanalLevelII *pLevel2 = (struct __shmCanalLevelII *)MapViewOfFile( hMap, FILE_MAP_WRITE, 0, 0, 0 ); if ( NULL == pLevel2 ) { delete (_clientstruct *)pThreadObject; // Delete the client structure CloseHandle( hMap ); ExitThread( -1 ); } void *pDataArea= pLevel2->m_data; vscpEvent *pEventArea = &pLevel2->m_VSCP_Event; pLevel2->m_command = VSCP_COMMAND_NOOP; // Create the client command semaphore HANDLE hSemCmd; sprintf( buf, CANAL_CLIENT_COMMAND_SEM_TEMPLATE, clientInfo.m_shmid ); if ( NULL == ( hSemCmd = CreateSemaphore( &sa, 0, 1, buf ) ) ) { delete (_clientstruct *)pThreadObject; // Delete the client structure CloseHandle( hMap ); ExitThread( -1 ); } // Create the client Done semaphore HANDLE hSemDone; sprintf( buf, CANAL_CLIENT_DONE_SEM_TEMPLATE, clientInfo.m_shmid ); if ( NULL == ( hSemDone = CreateSemaphore( &sa, 0, 1, buf ) ) ) { delete (_clientstruct *)pThreadObject; // Delete the client structure CloseHandle( hSemCmd ); CloseHandle( hMap ); ExitThread( -1 ); } // Share the command semaphore pLevel2->m_semCmd = clientInfo.m_shmid; // Add the client to the Client List pctrlObject->m_wxClientMutex.Lock(); pctrlObject->addClient( pClientItem ); pctrlObject->m_wxClientMutex.Unlock(); pLevel2->m_test = 0xaa55; // Confirm to client that we are here pClientItem->m_bOpen = true; while ( pClientItem->m_bOpen && !pctrlObject->m_bQuit ) { // Wait for command from client if ( WAIT_OBJECT_0 != WaitForSingleObject( hSemCmd, 500 ) ) { continue; } switch( pLevel2->m_command ) { // * * * * O P E N * * * * case VSCP_COMMAND_OPEN: wxLogTrace("wxTRACE_Canald_LevelII", "ClientThread2: Open"); pLevel2->m_Response = CANAL_RESPONSE_SUCCESS; break; // * * * * C L O S E * * * * case VSCP_COMMAND_CLOSE: wxLogTrace("wxTRACE_Canald_LevelII", "ClientThread2: Close"); pLevel2->m_Response = CANAL_RESPONSE_SUCCESS; pClientItem->m_bOpen = false; break; // * * * * S E N D * * * * case VSCP_COMMAND_SEND: wxLogTrace("wxTRACE_Canald_LevelII", "ClientThread2: Send %X", pClientItem->m_clientID ); pLevel2->m_Response = CANAL_RESPONSE_SUCCESS; pNode = new dllnode; if ( NULL != pNode ) { pEvent = new vscpEvent; // Create new VSCP Message if ( NULL != pEvent ) { // Save the originating clients id so // this client dont get the message back pNode->obid = pClientItem->m_clientID; // Copy message memcpy( pEvent, pEventArea, sizeof( vscpEvent ) ); // And data... if ( pEvent->sizeData > 0 ) { // Copy in data pEvent->pdata = new uint8_t[ pEvent->sizeData ]; if ( NULL != pEvent->pdata ) { memcpy( pEvent->pdata, pDataArea ,pEvent->sizeData ); } } else { // No data pEvent->pdata = NULL; } // Check if GUID of interface should be used // as packet GUID if ( pLevel2->m_cmdArg1 ) { memcpy( pEvent->GUID, pClientItem->m_GUID, 16 ); } // Statistics pClientItem->m_statistics.cntTransmitData += pEvent->sizeData; pClientItem->m_statistics.cntTransmitFrames++; // We use the message id as the sort key for the message // in the queue. The high part of this id is the priority // for the message. // The non-id part should possibly be nulled but this depends // on if we regard the message as "sent" or not. If not, a // message with a lower id should be transfered first over the // bus. pNode->Key = pEvent->head; pNode->pKey = &pNode->Key; pNode->pObject = pEvent; // There must be room in the send queue if ( pctrlObject->m_maxItemsInSendQueue > pctrlObject->m_sendLevel2Queue.nCount ) { pctrlObject->m_wxQ2OutMutex.Lock(); if ( !dll_addNode( &pctrlObject->m_sendLevel2Queue, pNode ) ) { pLevel2->m_Response = CANAL_RESPONSE_ERROR; pLevel2->m_ResponseCode = CANAL_IFERROR_SEND_STORAGE; } else { pLevel2->m_Response = CANAL_RESPONSE_SUCCESS; SetEvent( pctrlObject->m_hEventSendQ2 ); } pctrlObject->m_wxQ2OutMutex.Unlock(); } else { pLevel2->m_Response = CANAL_RESPONSE_ERROR; pLevel2->m_ResponseCode = CANAL_IFERROR_BUFFER_FULL; if ( NULL != pNode ) { if ( NULL != pNode->pObject ) { if ( NULL != pEvent->pdata ) delete [] pEvent->pdata; delete pEvent; } delete pNode; } } } else { delete pNode; pLevel2->m_Response = CANAL_RESPONSE_ERROR; pLevel2->m_ResponseCode = CANAL_IFERROR_SEND_MSG_ALLOCATON; } } // dllNode break; // * * * * R E C E I V E * * * * case VSCP_COMMAND_RECEIVE: wxLogTrace("wxTRACE_Canald_LevelII", "ClientThread2: Receive - before client lock %X", pClientItem->m_clientID ); pClientItem->m_wxMsgMutex.Lock(); if ( !pClientItem->m_bOpen ) { pLevel2->m_Response = CANAL_RESPONSE_ERROR; pLevel2->m_ResponseCode = CANAL_IFERROR_CHANNEL_CLOSED; } else { dllnode *pNode; vscpEvent *pEvent = (vscpEvent *)pEventArea; if ( NULL != ( pNode = pClientItem->m_inputQueue.pHead ) ) { // There is a message available pLevel2->m_Response = CANAL_RESPONSE_SUCCESS; // Copy message memcpy( pEvent, pNode->pObject, sizeof( vscpEvent ) ); // If there is data it also must be copied if ( ( pEvent->sizeData > 0 ) && ( NULL != pEvent->pdata ) ) { memcpy( pDataArea, pEvent->pdata, pEvent->sizeData ); } // Remove the old data if ( NULL != pEvent->pdata ) delete pEvent->pdata; pEvent->pdata = NULL; // Data stored in message // Remove the node dll_removeNode( &pClientItem->m_inputQueue, pNode ); // If queue empty reset receive flag if ( NULL == ( pNode = pClientItem->m_inputQueue.pHead ) ) { ResetEvent( pClientItem->m_hEventReceive ); } } } pClientItem->m_wxMsgMutex.Unlock(); break; // * * * * D A T A A V A I L A B L E * * * * case VSCP_COMMAND_CHECKDATA: //wxLogTrace("wxTRACE_Canald_LevelII", "ClientThread%n: Data Available %X", pClientItem->m_clientID. pClientItem->m_inputQueue.nCount); pClientItem->m_wxMsgMutex.Lock(); if ( !pClientItem->m_bOpen ) { pLevel2->m_Response = CANAL_RESPONSE_ERROR; pLevel2->m_ResponseCode = CANAL_IFERROR_CHANNEL_CLOSED; } else { pLevel2->m_Response = CANAL_RESPONSE_SUCCESS; unsigned int *pnMsg = (unsigned int *)pDataArea; //*pnMsg = dll_getNodeCount( &pClientItem->m_inputQueue ); *pnMsg = pClientItem->m_inputQueue.nCount; } pClientItem->m_wxMsgMutex.Unlock(); break; // * * * * S T A T U S * * * * case VSCP_COMMAND_STATUS: if ( !pClientItem->m_bOpen ) { pLevel2->m_Response = CANAL_RESPONSE_ERROR; pLevel2->m_ResponseCode = CANAL_IFERROR_CHANNEL_CLOSED; } else { pLevel2->m_Response = CANAL_RESPONSE_SUCCESS; // Status memcpy( pDataArea, &pClientItem->m_status, sizeof( canalStatus ) ); } break; // * * * * S T A T I S T I C S * * * * case VSCP_COMMAND_STATISTICS: if ( !pClientItem->m_bOpen ) { pLevel2->m_Response = CANAL_RESPONSE_ERROR; pLevel2->m_ResponseCode = CANAL_IFERROR_CHANNEL_CLOSED; } else { memcpy( pDataArea, &pClientItem->m_statistics, sizeof( &pClientItem->m_statistics ) ); pLevel2->m_Response = CANAL_RESPONSE_SUCCESS; } break; // * * * * F I L T E R * * * * case VSCP_COMMAND_FILTER: if ( !pClientItem->m_bOpen ) { pLevel2->m_Response = CANAL_RESPONSE_ERROR; pLevel2->m_ResponseCode = CANAL_IFERROR_CHANNEL_CLOSED; } else { // Set filter memcpy( &pClientItem->m_filter, pDataArea, sizeof( vscpEventFilter ) ); pLevel2->m_Response = CANAL_RESPONSE_SUCCESS; } break; // * * * * V E R S I O N * * * * case VSCP_COMMAND_VERSION: // Get version p = (char *)pDataArea; *( p + POS_VSCPD_MAJOR_VERSION ) = CANAL_MAIN_VERSION; *( p + POS_VSCPD_MINOR_VERSION ) = CANAL_MINOR_VERSION; *( p + POS_VSCPD_SUB_VERSION ) = CANAL_SUB_VERSION; pLevel2->m_Response = CANAL_RESPONSE_SUCCESS; break; // * * * * G E T I / F G U I D * * * * case VSCP_COMMAND_GET_GUID: memcpy( pDataArea, pClientItem->m_GUID, 16 ); pLevel2->m_Response = CANAL_RESPONSE_SUCCESS; break; // * * * * S E T I / F G U I D * * * * case VSCP_COMMAND_SET_GUID: memcpy( pClientItem->m_GUID, pDataArea, 16 ); pLevel2->m_Response = CANAL_RESPONSE_SUCCESS; break; // * * * * G E T C H A N N E L I D * * * * case VSCP_COMMAND_GET_CHID: break; // * * * * N O O P * * * * case VSCP_COMMAND_NOOP: wxLogTrace("wxTRACE_Canald_LevelII", "ClientThread2: NOOP %X", pClientItem->m_clientID); pLevel2->m_Response = CANAL_RESPONSE_SUCCESS; break; default: wxLogTrace("wxTRACE_Canald_LevelII", "ClientThread2: Unknown command %X", pClientItem->m_clientID); pLevel2->m_Response = CANAL_RESPONSE_ERROR; pLevel2->m_ResponseCode = CANAL_IFERROR_UNKNOWN_COMMAND; break; } // We are Done ReleaseSemaphore( hSemDone, 1, NULL ); } // while running wxLogTrace( "wxTRACE_Canald_LevelII", "ClientThread2: About to end. ClientId = %X", pClientItem->m_clientID ); // Remove messages in the client queues pctrlObject->removeClient( pClientItem ); wxLogDebug("ClientThread2: Removed client item."); delete (_clientstruct *)pThreadObject; CloseHandle( hMap ); CloseHandle( hSemCmd ); CloseHandle( hSemDone ); wxLogDebug("ClientThread2: Exit."); ExitThread( 0 ); }
void workThread( void *pThreadObject ) { bool bRun = true; bool bActivity = true; short nPollCnt = 0; DWORD errorCode = 0; HANDLE can232ObjMutex; // Must hav a valid work object if ( NULL == pThreadObject ) ExitThread( errorCode ); // Get the object pointer in place struct _can232obj *pcan232obj = (struct _can232obj *)pThreadObject; can232ObjMutex = OpenMutex( MUTEX_ALL_ACCESS, false, CAN232_OBJ_MUTEX ); while ( pcan232obj->m_bRun ) { /////////////////////////////////////////////////////////////////////// // Receive /////////////////////////////////////////////////////////////////////// WaitForSingleObject( can232ObjMutex, INFINITE ); int cnt; unsigned char c; c = pcan232obj->m_comm.readChar( &cnt ); while ( 0 != cnt ) { bActivity = true; if ( CAN232_STATE_NONE == pcan232obj->m_state ) { if ( ('t' == c ) || ( 'T' == c ) || ('r' == c ) || ( 'R' == c ) ) { pcan232obj->m_state = CAN232_STATE_MSG; pcan232obj->m_receiveBuf[ 0 ] = c; pcan232obj->m_cntRcv = 1; } } else if ( CAN232_STATE_MSG == pcan232obj->m_state ) { pcan232obj->m_receiveBuf[ pcan232obj->m_cntRcv++ ] = c; if ( 0x0d == c ) { // One full message received // If there is place in the queue // add message to it if ( pcan232obj->m_rcvList.nCount < CAN232_MAX_RCVMSG ) { PCANALMSG pMsg = new canalMsg; pMsg->flags = 0; if ( NULL != pMsg ) { dllnode *pNode = new dllnode; if ( NULL != pNode ) { if ( !can323ToCanal( pcan232obj->m_receiveBuf, pMsg ) ) { pNode->pObject = pMsg; dll_addNode( &pcan232obj->m_rcvList, pNode ); // Update statistics pcan232obj->m_stat.cntReceiveData += pMsg->sizeData; pcan232obj->m_stat.cntReceiveFrames += 1; } else { // Failed to translate message delete pMsg; delete pNode; } } else { delete pMsg; } } } pcan232obj->m_state = CAN232_STATE_NONE; } if ( pcan232obj->m_cntRcv > sizeof( pcan232obj->m_receiveBuf ) ) { // Problems start all over again pcan232obj->m_state = CAN232_STATE_NONE; } } c = pcan232obj->m_comm.readChar( &cnt ); } // while ReleaseMutex( can232ObjMutex ); /////////////////////////////////////////////////////////////////////// // Transmit /////////////////////////////////////////////////////////////////////// WaitForSingleObject( can232ObjMutex, INFINITE ); // Is there anything to transmit if ( ( NULL != pcan232obj->m_sndList.pHead ) && ( NULL != pcan232obj->m_sndList.pHead->pObject ) ) { char buf[ 80 ]; canalMsg msg; bActivity = true; memcpy( &msg, pcan232obj->m_sndList.pHead->pObject, sizeof( canalMsg ) ); dll_removeNode( &pcan232obj->m_sndList, pcan232obj->m_sndList.pHead ); // Must be a valid standard id if ( !( msg.flags & CANAL_IDFLAG_EXTENDED ) && ( msg.id > 0x7ff ) ) { msg.id &= 0x7ff; }; // Must be a valid extended id if ( ( msg.flags & CANAL_IDFLAG_EXTENDED ) && ( msg.id > 0x1fffffff ) ) { msg.id &= 0x1fffffff; } if ( msg.flags & CANAL_IDFLAG_EXTENDED ) { sprintf( buf, "T%08.8lX%i", msg.id, msg.sizeData ); } else { sprintf( buf, "t%03.3lX%i", msg.id, msg.sizeData ); } if ( msg.sizeData ) { char hex[5]; for ( int i= 0; i< msg.sizeData; i++ ) { sprintf( hex, "%02.2X", msg.data[i] ); strcat( buf, hex ); } } // Send the data char szResponse[ 32 ]; pcan232obj->m_comm.write( buf, true, true ); pcan232obj->m_comm.readBuf( szResponse, sizeof( szResponse ), -1 ); // Update statistics pcan232obj->m_stat.cntTransmitData += msg.sizeData; pcan232obj->m_stat.cntTransmitFrames += 1; // If not in autopoll mode if ( 0x0d == *szResponse ) { } // If in autopoll mode extended message else if ( ( msg.flags & CANAL_IDFLAG_EXTENDED ) && ( 'Z' == *szResponse ) ) { } // If in autopoll mode standard message else if ( !( msg.flags & CANAL_IDFLAG_EXTENDED ) && ( 'z' == *szResponse ) ) { } } // If not in autopoll mode we do a poll for all frames first nPollCnt++; if ( !pcan232obj->m_bAuto && ( nPollCnt > 5 ) ) { pcan232obj->m_comm.write( "A", true, true ); nPollCnt = 0; } ReleaseMutex( can232ObjMutex ); if ( !bActivity ) Sleep ( 100 ); bActivity = false; } // Release the mutex for other threads to use ReleaseMutex( can232ObjMutex ); ExitThread( errorCode ); }
void *workThreadReceive( void *pObject ) #endif { #ifdef WIN32 DWORD errorCode = 0; #else int rv = 0; #endif CPeakObj * pobj = ( CPeakObj *)pObject; if ( NULL == pobj ) { #ifdef WIN32 ExitThread( errorCode ); // Fail #else pthread_exit( &rv ); #endif } PeakCanMsg peakMsg; while ( pobj->m_bRun ) { // Noting to do if we should end... if ( !pobj->m_bRun ) continue; LOCK_MUTEX( pobj->m_peakMutex ); while ( 0 == ( pobj->m_procRead( &peakMsg ) & PEAK_CAN_ERR_QRCVEMPTY ) ) { // Check if this is a status message if ( PCAN_MSGTYPE_STATUS & peakMsg.msgType ) { continue; // TODO } // Write to the receive buffer if ( pobj->m_receiveList.nCount < PEAKDRV_MAX_RCVMSG ) { PCANALMSG pMsg = new canalMsg; pMsg->flags = 0; if ( NULL != pMsg ) { dllnode *pNode = new dllnode; if ( NULL != pNode ) { pMsg->timestamp = GetTickCount() * 1000; pMsg->id = peakMsg.id; pMsg->sizeData = peakMsg.len; memcpy( pMsg->data, peakMsg.data, pMsg->sizeData ); // If extended set extended flag if ( PCAN_MSGTYPE_EXTENDED & peakMsg.msgType ) { pMsg->flags |= CANAL_IDFLAG_EXTENDED; } // Check for RTS package if ( PCAN_MSGTYPE_RTR & peakMsg.msgType ) { pMsg->flags |= CANAL_IDFLAG_RTR; } pNode->pObject = pMsg; LOCK_MUTEX( pobj->m_receiveMutex ); dll_addNode( &pobj->m_receiveList, pNode ); UNLOCK_MUTEX( pobj->m_receiveMutex ); // Update statistics pobj->m_stat.cntReceiveData += pMsg->sizeData; pobj->m_stat.cntReceiveFrames += 1; } else { delete pMsg; } } } else { // Full buffer pobj->m_stat.cntOverruns++; } } // while rcv msg UNLOCK_MUTEX( pobj->m_peakMutex ); SLEEP( 1 ); } // while #ifdef WIN32 ExitThread( errorCode ); #else pthread_exit( &rv ); #endif }
void *workThreadReceive( void *pObject ) #endif { int cntMsg,readMsg; #ifdef WIN32 DWORD errorCode = 0; #else int rv = 0; #endif CVectorObj * pobj = ( CVectorObj *)pObject; if ( NULL == pobj ) { #ifdef WIN32 ExitThread( errorCode ); // Fail #else pthread_exit( &rv ); #endif } while ( pobj->m_bRun ) { // Noting to do if we should end... if ( !pobj->m_bRun ) continue; LOCK_MUTEX( pobj->m_vectorMutex ); // get # in receive queue ncdGetReceiveQueueLevel( pobj->m_portHandle, &cntMsg ); if ( cntMsg > 0 ) { // There are messages to fetch VCAN_EVENT *peventarray = new VCAN_EVENT[ cntMsg ]; if ( NULL != peventarray ) { readMsg = cntMsg; if ( VSUCCESS != ncdReceive( pobj->m_portHandle, VCAN_POLL, 0, &readMsg, peventarray ) ) { // Failed readMsg = 0; } if ( readMsg > 0 ) { // Write them to the receive buffer for ( int i=0; i<readMsg; i++ ) { if ( peventarray[ i ].tag == V_CHIP_STATE ) { pobj->m_status.channel_status = peventarray[ i ].tagData.chipState.txErrorCounter + (peventarray[ i ].tagData.chipState.rxErrorCounter << 8); if ( peventarray[ i ].tagData.chipState.busStatus & CHIPSTAT_BUSOFF ) { pobj->m_status.channel_status |= 0x80000000; } if ( peventarray[ i ].tagData.chipState.busStatus & CHIPSTAT_ERROR_PASSIVE ) { pobj->m_status.channel_status |= 0x20000000; } if ( peventarray[ i ].tagData.chipState.busStatus & CHIPSTAT_ERROR_WARNING ) { pobj->m_status.channel_status |= 0x40000000; } if ( peventarray[ i ].tagData.chipState.busStatus & CHIPSTAT_ERROR_ACTIVE ) { pobj->m_status.channel_status |= 0x10000000; } continue; } else if ( peventarray[ i ].tag == V_TRANSMIT_MSG ) { ; } else if ( peventarray[ i ].tag != V_RECEIVE_MSG ) { continue; } if ( pobj->m_receiveList.nCount < VECTOR_MAX_RCVMSG ) { PCANALMSG pMsg = new canalMsg; pMsg->flags = 0; // if echo mark as send message if ( peventarray[ i ].tag == V_TRANSMIT_MSG ) { pMsg->flags |= CANAL_IDFLAG_SEND; } if ( NULL != pMsg ) { dllnode *pNode = new dllnode; if ( NULL != pNode ) { pMsg->timestamp = peventarray[ i ].timeStamp; pMsg->id = peventarray[ i ].tagData.msg.id; if ( pMsg->id & CANAL_IDFLAG_EXTENDED ) { pMsg->id &= 0x7fffffff; pMsg->flags |= CANAL_IDFLAG_EXTENDED; } pMsg->sizeData = peventarray[ i ].tagData.msg.dlc; memcpy( pMsg->data, peventarray[ i ].tagData.msg.data, pMsg->sizeData ); // Check for RTS package if ( peventarray[ i ].tagData.msg.flags & MSGFLAG_REMOTE_FRAME ) { pMsg->flags |= CANAL_IDFLAG_RTR; } // Check for overrun error if ( peventarray[ i ].tagData.msg.flags & MSGFLAG_OVERRUN ) { pobj->m_stat.cntOverruns++; } // Check for error frame if ( peventarray[ i ].tagData.msg.flags & MSGFLAG_ERROR_FRAME ) { pMsg->flags |= CANAL_IDFLAG_STATUS; } pNode->pObject = pMsg; LOCK_MUTEX( pobj->m_receiveMutex ); dll_addNode( &pobj->m_receiveList, pNode ); UNLOCK_MUTEX( pobj->m_receiveMutex ); // Update statistics pobj->m_stat.cntReceiveData += pMsg->sizeData; pobj->m_stat.cntReceiveFrames += 1; } else { delete pMsg; } } } else { // Full buffer pobj->m_stat.cntOverruns++; } } } delete[] peventarray; } } UNLOCK_MUTEX( pobj->m_vectorMutex ); SLEEP( 1 ); } // while #ifdef WIN32 ExitThread( errorCode ); #else pthread_exit( &rv ); #endif }
void clientThreadLevel1( void *pThreadObject ) { char buf[ MAX_PATH ]; char *p; canalMsg *pMsg; dllnode *pNode; CControlObject *pctrlObject = NULL; HANDLE hMap; wxLogDebug("Level I Client Started"); // http://msdn.microsoft.com/msdnmag/issues/0300/security/default.aspx // here we use a SECURITY_DESCRIPTOR to say // that we don't want *any DACL at all* SECURITY_DESCRIPTOR sd; InitializeSecurityDescriptor( &sd, SECURITY_DESCRIPTOR_REVISION); SetSecurityDescriptorDacl(&sd, TRUE, 0, FALSE); SECURITY_ATTRIBUTES sa = { sizeof sa, &sd, TRUE }; _clientstruct clientInfo; memcpy( &clientInfo, (_clientstruct *)pThreadObject, sizeof( _clientstruct ) ); pctrlObject = clientInfo.m_pctrlObject; // We need to create a clientobject and add this object to the list CClientItem *pClientItem = new CClientItem; if ( NULL == pClientItem ) { delete (_clientstruct *)pThreadObject; // Delete the client structure ExitThread( -1 ); } wxLogDebug("Level I Client 1"); // This is a Level II Client pClientItem->m_ClientLevel = CLIENT_ITEM_LEVEL1; // We need to get the shared memory sprintf( buf, CANAL_LISTEN_CLIENT_SHM_TEMPLATE, clientInfo.m_shmid ); if ( NULL == ( hMap = ::OpenFileMapping( FILE_MAP_WRITE, TRUE, buf ) ) ) { delete (_clientstruct *)pThreadObject; // Delete the client structure ExitThread( -1 ); } wxLogDebug("Level I Client 5"); struct __shmCanalLevelI *pLevel1 = (struct __shmCanalLevelI *)MapViewOfFile( hMap, FILE_MAP_WRITE, 0, 0, 0 ); if ( NULL == pLevel1 ) { delete (_clientstruct *)pThreadObject; // Delete the client structure CloseHandle( hMap ); ExitThread( -1 ); } wxLogDebug("Level I Client 6"); void *pDataArea= pLevel1->m_data; pLevel1->m_command = CANAL_COMMAND_NOOP; // Create the client command semaphore HANDLE hSemCmd; sprintf( buf, CANAL_CLIENT_COMMAND_SEM_TEMPLATE, clientInfo.m_shmid ); if ( NULL == ( hSemCmd = CreateSemaphore( &sa, 0, 1, buf ) ) ) { delete (_clientstruct *)pThreadObject; // Delete the client structure CloseHandle( hMap ); ExitThread( -1 ); } wxLogDebug("Level I Client 7"); // Create the client Done semaphore HANDLE hSemDone; sprintf( buf, CANAL_CLIENT_DONE_SEM_TEMPLATE, clientInfo.m_shmid ); if ( NULL == ( hSemDone = CreateSemaphore( &sa, 0, 1, buf ) ) ) { delete (_clientstruct *)pThreadObject; // Delete the client structure CloseHandle( hSemCmd ); CloseHandle( hMap ); ExitThread( -1 ); } wxLogDebug("Level I Client 7"); // Share the command semaphore pLevel1->m_semCmd = clientInfo.m_shmid; // Add the client to the Client List pctrlObject->m_wxClientMutex.Lock(); pctrlObject->addClient( pClientItem ); pctrlObject->m_wxClientMutex.Unlock(); pLevel1->m_test = 0xaa55; // Confirm to client that we are here pClientItem->m_bOpen = true; while ( pClientItem->m_bOpen && !pctrlObject->m_bQuit ) { // Wait for command from client if ( WAIT_OBJECT_0 != WaitForSingleObject( hSemCmd, 500 ) ) { continue; } switch( pLevel1->m_command ) { // * * * * O P E N * * * * case CANAL_COMMAND_OPEN: pLevel1->m_Response = CANAL_RESPONSE_SUCCESS; break; // * * * * C L O S E * * * * case CANAL_COMMAND_CLOSE: pLevel1->m_Response = CANAL_RESPONSE_SUCCESS; pClientItem->m_bOpen = false; break; // * * * * S E N D * * * * case CANAL_COMMAND_SEND: pLevel1->m_Response = CANAL_RESPONSE_SUCCESS; pNode = new dllnode; if ( NULL != pNode ) { pMsg = new canalMsg; // Create new Canal Message if ( NULL != pMsg ) { // Save the originating clients id so // this client dont get the message back pNode->obid = pClientItem->m_clientID; // Copy message memcpy( pMsg, pDataArea, sizeof( canalMsg ) ); // Statistics pClientItem->m_statistics.cntTransmitData += pMsg->sizeData; pClientItem->m_statistics.cntTransmitFrames++; // We use the message id as the sort key for the message // in the queue. The high part of this id is the priority // for the message. // The non-id part should possibly be nulled but this depends // on if we regard the message as "sent" or not. If not, a // message with a lower id should be transfered first over the // bus. pNode->Key = pMsg->id; pNode->pKey = &pNode->Key; pNode->pObject = pMsg; // There must be room in the send queue if ( pctrlObject->m_maxItemsInSendQueue > pctrlObject->m_sendLevel1Queue.nCount ) { pctrlObject->m_wxQ1OutMutex.Lock(); if ( !dll_addNode( &pctrlObject->m_sendLevel1Queue, pNode ) ) { pLevel1->m_Response = CANAL_RESPONSE_ERROR; pLevel1->m_ResponseCode = CANAL_IFERROR_SEND_STORAGE; } else { pLevel1->m_Response = CANAL_RESPONSE_SUCCESS; SetEvent( pctrlObject->m_hEventSendQ1 ); } pctrlObject->m_wxQ1OutMutex.Unlock(); } else { pLevel1->m_Response = CANAL_RESPONSE_ERROR; pLevel1->m_ResponseCode = CANAL_IFERROR_BUFFER_FULL; if ( NULL != pNode ) { if ( NULL != pNode->pObject ) { delete pMsg; } delete pNode; } } } else { delete pNode; pLevel1->m_Response = CANAL_RESPONSE_ERROR; pLevel1->m_ResponseCode = CANAL_IFERROR_SEND_MSG_ALLOCATON; } } // dllNode break; // * * * * R E C E I V E * * * * case CANAL_COMMAND_RECEIVE: if ( !pClientItem->m_bOpen ) { pLevel1->m_Response = CANAL_RESPONSE_ERROR; pLevel1->m_ResponseCode = CANAL_IFERROR_CHANNEL_CLOSED; } else { pctrlObject->m_wxClientMutex.Lock(); dllnode *pNode; canalMsg *pMsg = (canalMsg *)pDataArea; if ( NULL != ( pNode = pClientItem->m_inputQueue.pHead ) ) { // There is a message available pLevel1->m_Response = CANAL_RESPONSE_SUCCESS; memcpy( pMsg, pNode->pObject, sizeof( canalMsg ) ); // Remove the node dll_removeNode( &pClientItem->m_inputQueue, pNode ); // If queue empty reset receive flag if ( NULL == ( pNode = pClientItem->m_inputQueue.pHead ) ) { ResetEvent( pClientItem->m_hEventReceive ); } } pctrlObject->m_wxClientMutex.Unlock(); } break; // * * * * D A T A A V A I L A B L E * * * * case CANAL_COMMAND_CHECKDATA: if ( !pClientItem->m_bOpen ) { pLevel1->m_Response = CANAL_RESPONSE_ERROR; pLevel1->m_ResponseCode = CANAL_IFERROR_CHANNEL_CLOSED; } else { pLevel1->m_Response = CANAL_RESPONSE_SUCCESS; unsigned int *pnMsg = (unsigned int *)pDataArea; //*pnMsg = dll_getNodeCount( &pClient->m_inputQueue ); *pnMsg = pClientItem->m_inputQueue.nCount; } break; // * * * * S T A T U S * * * * case CANAL_COMMAND_STATUS: if ( !pClientItem->m_bOpen ) { pLevel1->m_Response = CANAL_RESPONSE_ERROR; pLevel1->m_ResponseCode = CANAL_IFERROR_CHANNEL_CLOSED; } else { pLevel1->m_Response = CANAL_RESPONSE_SUCCESS; // Status memcpy( pDataArea, &pClientItem->m_status, sizeof( canalStatus ) ); } break; // * * * * S T A T I S T I C S * * * * case CANAL_COMMAND_STATISTICS: if ( !pClientItem->m_bOpen ) { pLevel1->m_Response = CANAL_RESPONSE_ERROR; pLevel1->m_ResponseCode = CANAL_IFERROR_CHANNEL_CLOSED; } else { memcpy( pDataArea, &pClientItem->m_statistics, sizeof( &pClientItem->m_statistics ) ); pLevel1->m_Response = CANAL_RESPONSE_SUCCESS; } break; // * * * * F I L T E R * * * * case CANAL_COMMAND_FILTER: if ( !pClientItem->m_bOpen ) { pLevel1->m_Response = CANAL_RESPONSE_ERROR; pLevel1->m_ResponseCode = CANAL_IFERROR_CHANNEL_CLOSED; } else { // Set filter memcpy( &pClientItem->m_filter, pDataArea, sizeof( pClientItem->m_filter ) ); pLevel1->m_Response = CANAL_RESPONSE_SUCCESS; } break; // * * * * M A S K * * * * case CANAL_COMMAND_MASK: if ( !pClientItem->m_bOpen ) { pLevel1->m_Response = CANAL_RESPONSE_ERROR; pLevel1->m_ResponseCode = CANAL_IFERROR_CHANNEL_CLOSED; } else { // Set mask memcpy( &pClientItem->m_mask, pDataArea, sizeof( pClientItem->m_mask ) ); pLevel1->m_Response = CANAL_RESPONSE_SUCCESS; } break; // * * * * B A U D R A T E * * * * case CANAL_COMMAND_BAUDRATE: if ( !pClientItem->m_bOpen ) { pLevel1->m_Response = CANAL_RESPONSE_ERROR; pLevel1->m_ResponseCode = CANAL_IFERROR_CHANNEL_CLOSED; } else { // Set baudrate // ============ // We don't have yo do more here the baudrate change // is just simulated in the pipe interface pLevel1->m_Response = CANAL_RESPONSE_SUCCESS; } break; // * * * * V E R S I O N * * * * case CANAL_COMMAND_VERSION: // Get version p = (char *)pDataArea; *( p + POS_VSCPD_MAJOR_VERSION ) = CANAL_MAIN_VERSION; *( p + POS_VSCPD_MINOR_VERSION ) = CANAL_MINOR_VERSION; *( p + POS_VSCPD_SUB_VERSION ) = CANAL_SUB_VERSION; pLevel1->m_Response = CANAL_RESPONSE_SUCCESS; break; // * * * * D L L - V E R S I O N * * * * case CANAL_COMMAND_DLL_VERSION: // Get DLL version // This application returns the vscp daemon // version. p = (char *)pDataArea; *( p + POS_VSCPD_MAJOR_VERSION ) = VSCPD_MAJOR_VERSION; *( p + POS_VSCPD_MINOR_VERSION ) = VSCPD_MINOR_VERSION; *( p + POS_VSCPD_SUB_VERSION ) = VSCPD_SUB_VERSION; *( p + POS_VSCPD_SUB_VERSION + 1 ) = 0; pLevel1->m_Response = CANAL_RESPONSE_SUCCESS; break; // * * * * V E N D O R S T R I N G * * * * case CANAL_COMMAND_VENDOR_STRING: // Get vendor string pLevel1->m_Response = CANAL_RESPONSE_SUCCESS; p = (char *)pDataArea; strcpy( p, VENDOR_STRING ); break; // * * * * L E V E L * * * * case CANAL_COMMAND_LEVEL: // Get i/f supported levels p = (char *)pDataArea; *( p + 0 ) = 0; *( p + 1 ) = 0; *( p + 2 ) = 0; *( p + 3 ) = CANAL_LEVEL_STANDARD; pLevel1->m_Response = CANAL_RESPONSE_SUCCESS; break; // * * * * N O O P * * * * case CANAL_COMMAND_NOOP: pLevel1->m_Response = CANAL_RESPONSE_SUCCESS; break; default: pLevel1->m_Response = CANAL_RESPONSE_ERROR; pLevel1->m_ResponseCode = CANAL_IFERROR_UNKNOWN_COMMAND; break; } // We are Done ReleaseSemaphore( hSemDone, 1, NULL ); } // while running // Client not needed anymore pctrlObject->removeClient( pClientItem ); delete (_clientstruct *)pThreadObject; CloseHandle( hMap ); CloseHandle( hSemCmd ); CloseHandle( hSemDone ); ExitThread( 0 ); }
void *workThreadReceive( void *pObject ) #endif { int cntMsg,readMsg; #ifdef WIN32 DWORD errorCode = 0; #else int rv = 0; #endif CIxxObj * pobj = ( CIxxObj *)pObject; if ( NULL == pobj ) { #ifdef WIN32 ExitThread( errorCode ); // Fail #else pthread_exit( &rv ); #endif } while ( pobj->m_bRun ) { // Noting to do if we should end... if ( !pobj->m_bRun ) continue; LOCK_MUTEX( pobj->m_ixxMutex ); if ( ( cntMsg = VCI_ReadQueStatus( pobj->m_hBoard, pobj->m_hRxQue ) ) > 0 ) { // There are messages to fetch VCI_CAN_OBJ *pobjarray = new VCI_CAN_OBJ[ cntMsg ]; if ( NULL != pobjarray ) { readMsg = VCI_ReadQueObj( pobj->m_hBoard, pobj->m_hRxQue, cntMsg, pobjarray ); if ( readMsg > 0 ) { // Write them to the receive buffer for ( int i=0; i<readMsg; i++ ) { if ( pobj->m_receiveList.nCount < IXXATVCI_MAX_RCVMSG ) { PCANALMSG pMsg = new canalMsg; pMsg->flags = 0; if ( NULL != pMsg ) { dllnode *pNode = new dllnode; if ( NULL != pNode ) { pMsg->timestamp = pobjarray[ i ].time_stamp; pMsg->id = pobjarray[ i ].id; pMsg->sizeData = pobjarray[ i ].len; memcpy( pMsg->data, pobjarray[ i ].a_data, pMsg->sizeData ); // If extended set extended flag if ( VCI_29B & pobj->m_initFlag ) pMsg->flags |= CANAL_IDFLAG_EXTENDED; // Check for RTS package if ( pobjarray[ i ].rtr ) pMsg->flags |= CANAL_IDFLAG_RTR; // Check for overrun error if ( pobjarray[ i ].sts & 0x80 ) pobj->m_stat.cntOverruns++; pNode->pObject = pMsg; LOCK_MUTEX( pobj->m_receiveMutex ); dll_addNode( &pobj->m_receiveList, pNode ); UNLOCK_MUTEX( pobj->m_receiveMutex ); // Update statistics pobj->m_stat.cntReceiveData += pMsg->sizeData; pobj->m_stat.cntReceiveFrames += 1; } else { delete pMsg; } } } else { // Full buffer pobj->m_stat.cntOverruns++; } } } delete pobjarray; } } UNLOCK_MUTEX( pobj->m_ixxMutex ); SLEEP( 1 ); } // while #ifdef WIN32 ExitThread( errorCode ); #else pthread_exit( &rv ); #endif }
bool CApoxObj::readUSBData( void ) { bool bData = false; DWORD eventStatus; DWORD nRxCnt; // Number of characters in receive queue DWORD nTxCnt; // Number of characters in transmit queue DWORD nRcvCnt; if ( FT_OK == FT_GetStatus( m_ftHandle, &nRxCnt, &nTxCnt, &eventStatus ) ) { // If there are characters to receive if ( nRxCnt ) { if ( nRxCnt > sizeof( m_bufferRx ) ) { nRxCnt = sizeof( m_bufferRx ); } if ( ( FT_OK == FT_Read( m_ftHandle, m_bufferRx, nRxCnt, &nRcvCnt ) ) && ( nRcvCnt > 0 ) ) { for ( uint32_t i=0; i<nRcvCnt; i++ ) { if ( USB_OK == processUSBByte( m_bufferRx[ i ], &m_lengthMsgRcv, m_bufferMsgRcv ) ) { if ( USB_MESSAGE_COMPLETE == m_RxMsgState ) { // A message if ( 0x00 == m_bufferMsgRcv[ 0 ] ) { // Response to control message from adapter // ---------------------------- // [0] 0x00 // [1] command | 0x80 // [2..n] response data if ( m_responseList.nCount < APOX_MAX_RESPONSEMSG ) { responseMsg *pMsg = new responseMsg; if ( NULL != pMsg ) { dllnode *pNode = new dllnode; if ( NULL != pNode ) { pMsg->id = 0x00; pMsg->command = m_bufferMsgRcv[ 1 ] & 0x7F; pMsg->len = (uint8_t)(m_lengthMsgRcv - 2); //(minus two for the first two bytes) memcpy( pMsg->data, ( m_bufferMsgRcv + 2 ), pMsg->len ); pNode->pObject = pMsg; LOCK_MUTEX( m_responseMutex ); dll_addNode( &m_responseList, pNode ); UNLOCK_MUTEX( m_responseMutex ); } else { delete pMsg; } } } } else if ( 0xff == m_bufferMsgRcv[ 0 ] ) { // Unsolicited emergency message from adapter // ---------------------------- // [0] 0xFF // [1] 0x80 // [2] ERRORCODE (0-255) switch( m_bufferMsgRcv[ 2 ] ) { case CAN_RCV_OVERFLOW: m_stat.cntOverruns++; m_emergencyInfo |= EMERGENCY_OVERFLOW; break; case CAN_RCV_WARNING: m_emergencyInfo |= EMERGENCY_RCV_WARNING; break; case CAN_TX_WARNING: m_emergencyInfo |= EMERGENCY_TX_WARNING; break; case CAN_RX_BUS_PASSIVE: m_emergencyInfo |= EMERGENCY_TXBUS_PASSIVE; break; case CAN_TX_BUS_PASSIVE: m_emergencyInfo |= EMERGENCY_RXBUS_PASSIVE; break; case CAN_BUS_OFF: m_emergencyInfo |= EMERGENCY_BUS_OFF; break; } } else { // CAN message // ---------------------------- // 0:[who|rtr|idMode|(unused)] // 1:[ID MSB] // 2:[ID3] // 3:[ID2] // 4:[ID LSB] // 5:[TIMESTAMP MSB] // 6:[TIMESTAMP LSB] // 7:[RX_FLAGS] // 8:[LENGTH] // 9-16:[DATA 0-8 bytes] if ( m_receiveList.nCount < APOX_MAX_RCVMSG ) { PCANALMSG pMsg = new canalMsg; pMsg->flags = 0; if ( NULL != pMsg ) { dllnode *pNode = new dllnode; if ( NULL != pNode ) { pMsg->timestamp = (((DWORD)m_bufferMsgRcv[8]<<24 ) & 0xff000000) | (((DWORD)m_bufferMsgRcv[7]<<16 ) & 0x00ff0000) | (((DWORD)m_bufferMsgRcv[6]<<8 ) & 0x0000ff00) | (((DWORD)m_bufferMsgRcv[5] ) & 0x000000ff) ; pMsg->id = (((DWORD)m_bufferMsgRcv[4]<<24) & 0x1f000000) | (((DWORD)m_bufferMsgRcv[3]<<16) & 0x00ff0000) | (((DWORD)m_bufferMsgRcv[2]<<8 ) & 0x0000ff00) | (((DWORD)m_bufferMsgRcv[1] ) & 0x000000ff) ; pMsg->sizeData = m_bufferMsgRcv[10]; memcpy( (void *)pMsg->data, (m_bufferMsgRcv + 11 ), pMsg->sizeData ); // If extended set extended flag if ( m_bufferMsgRcv[0] & 0x20 ) pMsg->flags |= CANAL_IDFLAG_EXTENDED; // Check for RTR package if ( (m_bufferMsgRcv[0] & 0x40) ) pMsg->flags |= CANAL_IDFLAG_RTR; pNode->pObject = pMsg; LOCK_MUTEX( m_receiveMutex ); dll_addNode( &m_receiveList, pNode ); UNLOCK_MUTEX( m_receiveMutex ); // Update statistics m_stat.cntReceiveData += pMsg->sizeData; m_stat.cntReceiveFrames += 1; } else { delete pMsg; } } } else { // Full buffer m_stat.cntOverruns++; } } // recv types m_RxMsgState = USB_IDLE; // reset state for next msg } // Complete msg } } // byte loop } // read OK } // Bytes to read } return bData; }