Example #1
0
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;
}
Example #2
0
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;		
}
Example #3
0
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;
}
Example #4
0
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;
}
Example #5
0
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;
}
Example #6
0
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 );
 
}
Example #8
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 );
}
Example #9
0
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

}
Example #10
0
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 );

}
Example #12
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

}
Example #13
0
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;
}