summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Elder <aelder@audioscience.com>2012-11-30 09:12:27 -0500
committerAndrew Elder <aelder@audioscience.com>2013-01-03 12:20:54 -0500
commit85b2382805e94ee827eff35a85fdc88b9cf63938 (patch)
treee8e64458e40a05c9f20e4db44f0e5009d09bf391
parentabf6de90d1419a6118f84c99ad5244ea1bf7a435 (diff)
downloadOpen-AVB-85b2382805e94ee827eff35a85fdc88b9cf63938.tar.gz
mrpd: examples, add code to parse mrpd notifications and query response strings
-rwxr-xr-xexamples/mrp_client/mrpdhelper.c306
-rwxr-xr-xexamples/mrp_client/mrpdhelper.h134
2 files changed, 440 insertions, 0 deletions
diff --git a/examples/mrp_client/mrpdhelper.c b/examples/mrp_client/mrpdhelper.c
new file mode 100755
index 00000000..b413e23d
--- /dev/null
+++ b/examples/mrp_client/mrpdhelper.c
@@ -0,0 +1,306 @@
+/******************************************************************************
+
+ Copyright (c) 2012, AudioScience, Inc
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ 3. Neither the name of the Intel Corporation nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+******************************************************************************/
+
+/******************************************************************************
+This module implements code that takes the notification strings that MRPD sends
+and parses them into a machine readable structure.
+******************************************************************************/
+
+#include <stdio.h>
+#include <string.h>
+#include <stdint.h> // for uint8_t etc
+#ifdef __linux__
+#include <inttypes.h>
+#else
+#define SCNu64 "I64u"
+#define SCNx64 "I64x"
+#endif
+
+#include "mrpdhelper.h"
+
+struct app_state_to_enum {
+ char *s;
+ enum mrpdhelper_applicant_state value;
+} mrp_app_state_mapping[12] = {
+ "VO", mrpdhelper_applicant_state_VO,
+ "VP", mrpdhelper_applicant_state_VP,
+ "VN", mrpdhelper_applicant_state_VN,
+ "AN", mrpdhelper_applicant_state_AN,
+ "AA", mrpdhelper_applicant_state_AA,
+ "QA", mrpdhelper_applicant_state_QA,
+ "LA", mrpdhelper_applicant_state_LA,
+ "AO", mrpdhelper_applicant_state_AO,
+ "QO", mrpdhelper_applicant_state_QO,
+ "AP", mrpdhelper_applicant_state_AP,
+ "QP", mrpdhelper_applicant_state_QP,
+ "LO", mrpdhelper_applicant_state_LO
+};
+
+
+static int parse_app_state(char *sz, struct mrpdhelper_notify *n)
+{
+ int i;
+
+ /* loop over mrp_app_state_mapping struct */
+ for (i=0; i < 12; i++) {
+ if (strncmp(sz, mrp_app_state_mapping[i].s, 2) == 0) {
+ n->app_state = mrp_app_state_mapping[i].value;
+ break;
+ }
+ }
+ if (n->app_state == mrpdhelper_applicant_state_null)
+ return -1;
+ else
+ return 0;
+}
+
+static int parse_state(char *sz, struct mrpdhelper_notify *n)
+{
+ if (strncmp(sz, "IN", 2) == 0) {
+ n->state = mrpdhelper_state_in;
+ } else if (strncmp(sz, "LV", 3) == 0) {
+ n->state = mrpdhelper_state_leave;
+ } else if (strncmp(sz, "MT", 3) == 0) {
+ n->state = mrpdhelper_state_empty;
+ } else {
+ return -1;
+ }
+ return 0;
+}
+
+static int parse_notification(char *sz, struct mrpdhelper_notify *n)
+{
+ if (strncmp(sz, "NE", 2) == 0) {
+ n->notify = mrpdhelper_notification_new;
+ } else if (strncmp(sz, "JO", 2) == 0) {
+ n->notify = mrpdhelper_notification_join;
+ } else if (strncmp(sz, "LE", 2) == 0) {
+ n->notify = mrpdhelper_notification_leave;
+ } else {
+ return -1;
+ }
+ return 0;
+}
+
+static int parse_registrar(char *sz, struct mrpdhelper_notify *n, char **rpos)
+{
+ char *r;
+
+ r = strstr(sz, "R=");
+ if (rpos)
+ *rpos = r;
+ if (!r)
+ return -1;
+
+ if (sscanf(r, "R=%" SCNx64, &n->registrar) == 1)
+ return 0;
+ else
+ return -1;
+}
+
+static int parse_mvrp(char *sz, size_t len, struct mrpdhelper_notify *n)
+{
+ /* format
+ VIN VJO 1234 R=112233445566
+ len = 28
+ */
+ if (len < 28)
+ return -1;
+
+ if (parse_notification(&sz[1], n) < 0)
+ return -1;
+
+ if (parse_state(&sz[5], n) < 0)
+ return -1;
+
+ n->attrib = mrpdhelper_attribtype_mvrp;
+ if (sscanf(&sz[8], "%04x ", &n->u.v.vid) != 1)
+ return -1;
+ return parse_registrar(sz, n, NULL);
+}
+
+static int parse_msrp_string(char *sz, size_t len, struct mrpdhelper_notify *n)
+{
+ int result;
+
+ sz[len] = 0;
+ switch (sz[0]) {
+ case 'D':
+ result = sscanf(sz, "D:C=%d,P=%d,V=%04x",
+ &n->u.sd.id, &n->u.sd.priority, &n->u.sd.vid);
+ if (result < 3)
+ return -1;
+ n->attrib = mrpdhelper_attribtype_msrp_domain;
+ break;
+ case 'L':
+ result = sscanf(sz, "L:D=%d,S=%" SCNx64,
+ &n->u.sl.substate, &n->u.sl.id);
+ if (result < 2)
+ return -1;
+ n->attrib = mrpdhelper_attribtype_msrp_listener;
+ break;
+ case 'T':
+ result = sscanf(sz,
+ "T:S=%" SCNx64
+ ",A=%" SCNx64
+ ",V=%04x"
+ ",Z=%d"
+ ",I=%d"
+ ",P=%d"
+ ",L=%d"
+ ",B=%" SCNx64
+ ",C=%d",
+ &n->u.st.id,
+ &n->u.st.dest_mac,
+ &n->u.st.vid,
+ &n->u.st.max_frame_size,
+ &n->u.st.max_interval_frames,
+ &n->u.st.priority_and_rank,
+ &n->u.st.accum_latency,
+ &n->u.st.bridge_id, &n->u.st.failure_code);
+ if (result < 9)
+ return -1;
+ n->attrib = mrpdhelper_attribtype_msrp_talker;
+ break;
+ default:
+ return -1;
+
+ }
+ return 0;
+}
+
+static int parse_msrp(char *sz, size_t len, struct mrpdhelper_notify *n)
+{
+ if (parse_notification(&sz[1], n) < 0)
+ return -1;
+
+ if (parse_msrp_string(&sz[4], len - 4, n) < 0)
+ return -1;
+
+ return parse_registrar(sz, n, NULL);
+}
+
+
+static int parse_msrp_query(char *sz, size_t len, struct mrpdhelper_notify *n)
+{
+ char *r;
+
+ if (parse_msrp_string(sz, len, n) < 0)
+ return -1;
+
+ if (parse_registrar(sz, n, &r) < 0)
+ return -1;
+
+ if (parse_app_state(&r[15], n) < 0)
+ return -1;
+
+ return parse_state(&r[18], n);
+}
+
+static int parse_mmrp(char *sz, size_t len, struct mrpdhelper_notify *n)
+{
+ /* format
+ MIN MJO M=112233445566 R=112233445566
+ len = 38
+ */
+ if (len < 38)
+ return -1;
+
+ if (parse_notification(&sz[1], n) < 0)
+ return -1;
+
+ if (parse_state(&sz[5], n) < 0)
+ return -1;
+
+ n->attrib = mrpdhelper_attribtype_mvrp;
+ if (sscanf(&sz[8], "M=%" SCNx64, &n->u.m.mac) != 1)
+ return -1;
+ return parse_registrar(sz, n, NULL);
+}
+
+int mrpdhelper_parse_notification(char *sz, size_t len,
+ struct mrpdhelper_notify *n)
+{
+ memset(n, 0, sizeof(*n));
+ switch (sz[0]) {
+ case 'V':
+ return parse_mvrp(sz, len, n);
+ case 'S':
+ return parse_msrp(sz, len, n);
+ case 'M':
+ return parse_mmrp(sz, len, n);
+ case 'L':
+ case 'D':
+ case 'T':
+ return parse_msrp_query(sz, len, n);
+ default:
+ return -1;
+ }
+}
+
+int mrpdhelper_notify_equal(struct mrpdhelper_notify *n1,
+ struct mrpdhelper_notify *n2)
+{
+ if (n1->attrib != n2->attrib)
+ return 0;
+
+ switch (n1->attrib) {
+ case mrpdhelper_attribtype_mmrp:
+ if (n1->u.m.mac != n2->u.m.mac)
+ return 0;
+ break;
+ case mrpdhelper_attribtype_mvrp:
+ if (n1->u.v.vid != n2->u.v.vid)
+ return 0;
+ break;
+ case mrpdhelper_attribtype_msrp_domain:
+ if ((n1->u.sd.id != n1->u.sd.id) ||
+ (n1->u.sd.priority != n1->u.sd.priority) ||
+ (n1->u.sd.vid != n1->u.sd.vid))
+ return 0;
+ break;
+ case mrpdhelper_attribtype_msrp_talker:
+ case mrpdhelper_attribtype_msrp_talker_fail:
+ if (n1->u.st.id != n2->u.st.id)
+ return 0;
+ break;
+ case mrpdhelper_attribtype_msrp_listener:
+ case mrpdhelper_attribtype_msrp_listener_fail:
+ if (n1->u.sl.id != n2->u.sl.id)
+ return 0;
+ break;
+ default:
+ return 0;
+ }
+ return 1;
+}
diff --git a/examples/mrp_client/mrpdhelper.h b/examples/mrp_client/mrpdhelper.h
new file mode 100755
index 00000000..398d5435
--- /dev/null
+++ b/examples/mrp_client/mrpdhelper.h
@@ -0,0 +1,134 @@
+/******************************************************************************
+
+ Copyright (c) 2012, AudioScience, Inc
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ 3. Neither the name of the Intel Corporation nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+******************************************************************************/
+
+#ifndef _MRPDHELPER_H_
+#define _MRPDHELPER_H_
+
+/**************************************************************************
+This module provides helper functions for communicating with the MRPD daemon.
+***************************************************************************/
+
+enum mrpdhelper_attribtype {
+ mrpdhelper_attribtype_null,
+ mrpdhelper_attribtype_mmrp,
+ mrpdhelper_attribtype_mvrp,
+ mrpdhelper_attribtype_msrp_domain,
+ mrpdhelper_attribtype_msrp_talker,
+ mrpdhelper_attribtype_msrp_listener,
+ mrpdhelper_attribtype_msrp_talker_fail,
+ mrpdhelper_attribtype_msrp_listener_fail
+};
+
+enum mrpdhelper_notification {
+ mrpdhelper_notification_null,
+ mrpdhelper_notification_new,
+ mrpdhelper_notification_join,
+ mrpdhelper_notification_leave
+};
+
+enum mrpdhelper_state {
+ mrpdhelper_state_null,
+ mrpdhelper_state_in,
+ mrpdhelper_state_leave,
+ mrpdhelper_state_empty
+};
+
+enum mrpdhelper_applicant_state {
+ mrpdhelper_applicant_state_null,
+ mrpdhelper_applicant_state_VO,
+ mrpdhelper_applicant_state_VP,
+ mrpdhelper_applicant_state_VN,
+ mrpdhelper_applicant_state_AN,
+ mrpdhelper_applicant_state_AA,
+ mrpdhelper_applicant_state_QA,
+ mrpdhelper_applicant_state_LA,
+ mrpdhelper_applicant_state_AO,
+ mrpdhelper_applicant_state_QO,
+ mrpdhelper_applicant_state_AP,
+ mrpdhelper_applicant_state_QP,
+ mrpdhelper_applicant_state_LO
+};
+
+struct mrpdhelper_mmrp_notify {
+ uint64_t mac;
+};
+
+struct mrpdhelper_mvrp_notify {
+ uint32_t vid;
+};
+
+struct mrpdhelper_msrp_domain {
+ uint32_t id;
+ uint32_t priority;
+ uint32_t vid;
+};
+
+struct mrpdhelper_msrp_listener {
+ uint32_t substate;
+ uint64_t id;
+};
+
+struct mrpdhelper_msrp_talker {
+ uint64_t id;
+ uint64_t dest_mac;
+ uint32_t vid;
+ uint32_t max_frame_size;
+ uint32_t max_interval_frames;
+ uint32_t priority_and_rank;
+ uint32_t accum_latency;
+ uint64_t bridge_id;
+ uint32_t failure_code;
+};
+
+struct mrpdhelper_notify {
+ enum mrpdhelper_attribtype attrib;
+ enum mrpdhelper_notification notify;
+ enum mrpdhelper_state state;
+ enum mrpdhelper_applicant_state app_state;
+ uint64_t registrar;
+ union {
+ struct mrpdhelper_mmrp_notify m;
+ struct mrpdhelper_mvrp_notify v;
+ struct mrpdhelper_msrp_domain sd;
+ struct mrpdhelper_msrp_listener sl;
+ struct mrpdhelper_msrp_talker st;
+ } u;
+};
+
+int mrpdhelper_parse_notification(char *sz,
+ size_t len, struct mrpdhelper_notify *n);
+
+int mrpdhelper_notify_equal(struct mrpdhelper_notify *n1,
+ struct mrpdhelper_notify *n2);
+
+#endif