From 2f7a78002f012c7ed322767cf3e413b961a640b4 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Mon, 25 Aug 2014 07:35:41 -0400 Subject: Split firmwqre version query out of the init method. This enables us to force readonly off while it's being called. The practical effect is that gpsmon can get a firmware version (if this is possible) without reconfiguring the device. --- TODO | 5 ----- driver_evermore.c | 1 + driver_garmin.c | 3 +++ driver_geostar.c | 11 +++++++++-- driver_italk.c | 1 + driver_navcom.c | 1 + driver_nmea2000.c | 1 + driver_oncore.c | 3 ++- driver_proto.c | 2 ++ driver_sirf.c | 22 ++++++++++++---------- driver_superstar2.c | 4 ++++ driver_tsip.c | 24 +++++++++++++++--------- driver_ubx.c | 14 +++++++++++--- driver_zodiac.c | 1 + drivers.c | 21 +++++++++++++++++++-- gpsd.h-tail | 1 + libgpsd_core.c | 14 ++++++++++++++ www/writing-a-driver.xml | 13 +++++++++++++ 18 files changed, 110 insertions(+), 32 deletions(-) diff --git a/TODO b/TODO index aee80655..4184320c 100644 --- a/TODO +++ b/TODO @@ -39,11 +39,6 @@ uncertainty in output JSON. *** Client bugs -*** gpsmon on a SiRF doesn't get firmware version *** - -For this to work, the firmware probe needs to be split out of the -configure method so gpsmon can call it separately. - **** In gpsmon's PPS Offset field Presently PPS Offset is displayed in direct mode for NMEA, SiRF, and diff --git a/driver_evermore.c b/driver_evermore.c index d8ec713c..ea315643 100644 --- a/driver_evermore.c +++ b/driver_evermore.c @@ -623,6 +623,7 @@ const struct gps_type_t driver_evermore = .get_packet = generic_get, /* use generic one */ .parse_packet = generic_parse_input, /* parse message packets */ .rtcm_writer = gpsd_write, /* send RTCM data straight */ + .init_query = NULL, /* non-perturbing query */ .event_hook = evermore_event_hook, /* lifetime event handler */ #ifdef RECONFIGURE_ENABLE .speed_switcher = evermore_speed, /* we can change baud rates */ diff --git a/driver_garmin.c b/driver_garmin.c index 4ecdad49..acdbc90b 100644 --- a/driver_garmin.c +++ b/driver_garmin.c @@ -1384,6 +1384,7 @@ const struct gps_type_t driver_garmin_usb_binary_old = .get_packet = garmin_get_packet,/* how to grab a packet */ .parse_packet = garmin_usb_parse, /* parse message packets */ .rtcm_writer = NULL, /* don't send DGPS corrections */ + .init_query = NULL, /* non-perturbing initial query */ .event_hook = garmin_event_hook,/* lifetime event handler */ #ifdef RECONFIGURE_ENABLE .speed_switcher = NULL, /* no speed switcher */ @@ -1413,6 +1414,7 @@ const struct gps_type_t driver_garmin_usb_binary = .get_packet = generic_get, /* how to grab a packet */ .parse_packet = garmin_ser_parse, /* parse message packets */ .rtcm_writer = NULL, /* don't send DGPS corrections */ + .init_query = NULL, /* non-perturbing initial query */ .event_hook = garmin_event_hook,/* lifetime ebent handler */ #ifdef RECONFIGURE_ENABLE .speed_switcher = NULL, /* no speed switcher */ @@ -1441,6 +1443,7 @@ const struct gps_type_t driver_garmin_ser_binary = .get_packet = generic_get, /* how to grab a packet */ .parse_packet = garmin_ser_parse, /* parse message packets */ .rtcm_writer = NULL, /* don't send DGPS corrections */ + .init_query = NULL, /* non-perturbing initial query */ .event_hook = NULL, /* lifetime event handler */ #ifdef RECONFIGURE_ENABLE .speed_switcher = NULL, /* no speed switcher */ diff --git a/driver_geostar.c b/driver_geostar.c index e2f5899e..a7c37689 100644 --- a/driver_geostar.c +++ b/driver_geostar.c @@ -502,6 +502,14 @@ static ssize_t geostar_control_send(struct gps_device_t *session, } #endif /* CONTROLSEND_ENABLE */ + +static void geostar_init_query(struct gps_device_t *session) +{ + unsigned char buf[2 * 4]; + /* Poll Software Version */ + (void)geostar_write(session, 0xc1, buf, 1); +} + static void geostar_event_hook(struct gps_device_t *session, event_t event) { unsigned char buf[2 * 4]; @@ -537,8 +545,6 @@ static void geostar_event_hook(struct gps_device_t *session, event_t event) (void)geostar_write(session, 0x8e, buf, 1); /* Poll binary packets selected */ (void)geostar_write(session, 0x8f, buf, 1); - /* Poll Software Version */ - (void)geostar_write(session, 0xc1, buf, 1); } if (event == event_deactivate) { @@ -620,6 +626,7 @@ const struct gps_type_t driver_geostar = .get_packet = generic_get, /* use the generic packet getter */ .parse_packet = geostar_parse_input, /* parse message packets */ .rtcm_writer = NULL, /* doesn't accept DGPS corrections */ + .init_query = geostar_init_query, /* non-perturbing initial query */ .event_hook = geostar_event_hook, /* fire on various lifetime events */ #ifdef RECONFIGURE_ENABLE .speed_switcher = geostar_speed_switch,/* change baud rate */ diff --git a/driver_italk.c b/driver_italk.c index 75f8e738..94f78118 100644 --- a/driver_italk.c +++ b/driver_italk.c @@ -416,6 +416,7 @@ const struct gps_type_t driver_italk = .get_packet = generic_get, /* use generic packet grabber */ .parse_packet = italk_parse_input,/* parse message packets */ .rtcm_writer = gpsd_write, /* send RTCM data straight */ + .init_query = NULL, /* non-perturbing initial query */ .event_hook = NULL, /* lifetime event handler */ #ifdef RECONFIGURE_ENABLE .speed_switcher = NULL, /* no speed switcher */ diff --git a/driver_navcom.c b/driver_navcom.c index fdecf661..213b6d25 100644 --- a/driver_navcom.c +++ b/driver_navcom.c @@ -1285,6 +1285,7 @@ const struct gps_type_t driver_navcom = .get_packet = generic_get, /* use generic one */ .parse_packet = navcom_parse_input, /* parse message packets */ .rtcm_writer = gpsd_write, /* send RTCM data straight */ + .init_query = NULL, /* non-perturbing query */ .event_hook = navcom_event_hook, /* lifetime event handler */ #ifdef RECONFIGURE_ENABLE .speed_switcher = navcom_speed, /* we do change baud rates */ diff --git a/driver_nmea2000.c b/driver_nmea2000.c index 147eba57..dc6eb474 100644 --- a/driver_nmea2000.c +++ b/driver_nmea2000.c @@ -1675,6 +1675,7 @@ const struct gps_type_t driver_nmea2000 = { .get_packet = nmea2000_get, /* how to get a packet */ .parse_packet = nmea2000_parse_input, /* how to interpret a packet */ .rtcm_writer = NULL, /* Don't send RTCM to this */ + .init_query = NULL, /* non-perturbing query */ .event_hook = NULL, #ifdef RECONFIGURE_ENABLE .speed_switcher = NULL, /* no speed switcher */ diff --git a/driver_oncore.c b/driver_oncore.c index d745b476..e9dbecfd 100644 --- a/driver_oncore.c +++ b/driver_oncore.c @@ -498,7 +498,8 @@ const struct gps_type_t driver_oncore = { .get_packet = generic_get, /* packet getter */ .parse_packet = oncore_parse_input, /* packet parser */ .rtcm_writer = gpsd_write, /* device accepts RTCM */ - .event_hook = oncore_event_hook, /* lifetime event hook */ + .init_query = NULL, /* non-perturbing query */ + .event_hook = oncore_event_hook, /* lifetime event hook */ #ifdef RECONFIGURE_ENABLE .speed_switcher = NULL, /* no speed setter */ .mode_switcher = NULL, /* no mode setter */ diff --git a/driver_proto.c b/driver_proto.c index d0de2410..10fb05ac 100644 --- a/driver_proto.c +++ b/driver_proto.c @@ -512,6 +512,8 @@ const struct gps_type_t driver__proto__binary = { .parse_packet = _proto__parse_input, /* RTCM handler (using default routine) */ .rtcm_writer = pass_rtcm, + /* non-perturbing initial query (e.g. for version) */ + .init_query = NULL, /* fire on various lifetime events */ .event_hook = _proto__event_hook, #ifdef RECONFIGURE_ENABLE diff --git a/driver_sirf.c b/driver_sirf.c index d0506e7f..0a81781c 100644 --- a/driver_sirf.c +++ b/driver_sirf.c @@ -1373,6 +1373,13 @@ static gps_mask_t sirfbin_parse_input(struct gps_device_t *session) return 0; } +static void sirfbin_init_query(struct gps_device_t *session) +{ + gpsd_report(session->context->debug, LOG_PROG, + "SiRF: Probing for firmware version.\n"); + (void)sirf_write(session, versionprobe); +} + static void sirfbin_event_hook(struct gps_device_t *session, event_t event) { if (session->context->readonly) @@ -1401,9 +1408,11 @@ static void sirfbin_event_hook(struct gps_device_t *session, event_t event) return; case 1: + /* disable navigation debug messages (the value 5 is magic) */ gpsd_report(session->context->debug, LOG_PROG, - "SiRF: Probing for firmware version.\n"); - (void)sirf_write(session, versionprobe); + "SiRF: disable MID 7, 28, 29, 30, 31.\n"); + putbyte(unsetmidXX, 5, 0x05); + (void)sirf_write(session, unsetmidXX); break; case 2: @@ -1484,14 +1493,6 @@ static void sirfbin_event_hook(struct gps_device_t *session, event_t event) } break; - case 12: - /* disable navigation debug messages (the value 5 is magic) */ - gpsd_report(session->context->debug, LOG_PROG, - "SiRF: disable MID 7, 28, 29, 30, 31.\n"); - putbyte(unsetmidXX, 5, 0x05); - (void)sirf_write(session, unsetmidXX); - break; - #endif /* RECONFIGURE_ENABLE */ default: /* initialization is done */ @@ -1546,6 +1547,7 @@ const struct gps_type_t driver_sirf = .get_packet = generic_get, /* be prepared for SiRF or NMEA */ .parse_packet = sirfbin_parse_input,/* parse message packets */ .rtcm_writer = gpsd_write, /* send RTCM data straight */ + .init_query = sirfbin_init_query,/* non-perturbing initial qury */ .event_hook = sirfbin_event_hook,/* lifetime event handler */ #ifdef RECONFIGURE_ENABLE .speed_switcher = sirfbin_speed, /* we can change baud rate */ diff --git a/driver_superstar2.c b/driver_superstar2.c index ff151f6d..9db21e02 100644 --- a/driver_superstar2.c +++ b/driver_superstar2.c @@ -430,6 +430,8 @@ superstar2_dispatch(struct gps_device_t * session, unsigned char *buf, * **********************************************************/ +/* FIXME: factor out Superstar init_query for version */ + static void superstar2_event_hook(struct gps_device_t *session, event_t event) { if (session->context->readonly) @@ -556,6 +558,8 @@ const struct gps_type_t driver_superstar2 = { .parse_packet = superstar2_parse_input, /* RTCM handler (using default routine) */ .rtcm_writer = gpsd_write, + /* non-perturbing initial query */ + .init_query = NULL, /* Fire on various lifetime events */ .event_hook = superstar2_event_hook, #ifdef RECONFIGURE_ENABLE diff --git a/driver_tsip.c b/driver_tsip.c index ea29145e..d8736736 100644 --- a/driver_tsip.c +++ b/driver_tsip.c @@ -1012,6 +1012,19 @@ static ssize_t tsip_control_send(struct gps_device_t *session, } #endif /* CONTROLSEND_ENABLE */ +static void tsip_init_query(struct gps_device_t *session) +{ + unsigned char buf[100]; + + /* Request Hardware Version Information */ + putbyte(buf, 0, 0x03); /* Subcode */ + (void)tsip_write(session, 0x1c, buf, 1); + /* + * After HW information packet is received, a + * decision is made how to configure the device. + */ +} + static void tsip_event_hook(struct gps_device_t *session, event_t event) { if (session->context->readonly) @@ -1020,7 +1033,7 @@ static void tsip_event_hook(struct gps_device_t *session, event_t event) unsigned char buf[100]; /* - * Set basic configuration, in case no hardware config resonse + * Set basic configuration, in case no hardware config response * comes back. */ putbyte(buf, 0, 0x1e); /* Position: DP, MSL, LLA */ @@ -1028,14 +1041,6 @@ static void tsip_event_hook(struct gps_device_t *session, event_t event) putbyte(buf, 2, 0x00); /* Time: GPS */ putbyte(buf, 3, 0x08); /* Aux: dBHz */ (void)tsip_write(session, 0x35, buf, 4); - - /* Request Hardware Version Information */ - putbyte(buf, 0, 0x03); /* Subcode */ - (void)tsip_write(session, 0x1c, buf, 1); - /* - * After HW information packet is received, a - * decision is made how to configure the device. - */ } if (event == event_configure && session->packet.counter == 0) { /* @@ -1256,6 +1261,7 @@ const struct gps_type_t driver_tsip = .get_packet = generic_get, /* use the generic packet getter */ .parse_packet = tsip_parse_input, /* parse message packets */ .rtcm_writer = NULL, /* doesn't accept DGPS corrections */ + .init_query = tsip_init_query, /* non-perturbing initial query */ .event_hook = tsip_event_hook, /* fire on various lifetime events */ #ifdef RECONFIGURE_ENABLE .speed_switcher = tsip_speed_switch,/* change baud rate */ diff --git a/driver_ubx.c b/driver_ubx.c index 88633919..cf51afd0 100644 --- a/driver_ubx.c +++ b/driver_ubx.c @@ -619,6 +619,16 @@ static ssize_t ubx_control_send(struct gps_device_t *session, char *msg, } #endif /* CONTROLSEND_ENABLE */ +static void ubx_init_query(struct gps_device_t *session) +{ + unsigned char msg[32]; + + /*@ -type @*/ + /* MON_VER: query for version information */ + (void)ubx_write(session, UBX_CLASS_MON, 0x04, msg, 0); + /*@ +type @*/ +} + static void ubx_event_hook(struct gps_device_t *session, event_t event) { if (session->context->readonly) @@ -638,9 +648,6 @@ static void ubx_event_hook(struct gps_device_t *session, event_t event) msg[6] = 0x00; msg[7] = 0x00; (void)ubx_write(session, 0x06u, 0x16, msg, 8); - - /* MON_VER: query for version information */ - (void)ubx_write(session, UBX_CLASS_MON, 0x04, msg, 0); /*@ +type @*/ #ifdef RECONFIGURE_ENABLE @@ -969,6 +976,7 @@ const struct gps_type_t driver_ubx = { .get_packet = generic_get, /* Packet getter (using default routine) */ .parse_packet = parse_input, /* Parse message packets */ .rtcm_writer = gpsd_write, /* RTCM handler (using default routine) */ + .init_query = ubx_init_query, /* non-perturbing initial query */ .event_hook = ubx_event_hook, /* Fire on various lifetime events */ #ifdef RECONFIGURE_ENABLE .speed_switcher = ubx_speed, /* Speed (baudrate) switch */ diff --git a/driver_zodiac.c b/driver_zodiac.c index 240c7909..be7d8b54 100644 --- a/driver_zodiac.c +++ b/driver_zodiac.c @@ -474,6 +474,7 @@ const struct gps_type_t driver_zodiac = .get_packet = generic_get, /* use the generic packet getter */ .parse_packet = zodiac_analyze, /* parse message packets */ .rtcm_writer = zodiac_send_rtcm, /* send DGPS correction */ + .init_query = NULL, /* non-perturbing initial query */ .event_hook = NULL, /* no configuration */ #ifdef RECONFIGURE_ENABLE .speed_switcher = zodiac_speed_switch,/* we can change baud rate */ diff --git a/drivers.c b/drivers.c index 13cf4ef8..725fb709 100644 --- a/drivers.c +++ b/drivers.c @@ -87,6 +87,7 @@ const struct gps_type_t driver_unknown = { .get_packet = generic_get, /* use generic packet getter */ .parse_packet = generic_parse_input, /* how to interpret a packet */ .rtcm_writer = NULL, /* write RTCM data straight */ + .init_query = NULL, /* non-perturbing initial query */ .event_hook = NULL, /* lifetime event handler */ #ifdef RECONFIGURE_ENABLE .speed_switcher = NULL, /* no speed switcher */ @@ -252,6 +253,7 @@ const struct gps_type_t driver_nmea0183 = { .get_packet = generic_get, /* use generic packet getter */ .parse_packet = generic_parse_input, /* how to interpret a packet */ .rtcm_writer = gpsd_write, /* write RTCM data straight */ + .init_query = NULL, /* non-perturbing initial query */ .event_hook = nmea_event_hook, /* lifetime event handler */ #ifdef RECONFIGURE_ENABLE .speed_switcher = NULL, /* no speed switcher */ @@ -357,6 +359,7 @@ const struct gps_type_t driver_garmin = { .get_packet = generic_get, /* use generic packet getter */ .parse_packet = generic_parse_input, /* how to interpret a packet */ .rtcm_writer = NULL, /* some do, some don't, skip for now */ + .init_query = NULL, /* non-perturbing initial query */ .event_hook = garmin_nmea_event_hook, /* lifetime event handler */ #ifdef RECONFIGURE_ENABLE .speed_switcher = NULL, /* no speed switcher */ @@ -419,6 +422,7 @@ const struct gps_type_t driver_ashtech = { .get_packet = generic_get, /* how to get a packet */ .parse_packet = generic_parse_input, /* how to interpret a packet */ .rtcm_writer = gpsd_write, /* write RTCM data straight */ + .init_query = NULL, /* non-perturbing initial query */ .event_hook = ashtech_event_hook, /* lifetime event handler */ #ifdef RECONFIGURE_ENABLE .speed_switcher = NULL, /* no speed switcher */ @@ -470,6 +474,7 @@ const struct gps_type_t driver_fv18 = { .get_packet = generic_get, /* how to get a packet */ .parse_packet = generic_parse_input, /* how to interpret a packet */ .rtcm_writer = gpsd_write, /* write RTCM data straight */ + .init_query = NULL, /* non-perturbing initial query */ .event_hook = fv18_event_hook, /* lifetime event handler */ #ifdef RECONFIGURE_ENABLE .speed_switcher = NULL, /* no speed switcher */ @@ -524,6 +529,7 @@ const struct gps_type_t driver_gpsclock = { .get_packet = generic_get, /* how to get a packet */ .parse_packet = generic_parse_input, /* how to interpret a packet */ .rtcm_writer = gpsd_write, /* write RTCM data straight */ + .init_query = NULL, /* non-perturbing initial query */ .event_hook = gpsclock_event_hook, /* lifetime event handler */ #ifdef RECONFIGURE_ENABLE .speed_switcher = NULL, /* no speed switcher */ @@ -577,8 +583,9 @@ static const struct gps_type_t driver_tripmate = { .channels = 12, /* consumer-grade GPS */ .probe_detect = NULL, /* no probe */ .get_packet = generic_get, /* how to get a packet */ - .parse_packet = generic_parse_input, /* how to interpret a packet */ - .rtcm_writer = gpsd_write, /* send RTCM data straight */ + .parse_packet = generic_parse_input, /* how to interpret a packet */ + .rtcm_writer = gpsd_write, /* send RTCM data straight */ + .init_query = NULL, /* non-perturbing query */ .event_hook = tripmate_event_hook, /* lifetime event handler */ #ifdef RECONFIGURE_ENABLE .speed_switcher= NULL, /* no speed switcher */ @@ -630,6 +637,7 @@ static const struct gps_type_t driver_earthmate = { .get_packet = generic_get, /* how to get a packet */ .parse_packet = generic_parse_input, /* how to interpret a packet */ .rtcm_writer = NULL, /* don't send RTCM data */ + .init_query = NULL, /* non-perturbing query */ .event_hook = earthmate_event_hook, /* lifetime event handler */ #ifdef RECONFIGURE_ENABLE .speed_switcher= NULL, /* no speed switcher */ @@ -755,6 +763,7 @@ const struct gps_type_t driver_trueNorth = { .get_packet = generic_get, /* how to get a packet */ .parse_packet = generic_parse_input, /* how to interpret a packet */ .rtcm_writer = NULL, /* Don't send */ + .init_query = NULL, /* non-perturbing initial query */ .event_hook = tnt_event_hook, /* lifetime event handler */ #ifdef RECONFIGURE_ENABLE .speed_switcher = tnt_speed, /* no speed switcher */ @@ -833,6 +842,7 @@ static const struct gps_type_t driver_oceanServer = { .get_packet = generic_get, /* how to get a packet */ .parse_packet = generic_parse_input, /* how to interpret a packet */ .rtcm_writer = NULL, /* Don't send */ + .init_query = NULL, /* non-perturbing initial query */ .event_hook = oceanserver_event_hook, #ifdef RECONFIGURE_ENABLE .speed_switcher = NULL, /* no speed switcher */ @@ -900,6 +910,7 @@ static const struct gps_type_t driver_fury = { .get_packet = generic_get, /* how to get a packet */ .parse_packet = generic_parse_input, /* how to interpret a packet */ .rtcm_writer = NULL, /* Don't send */ + .init_query = NULL, /* non-perturbing initial query */ .event_hook = fury_event_hook, #ifdef RECONFIGURE_ENABLE .speed_switcher = NULL, /* no speed switcher */ @@ -954,6 +965,7 @@ static const struct gps_type_t driver_rtcm104v2 = { .get_packet = generic_get, /* how to get a packet */ .parse_packet = rtcm104v2_analyze, /* */ .rtcm_writer = NULL, /* don't send RTCM data, */ + .init_query = NULL, /* non-perturbing initial query */ .event_hook = NULL, /* no event_hook */ #ifdef RECONFIGURE_ENABLE .speed_switcher= NULL, /* no speed switcher */ @@ -1000,6 +1012,7 @@ static const struct gps_type_t driver_rtcm104v3 = { .get_packet = generic_get, /* how to get a packet */ .parse_packet = rtcm104v3_analyze, /* */ .rtcm_writer = NULL, /* don't send RTCM data, */ + .init_query = NULL, /* non-perturbing initial query */ .event_hook = NULL, /* no event hook */ #ifdef RECONFIGURE_ENABLE .speed_switcher= NULL, /* no speed switcher */ @@ -1035,6 +1048,7 @@ static const struct gps_type_t driver_garmintxt = { .get_packet = generic_get, /* how to get a packet */ .parse_packet = garmintxt_parse, /* how to parse one */ .rtcm_writer = NULL, /* don't send RTCM data, */ + .init_query = NULL, /* non-perturbing initial query */ .event_hook = NULL, /* no event hook */ #ifdef RECONFIGURE_ENABLE .speed_switcher= NULL, /* no speed switcher */ @@ -1130,6 +1144,7 @@ const struct gps_type_t driver_mtk3301 = { .get_packet = generic_get, /* how to get a packet */ .parse_packet = generic_parse_input, /* how to interpret a packet */ .rtcm_writer = gpsd_write, /* write RTCM data straight */ + .init_query = NULL, /* non-perturbing initial query */ .event_hook = mtk3301_event_hook, /* lifetime event handler */ #ifdef RECONFIGURE_ENABLE .speed_switcher = NULL, /* no speed switcher */ @@ -1372,6 +1387,7 @@ const struct gps_type_t driver_aivdm = { .get_packet = generic_get, /* how to get a packet */ .parse_packet = aivdm_analyze, /* how to analyze a packet */ .rtcm_writer = NULL, /* don't send RTCM data, */ + .init_query = NULL, /* non-perturbing initial query */ .event_hook = NULL, /* lifetime event handler */ #ifdef RECONFIGURE_ENABLE .speed_switcher = NULL, /* no speed switcher */ @@ -1475,6 +1491,7 @@ const struct gps_type_t driver_json_passthrough = { .get_packet = generic_get, /* use generic packet getter */ .parse_packet = json_pass_packet, /* how to interpret a packet */ .rtcm_writer = NULL, /* write RTCM data straight */ + .init_query = NULL, /* non-perturbing initial query */ .event_hook = NULL, /* lifetime event handler */ #ifdef RECONFIGURE_ENABLE .speed_switcher = NULL, /* no speed switcher */ diff --git a/gpsd.h-tail b/gpsd.h-tail index 34bfe71e..f28152b8 100644 --- a/gpsd.h-tail +++ b/gpsd.h-tail @@ -345,6 +345,7 @@ struct gps_type_t { /*@null@*/ssize_t (*get_packet)(struct gps_device_t *session); /*@null@*/gps_mask_t (*parse_packet)(struct gps_device_t *session); /*@null@*/ssize_t (*rtcm_writer)(struct gps_device_t *session, const char *rtcmbuf, size_t rtcmbytes); + /*@null@*/void (*init_query)(struct gps_device_t *session); /*@null@*/void (*event_hook)(struct gps_device_t *session, event_t event); #ifdef RECONFIGURE_ENABLE /*@null@*/bool (*speed_switcher)(struct gps_device_t *session, diff --git a/libgpsd_core.c b/libgpsd_core.c index f7e8075c..f11e4831 100644 --- a/libgpsd_core.c +++ b/libgpsd_core.c @@ -1325,6 +1325,20 @@ gps_mask_t gpsd_poll(struct gps_device_t *session) timestamp() - session->opentime, (unsigned int)speed); /*@+nullderef@*/ + + /* fire the init_query method */ + if (session->device_type != NULL + && session->device_type->init_query != NULL) { + /* + * We can force readonly off knowing this method does + * not alter device state. + */ + bool saved = session->context->readonly; + session->context->readonly = false; + session->device_type->init_query(session); + session->context->readonly = saved; + } + /* fire the identified hook */ if (session->device_type != NULL && session->device_type->event_hook != NULL) diff --git a/www/writing-a-driver.xml b/www/writing-a-driver.xml index 91e751b4..9cac39b3 100644 --- a/www/writing-a-driver.xml +++ b/www/writing-a-driver.xml @@ -14,6 +14,14 @@ + + 1.13 + 25 Aug 2014 + er + + Updated by esr; added init_query method. + + 1.12 31 Oct 2013 @@ -639,6 +647,11 @@ original settings for later restoration, probably by .wrapup mentioned below. Later in this document I discuss my work to implement this function. + +.init_query points to a block of code +that will be called to query the firmware version of the device. This +code must not alter device state or settings. + .event_hook points to a block of code that will be executed on and after various events, distinguished by a second argument that specifies the event type. The event_hook hook is -- cgit v1.2.1