Example #1
0
CClientList::~CClientList()
{
	//dll_removeAllNodes( &m_list );	
	while ( NULL != m_clientList.pHead ) {
		CClientItem *pClientItem = (CClientItem *)m_clientList.pTail->pObject;
		if ( NULL != pClientItem ) delete pClientItem;
		m_clientList.pTail->pObject = NULL;
		dll_removeNode( &m_clientList, m_clientList.pTail );
	}	 
}
Example #2
0
bool CClientList::removeClient( CClientItem *pClientItem )
{
	if ( NULL == pClientItem ) return false;

	dllnode *pNode = dll_findNodeFromID( &m_clientList, pClientItem->m_clientID );
	
	removeData( &pClientItem->m_inputQueue );
	if ( NULL != pNode ) {
		dll_removeNode( &m_clientList, pNode );
	}

	return true;
}
Example #3
0
BOOL dll_removeAllNodes( struct DoubleLinkedList *pdll )
{	
  if ( NULL == pdll ) return FALSE;

  while ( NULL != pdll->pHead ) {
    dll_removeNode( pdll, pdll->pTail );
  }	
  
  dll_init( pdll, 0 );

  pdll->nCount = 0;

  return TRUE;
};
Example #4
0
bool CPeakObj::readMsg( canalMsg *pMsg )
{
    bool rv = false;

    if ( ( NULL != m_receiveList.pHead ) &&
            ( NULL != m_receiveList.pHead->pObject ) ) {

        memcpy( pMsg, m_receiveList.pHead->pObject, sizeof( canalMsg ) );
        LOCK_MUTEX( m_receiveMutex );
        dll_removeNode( &m_receiveList, m_receiveList.pHead );
        UNLOCK_MUTEX( m_receiveMutex );

        rv = true;
    }

    return rv;
}
Example #5
0
int CCAN232Obj::readMsg( canalMsg *pMsg )
{			
	int rv = false;
	
	if ( ( NULL != m_can232obj.m_rcvList.pHead ) && 
			( NULL != m_can232obj.m_rcvList.pHead->pObject ) ) {
		
		WaitForSingleObject( m_can232ObjMutex, INFINITE );
		
		memcpy( pMsg, m_can232obj.m_rcvList.pHead->pObject, sizeof( canalMsg ) );
		dll_removeNode( &m_can232obj.m_rcvList, m_can232obj.m_rcvList.pHead );
		
		ReleaseMutex( m_can232ObjMutex );
		rv = true;
	}

	return rv;
}
Example #6
0
int CCAN232Obj::readMsg(canalMsg *pMsg)
{
    int rv = false;

    if ((NULL != m_can232obj.m_rcvList.pHead) &&
            (NULL != m_can232obj.m_rcvList.pHead->pObject)) {

        LOCK_MUTEX(m_can232ObjMutex);

        memcpy(pMsg, m_can232obj.m_rcvList.pHead->pObject, sizeof( canalMsg));
        dll_removeNode(&m_can232obj.m_rcvList, m_can232obj.m_rcvList.pHead);

        UNLOCK_MUTEX(m_can232ObjMutex);

        rv = true;
    }

    return rv;
}
Example #7
0
CClientItem::~CClientItem()
{
	//dll_removeAllNodes( &m_inputQueue );
	while ( NULL != m_inputQueue.pHead ) {
		
		CClientItem *pClientItem = (CClientItem *)m_inputQueue.pTail->pObject;		
		
		if ( NULL != pClientItem ) {
	
			if ( NULL != ( (vscpMsg2*)pClientItem )->pdata ) {
				delete [] ( ( (vscpMsg2*)pClientItem )->pdata );
				( (vscpMsg2*)pClientItem )->pdata = NULL;
			}
			
		}

		dll_removeNode( &m_inputQueue, m_inputQueue.pTail );

	}
}
Example #8
0
bool CApoxObj::waitResponse( responseMsg *pMsg, uint32_t timeout )
{
	uint32_t start = GetTickCount();
	while (  GetTickCount() < ( start + timeout ) ){
	
		if ( ( NULL != m_responseList.pHead ) && 
				( NULL != m_responseList.pHead->pObject ) ) {

			memcpy( pMsg, m_responseList.pHead->pObject, sizeof( responseMsg ) ); 
			LOCK_MUTEX( m_responseMutex );
			dll_removeNode( &m_responseList, m_responseList.pHead );
			UNLOCK_MUTEX( m_responseMutex );

			return true;
		}
		
	}

	return false;
}
Example #9
0
void CClientList::removeData( DoubleLinkedList* pdll ) 
{
	// Must be something to worl with
	if ( NULL == pdll ) return;
	
	while ( NULL != pdll->pHead ) {
		
		CClientItem *pClientItem = (CClientItem *)pdll->pTail->pObject;		
		
		if ( NULL != pClientItem ) {
	
			if ( NULL != ( (vscpMsg2*)pClientItem )->pdata ) {
				delete [] ( ( (vscpMsg2*)pClientItem )->pdata );
				( (vscpMsg2*)pClientItem )->pdata = NULL;
			}
			
		}

		dll_removeNode( pdll, pdll->pTail );

	}
}
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 #11
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 #12
0
void *workThreadTransmit( 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
    }

    while ( pobj->m_bRun ) {

        LOCK_MUTEX( pobj->m_peakMutex );

        // Noting to do if we should end...
        if ( !pobj->m_bRun ) continue;

        // Is there something to transmit...
        int ret;
        while ( ( NULL != pobj->m_transmitList.pHead ) &&
                ( NULL != pobj->m_transmitList.pHead->pObject ) ) {

            canalMsg msg;
            memcpy( &msg, pobj->m_transmitList.pHead->pObject, sizeof( canalMsg ) );
            LOCK_MUTEX( pobj->m_transmitMutex );
            dll_removeNode( &pobj->m_transmitList, pobj->m_transmitList.pHead );
            UNLOCK_MUTEX( pobj->m_transmitMutex );

            PeakCanMsg peakMsg;

            peakMsg.id = msg.id;
            peakMsg.msgType = 0;
            peakMsg.len = msg.sizeData;
            memcpy( peakMsg.data, msg.data, peakMsg.len );

            // Check if RTR
            if ( ( msg.flags & CANAL_IDFLAG_RTR ) ) {
                peakMsg.msgType |= PCAN_MSGTYPE_RTR;
            }

            // Check if extended
            if ( ( msg.flags & CANAL_IDFLAG_EXTENDED ) ) {
                peakMsg.msgType |= PCAN_MSGTYPE_EXTENDED;
            }

            if ( PEAK_CAN_ERR_OK == ( ret = pobj->m_procWrite( &peakMsg ) ) ) {

                // Message sent successfully
                // Update statistics
                pobj->m_stat.cntTransmitData += msg.sizeData;
                pobj->m_stat.cntTransmitFrames += 1;


            }
            else {

                // Failed - put message back in queue front
                PCANALMSG pMsg	= new canalMsg;
                if ( NULL != pMsg ) {

                    // Copy in data
                    memcpy ( pMsg, &msg, sizeof( canalMsg ) );

                    dllnode *pNode = new dllnode;
                    if ( NULL != pNode ) {

                        pNode->pObject = pMsg;
                        LOCK_MUTEX( pobj->m_transmitMutex );
                        dll_addNodeHead( &pobj->m_transmitList, pNode );
                        UNLOCK_MUTEX( pobj->m_transmitMutex );

                    }
                    else {

                        delete pMsg;
                    }

                } // unable to allocate storage

            } // faild to send message

        } // while data


        // No data to write

        UNLOCK_MUTEX( pobj->m_peakMutex );
        SLEEP( 1 );

        //}

    } // while


#ifdef WIN32
    ExitThread( errorCode );
#else
    pthread_exit( &rv );
#endif

}
Example #13
0
void *workThreadTransmit( void *pObject )
#endif
{
#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 ) {

		LOCK_MUTEX( pobj->m_vectorMutex );
		
		// Noting to do if we should end...
		if ( !pobj->m_bRun ) continue;

		// Is there something to transmit
		while ( ( NULL != pobj->m_transmitList.pHead ) && 
				( NULL != pobj->m_transmitList.pHead->pObject ) ) {

			canalMsg msg;
			memcpy( &msg, pobj->m_transmitList.pHead->pObject, sizeof( canalMsg ) ); 
			LOCK_MUTEX( pobj->m_transmitMutex );
			dll_removeNode( &pobj->m_transmitList, pobj->m_transmitList.pHead );
			UNLOCK_MUTEX( pobj->m_transmitMutex );

			VCAN_EVENT event;
			
			event.tag = V_TRANSMIT_MSG;
			
			// id
			event.tagData.msg.id = msg.id;
			if ( msg.flags & CANAL_IDFLAG_EXTENDED ) {
				event.tagData.msg.id |= VCAN_EXT_MSG_ID;	// Extended
			}
		
			// size
			event.tagData.msg.dlc = msg.sizeData;

			// Vector flags
			event.tagData.msg.flags = 0;
			if ( msg.flags & CANAL_IDFLAG_RTR ) {
				event.tagData.msg.flags |= MSGFLAG_REMOTE_FRAME;	// RTR
			}
			
			// Data
			memcpy( event.tagData.msg.data, msg.data, msg.sizeData );

			if ( VERR_QUEUE_IS_FULL != 
					ncdTransmit( pobj->m_portHandle, pobj->m_channelMask, &event ) ) {
					
					// Message sent successfully
					// Update statistics
					pobj->m_stat.cntTransmitData += msg.sizeData;
					pobj->m_stat.cntTransmitFrames += 1;
			
			}
			else {

				// Failed - put message back in queue front
				PCANALMSG pMsg	= new canalMsg;
				if ( NULL != pMsg ) {
						
					// Copy in data
					memcpy ( pMsg, &msg, sizeof( canalMsg ) );

					dllnode *pNode = new dllnode; 
					if ( NULL != pNode ) {
																
						pNode->pObject = pMsg;
						LOCK_MUTEX( pobj->m_transmitMutex );
						dll_addNodeHead( &pobj->m_transmitList, pNode );
						UNLOCK_MUTEX( pobj->m_transmitMutex );

					}
					else {

						delete pMsg;

					}

				}
			} // send message
							
		} // while data


		// No data to write

		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 #15
0
void *workThreadTransmit( void *pObject )
#endif
{
#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 ) {

		LOCK_MUTEX( pobj->m_ixxMutex );
		
		// Noting to do if we should end...
		if ( !pobj->m_bRun ) continue;

		// Is there something to transmit
		while ( ( NULL != pobj->m_transmitList.pHead ) && 
				( NULL != pobj->m_transmitList.pHead->pObject ) ) {

			canalMsg msg;
			memcpy( &msg, pobj->m_transmitList.pHead->pObject, sizeof( canalMsg ) ); 
			LOCK_MUTEX( pobj->m_transmitMutex );
			dll_removeNode( &pobj->m_transmitList, pobj->m_transmitList.pHead );
			UNLOCK_MUTEX( pobj->m_transmitMutex );
			
			if ( !( msg.flags & CANAL_IDFLAG_RTR ) ) {

				// Standard message
			
				if (  VCI_OK == VCI_TransmitObj( pobj->m_hBoard, 
													pobj->m_hTxQue, 
													msg.id, 
													msg.sizeData, 
													msg.data ) ) {
				
					// Message sent successfully
					// Update statistics
					pobj->m_stat.cntTransmitData += msg.sizeData;
					pobj->m_stat.cntTransmitFrames += 1;

				}
				else {
					
					// Failed - put message back in queue front
					PCANALMSG pMsg	= new canalMsg;
					if ( NULL != pMsg ) {
						
						// Copy in data
						memcpy ( pMsg, &msg, sizeof( canalMsg ) );

						dllnode *pNode = new dllnode; 
						if ( NULL != pNode ) {
																
							pNode->pObject = pMsg;
							LOCK_MUTEX( pobj->m_transmitMutex );
							dll_addNodeHead( &pobj->m_transmitList, pNode );
							UNLOCK_MUTEX( pobj->m_transmitMutex );

						}
						else {

							delete pMsg;

						}

					}

				}
			}
			else {

				// Remote request

				if (  VCI_OK == VCI_RequestObj( pobj->m_hBoard, 
													pobj->m_hTxQue, 
													msg.id, 
													msg.sizeData ) ) {
				
					// Message sent successfully
					// Update statistics
					pobj->m_stat.cntTransmitFrames += 1;

				}
				else {
					
					// Failed - put message back in queue front
					PCANALMSG pMsg	= new canalMsg;
					if ( NULL != pMsg ) {
						
						// Copy in data
						memcpy ( pMsg, &msg, sizeof( canalMsg ) );

						dllnode *pNode = new dllnode; 
						if ( NULL != pNode ) {
																
							pNode->pObject = pMsg;
							LOCK_MUTEX( pobj->m_transmitMutex );
							dll_addNodeHead( &pobj->m_transmitList, pNode );
							UNLOCK_MUTEX( pobj->m_transmitMutex );

						}
						else {

							delete pMsg;

						}

					}

				}	
				
			}
							
		} // while data


		// No data to write

		UNLOCK_MUTEX( pobj->m_ixxMutex );
		SLEEP( 1 );

		//}	 
	
	} // while 	 


#ifdef WIN32
	ExitThread( errorCode );
#else
	pthread_exit( &rv );
#endif

}
Example #16
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);
}
Example #17
0
void *workThreadTransmit( void *pObject )
#endif
{
#ifdef WIN32
	DWORD errorCode = 0;
#else
	int rv = 0;
#endif

	CApoxObj * pobj = ( CApoxObj *)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;

		// Is there something to transmit
		while ( ( NULL != pobj->m_transmitList.pHead ) && 
				( NULL != pobj->m_transmitList.pHead->pObject ) ) {

			canalMsg msg;
			memcpy( &msg, pobj->m_transmitList.pHead->pObject, sizeof( canalMsg ) ); 
			LOCK_MUTEX( pobj->m_transmitMutex );
			dll_removeNode( &pobj->m_transmitList, pobj->m_transmitList.pHead );
			UNLOCK_MUTEX( pobj->m_transmitMutex );

			// Outgoing CAN message
			// --------------------------
			// [0] ([1][RTR][EXT][unused 0..4])
			// [1] ID MSB
			// [2] ID
			// [3] ID
			// [4] ID LSB
			// [5] FUTURE USE (CANopen or DeviceNet) // ex. Wait for response? Etc..
			// [6] FUTURE USE (CANopen or DeviceNet)
			// [7] RESERVED FOR TX FLAGS 
			// [8] DATA LEN (0-8)
			// [9-16] 

			uint8_t sendData[ 20 ];
			short size = 0;

			sendData[ size++ ] = 
				0x80 | 
				( ( msg.flags & CANAL_IDFLAG_RTR ) ? 0x40:0x00) | 
				( ( msg.flags & CANAL_IDFLAG_EXTENDED ) ? 0x20 : 0x00 );
			sendData[ size++ ] = ( uint8_t )( msg.id >> 24 ) & 0x1f;
			sendData[ size++ ] = ( uint8_t )( msg.id >> 16 ) & 0xff;
			sendData[ size++ ] = ( uint8_t )( msg.id >> 8 )  & 0xff;
			sendData[ size++ ] = ( uint8_t )( msg.id ) & 0xff;

			sendData[size++] = 0x00; // future use
			sendData[size++] = 0x00; // future use

			sendData[size++] = 0; // txFlags;
			sendData[size++] = msg.sizeData;

			memcpy( sendData, msg.data, msg.sizeData );
			size += msg.sizeData;
			 
			LOCK_MUTEX( pobj->m_apoxMutex );

			if ( USB_OK == pobj->sendUSBMsg( sendData, size ) ) {
	
				// Message sent successfully
				// Update statistics
				pobj->m_stat.cntTransmitData += msg.sizeData;
				pobj->m_stat.cntTransmitFrames += 1;

			}
			else {
					
				// Failed - put message back in queue front
				PCANALMSG pMsg	= new canalMsg;
				if ( NULL != pMsg ) {
						
					// Copy in data
					memcpy ( pMsg, &msg, sizeof( canalMsg ) );

					dllnode *pNode = new dllnode; 
					if ( NULL != pNode ) {
																
						pNode->pObject = pMsg;
						LOCK_MUTEX( pobj->m_transmitMutex );
						dll_addNodeHead( &pobj->m_transmitList, pNode );
						UNLOCK_MUTEX( pobj->m_transmitMutex );

					}
					else {

						delete pMsg;

					}

				}

			}

			UNLOCK_MUTEX( pobj->m_apoxMutex );
										
		} // while data


		// No data to write

		SLEEP( 1 );

		//}	 
	
	} // while 	 


#ifdef WIN32
	ExitThread( errorCode );
#else
	pthread_exit( &rv );
#endif

}