1 #include <loudmouth/loudmouth.h> |
1 #include <loudmouth/loudmouth.h> |
2 #include <string.h> |
2 #include <string.h> |
3 |
3 |
4 #include "parse.h" |
4 #include "parse.h" |
|
5 #include "jingle.h" |
5 |
6 |
6 int parse_jingle(LmMessageNode *node, struct info_jingle *ij) |
7 const gchar *jingle_actions[] = { |
|
8 "content-accept", |
|
9 "content-add", |
|
10 "content-modify", |
|
11 "content-reject", |
|
12 "content-remove", |
|
13 "description-info", |
|
14 "security-info", |
|
15 "session-accept", |
|
16 "session-info", |
|
17 "session-initiate", |
|
18 "session-terminate", |
|
19 "transport-accept", |
|
20 "transport-info", |
|
21 "transport-reject", |
|
22 "transport-replace", |
|
23 NULL |
|
24 }; |
|
25 |
|
26 const gchar *jingle_content_creator[] = { |
|
27 "initiator", |
|
28 "responder", |
|
29 NULL |
|
30 }; |
|
31 |
|
32 const gchar *jingle_content_senders[] = { |
|
33 "both", |
|
34 "initiator", |
|
35 "none", |
|
36 "responder", |
|
37 NULL |
|
38 }; |
|
39 |
|
40 /** |
|
41 * Populate a jingle_data struct from a <jingle> element. |
|
42 * Check if the element is in compliance with the XEP. |
|
43 */ |
|
44 int check_jingle(LmMessageNode *node, struct jingle_data *ij) |
7 { |
45 { |
8 int nb_reason = 0; |
46 int nb_reason = 0; |
9 LmMessageNode *child = NULL; |
47 LmMessageNode *child = NULL; |
10 |
|
11 if (!strcmp(ij->name, "jingle")) |
|
12 return PARSE_ERROR_NAME; |
|
13 |
48 |
14 ij->action = g_strdup(lm_message_node_get_attribute(node, "action")); |
49 ij->action = lm_message_node_get_attribute(node, "action"); |
15 ij->initiator = g_strdup(lm_message_node_get_attribute(node, "initiator")); |
50 ij->initiator = lm_message_node_get_attribute(node, "initiator"); |
16 ij->responder = g_strdup(lm_message_node_get_attribute(node, "responder")); |
51 ij->responder = lm_message_node_get_attribute(node, "responder"); |
17 ij->sid = g_strdup(lm_message_node_get_attribute(node, "sid")); |
52 ij->sid = lm_message_node_get_attribute(node, "sid"); |
18 |
53 |
19 // check required |
|
20 if (ij->action == NULL || ij->sid == NULL) |
54 if (ij->action == NULL || ij->sid == NULL) |
21 return PARSE_ERROR_REQUIRED; |
55 return PARSE_ERROR_REQUIRED; // those elements are required |
22 |
56 |
23 // check restrictions |
57 if (!str_in_array(ij->action, jingle_actions)) |
24 if (!check_restriction(ij->action, {"content-accept", "content-add", |
|
25 "content-modify", "content-reject", "content-remove", "description-info", |
|
26 "security-info", "session-accept", "session-info", "session-initiate", |
|
27 "session-terminate", "transport-accept", "transport-info", "transport-reject", |
|
28 "transport-replace", NULL})) |
|
29 return PARSE_ERROR_RESTRICTION; |
58 return PARSE_ERROR_RESTRICTION; |
30 |
59 |
31 // check childs |
60 // check childs |
32 for (child = node->children; child; child = child->next) { |
61 for (child = node->children; child; child = child->next) { |
33 if (!strcmp(child->name, "reason")) |
62 if (!strcmp(child->name, "reason")) |
34 nb_reason++; |
63 nb_reason++; |
35 } |
64 } |
36 |
65 |
37 if (reason > 1) |
66 if (nb_reason > 1) |
38 return PARSE_ERROR_TOO_MANY_CHILDS; |
67 return PARSE_ERROR_TOO_MANY_CHILDS; |
39 |
68 |
40 return PARSE_OK; |
69 return PARSE_OK; |
41 } |
70 } |
42 |
71 |
43 |
72 int parse_content(LmMessageNode* node, struct content_data* ic) |
44 void free_jingle(struct info_jingle *ij) |
|
45 { |
|
46 g_free(ij->action); |
|
47 g_free(ij->initiator); |
|
48 g_free(ij->responder); |
|
49 g_free(ij->sid); |
|
50 } |
|
51 |
|
52 |
|
53 int parse_content(LmMessageNode* node, struct info_content* ic) |
|
54 { |
73 { |
55 if (!strcmp(ic->name, "content")) |
74 if (!strcmp(ic->name, "content")) |
56 return PARSE_ERROR_NAME; |
75 return PARSE_ERROR_NAME; |
57 |
76 |
58 ic->creator = g_strdup(lm_message_node_get_attribute(node, "creator")); |
77 ic->creator = lm_message_node_get_attribute(node, "creator"); |
59 ic->disposition = g_strdup(lm_message_node_get_attribute(node, "disposition")); |
78 ic->disposition = lm_message_node_get_attribute(node, "disposition"); |
60 ic->name = g_strdup(lm_message_node_get_attribute(node, "name")); |
79 ic->name = lm_message_node_get_attribute(node, "name"); |
61 ic->senders = g_strdup(lm_message_node_get_attribute(node, "senders")); |
80 ic->senders = lm_message_node_get_attribute(node, "senders"); |
62 |
81 |
63 // Put default if none |
|
64 if (ic->disposition == NULL) |
82 if (ic->disposition == NULL) |
65 ic->disposition = g_strdup("session"); |
83 ic->disposition = "session"; |
66 |
84 |
67 // check required |
|
68 if (ic->creator == NULL || ic->name == NULL) |
85 if (ic->creator == NULL || ic->name == NULL) |
69 return PARSE_ERROR_REQUIRED; |
86 return PARSE_ERROR_REQUIRED; |
70 |
87 |
71 // check restrictions |
88 if (!str_in_array(ic->creator, jingle_content_creator)) |
72 if (!check_restriction(ic->creator, {"initiator", "responder", NULL})) |
|
73 return PARSE_ERROR_RESTRICTION; |
89 return PARSE_ERROR_RESTRICTION; |
74 if (!check_restriction(ic->senders, {"both", "initiator", "none", "responder", NULL})) |
90 if (!str_in_array(ic->senders, jingle_content_senders)) |
75 ic->senders = NULL; // because it's optional |
91 ic->senders = NULL; |
76 |
92 |
77 return PARSE_OK; |
93 return PARSE_OK; |
78 } |
94 } |
79 |
95 |
|
96 /** |
|
97 * Check if needle exists in haystack. |
|
98 * The last element of haystack must be NULL. |
|
99 */ |
|
100 gint str_in_array(const gchar* needle, const gchar** haystack) |
|
101 { |
|
102 const gchar* value; |
|
103 gint found = 0; |
|
104 for (value = haystack[0]; value && !found; value++) |
|
105 if (!g_strcmp0(needle, value)) |
|
106 found = 1; |
80 |
107 |
81 void free_content(struct info_content *ic) |
|
82 { |
|
83 g_free(ic->creator); |
|
84 g_free(ic->disposition); |
|
85 g_free(ic->name); |
|
86 g_free(ic->senders); |
|
87 } |
|
88 |
|
89 |
|
90 int check_restriction(const gchar* name, const gchar** values) |
|
91 { |
|
92 const char* value; |
|
93 int found = 0; |
|
94 value = values[0]; |
|
95 while (value && !found) { |
|
96 if (!strcmp(name, value)) |
|
97 found = 1; |
|
98 value++; |
|
99 } |
|
100 return found; |
108 return found; |
101 } |
109 } |