1 /******************************************************************************
3 Copyright (c) 2012, AudioScience, Inc
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions are met:
9 1. Redistributions of source code must retain the above copyright notice,
10 this list of conditions and the following disclaimer.
12 2. Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in the
14 documentation and/or other materials provided with the distribution.
16 3. Neither the name of the Intel Corporation nor the names of its
17 contributors may be used to endorse or promote products derived from
18 this software without specific prior written permission.
20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 POSSIBILITY OF SUCH DAMAGE.
32 ******************************************************************************/
34 /******************************************************************************
35 This module implements code that takes the notification strings that MRPD sends
36 and parses them into a machine readable structure.
37 ******************************************************************************/
41 #include <stdint.h> // for uint8_t etc
49 #include "mrpdhelper.h"
51 struct app_state_to_enum {
53 enum mrpdhelper_applicant_state value;
54 } mrp_app_state_mapping[12] = {
55 {"VO", mrpdhelper_applicant_state_VO},
56 {"VP", mrpdhelper_applicant_state_VP},
57 {"VN", mrpdhelper_applicant_state_VN},
58 {"AN", mrpdhelper_applicant_state_AN},
59 {"AA", mrpdhelper_applicant_state_AA},
60 {"QA", mrpdhelper_applicant_state_QA},
61 {"LA", mrpdhelper_applicant_state_LA},
62 {"AO", mrpdhelper_applicant_state_AO},
63 {"QO", mrpdhelper_applicant_state_QO},
64 {"AP", mrpdhelper_applicant_state_AP},
65 {"QP", mrpdhelper_applicant_state_QP},
66 {"LO", mrpdhelper_applicant_state_LO}
70 static int parse_app_state(char *sz, struct mrpdhelper_notify *n)
74 /* loop over mrp_app_state_mapping struct */
75 for (i=0; i < 12; i++) {
76 if (strncmp(sz, mrp_app_state_mapping[i].s, 2) == 0) {
77 n->app_state = mrp_app_state_mapping[i].value;
81 if (n->app_state == mrpdhelper_applicant_state_null)
87 static int parse_state(char *sz, struct mrpdhelper_notify *n)
89 if (strncmp(sz, "IN", 2) == 0) {
90 n->state = mrpdhelper_state_in;
91 } else if (strncmp(sz, "LV", 3) == 0) {
92 n->state = mrpdhelper_state_leave;
93 } else if (strncmp(sz, "MT", 3) == 0) {
94 n->state = mrpdhelper_state_empty;
101 static int parse_notification(char *sz, struct mrpdhelper_notify *n)
103 if (strncmp(sz, "NE", 2) == 0) {
104 n->notify = mrpdhelper_notification_new;
105 } else if (strncmp(sz, "JO", 2) == 0) {
106 n->notify = mrpdhelper_notification_join;
107 } else if (strncmp(sz, "LE", 2) == 0) {
108 n->notify = mrpdhelper_notification_leave;
115 static int parse_registrar(char *sz, struct mrpdhelper_notify *n, char **rpos)
119 r = strstr(sz, "R=");
125 if (sscanf(r, "R=%" SCNx64, &n->registrar) == 1)
131 static int parse_mvrp(char *sz, size_t len, struct mrpdhelper_notify *n)
134 VIN VJO 1234 R=112233445566
140 if (parse_notification(&sz[1], n) < 0)
143 if (parse_state(&sz[5], n) < 0)
146 n->attrib = mrpdhelper_attribtype_mvrp;
147 if (sscanf(&sz[8], "%04x ", &n->u.v.vid) != 1)
149 return parse_registrar(sz, n, NULL);
152 static int parse_msrp_string(char *sz, size_t len, struct mrpdhelper_notify *n)
159 result = sscanf(sz, "D:C=%d,P=%d,V=%04x",
160 &n->u.sd.id, &n->u.sd.priority, &n->u.sd.vid);
163 n->attrib = mrpdhelper_attribtype_msrp_domain;
166 result = sscanf(sz, "L:D=%d,S=%" SCNx64,
167 &n->u.sl.substate, &n->u.sl.id);
170 n->attrib = mrpdhelper_attribtype_msrp_listener;
186 &n->u.st.max_frame_size,
187 &n->u.st.max_interval_frames,
188 &n->u.st.priority_and_rank,
189 &n->u.st.accum_latency,
190 &n->u.st.bridge_id, &n->u.st.failure_code);
193 n->attrib = mrpdhelper_attribtype_msrp_talker;
202 static int parse_msrp(char *sz, size_t len, struct mrpdhelper_notify *n)
204 if (parse_notification(&sz[1], n) < 0)
207 if (parse_msrp_string(&sz[4], len - 4, n) < 0)
210 return parse_registrar(sz, n, NULL);
214 static int parse_msrp_query(char *sz, size_t len, struct mrpdhelper_notify *n)
218 if (parse_msrp_string(sz, len, n) < 0)
221 if (parse_registrar(sz, n, &r) < 0)
224 if (parse_app_state(&r[15], n) < 0)
227 return parse_state(&r[18], n);
230 static int parse_mmrp(char *sz, size_t len, struct mrpdhelper_notify *n)
233 MIN MJO M=112233445566 R=112233445566
239 if (parse_notification(&sz[1], n) < 0)
242 if (parse_state(&sz[5], n) < 0)
245 n->attrib = mrpdhelper_attribtype_mvrp;
246 if (sscanf(&sz[8], "M=%" SCNx64, &n->u.m.mac) != 1)
248 return parse_registrar(sz, n, NULL);
251 int mrpdhelper_parse_notification(char *sz, size_t len,
252 struct mrpdhelper_notify *n)
254 memset(n, 0, sizeof(*n));
257 return parse_mvrp(sz, len, n);
259 return parse_msrp(sz, len, n);
261 return parse_mmrp(sz, len, n);
265 return parse_msrp_query(sz, len, n);
271 int mrpdhelper_notify_equal(struct mrpdhelper_notify *n1,
272 struct mrpdhelper_notify *n2)
274 if (n1->attrib != n2->attrib)
277 switch (n1->attrib) {
278 case mrpdhelper_attribtype_mmrp:
279 if (n1->u.m.mac != n2->u.m.mac)
282 case mrpdhelper_attribtype_mvrp:
283 if (n1->u.v.vid != n2->u.v.vid)
286 case mrpdhelper_attribtype_msrp_domain:
287 if ((n1->u.sd.id != n1->u.sd.id) ||
288 (n1->u.sd.priority != n1->u.sd.priority) ||
289 (n1->u.sd.vid != n1->u.sd.vid))
292 case mrpdhelper_attribtype_msrp_talker:
293 case mrpdhelper_attribtype_msrp_talker_fail:
294 if (n1->u.st.id != n2->u.st.id)
297 case mrpdhelper_attribtype_msrp_listener:
298 case mrpdhelper_attribtype_msrp_listener_fail:
299 if (n1->u.sl.id != n2->u.sl.id)