Exemplo n.º 1
0
size_t gnrc_netif_addr_from_str(const char *str, uint8_t *out)
{
    /* Walk over str from the end. */
    /* Take two chars a time as one hex value (%hhx). */
    /* Leading zeros can be omitted. */
    /* Every non-hexadimal character is a delimiter. */
    /* Leading, tailing and adjacent delimiters are forbidden. */
    const char *end_str = str;
    uint8_t *out_end = out;
    size_t count = 0;
    int assert_cell = 1;

    assert(out != NULL);
    if ((str == NULL) || (str[0] == '\0')) {
        return 0;
    }
    /* find end of string */
    while (end_str[1]) {
        ++end_str;
    }
    while (end_str >= str) {
        int a = 0, b = _dehex(*end_str--, -1);

        if (b < 0) {
            if (assert_cell) {
                return 0;
            }
            else {
                assert_cell = 1;
                continue;
            }
        }
        assert_cell = 0;
        if (end_str >= str) {
            a = _dehex(*end_str--, 0);
        }
        count++;
        *out_end++ = (a << 4) | b;
    }
    if (assert_cell) {
        return 0;
    }
    /* out is reversed */
    while (out < --out_end) {
        uint8_t tmp = *out_end;
        *out_end = *out;
        *out++ = tmp;
    }
    return count;
}
Exemplo n.º 2
0
Arquivo: cmd.c Projeto: ant9000/RIOT
static int _parse_addr(uint8_t *out, size_t out_len, const char *in)
{
    const char *end_str = in;
    uint8_t *out_end = out;
    size_t count = 0;
    int assert_cell = 1;

    if (!in || !*in) {
        return 0;
    }
    while (end_str[1]) {
        ++end_str;
    }

    while (end_str >= in) {
        int a = 0, b = _dehex(*end_str--, -1);
        if (b < 0) {
            if (assert_cell) {
                return 0;
            }
            else {
                assert_cell = 1;
                continue;
            }
        }
        assert_cell = 0;

        if (end_str >= in) {
            a = _dehex(*end_str--, 0);
        }

        if (++count > out_len) {
            return 0;
        }
        *out_end++ = (a << 4) | b;
    }
    if (assert_cell) {
        return 0;
    }
    /* out is reversed */

    while (out < --out_end) {
        uint8_t tmp = *out_end;
        *out_end = *out;
        *out++ = tmp;
    }

    return count;
}
Exemplo n.º 3
0
int nmea_parse(char c) {
  // avoid runaway sentences (>99 chars or >29 terms) and terms (>14 chars)
  if ((n >= 100) || (_terms >= 30) || (_nt >= 15)) { _state = 0; }
  // LF and CR always reset parser
  if ((c == 0x0A) || (c == 0x0D)) { _state = 0; }
  // '$' always starts a new sentence
  if (c == '$') {
    _gprmc_tag = 0;
    _parity = 0;
    _terms = 0;
    _nt = 0;
    _sentence[0] = c;
    n = 1;
    _state = 1;
    return 0;
  }
  // parse other chars according to parser state
  switch(_state) {
  case 0:
    // waiting for '$', do nothing
    break;
  case 1:
  	// decode chars after '$' and before '*' found
    if (n < 7) {
    	// see if first seven chars match "$GPRMC,"
    	if (c == _GPRMC_TERM[n]) { _gprmc_tag++; }
    }
    // add received char to sentence
    _sentence[n++] = c;
    switch (c) {
    case ',':
    	// ',' delimits the individual terms
      (_term[_terms++])[_nt] = 0;
      _nt = 0;
      _parity = _parity ^ c;
      break;
    case '*':
    	// '*' delimits term and precedes checksum term
      (_term[_terms++])[_nt] = 0;
      _nt = 0;
      _state++;
      break;
    default:
    	// all other chars between '$' and '*' are part of a term
      (_term[_terms])[_nt++] = c;
      _parity = _parity ^ c;
      break;
    }
    break;
  case 2:
  	// first char following '*' is checksum MSB
    _sentence[n++] = c;
    (_term[_terms])[_nt++] = c;
    _parity = _parity - (16 * _dehex(c));		// replace with bitshift?
    _state++;
    break;
  case 3:
  	// second char after '*' completes the checksum (LSB)
    _sentence[n++] = c;
    _sentence[n++] = 0;
    (_term[_terms])[_nt++] = c;
    (_term[_terms++])[_nt] = 0;
    _state = 0;
    _parity = _parity - _dehex(c);
    // when parity is zero, checksum was correct!
    if (_parity == 0) {
    	// accept all sentences, or only GPRMC datatype?
    	if ((!_gprmc_only) || (_gprmc_tag == 6)) {
	    	// copy _sentence[] to f_sentence[]
	    	while ((--n) >= 0) { f_sentence[n] = _sentence[n]; }
	    	// copy all _terms[] to f_terms[]
	      for (f_terms=0; f_terms<_terms; f_terms++) {
	      	_nt = 0;
	      	while ((_term[f_terms])[_nt]) {
	        	(f_term[f_terms])[_nt] = (_term[f_terms])[_nt];
	        	_nt++;
	        }
	        (f_term[f_terms])[_nt] = 0;
	      }
	      // when sentence is of datatype GPRMC
	      if (_gprmc_tag == 6) {
	      	// store values of relevant GPRMC terms
	      	_gprmc_utc = _decimal(_term[1]);
	      	_gprmc_status = (_term[2])[0];
	        // calculate signed degree-decimal value of latitude term
	        _gprmc_lat = _decimal(_term[3]) / 100.0;
	        _degs = floor(_gprmc_lat);
	        _gprmc_lat = (100.0 * (_gprmc_lat - _degs)) / 60.0;
	        _gprmc_lat += _degs;
	        // southern hemisphere is negative-valued
	        if ((_term[4])[0] == 'S') {
	          _gprmc_lat = 0.0 - _gprmc_lat;
	        }
	        // calculate signed degree-decimal value of longitude term
	        _gprmc_long = _decimal(_term[5]) / 100.0;
	        _degs = floor(_gprmc_long);
	        _gprmc_long = (100.0 * (_gprmc_long - _degs)) / 60.0;
	        _gprmc_long += _degs;
	        // western hemisphere is negative-valued
	        if ((_term[6])[0] == 'W') {
	          _gprmc_long = 0.0 - _gprmc_long;
	        }
	        _gprmc_speed = _decimal(_term[7]);
	        _gprmc_angle = _decimal(_term[8]);
	      }
      	// sentence accepted!
      	return 1;
      }
    }
    break;
  default:
    _state = 0;
    break;
  }
  return 0;
}
bool SimpleTelemetry::parseMessage(char c)
{
	// Dont let sentences run away
	if ((n >= MAXSENTENCE) || (_terms >= MAXTERMS) || (_nt >= MAXWORD))
	{
/*
#ifdef DEBUG
		debugPort->println("Runaway sentance. Resetting state. ");
		debugPort->print("Sentence is: ");
		debugPort->print(n);
		debugPort->print(" chars ");
		debugPort->print(_terms);
		debugPort->print(" terms ");
		debugPort->print(_nt);
		debugPort->println(" words.");
#endif
*/
		_state = 0;
		n = 0;
		_terms = 0;
		_nt = 0;
	}
	// LF and CR always reset parser
	if ((c == 0x0A) || (c == 0x0D))
	{
/*
#ifdef DEBUG
		debugPort->println("LF or CR received. Resetting state.");
#endif
*/
		_state = 0;
	}
	// $ Always starts a new sentence
	if (c == '$')
	{
/*
#ifdef DEBUG
	debugPort->println("New sentence.");
#endif
*/
		//_sentence[0] = c;
		_state = 1;
		_terms = 0;
		n = 1;
		_nt = 0;
		checksum = 0;
		return 0;
	}
  
	switch (_state)
	{
		case 0 :
		{
			// Waiting for $. Do nothing
/*
#ifdef DEBUG
			debugPort->println("Waiting for $.");
#endif
*/
			break;
		}
		case 1 :
		{
			//_sentence[n++] = c;
			n++;
			switch (c)
			{
			// Delimits the terms in sentence
				case ',' :
				{
/*
#ifdef DEBUG
					debugPort->print(",");
#endif
*/
					(_term[_terms++])[_nt] = 0;
					_nt = 0;
					checksum = checksum ^ c;
					break;
				}
				// End of terms
				case '*' :
				{
/*
#ifdef DEBUG
					debugPort->print("*");
#endif
*/
					(_term[_terms++])[_nt] = 0;
					_nt = 0;
					_state++;
					break;
				}
				// All characters between $ and *
				default :
				{
/*
#ifdef DEBUG
					debugPort->print(c);
#endif
*/
					(_term[_terms])[_nt++] = c;
					checksum = checksum ^ c;
					break;
				}
			}
			break;
		}
		// Checksum MSB
		case 2 :
		{
/*
#ifdef DEBUG
			debugPort->print(c);
#endif
*/
			checksum = checksum - (16 * _dehex(c));
			_state++;
			break;
		}
		// Sentence complete
		case 3 :
		{
/*
#ifdef DEBUG
			debugPort->println(c);
#endif
*/
			checksum = checksum - _dehex(c);
/*
#ifdef DEBUG
			debugPort->print("Scentence complete. Checksum is: ");
			debugPort->println(checksum, HEX);
#endif
*/
			if (checksum == 0)
			{
				for (f_terms=0; f_terms<_terms; f_terms++)
				{
					_nt = 0;
					while ((_term[f_terms])[_nt])
					{
						(f_term[f_terms])[_nt] = (_term[f_terms])[_nt];
						_nt++;
					}
					(f_term[f_terms])[_nt] = 0;        
				}

				_state = 0;
				return 1;
			}
			break;
		}
		default :
		{
			_state = 0;
			break;
		}
  }

  return 0;
}