diff options
author | Andrew Elder <aelder@audioscience.com> | 2012-11-30 09:12:27 -0500 |
---|---|---|
committer | Andrew Elder <aelder@audioscience.com> | 2013-01-03 12:20:54 -0500 |
commit | 85b2382805e94ee827eff35a85fdc88b9cf63938 (patch) | |
tree | e8e64458e40a05c9f20e4db44f0e5009d09bf391 | |
parent | abf6de90d1419a6118f84c99ad5244ea1bf7a435 (diff) | |
download | Open-AVB-85b2382805e94ee827eff35a85fdc88b9cf63938.tar.gz |
mrpd: examples, add code to parse mrpd notifications and query response strings
-rwxr-xr-x | examples/mrp_client/mrpdhelper.c | 306 | ||||
-rwxr-xr-x | examples/mrp_client/mrpdhelper.h | 134 |
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 |