[PATCH] ubus: add option for enabling ubus notification

Wojciech Jowsa wojciech.jowsa at gmail.com
Thu Nov 4 04:41:43 PDT 2021


ubus notifications have to be enabled to
support publish / subscribe pattern. This pattern
is an alternative to polling, and can be used
e.g. for streaming gps data directly to other
application or a browser.

Signed-off-by: Wojciech Jowsa <wojciech.jowsa at gmail.com>
---
 main.c | 41 +++++++++++++++++++++++++++++++++++------
 nmea.c |  5 ++++-
 nmea.h |  1 +
 3 files changed, 40 insertions(+), 7 deletions(-)

diff --git a/main.c b/main.c
index 2ab0f8c..1626c01 100644
--- a/main.c
+++ b/main.c
@@ -13,7 +13,7 @@
  *   along with this program; if not, write to the Free Software
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
  *
- *   Copyright (C) 2014 John Crispin <blogic at openwrt.org> 
+ *   Copyright (C) 2014 John Crispin <blogic at openwrt.org>
  */
 
 #include <string.h>
@@ -34,6 +34,7 @@ static struct blob_buf b;
 static char *ubus_socket;
 struct timespec stamp = { 0 };
 unsigned int adjust_clock = 0;
+bool notify = false;
 
 void
 gps_timestamp(void)
@@ -41,10 +42,8 @@ gps_timestamp(void)
 	clock_gettime(CLOCK_MONOTONIC, &stamp);
 }
 
-static int
-gps_info(struct ubus_context *ctx, struct ubus_object *obj,
-	struct ubus_request_data *req, const char *method,
-	struct blob_attr *msg)
+static void
+prepare_data()
 {
 	struct timespec now;
 
@@ -67,6 +66,15 @@ gps_info(struct ubus_context *ctx, struct ubus_object *obj,
 		if (gps_fields & GPS_FIELD_SPD)
 			blobmsg_add_string(&b, "speed", speed);
 	}
+}
+
+static int
+gps_info(struct ubus_context *ctx, struct ubus_object *obj,
+	struct ubus_request_data *req, const char *method,
+	struct blob_attr *msg)
+{
+	prepare_data();
+
 	ubus_send_reply(ctx, req, b.head);
 
 	return UBUS_STATUS_OK;
@@ -105,10 +113,28 @@ usage(const char *prog)
 		"	-s <path>	Path to ubus socket\n"
 		"	-d <level>	Enable debug messages\n"
 		"	-S		Print messages to stdout\n"
+		"	-n		Enable ubus notfication\n"
 		"\n", prog);
 	return -1;
 }
 
+void
+notify_ubus()
+{
+	int err;
+
+	if (!notify) {
+		return;
+	}
+
+	prepare_data();
+
+	err = ubus_notify(&(conn.ctx), &gps_object, "update", b.head, -1);
+	if (err) {
+		ERROR("Ubus notify failed: %s\n", ubus_strerror(err));
+	}
+}
+
 int
 main(int argc, char ** argv)
 {
@@ -124,7 +150,7 @@ main(int argc, char ** argv)
 		unsetenv("DBGLVL");
 	}
 
-	while ((ch = getopt(argc, argv, "ad:s:S")) != -1) {
+	while ((ch = getopt(argc, argv, "and:s:S")) != -1) {
 		switch (ch) {
 		case 'a':
 			adjust_clock = -1;
@@ -138,6 +164,9 @@ main(int argc, char ** argv)
 		case 'S':
 			ulog_channels = ULOG_STDIO;
 			break;
+		case 'n':
+			notify = true;
+			break;
 		default:
 			return usage(argv[0]);
 		}
diff --git a/nmea.c b/nmea.c
index e86f68f..44a739a 100644
--- a/nmea.c
+++ b/nmea.c
@@ -52,7 +52,7 @@ struct nmea_param {
 } nmea_params[MAX_NMEA_PARAM];
 
 static int nmea_bad_time;
-char longitude[33] = { 0 }, latitude[33] = { 0 }, course[17] = { 0 }, speed[17] = { 0 }, elevation[17] = { 0 };
+char longitude[33] = { 0 }, latitude[33] = { 0 }, course[17] = { 0 }, speed[17] = { 0 }, elevation[17] = { 0 }; 
 int gps_valid = 0;
 char gps_fields = 0;
 
@@ -123,6 +123,7 @@ parse_gps_coords(char *latstr, char *vhem, char *lonstr, char *hhem)
 	gps_fields |= GPS_FIELD_LAT | GPS_FIELD_LON;
 
 	gps_timestamp();
+	notify_ubus();
 }
 
 static void
@@ -224,6 +225,7 @@ nmea_gga_cb(void)
 		return;
 	strncpy(elevation, nmea_params[9].str, sizeof(elevation));
 	gps_fields |= GPS_FIELD_ALT;
+	notify_ubus();
 	DEBUG(4, "height: %s\n", elevation);
 }
 
@@ -235,6 +237,7 @@ nmea_vtg_cb(void)
 	strncpy(course, nmea_params[1].str, sizeof(course));
 	strncpy(speed, nmea_params[7].str, sizeof(speed));
 	gps_fields |= GPS_FIELD_COG | GPS_FIELD_SPD;
+	notify_ubus();
 	DEBUG(4, "course: %s\n", course);
 	DEBUG(4, "speed: %s\n", speed);
 }
diff --git a/nmea.h b/nmea.h
index 2de06dc..4bd07d8 100644
--- a/nmea.h
+++ b/nmea.h
@@ -27,6 +27,7 @@ extern char longitude[33], latitude[33], course[17], speed[17], elevation[17];
 extern int nmea_open(char *dev, struct ustream_fd *s, speed_t speed);
 extern void gps_timestamp(void);
 extern unsigned int adjust_clock;
+extern void notify_ubus(void);
 extern char gps_fields;
 #define GPS_FIELD_LAT (1<<0)
 #define GPS_FIELD_LON (1<<1)
-- 
2.25.1




More information about the openwrt-devel mailing list