void tlvReceiveFSM(TLV_FSM *fsm, TLV_Buffer *tlvBuf, uint8 *ptr)
{
    ptr[fsm->i] = uartGetByte();

    switch(fsm->state)
    {
        case WAIT_FOR_TYPE:
            if(ptr[fsm->i] == PROGRAMMING_MODE)
            {
                setProgrammingMode();
				// while(Busy1USART());		//for debugging purpose
                resetTarget = 1;
            }
            else if(ptr[fsm->i] == START_RUNNING)
            {
                setStartRunningMode();
                resetTarget = 1;
            }
            else
                fsm->state = WAIT_FOR_LENGTH;
            break;
        case WAIT_FOR_LENGTH:
            fsm->length = ptr[fsm->i];
            fsm->state = WAIT_FOR_VALUE;
            break;
        case WAIT_FOR_VALUE:
            if((fsm->i - 1) < fsm->length)
                fsm->state = WAIT_FOR_VALUE;
            else
            {
                fsm->state = WAIT_FOR_TYPE;
                if(!verifyCheckSum(ptr))
                {
                    if(!verifyType(ptr))
                        uartSendByte(ERR_WRONG_TYPE);
                    else
                        uartSendByte(ERR_WRONG_CHECKSUM);
                }
                else
                    setTLVframe(tlvBuf, ptr);
            }
            break;
        default:
            break;
    }

    if(fsm->state == WAIT_FOR_TYPE)
        fsm->i = 0;
    else
        fsm->i++;
}
Example #2
0
bool InstructionSet::Instruction::execute( Processor* dev, const std::vector<char>& p, std::vector<char>& r) const
{
	printCall( std::cerr, (const char*)&p[0] );

	bool ret=false;
	
	// Ein Befehl ist immer genau 4 byte lang
	// CODE, P1, P2, XOR-CHKSUM
	// die Antwort kann auch länger sein, niemals aber länger
	// als als max( n*(X+Y) + 4 ) = 256*16+4 = 4096+4 = 4100;
	// für normale (nicht Schleifen) Befehle aber nur 8 byte
	static char buffer[4+8]; // max antwort + 4 bytes command
	std::fill( buffer, buffer+12, 0x00 );
	Device *d = static_cast<Device*>(dev);
	// instruction codes des Scanners sind immer ein byte lang
	buffer[0] = code()[0];
	buffer[1] = paramLength()>0 ? p[0] : 0;
	buffer[2] = paramLength()>1 ? p[1] : 0;
	calcCheckSum(buffer, 4);
    // calc return length
    // 0 -> 1
    // 2 -> 4
    // 4 -> 8
    unsigned int ret_length = (returnLength()==0) ? 1 : (returnLength()<<1);
    // send

//	Processor::usleep( 1000 );

	if( d->sendCommand( buffer, 4  ) )
		if( d->receiveAnswer( buffer+4, ret_length, _millies ) )
		{
//			if( ret_length > 1 )
//				buffer[4] = buffer[0];

			if( !verifyCheckSum(buffer+4, ret_length) )
				std::cerr << "\t\t\t\tWARNING CRC failed!" << std::endl;

			{
				// Hier müssen wir insgesamt returnLength() Werte zurück liefern
				//  0: __
				//  2: __ XX XX __
				//  4: __ XX XX __ __ XX XX __ __ XX XX __
				//        0  1  2     2  3        4  5
				//        1  1  1     3  3        5  5
				//        1  2  3->   5  6        9  10
				unsigned offset=1;
				unsigned index =0;

				//std::cerr << " returns " << std::hex;

				while( index < returnLength() )
				{
					assert( offset+index < ret_length );

					//std::cerr << (unsigned(buffer[4+index+offset])&255) << " ";

					r.push_back( buffer[4+offset+index] );
					index++;
					if( (offset+index)&3 == 3 )
						offset+=2;
				}
				//******************
				//std::cerr << "  -------> answer was: ";
				//for( index = 0; index<ret_length; index++ )
				//std::cerr << unsigned((buffer[4+index]>>4)&15) << unsigned(buffer[4+index]&15) << " ";
				//*************************************
				ret=true;
			}
		}
	//std::cerr << std::dec << std::endl;
	return ret;
}
Example #3
0
bool InstructionSet::SequenceInstruction::execute( Processor* dev, const char *p, char *r) const
{
	printCall( std::cerr, p ) << std::endl;

	// Answer length = max( n*(X+Y) + 4 ) = 256*16+4 = 4096+4 = 4100;
	static char buffer[4104];
	Device *d = static_cast<Device*>(dev);
	// complete length of sequence to receive
	unsigned int sequence_length=0;
	// answer length to be returned (use data)
	unsigned int answer_length  =0;
	// sequence and answer length of single command inside loop
	unsigned int seq1_length    =0;
	unsigned int seq2_length    =0;
	unsigned int ans1_length    =0;
	unsigned int ans2_length    =0;
	// additional bytes to receive
	unsigned int suffix_length = 0;

	switch( code()[0] )
	{
		case	REPT:		// set loop count and send REPT command
				_counter = *(reinterpret_cast<const unsigned int*>(p));
				return Instruction::execute( dev, p, r );
			
		case	SEQUEX:		// Sequence 1
				{
				const ::InstructionSet::Instruction* ins1=0;
				const ::InstructionSet::Instruction* ins2=0;
				ins1 = d->instructionSet()->instruction(unsigned(p[0]));
				ins2 = d->instructionSet()->instruction(unsigned(p[1]));
				ans1_length = ins1 ? ins1->returnLength() : 0;
				seq1_length = ans1_length ? ans1_length<<1 : 1;
				ans2_length = ins2 ? ins2->returnLength() : 0;
				seq2_length = ans2_length ? ans2_length<<1 : 1;
				suffix_length	= 4;
				}
				break;
		case	SEQ2:
		case	SEQ3:
				seq1_length		= 5;
				ans1_length		= 4;
				seq2_length		= 0;
				ans2_length		= 0;
				suffix_length	= 0;
				break;
		case	LEDCHK:
				_counter		= 9;
				seq1_length		= 4;
				ans1_length		= 2;
				seq2_length		= 0;
				ans2_length		= 0;
				suffix_length	= 0;
		default:
				return false;
	}
	sequence_length = (seq1_length+seq2_length)*_counter;
	answer_length	= (ans1_length+ans2_length)*_counter;

	// commando aufbauen
	// instruction codes des Scanners sind immer ein byte lang
	buffer[0] = code()[0];
	buffer[1] = paramLength()>0 ? p[0] : 0;
	buffer[2] = paramLength()>1 ? p[1] : 0;
	calcCheckSum(buffer, 4);
	// calc return length
	// 0 -> 1
	// 2 -> 4
	// 4 -> 8
	// send
	if( d->sendCommand( buffer, 4 ) )
	{
		char *t = r;
		char *s = buffer+4;
		unsigned int cnt = sequence_length;
		while( _counter > 0 )
		{
			if( seq1_length > 0 &&
				!d->receiveAnswer( s, seq1_length, _millies  ))
				break;
			if( seq2_length > 0 &&
				!d->receiveAnswer( s+seq1_length, seq2_length, _millies  ))
				break;
			
			if( seq1_length > 0 && verifyCheckSum(s, seq1_length) )
			{
				unsigned i = 0;
				unsigned o = (seq1_length-ans1_length)>>1;
				while( i < ans1_length ) {
					*t++ = s[i+o];
					i++;
				}
				answer_length -= ans1_length;
			}
			if( seq2_length > 0 && verifyCheckSum(s+seq1_length, seq2_length) )
			{
				unsigned i = 0;
				unsigned o = seq1_length + (seq2_length-ans2_length)>>1;
				while( i < ans2_length ) {
					*t++ = s[i+o];
					i++;
				}
				answer_length -= ans2_length;
			}
Example #4
0
/**
 * This method tries to read all lines contained in the receive buffer. A line
 * is always terminated by a newline and is taken over in the receiver queue,
 * if the checksum is valid and the GPS identifier is requested.
 */
void GpsClient::readSentenceFromBuffer()
{
    char *start = databuffer;
    char *end   = 0;

    while(strlen(start))
    {
        // Search for a newline in the receiver buffer.
        // That is the normal end of a GPS sentence.
        if( ! (end = strchr( start, '\n' )) )
        {
            // No newline in the receiver buffer, wait for more characters
            return;
        }

        if( start == end )
        {
            // skip newline and start at next position with a new search
            start++;
            continue;
        }

        // found a complete record in the buffer, it will be extracted now
        char *record = (char *) malloc( end-start + 2 );

        memset( record, 0, end-start + 2 );

        strncpy( record, start, end-start + 1);

        if( verifyCheckSum( record ) == true )
        {
            // Forward sentence to the server, if checksum is ok and
            // processing is desired.
            if( checkGpsMessageFilter( record ) == true && forwardGpsData == true )
            {
                QByteArray ba;
                ba.append( MSG_GPS_DATA );
                ba.append( ' ' );
                ba.append( record );
                writeForwardMsg( ba.data() );
            }
        }

#ifdef DEBUG_NMEA
        qDebug() << "GpsClient::read():" << record;
#endif

        free(record);
        record = 0;

        // remove queued record from receive buffer
        memmove( databuffer, end+1,
                 databuffer + sizeof(databuffer)-1 - end );

        datapointer -= (end+1 - databuffer);

        dbsize -= ( end+1 - databuffer);

        start = databuffer;

        end = 0;
    }
}