static void do_set_npe_mac(int argc, char *argv[]) { bool portnum_set; int portnum, i; char *addr = 0; struct option_info opts[1]; cyg_uint8 mac[6]; init_opts(&opts[0], 'p', true, OPTION_ARG_TYPE_NUM, (void **)&portnum, (bool *)&portnum_set, "port number"); if (!scan_opts(argc, argv, 1, opts, 1, (void *)&addr, OPTION_ARG_TYPE_STR, "MAC address")) { return; } if ((!portnum_set && addr) || (portnum_set && portnum != 0 && portnum != 1)) { diag_printf("Must specify port with \"-p <0|1>\"\n"); return; } if (!portnum_set) { for (i = 0; i < 2; i++) { cyghal_get_npe_esa(i, mac); diag_printf("NPE eth%d mac: %02x:%02x:%02x:%02x:%02x:%02x\n", i, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); } return; } if (!addr) { cyghal_get_npe_esa(portnum, mac); diag_printf("NPE eth%d mac: %02x:%02x:%02x:%02x:%02x:%02x\n", portnum, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); return; } // parse MAC address from user. // acceptable formats are "nn:nn:nn:nn:nn:nn" and "nnnnnnnnnnnn" for (i = 0; i < 6; i++) { if (!_is_hex(addr[0]) || !_is_hex(addr[1])) break; mac[i] = (_from_hex(addr[0]) * 16) + _from_hex(addr[1]); addr += 2; if (*addr == ':') addr++; } if (i != 6 || *addr != '\0') { diag_printf("Malformed MAC address.\n"); return; } for (i = 0; i < 6; i++) { eeprom_write(MAC_EEPROM_OFFSET(portnum) + i, mac[i]); hal_delay_us(100000); } }
/* Parse (scan) a number */ bool parse_num (char *s, unsigned long *val, char **es, char *delim) { bool first = true; int radix = 10; char c; unsigned long result = 0; int digit; while (*s == ' ') s++; while (*s) { if (first && (s[0] == '0') && (_tolower (s[1]) == 'x')) { radix = 16; s += 2; } first = false; c = *s++; if (_is_hex (c) && ((digit = _from_hex (c)) < radix)) { /* Valid digit */ #ifdef CYGPKG_HAL_MIPS /* FIXME: tx49 compiler generates 0x2539018 for MUL which */ /* isn't any good. */ if (16 == radix) result = result << 4; else result = 10 * result; result += digit; #else result = (result * radix) + digit; #endif } else { if (delim != (char *) 0) { /* See if this character is one of the delimiters */ char *dp = delim; while (*dp && (c != *dp)) dp++; if (*dp) break; /* Found a good delimiter */ } return false; /* Malformatted number */ } } *val = result; if (es != (char **) 0) { *es = s; } return true; }
// // Scan a string of hex bytes and update the checksum // static long _hex2(int (*getc)(void), int len, long *sum) { int val, byte; char c1, c2; val = 0; while (len-- > 0) { c1 = (*getc)(); c2 = (*getc)(); if (_is_hex(c1) && _is_hex(c2)) { val <<= 8; byte = (_from_hex(c1)<<4) | _from_hex(c2); val |= byte; if (sum) { *sum += byte; } } else { return (-1); } } return (val); }
/* Parse (scan) a number */ unsigned int parse_num(char *s, unsigned long *val, char **es, char *delim) { unsigned int first = 1; int radix = 10; char c; unsigned long result = 0; int digit; while(*s == ' ') s++; while(*s){ if(first && (s[0] == '0') && (_tolower(s[1]) == 'x')){ radix = 16; s += 2; } first = 0; c = *s++; if(_is_hex(c) && ((digit = _from_hex(c)) < radix)){ /* Valid digit */ result = (result * radix) + digit; } else { if(delim != (char *)0){ /* See if this character is one of the delimiters */ char *dp = delim; while(*dp && (c != *dp)) dp++; /* Found a good delimiter */ if(*dp) break; } /* Malformatted number */ return 0; } } *val = result; if(es != (char **)0){ *es = s; } return 1; }
bool inet_aton(const char *s, in_addr_t *addr) { int i, val, radix, digit; unsigned long res = 0; bool first; char c; for (i = 0; i < 4; i++) { // Parse next digit string first = true; val = 0; radix = 10; while ((c = *s++) != '\0') { if (first && (c == '0') && (_tolower(*s) == 'x')) { radix = 16; s++; // Skip over 0x c = *s++; } first = false; if (_is_hex(c) && ((digit = _from_hex(c)) < radix)) { // Valid digit val = (val * radix) + digit; } else if (c == '.' && i < 3) { // all but last terminate by '.' break; } else { return false; } } // merge result #ifdef __LITTLE_ENDIAN__ res |= val << ((3-i)*8); // 24, 16, 8, 0 #else res = (res << 8) | val; #endif if ('\0' == c) { if (0 == i) { // first field found end of string res = val; // no shifting, use it as the whole thing break; // permit entering a single number } if (3 > i) // we found end of string before getting 4 fields return false; } // after that we check that it was 0..255 only if (val &~0xff) return false; } addr->s_addr = htonl(res); return true; }
// Processes a just-completed term // Returns true if new sentence has just passed checksum test and is validated bool AP_GPS_NMEA::_term_complete() { // handle the last term in a message if (_is_checksum_term) { uint8_t checksum = 16 * _from_hex(_term[0]) + _from_hex(_term[1]); if (checksum == _parity) { if (_gps_data_good) { switch (_sentence_type) { case _GPS_SENTENCE_GPRMC: time = _new_time; date = _new_date; latitude = _new_latitude * 10; // degrees*10e5 -> 10e7 longitude = _new_longitude * 10; // degrees*10e5 -> 10e7 ground_speed = _new_speed; ground_course = _new_course; fix = true; break; case _GPS_SENTENCE_GPGGA: altitude = _new_altitude; time = _new_time; latitude = _new_latitude * 10; // degrees*10e5 -> 10e7 longitude = _new_longitude * 10; // degrees*10e5 -> 10e7 num_sats = _new_satellite_count; hdop = _new_hdop; fix = true; break; case _GPS_SENTENCE_GPVTG: ground_speed = _new_speed; ground_course = _new_course; // VTG has no fix indicator, can't change fix status break; } } else { switch (_sentence_type) { case _GPS_SENTENCE_GPRMC: case _GPS_SENTENCE_GPGGA: // Only these sentences give us information about // fix status. fix = false; } } // we got a good message return true; } // we got a bad message, ignore it return false; } // the first term determines the sentence type if (_term_number == 0) { if (!strcmp_P(_term, _gprmc_string)) { _sentence_type = _GPS_SENTENCE_GPRMC; } else if (!strcmp_P(_term, _gpgga_string)) { _sentence_type = _GPS_SENTENCE_GPGGA; } else if (!strcmp_P(_term, _gpvtg_string)) { _sentence_type = _GPS_SENTENCE_GPVTG; // VTG may not contain a data qualifier, presume the solution is good // unless it tells us otherwise. _gps_data_good = true; } else { _sentence_type = _GPS_SENTENCE_OTHER; } return false; } // 32 = RMC, 64 = GGA, 96 = VTG if (_sentence_type != _GPS_SENTENCE_OTHER && _term[0]) { switch (_sentence_type + _term_number) { // operational status // case _GPS_SENTENCE_GPRMC + 2: // validity (RMC) _gps_data_good = _term[0] == 'A'; break; case _GPS_SENTENCE_GPGGA + 6: // Fix data (GGA) _gps_data_good = _term[0] > '0'; break; case _GPS_SENTENCE_GPVTG + 9: // validity (VTG) (we may not see this field) _gps_data_good = _term[0] != 'N'; break; case _GPS_SENTENCE_GPGGA + 7: // satellite count (GGA) _new_satellite_count = atol(_term); break; case _GPS_SENTENCE_GPGGA + 8: // HDOP (GGA) _new_hdop = _parse_decimal(); break; // time and date // case _GPS_SENTENCE_GPRMC + 1: // Time (RMC) case _GPS_SENTENCE_GPGGA + 1: // Time (GGA) _new_time = _parse_decimal(); break; case _GPS_SENTENCE_GPRMC + 9: // Date (GPRMC) _new_date = atol(_term); break; // location // case _GPS_SENTENCE_GPRMC + 3: // Latitude case _GPS_SENTENCE_GPGGA + 2: _new_latitude = _parse_degrees(); break; case _GPS_SENTENCE_GPRMC + 4: // N/S case _GPS_SENTENCE_GPGGA + 3: if (_term[0] == 'S') _new_latitude = -_new_latitude; break; case _GPS_SENTENCE_GPRMC + 5: // Longitude case _GPS_SENTENCE_GPGGA + 4: _new_longitude = _parse_degrees(); break; case _GPS_SENTENCE_GPRMC + 6: // E/W case _GPS_SENTENCE_GPGGA + 5: if (_term[0] == 'W') _new_longitude = -_new_longitude; break; case _GPS_SENTENCE_GPGGA + 9: // Altitude (GPGGA) _new_altitude = _parse_decimal(); break; // course and speed // case _GPS_SENTENCE_GPRMC + 7: // Speed (GPRMC) case _GPS_SENTENCE_GPVTG + 5: // Speed (VTG) _new_speed = (_parse_decimal() * 514) / 1000; // knots-> m/sec, approximiates * 0.514 break; case _GPS_SENTENCE_GPRMC + 8: // Course (GPRMC) case _GPS_SENTENCE_GPVTG + 1: // Course (VTG) _new_course = _parse_decimal(); break; } } return false; }