示例#1
0
//132405.000,A,4809.2356,N,01704.4263,E,0.15,317.49,270115,,,A
//hhmmss.XXX,
void gps_parse_rmc()
{
//	DEBUG("\nRMC\n");

	gps_init_ok = true;

//	strcpy(gps_parser_buffer, "$GPRMC,044434.000,A,3319.1312,S,14805.03,E,24.00,37.86,090116,,,A*71");

	char * ptr = find_comma(gps_parser_buffer);

	//UTC time
	uint8_t hour = atoi_n(ptr + 0, 2);
	uint8_t min = atoi_n(ptr + 2, 2);
	uint8_t sec = atoi_n(ptr + 4, 2);

//	DEBUG("%02d:%02d:%02d\n", hour, min, sec);

	ptr = find_comma(ptr);

	//Valid (A = valid)
	fc.gps_data.valid = (*ptr) == 'A';

	if (fc.gps_data.valid)
	{
		if (fc.gps_data.fix_cnt < GPS_FIX_CNT_MAX)
			fc.gps_data.fix_cnt++;
	}
	else
	{
		fc.gps_data.fix_cnt = 0;
	}

	ptr = find_comma(ptr);

	uint32_t loc_deg;
	uint32_t loc_min;

	//Latitude
	loc_deg = atoi_n(ptr, 2);
	loc_min = atoi_n(ptr + 2, 6);

	int32_t latitude = (loc_min * 100ul) / 6;
	latitude = loc_deg * 10000000ul + latitude;

	ptr = find_comma(ptr);

	//Latitude sign
	if ((*ptr) == 'S')
		latitude *= -1;

	fc.gps_data.latitude = latitude;

	sprintf_P((char *)fc.gps_data.cache_igc_latitude, PSTR("%02lu%05lu%c"), loc_deg, loc_min / 10, (*ptr));

	ptr = find_comma(ptr);

	//Longitude
	loc_deg = atoi_n(ptr, 3);
	loc_min = atoi_n(ptr + 3, 6);

	int32_t longitude = (loc_min * 100ul) / 6;
	longitude = loc_deg * 10000000ul + longitude;

	ptr = find_comma(ptr);

//	DEBUG("ptr = '%s'\n", ptr);

	//Longitude sign
	if ((*ptr) == 'W')
		longitude *= -1;

	fc.gps_data.longtitude = longitude;

	sprintf_P((char *)fc.gps_data.cache_igc_longtitude, PSTR("%03lu%05lu%c"), loc_deg, loc_min / 10, (*ptr));

	ptr = find_comma(ptr);

//	DEBUG("lat+lon %07ld %08ld\n", latitude, longitude);

	fc.gps_data.groud_speed = atoi_f(ptr); //in knots

	ptr = find_comma(ptr);

	//Ground course
	fc.gps_data.heading = atoi_f(ptr);

	ptr = find_comma(ptr);

	//UTC date
	uint8_t day = atoi_n(ptr + 0, 2);
	uint8_t month = atoi_n(ptr + 2, 2);
	uint16_t year = atoi_n(ptr + 4, 2) + 2000;

//	DEBUG("%02d.%02d.%04d\n", day, month, year);

	fc.gps_data.utc_time = datetime_to_epoch(sec, min, hour, day, month, year);

	if (config.connectivity.forward_gps)
	{
		char tmp[NMEA_MAX_LEN];
		sprintf(tmp, "$%s", gps_parser_buffer);
		bt_send(tmp);
		if (config.connectivity.uart_function > UART_FORWARD_OFF)
			uart_send(tmp);
	}

	uint16_t tdeg, tmin, tsec;
	int32_t tmp;

	switch (config.connectivity.gps_format_flags & GPS_FORMAT_MASK)
	{
		case(GPS_DDdddddd):
			sprintf_P((char *)fc.gps_data.cache_gui_latitude, PSTR(" %+010ld"), fc.gps_data.latitude);
			memcpy((void *)fc.gps_data.cache_gui_latitude, (void *)(fc.gps_data.cache_gui_latitude + 1), 3);
			fc.gps_data.cache_gui_latitude[3] = '.';
			if (fc.gps_data.cache_gui_latitude[1] == '0')
				memcpy((void *)(fc.gps_data.cache_gui_latitude + 1), (void *)(fc.gps_data.cache_gui_latitude + 2), 10);

			sprintf_P((char *)fc.gps_data.cache_gui_longtitude, PSTR(" %+011ld"), fc.gps_data.longtitude);
			memcpy((void *)fc.gps_data.cache_gui_longtitude, (void *)(fc.gps_data.cache_gui_longtitude + 1), 4);
			fc.gps_data.cache_gui_longtitude[4] = '.';

			if (fc.gps_data.cache_gui_longtitude[1] == '0')
			{
				if (fc.gps_data.cache_gui_longtitude[2] == '0')
					memcpy((void *)(fc.gps_data.cache_gui_longtitude + 1), (void *)(fc.gps_data.cache_gui_longtitude + 3), 10);
				else
					memcpy((void *)(fc.gps_data.cache_gui_longtitude + 1), (void *)(fc.gps_data.cache_gui_longtitude + 2), 11);
			}
		break;

		case(GPS_DDMMmmm):
			memcpy((void *)fc.gps_data.cache_gui_latitude, (void *)fc.gps_data.cache_igc_latitude, 2);
			fc.gps_data.cache_gui_latitude[2] = '*';
			memcpy((void *)(fc.gps_data.cache_gui_latitude + 3), (void *)(fc.gps_data.cache_igc_latitude + 2), 2);
			fc.gps_data.cache_gui_latitude[5] = '.';
			memcpy((void *)(fc.gps_data.cache_gui_latitude + 6), (void *)(fc.gps_data.cache_igc_latitude + 4), 4);
			fc.gps_data.cache_gui_latitude[10] = 0;

			memcpy((void *)fc.gps_data.cache_gui_longtitude, (void *)fc.gps_data.cache_igc_longtitude, 3);
			fc.gps_data.cache_gui_longtitude[3] = '*';
			memcpy((void *)(fc.gps_data.cache_gui_longtitude + 4), (void *)(fc.gps_data.cache_igc_longtitude + 3), 2);
			fc.gps_data.cache_gui_longtitude[6] = '.';
			memcpy((void *)(fc.gps_data.cache_gui_longtitude + 7), (void *)(fc.gps_data.cache_igc_longtitude + 5), 4);
			fc.gps_data.cache_gui_longtitude[11] = 0;
		break;

		case(GPS_DDMMSS):
			tdeg = abs(fc.gps_data.latitude) / 10000000ul;
			tmp = ((abs(fc.gps_data.latitude) % 10000000ul) * 60);
			tmin = tmp / 10000000ul;
			tsec = ((tmp % 10000000ul) * 60) / 10000000ul;

			sprintf_P((char *)fc.gps_data.cache_gui_latitude,
					PSTR("%02u*%02u'%02u\"%c"), tdeg, tmin, tsec, (*(fc.gps_data.cache_igc_latitude + 7)));

			tdeg = abs(fc.gps_data.longtitude) / 10000000ul;
			tmp = ((abs(fc.gps_data.longtitude) % 10000000ul) * 60);
			tmin = tmp / 10000000ul;
			tsec = ((tmp % 10000000ul) * 60) / 10000000ul;

			sprintf_P((char *)fc.gps_data.cache_gui_longtitude,
					PSTR("%03u*%02u'%02u\"%c"), tdeg, tmin, tsec, (*(fc.gps_data.cache_igc_longtitude + 8)));
		break;
	}

//	DEBUG("clat = %s\n", fc.gps_data.cache_gui_latitude);
//	DEBUG("clon = %s\n", fc.gps_data.cache_gui_longtitude);
}
示例#2
0
文件: marcdump.c 项目: nla/yaz
static void dump(const char *fname, const char *from, const char *to,
                 int input_format, int output_format,
                 int write_using_libxml2,
                 int print_offset, const char *split_fname, int split_chunk,
                 int verbose, FILE *cfile, const char *leader_spec)
{
    yaz_marc_t mt = yaz_marc_create();
    yaz_iconv_t cd = 0;

    if (yaz_marc_leader_spec(mt, leader_spec))
    {
        fprintf(stderr, "bad leader spec: %s\n", leader_spec);
        yaz_marc_destroy(mt);
        exit(2);
    }
    if (from && to)
    {
        cd = yaz_iconv_open(to, from);
        if (!cd)
        {
            fprintf(stderr, "conversion from %s to %s "
                    "unsupported\n", from, to);
            yaz_marc_destroy(mt);
            exit(2);
        }
        yaz_marc_iconv(mt, cd);
    }
    yaz_marc_enable_collection(mt);
    yaz_marc_xml(mt, output_format);
    yaz_marc_write_using_libxml2(mt, write_using_libxml2);
    yaz_marc_debug(mt, verbose);

    if (input_format == YAZ_MARC_MARCXML || input_format == YAZ_MARC_TURBOMARC || input_format == YAZ_MARC_XCHANGE)
    {
#if YAZ_HAVE_XML2
        marcdump_read_xml(mt, fname);
#endif
    }
    else if (input_format == YAZ_MARC_LINE)
    {
        marcdump_read_line(mt, fname);
    }
    else if (input_format == YAZ_MARC_ISO2709)
    {
        FILE *inf = fopen(fname, "rb");
        int num = 1;
        int marc_no = 0;
        int split_file_no = -1;
        if (!inf)
        {
            fprintf(stderr, "%s: cannot open %s:%s\n",
                    prog, fname, strerror(errno));
            exit(1);
        }
        if (cfile)
            fprintf(cfile, "char *marc_records[] = {\n");
        for(;; marc_no++)
        {
            const char *result = 0;
            size_t len;
            size_t rlen;
            size_t len_result;
            size_t r;
            char buf[100001];

            r = fread(buf, 1, 5, inf);
            if (r < 5)
            {
                if (r == 0) /* normal EOF, all good */
                    break;
                if (print_offset && verbose)
                {
                    printf("<!-- Extra %ld bytes at end of file -->\n",
                           (long) r);
                }
                break;
            }
            while (*buf < '0' || *buf > '9')
            {
                int i;
                long off = ftell(inf) - 5;
                printf("<!-- Skipping bad byte %d (0x%02X) at offset "
                       "%ld (0x%lx) -->\n",
                       *buf & 0xff, *buf & 0xff,
                       off, off);
                for (i = 0; i<4; i++)
                    buf[i] = buf[i+1];
                r = fread(buf+4, 1, 1, inf);
                no_errors++;
                if (r < 1)
                    break;
            }
            if (r < 1)
            {
                if (verbose || print_offset)
                    printf("<!-- End of file with data -->\n");
                break;
            }
            if (print_offset)
            {
                long off = ftell(inf) - 5;
                printf("<!-- Record %d offset %ld (0x%lx) -->\n",
                       num, off, off);
            }
            len = atoi_n(buf, 5);
            if (len < 25 || len > 100000)
            {
                long off = ftell(inf) - 5;
                printf("<!-- Bad Length %ld read at offset %ld (%lx) -->\n",
                       (long)len, (long) off, (long) off);
                no_errors++;
                break;
            }
            rlen = len - 5;
            r = fread(buf + 5, 1, rlen, inf);
            if (r < rlen)
            {
                long off = ftell(inf);
                printf("<!-- Premature EOF at offset %ld (%lx) -->\n",
                       (long) off, (long) off);
                no_errors++;
                break;
            }
            while (buf[len-1] != ISO2709_RS)
            {
                if (len > sizeof(buf)-2)
                {
                    r = 0;
                    break;
                }
                r = fread(buf + len, 1, 1, inf);
                if (r != 1)
                    break;
                len++;
            }
            if (r < 1)
            {
                printf("<!-- EOF while searching for RS -->\n");
                no_errors++;
                break;
            }
            if (split_fname)
            {
                char fname[256];
                const char *mode = 0;
                FILE *sf;
                if ((marc_no % split_chunk) == 0)
                {
                    mode = "wb";
                    split_file_no++;
                }
                else
                    mode = "ab";
                sprintf(fname, "%.200s%07d", split_fname, split_file_no);
                sf = fopen(fname, mode);
                if (!sf)
                {
                    fprintf(stderr, "Could not open %s\n", fname);
                    split_fname = 0;
                }
                else
                {
                    if (fwrite(buf, 1, len, sf) != len)
                    {
                        fprintf(stderr, "Could write content to %s\n",
                                fname);
                        split_fname = 0;
                        no_errors++;
                    }
                    fclose(sf);
                }
            }
            len_result = rlen;
            r = yaz_marc_decode_buf(mt, buf, -1, &result, &len_result);
            if (r == -1)
                no_errors++;
            if (r > 0 && result && len_result)
            {
                if (fwrite(result, len_result, 1, stdout) != 1)
                {
                    fprintf(stderr, "Write to stdout failed\n");
                    no_errors++;
                    break;
                }
            }
            if (r > 0 && cfile)
            {
                char *p = buf;
                size_t i;
                if (marc_no)
                    fprintf(cfile, ",");
                fprintf(cfile, "\n");
                for (i = 0; i < r; i++)
                {
                    if ((i & 15) == 0)
                        fprintf(cfile, "  \"");
                    fprintf(cfile, "\\x%02X", p[i] & 255);

                    if (i < r - 1 && (i & 15) == 15)
                        fprintf(cfile, "\"\n");

                }
                fprintf(cfile, "\"\n");
            }
            num++;
            if (verbose)
                printf("\n");
        }
        if (cfile)
            fprintf(cfile, "};\n");
        fclose(inf);
    }
    {
        WRBUF wrbuf = wrbuf_alloc();
        yaz_marc_write_trailer(mt, wrbuf);
        fputs(wrbuf_cstr(wrbuf), stdout);
        wrbuf_destroy(wrbuf);
    }
    if (cd)
        yaz_iconv_close(cd);
    yaz_marc_destroy(mt);
}
示例#3
0
int yaz_marc_read_iso2709(yaz_marc_t mt, const char *buf, int bsize)
{
    int entry_p;
    int record_length;
    int indicator_length;
    int identifier_length;
    int end_of_directory;
    int base_address;
    int length_data_entry;
    int length_starting;
    int length_implementation;

    yaz_marc_reset(mt);

    record_length = atoi_n (buf, 5);
    if (record_length < 25)
    {
        yaz_marc_cprintf(mt, "Record length %d < 24", record_length);
        return -1;
    }
    /* ballout if bsize is known and record_length is less than that */
    if (bsize != -1 && record_length > bsize)
    {
        yaz_marc_cprintf(mt, "Record appears to be larger than buffer %d < %d",
                         record_length, bsize);
        return -1;
    }
    if (yaz_marc_get_debug(mt))
        yaz_marc_cprintf(mt, "Record length         %5d", record_length);

    yaz_marc_set_leader(mt, buf,
                        &indicator_length,
                        &identifier_length,
                        &base_address,
                        &length_data_entry,
                        &length_starting,
                        &length_implementation);

    /* First pass. determine length of directory & base of data */
    for (entry_p = 24; buf[entry_p] != ISO2709_FS; )
    {
        /* length of directory entry */
        int l = 3 + length_data_entry + length_starting;
        if (entry_p + l >= record_length)
        {
            yaz_marc_cprintf(mt, "Directory offset %d: end of record."
                             " Missing FS char", entry_p);
            return -1;
        }
        if (yaz_marc_get_debug(mt))
        {
            yaz_marc_cprintf(mt, "Directory offset %d: Tag %.3s",
                             entry_p, buf+entry_p);
        }
        /* Check for digits in length info */
        while (--l >= 3)
            if (!isdigit(*(const unsigned char *) (buf + entry_p+l)))
                break;
        if (l >= 3)
        {
            /* Not all digits, so stop directory scan */
            yaz_marc_cprintf(mt, "Directory offset %d: Bad value for data"
                             " length and/or length starting", entry_p);
            break;
        }
        entry_p += 3 + length_data_entry + length_starting;
    }
    end_of_directory = entry_p;
    if (base_address != entry_p+1)
    {
        yaz_marc_cprintf(mt, "Base address not at end of directory,"
                         " base %d, end %d", base_address, entry_p+1);
    }

    /* Second pass. parse control - and datafields */
    for (entry_p = 24; entry_p != end_of_directory; )
    {
        int data_length;
        int data_offset;
        int end_offset;
        int i;
        char tag[4];
        int identifier_flag = 0;
        int entry_p0 = entry_p;

        memcpy (tag, buf+entry_p, 3);
        entry_p += 3;
        tag[3] = '\0';
        data_length = atoi_n(buf+entry_p, length_data_entry);
        entry_p += length_data_entry;
        data_offset = atoi_n(buf+entry_p, length_starting);
        entry_p += length_starting;
        i = data_offset + base_address;
        end_offset = i+data_length-1;

        if (data_length <= 0 || data_offset < 0)
            break;
        
        if (yaz_marc_get_debug(mt))
        {
            yaz_marc_cprintf(mt, "Tag: %s. Directory offset %d: data-length %d,"
                             " data-offset %d",
                             tag, entry_p0, data_length, data_offset);
        }
        if (end_offset >= record_length)
        {
            yaz_marc_cprintf(mt, "Directory offset %d: Data out of bounds %d >= %d",
                             entry_p0, end_offset, record_length);
            break;
        }
        
        if (memcmp (tag, "00", 2))
            identifier_flag = 1;  /* if not 00X assume subfields */
        else if (indicator_length < 4 && indicator_length > 0)
        {
            /* Danmarc 00X have subfields */
            if (buf[i + indicator_length] == ISO2709_IDFS)
                identifier_flag = 1;
            else if (buf[i + indicator_length + 1] == ISO2709_IDFS)
                identifier_flag = 2;
        }

        if (identifier_flag)
        {
            /* datafield */
            i += identifier_flag-1;
            if (indicator_length)
            {
                /* skip RS/FS bytes in indicator. They are not allowed there */
                int j;
                for (j = indicator_length; --j >= 0; )
                    if (buf[j+i] < ' ')
                    {
                        j++;
                        i += j;
                        end_offset += j;
                        yaz_marc_cprintf(mt, "Bad indicator data. "
                                         "Skipping %d bytes", j);
                        break;
                    }
                yaz_marc_add_datafield(mt, tag, buf+i, indicator_length);
                i += indicator_length;
            }

            while (i < end_offset &&
                    buf[i] != ISO2709_RS && buf[i] != ISO2709_FS)
            {
                int code_offset = i+1;

                i ++;
                while (i < end_offset &&
                        buf[i] != ISO2709_RS && buf[i] != ISO2709_IDFS &&
                       buf[i] != ISO2709_FS)
                    i++;
                if (i > code_offset)
                    yaz_marc_add_subfield(mt, buf+code_offset, i - code_offset);
            }
        }
        else
        {
            /* controlfield */
            int i0 = i;
            while (i < end_offset && 
                buf[i] != ISO2709_RS && buf[i] != ISO2709_FS)
                i++;
            yaz_marc_add_controlfield(mt, tag, buf+i0, i-i0);
        }
        if (i < end_offset)
        {
            yaz_marc_cprintf(mt, "Separator but not at end of field length=%d",
                    data_length);
        }
        if (buf[i] != ISO2709_RS && buf[i] != ISO2709_FS)
        {
            yaz_marc_cprintf(mt, "No separator at end of field length=%d",
                             data_length);
        }
    }
    return record_length;
}