|
1 /* |
|
2 * check.c |
|
3 * |
|
4 * Copyrigth (C) 2010 Nicolas Cornu <nicolas.cornu@ensi-bourges.fr> |
|
5 * |
|
6 * This program is free software; you can redistribute it and/or modify |
|
7 * it under the terms of the GNU General Public License as published by |
|
8 * the Free Software Foundation; either version 2 of the License, or (at |
|
9 * your option) any later version. |
|
10 * |
|
11 * This program is distributed in the hope that it will be useful, but |
|
12 * WITHOUT ANY WARRANTY; without even the implied warranty of |
|
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
14 * General Public License for more details. |
|
15 * |
|
16 * You should have received a copy of the GNU General Public License |
|
17 * along with this program; if not, write to the Free Software |
|
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 |
|
19 * USA |
|
20 */ |
|
21 |
|
22 #include <glib.h> |
|
23 #include <loudmouth/loudmouth.h> |
|
24 |
|
25 #include "check.h" |
|
26 #include "jingle.h" |
|
27 |
|
28 |
|
29 JingleContentNode *check_content(LmMessageNode *node, GError **err); |
|
30 gint index_in_array(const gchar *str, const gchar **array); |
|
31 |
|
32 |
|
33 |
|
34 const gchar *jingle_content_creator[] = { |
|
35 "initiator", |
|
36 "responder", |
|
37 NULL |
|
38 }; |
|
39 |
|
40 const gchar *jingle_content_senders[] = { |
|
41 "both", |
|
42 "initiator", |
|
43 "none", |
|
44 "responder", |
|
45 NULL |
|
46 }; |
|
47 |
|
48 |
|
49 /** |
|
50 * Populate a jingle_data struct from a <jingle> element. |
|
51 * Check if the element is in compliance with the XEP. |
|
52 */ |
|
53 gboolean check_jingle(LmMessageNode *node, JingleNode *jn, GError **err) |
|
54 { |
|
55 //gint nb_reason = 0; |
|
56 LmMessageNode *child = NULL; |
|
57 const gchar *actionstr; |
|
58 JingleContentNode *cn; |
|
59 |
|
60 actionstr = lm_message_node_get_attribute(node, "action"); |
|
61 jn->initiator = lm_message_node_get_attribute(node, "initiator"); |
|
62 jn->responder = lm_message_node_get_attribute(node, "responder"); |
|
63 jn->sid = lm_message_node_get_attribute(node, "sid"); |
|
64 |
|
65 if (actionstr == NULL || jn->sid == NULL) { |
|
66 g_set_error(err, JINGLE_CHECK_ERROR, JINGLE_CHECK_ERROR_MISSING, |
|
67 "an attribute of the jingle element is missing"); |
|
68 return FALSE; |
|
69 } |
|
70 |
|
71 jn->action = jingle_action_from_str(actionstr); |
|
72 if (jn->action == JINGLE_UNKNOWN_ACTION) { |
|
73 g_set_error(err, JINGLE_CHECK_ERROR, JINGLE_CHECK_ERROR_BADVALUE, |
|
74 "the action attribute is invalid"); |
|
75 return FALSE; |
|
76 } |
|
77 |
|
78 /*for (child = node->children; child; child = child->next) { |
|
79 if (!g_strcmp0(child->name, "reason")) |
|
80 nb_reason++; |
|
81 } |
|
82 |
|
83 if (nb_reason > 1) { |
|
84 g_set_error(err, JINGLE_CHECK_ERROR, JINGLE_CHECK_ERROR_BADELEM, |
|
85 "too many reason elements"); |
|
86 return FALSE; |
|
87 }*/ |
|
88 |
|
89 for (child = node->children; child; child = child->next) { |
|
90 if (!g_strcmp0(child->name, "content")) { |
|
91 cn = check_content(node, err); |
|
92 if(cn == NULL) { |
|
93 g_assert (*err != NULL); |
|
94 return FALSE; |
|
95 } |
|
96 jn->content = g_list_append(jn->content, cn); |
|
97 } |
|
98 } |
|
99 |
|
100 return TRUE; |
|
101 } |
|
102 |
|
103 JingleContentNode *check_content(LmMessageNode *node, GError **err) |
|
104 { |
|
105 JingleContentNode *cn = g_new0(JingleContentNode, 1); |
|
106 const gchar *creatorstr, *sendersstr; |
|
107 gint tmp, tmp2; |
|
108 |
|
109 creatorstr = lm_message_node_get_attribute(node, "action"); |
|
110 cn->disposition = lm_message_node_get_attribute(node, "disposition"); |
|
111 cn->name = lm_message_node_get_attribute(node, "name"); |
|
112 sendersstr = lm_message_node_get_attribute(node, "senders"); |
|
113 |
|
114 if (creatorstr == NULL || cn->name == NULL) { |
|
115 g_set_error(err, JINGLE_CHECK_ERROR, JINGLE_CHECK_ERROR_MISSING, |
|
116 "an attribute of the content element is missing"); |
|
117 g_free(cn); |
|
118 return NULL; |
|
119 } |
|
120 |
|
121 tmp = index_in_array(creatorstr, jingle_content_creator); |
|
122 tmp2 = index_in_array(sendersstr, jingle_content_senders); |
|
123 if (tmp < 0 || tmp2 < 0) { |
|
124 g_set_error(err, JINGLE_CHECK_ERROR, JINGLE_CHECK_ERROR_BADVALUE, |
|
125 "the attribute creator or sender is invalid"); |
|
126 g_free(cn); |
|
127 return NULL; |
|
128 } |
|
129 cn->creator = (JingleCreator)tmp; |
|
130 cn->senders = (JingleSenders)tmp2; |
|
131 |
|
132 |
|
133 cn->description = lm_message_node_get_child(node, "description"); |
|
134 cn->transport = lm_message_node_get_child(node, "transport"); |
|
135 if (cn->description == NULL || cn->transport == NULL) { |
|
136 g_set_error(err, JINGLE_CHECK_ERROR, JINGLE_CHECK_ERROR_MISSING, |
|
137 "a child element of content is missing"); |
|
138 g_free(cn); |
|
139 return NULL; |
|
140 } |
|
141 |
|
142 return cn; |
|
143 } |
|
144 |
|
145 gint index_in_array(const gchar *str, const gchar **array) |
|
146 { |
|
147 gint i; |
|
148 for (i = 0; array[i]; i++) { |
|
149 if (!g_strcmp0(array[i], str)) { |
|
150 return i; |
|
151 } |
|
152 } |
|
153 return -1; |
|
154 } |
|
155 |
|
156 GQuark jingle_check_error_quark() |
|
157 { |
|
158 return g_quark_from_string("JINGLE_CHECK_ERROR"); |
|
159 } |