Index: configure.ac =================================================================== --- configure.ac (revision 4804) +++ configure.ac (working copy) @@ -409,6 +409,21 @@ AC_MSG_RESULT([no]) fi +dnl check for OceanServer support +AC_ARG_ENABLE(oceanserver, + AC_HELP_STRING([--enable-oceanserver], + [enable OceanServer support]), + [ac_oceanserver=$enableval], [ac_oceanserver=no]) +AC_MSG_CHECKING([for OceanServer support]) +if test x"$ac_oceanserver" = "xyes"; then + ac_nmea=yes + AC_MSG_RESULT([yes]) + AC_DEFINE([OCEANSERVER_ENABLE], 1, [OceanServer support]) + AC_DEFINE([NMEA_ENABLE], 1, [OceanServer requires NMEA support]) +else + AC_MSG_RESULT([no]) +fi + dnl check for UBX support AC_ARG_ENABLE(ubx, AC_HELP_STRING([--disable-ubx], @@ -759,6 +774,7 @@ echo "Trimble TSIP : $ac_tsip" echo "Tripmate : $ac_tripmate" echo "True North : $ac_tnt" +echo "OceanServer : $ac_oceanserver" echo "UBX : $ac_ubx" echo "GPSclock : $ac_gpsclock" dnl Below this line are non-protocol switches @@ -793,6 +809,7 @@ x"$ac_rtcm104v2" = "xno" -a \ x"$ac_sirf" = "xno" -a \ x"$ac_tnt" = "xno" -a \ + x"$ac_oceanserver" = "xno" -a \ x"$ac_tripmate" = "xno" -a \ x"$ac_tsip" = "xno" -a \ x"$ac_ubx" = "xno"; then Index: gpsutils.c =================================================================== --- gpsutils.c (revision 4804) +++ gpsutils.c (working copy) @@ -12,6 +12,9 @@ #include "gpsd_config.h" #include "gpsd.h" +#define isnan(x) (FP_NAN == x) + + #define MONTHSPERYEAR 12 /* months per calendar year */ void gps_clear_fix(/*@out@*/struct gps_fix_t *fixp) Index: gpsd.c =================================================================== --- gpsd.c (revision 4804) +++ gpsd.c (working copy) @@ -83,6 +83,8 @@ #define sub_index(s) (s - subscribers) +#define isnan(x) (FP_NAN == x) + static fd_set all_fds; static int maxfd; static int debuglevel; Index: drivers.c =================================================================== --- drivers.c (revision 4804) +++ drivers.c (working copy) @@ -39,6 +39,7 @@ gps_mask_t nmea_parse_input(struct gps_device_t *session) { + gpsd_report(LOG_WARN, "=> PARSE INPUT\n"); if (session->packet.type == COMMENT_PACKET) { return 0; } else if (session->packet.type == SIRF_PACKET) { @@ -85,6 +86,14 @@ } } #endif /* GARMINTXT_ENABLE */ + +#ifdef OCEANSERVER_ENABLE + if (strncmp((char *)session->packet.outbuffer, "$C", 2)==0 || strncmp((char *)session->packet.outbuffer, "$OHPR", 5)==0) { + (void)gpsd_switch_driver(session, "OceanServer Digital Compas OS5000"); + return 1; + } +#endif /* OCEANSERVER_ENABLE */ + gpsd_report(LOG_IO, "<= GPS: %s", session->packet.outbuffer); if ((st=nmea_parse((char *)session->packet.outbuffer, session))==0) { #ifdef NON_NMEA_ENABLE @@ -119,6 +128,7 @@ static void nmea_probe_subtype(struct gps_device_t *session, unsigned int seq) { + gpsd_report(LOG_WARN, "=> PROBING SUBTYPE %d\n", seq); /* * The reason for splitting these probes up by packet sequence * number, interleaving them with the first few packet receives, @@ -737,6 +747,76 @@ .cycle = 20, /* updates per second */ }; #endif +#ifdef OCEANSERVER_ENABLE +/************************************************************************** + * OceanServer - Digital Compass, OS5000 Series + * + * More info: http://www.ocean-server.com/download/OS5000_Compass_Manual.pdf + * + * This is a digital compass which uses magnetometers to measure the + * strength of the earth's magnetic field. Based on these measurements + * it provides a compass heading using NMEA formatted output strings. + * This is useful to supplement the heading provided by another GPS + * unit. A GPS heading is unreliable at slow speed or no speed. + * + **************************************************************************/ + +static int oceanserver_send(int fd, const char *fmt, ... ) +{ + int status; + char buf[BUFSIZ]; + va_list ap; + + va_start(ap, fmt) ; + (void)vsnprintf(buf, sizeof(buf)-5, fmt, ap); + va_end(ap); + strlcat(buf, "", BUFSIZ); + status = (int)write(fd, buf, strlen(buf)); + tcdrain(fd); + if (status == (int)strlen(buf)) { + gpsd_report(LOG_IO, "=> GPS: %s\n", buf); + return status; + } else { + gpsd_report(LOG_WARN, "=> GPS: %s FAILED\n", buf); + return -1; + } +} + +#ifdef ALLOW_RECONFIGURE +static void oceanserver_configure(struct gps_device_t *session, unsigned int seq) +{ + gpsd_report(LOG_WARN, "=> OCEAN CONFIGURE\n"); + if (seq == 0){ + (void)oceanserver_send(session->gpsdata.gps_fd, "2\n"); + (void)oceanserver_send(session->gpsdata.gps_fd, "X4096 "); + } +} +#endif /* ALLOW_RECONFIGURE */ + +struct gps_type_t oceanServer = { + .type_name = "OceanServer Digital Compas OS5000", /* full name of type */ + .trigger = "$C", + .channels = 0, /* not an actual GPS at all */ + .probe_wakeup = NULL, /* this will become a real method */ + .probe_detect = NULL, /* probe by sending ID query */ + .probe_subtype = NULL, /* probe for True North Digital Compass */ +#ifdef ALLOW_RECONFIGURE + .configurator = oceanserver_configure, /* no setting changes */ +#endif /* ALLOW_RECONFIGURE */ + .get_packet = generic_get, /* how to get a packet */ + .parse_packet = nmea_parse_input, /* how to interpret a packet */ + .rtcm_writer = NULL, /* Don't send */ + .speed_switcher = NULL, /* no speed switcher */ + .mode_switcher = NULL, /* no mode switcher */ + .rate_switcher = NULL, /* no wrapup */ + .cycle_chars = -1, /* not relevant, no rate switch */ +#ifdef ALLOW_RECONFIGURE + .revert = NULL, /* no setting-reversion method */ +#endif /* ALLOW_RECONFIGURE */ + .wrapup = NULL, /* no wrapup */ + .cycle = 20, /* updates per second */ +}; +#endif #ifdef RTCM104V2_ENABLE /************************************************************************** * @@ -912,6 +992,9 @@ #ifdef TNT_ENABLE &trueNorth, #endif /* TSIP_ENABLE */ +#ifdef OCEANSERVER_ENABLE + &oceanServer, +#endif /* OCEANSERVER_ENABLE */ #ifdef EVERMORE_ENABLE &evermore_binary, #endif /* EVERMORE_ENABLE */ Index: nmea_parse.c =================================================================== --- nmea_parse.c (revision 4804) +++ nmea_parse.c (working copy) @@ -13,6 +13,9 @@ #include "gpsd.h" #include "timebase.h" +#define isnan(x) (FP_NAN == x) + + #ifdef NMEA_ENABLE /************************************************************************** * @@ -599,6 +602,65 @@ } #endif /* TNT_ENABLE */ +#ifdef OCEANSERVER_ENABLE +static gps_mask_t processOHPR(int c UNUSED, char *field[], struct gps_device_t *session) +{ + /* + * Proprietary sentence for OceanServer Magnetic Compass. + + OHPR,x.x,x.x,x.x,x.x,x.x,x.x,x.x,x.x,x.x,x.x,x.x,x.x,x.x,x.x,x.x,x.x,x.x,x.x*hh + Fields in order: + 1. Azimuth + 2. Pitch Angle + 3. Roll Angle + 4. Temperature + 5. Depth (feet) + 6. Magnetic Vector Length + 7-9. 3 axis Magnetic Field readings x,y,z + 10. Acceleration Vector Length + 11-13. 3 axis Acceleration Readings x,y,z + 14. Reserved + 15-16. 2 axis Gyro Output, X,y + 17. Reserved + 18. Reserved + *hh mandatory nmea_checksum + */ + gps_mask_t mask; + mask = ONLINE_SET; + + //gpsd_zero_satellites(&session->gpsdata); + + /* + * Heading maps to track. + * Pitch maps to climb. + * Roll maps to speed. + * Depth maps to altitude. + */ + session->gpsdata.fix.time = timestamp(); + session->gpsdata.fix.track = atof(field[1]); + session->gpsdata.fix.climb = atof(field[2]); + session->gpsdata.fix.speed = atof(field[3]); + session->gpsdata.temperature = atof(field[4]); + session->gpsdata.fix.altitude = atof(field[5]); + session->gpsdata.magnetic_length = atof(field[6]); + session->gpsdata.magnetic_field_x = atof(field[7]); + session->gpsdata.magnetic_field_y = atof(field[8]); + session->gpsdata.magnetic_field_z = atof(field[9]); + session->gpsdata.acceleration_length = atof(field[10]); + session->gpsdata.acceleration_field_x = atof(field[11]); + session->gpsdata.acceleration_field_y = atof(field[12]); + session->gpsdata.acceleration_field_z = atof(field[13]); + session->gpsdata.gyro_output_x = atof(field[15]); + session->gpsdata.gyro_output_y = atof(field[16]); + session->gpsdata.fix.mode = MODE_3D; + mask |= (STATUS_SET | MODE_SET | TRACK_SET | SPEED_SET | CLIMB_SET | ALTITUDE_SET); + session->gpsdata.status = STATUS_FIX; /* could be DGPS_FIX */ + + gpsd_report(LOG_RAW, "Heading %lf.\n", session->gpsdata.fix.track); + return mask; +} +#endif /* OCEANSERVER_ENABLE */ + #ifdef ASHTECH_ENABLE static gps_mask_t processPASHR(int c UNUSED, char *field[], struct gps_device_t *session) { @@ -705,7 +767,10 @@ #endif /* TNT_ENABLE */ #ifdef ASHTECH_ENABLE {"PASHR", 3, processPASHR}, /* general handler for Ashtech */ -#endif /* TNT_ENABLE */ +#endif /* ASHTECH_ENABLE */ +#ifdef OCEANSERVER_ENABLE + {"OHPR", 18, processOHPR}, +#endif /* OCEANSERVER_ENABLE */ }; volatile unsigned char buf[NMEA_MAX+1]; Index: packet.c =================================================================== --- packet.c (revision 4804) +++ packet.c (working copy) @@ -207,10 +207,12 @@ lexer->state = NMEA_PUB_LEAD; else if (c == 'P') /* vendor sentence */ lexer->state = NMEA_VENDOR_LEAD; - else if (c =='I') /* Seatalk */ + else if (c == 'I') /* Seatalk */ lexer->state = SEATALK_LEAD_1; - else if (c =='A') /* SiRF Ack */ + else if (c == 'A') /* SiRF Ack */ lexer->state = SIRF_ACK_LEAD_1; + else if (c == 'C') + lexer->state = NMEA_LEADER_END; else lexer->state = GROUND_STATE; break; Index: libgpsd_core.c =================================================================== --- libgpsd_core.c (revision 4804) +++ libgpsd_core.c (working copy) @@ -22,7 +22,9 @@ #endif #endif +#define isnan(x) (FP_NAN == x) + int gpsd_switch_driver(struct gps_device_t *session, char* type_name) { struct gps_type_t **dp; @@ -47,9 +49,14 @@ /*@i@*/session->device_type = *dp; if (!session->context->readonly && session->device_type->probe_subtype != NULL) session->device_type->probe_subtype(session, session->packet.counter = 0); + + gpsd_report(LOG_PROG, "blabla\n"); #ifdef ALLOW_RECONFIGURE + + gpsd_report(LOG_PROG, "blabla2 %d\n", session->enable_reconfigure); if (session->enable_reconfigure && session->device_type->configurator != NULL) { + gpsd_report(LOG_PROG, "configuring for %s...\n", session->device_type->type_name); session->device_type->configurator(session, 0); } Index: gps.h =================================================================== --- gps.h (revision 4804) +++ gps.h (working copy) @@ -531,12 +531,28 @@ #define SAT_FIX_USED 0x40 /* used for position fix */ #endif +#ifdef TNT_ENABLE /* compass status -- TrueNorth (and any similar) devices only */ char headingStatus; char pitchStatus; char rollStatus; double horzField; /* Magnitude of horizontal magnetic field */ +#endif +#ifdef OCEANSERVER_ENABLE + double magnetic_length; /* unitvector sqrt(x^2 + y^2 +z^2) */ + double magnetic_field_x; + double magnetic_field_y; + double magnetic_field_z; + double acceleration_length; /* unitvector sqrt(x^2 + y^2 +z^2) */ + double acceleration_field_x; + double acceleration_field_y; + double acceleration_field_z; + double gyro_output_x; + double gyro_output_y; + double temperature; +#endif + /* where and what gpsd thinks the device is */ char gps_device[PATH_MAX]; /* only valid if non-null. */ char *gps_id; /* only valid if non-null. */