1 /* 2 * This program is free software; you can redistribute it and/or modify 3 * it under the terms of the GNU General Public License as published by 4 * the Free Software Foundation; either version 2 of the License, or 5 * (at your option) any later version. 6 * 7 * This program is distributed in the hope that it will be useful, 8 * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 * GNU General Public License for more details. 11 * 12 * You should have received a copy of the GNU General Public License 13 * along with this program; if not, write to the Free Software 14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. 15 * 16 * Copyright (C) 2014 John Crispin <blogic@openwrt.org> 17 */ 18 19 #include <string.h> 20 #include <stdint.h> 21 #include <stdlib.h> 22 #include <unistd.h> 23 24 #include <libubox/uloop.h> 25 #include <libubus.h> 26 27 #include "log.h" 28 #include "nmea.h" 29 30 unsigned int debug; 31 static struct ustream_fd stream; 32 static struct ubus_auto_conn conn; 33 static struct blob_buf b; 34 static char *ubus_socket; 35 struct timespec stamp = { 0 }; 36 unsigned int adjust_clock = 0; 37 38 void 39 gps_timestamp(void) 40 { 41 clock_gettime(CLOCK_MONOTONIC, &stamp); 42 } 43 44 static int 45 gps_info(struct ubus_context *ctx, struct ubus_object *obj, 46 struct ubus_request_data *req, const char *method, 47 struct blob_attr *msg) 48 { 49 struct timespec now; 50 51 clock_gettime(CLOCK_MONOTONIC, &now); 52 53 blob_buf_init(&b, 0); 54 55 if (!stamp.tv_sec || !gps_fields) { 56 blobmsg_add_u8(&b, "signal", 0); 57 } else { 58 blobmsg_add_u32(&b, "age", now.tv_sec - stamp.tv_sec); 59 if (gps_fields & GPS_FIELD_LAT) 60 blobmsg_add_string(&b, "latitude", latitude); 61 if (gps_fields & GPS_FIELD_LON) 62 blobmsg_add_string(&b, "longitude", longitude); 63 if (gps_fields & GPS_FIELD_ALT) 64 blobmsg_add_string(&b, "elevation", elevation); 65 if (gps_fields & GPS_FIELD_COG) 66 blobmsg_add_string(&b, "course", course); 67 if (gps_fields & GPS_FIELD_SPD) 68 blobmsg_add_string(&b, "speed", speed); 69 if (gps_fields & GPS_FIELD_SAT) 70 blobmsg_add_string(&b, "satellites", satellites); 71 if (gps_fields & GPS_FIELD_HDP) 72 blobmsg_add_string(&b, "HDOP", hdop); 73 } 74 ubus_send_reply(ctx, req, b.head); 75 76 return UBUS_STATUS_OK; 77 } 78 79 static const struct ubus_method gps_methods[] = { 80 UBUS_METHOD_NOARG("info", gps_info), 81 }; 82 83 static struct ubus_object_type gps_object_type = 84 UBUS_OBJECT_TYPE("gps", gps_methods); 85 86 static struct ubus_object gps_object = { 87 .name = "gps", 88 .type = &gps_object_type, 89 .methods = gps_methods, 90 .n_methods = ARRAY_SIZE(gps_methods), 91 }; 92 93 static void 94 ubus_connect_handler(struct ubus_context *ctx) 95 { 96 int ret; 97 98 ret = ubus_add_object(ctx, &gps_object); 99 if (ret) 100 fprintf(stderr, "Failed to add object: %s\n", ubus_strerror(ret)); 101 } 102 103 static int 104 usage(const char *prog) 105 { 106 fprintf(stderr, "Usage: %s [options] <device>\n" 107 "Options:\n" 108 " -a Adjust system clock from gps\n" 109 " -s <path> Path to ubus socket\n" 110 " -d <level> Enable debug messages\n" 111 " -S Print messages to stdout\n" 112 " -b Set gps device baud rate\n" 113 "\n", prog); 114 return -1; 115 } 116 117 static speed_t get_baudrate(int baudrate) 118 { 119 switch (baudrate) { 120 case 4800: 121 return B4800; 122 case 9600: 123 return B9600; 124 case 19200: 125 return B19200; 126 case 38400: 127 return B38400; 128 case 57600: 129 return B57600; 130 case 115200: 131 return B115200; 132 default: 133 fprintf(stderr, "ERROR: incorrect baud rate. Default 4800 baud rate has been set\n"); 134 return B4800; 135 } 136 } 137 138 int 139 main(int argc, char ** argv) 140 { 141 int ch; 142 char *device = NULL; 143 char *dbglvl = getenv("DBGLVL"); 144 int ulog_channels = ULOG_KMSG; 145 speed_t baudrate = B4800; 146 147 signal(SIGPIPE, SIG_IGN); 148 149 if (dbglvl) { 150 debug = atoi(dbglvl); 151 unsetenv("DBGLVL"); 152 } 153 154 while ((ch = getopt(argc, argv, "ad:s:Sb:")) != -1) { 155 switch (ch) { 156 case 'a': 157 adjust_clock = -1; 158 break; 159 case 's': 160 ubus_socket = optarg; 161 break; 162 case 'd': 163 debug = atoi(optarg); 164 break; 165 case 'S': 166 ulog_channels = ULOG_STDIO; 167 break; 168 case 'b': 169 baudrate = get_baudrate(atoi(optarg)); 170 break; 171 default: 172 return usage(argv[0]); 173 } 174 } 175 176 if (argc - optind < 1) { 177 fprintf(stderr, "ERROR: missing device parameter\n"); 178 return usage(argv[0]); 179 } 180 181 device = argv[optind]; 182 ulog_open(ulog_channels, LOG_DAEMON, "ugps"); 183 184 uloop_init(); 185 conn.path = ubus_socket; 186 conn.cb = ubus_connect_handler; 187 ubus_auto_connect(&conn); 188 189 if (nmea_open(device, &stream, baudrate) < 0) 190 return -1; 191 192 uloop_run(); 193 uloop_done(); 194 195 return 0; 196 } 197
This page was automatically generated by LXR 0.3.1. • OpenWrt