27 #include <jingle/check.h> |
27 #include <jingle/check.h> |
28 #include <jingle/sessions.h> |
28 #include <jingle/sessions.h> |
29 #include <jingle/register.h> |
29 #include <jingle/register.h> |
30 #include <jingle/send.h> |
30 #include <jingle/send.h> |
31 #include <jingle/action-handlers.h> |
31 #include <jingle/action-handlers.h> |
|
32 |
|
33 void handle_content_add(LmMessage *m, JingleNode *jn) |
|
34 { |
|
35 GError *err = NULL; |
|
36 GSList *child = NULL; |
|
37 JingleContent *cn; |
|
38 JingleAppFuncs *appfuncs; |
|
39 JingleTransportFuncs *transfuncs; |
|
40 gconstpointer description, transport; |
|
41 const gchar *xmlns; |
|
42 JingleSession *sess; |
|
43 |
|
44 if (!check_contents(jn, &err)) { |
|
45 scr_log_print(LPRINT_DEBUG, "jingle: One of the content element was invalid (%s)", |
|
46 err->message); |
|
47 jingle_send_iq_error(m, "cancel", "bad-request", NULL); |
|
48 return; |
|
49 } |
|
50 |
|
51 /* it's better if there is at least one content elem */ |
|
52 if (g_slist_length(jn->content) < 1) { |
|
53 jingle_send_iq_error(m, "cancel", "bad-request", NULL); |
|
54 return; |
|
55 } |
|
56 |
|
57 // if a session with the same sid doesn't already exists |
|
58 if ((sess = session_find(jn)) == NULL) { |
|
59 jingle_send_iq_error(m, "cancel", "unexpected-request", "out-of-order"); |
|
60 return; |
|
61 } |
|
62 |
|
63 jingle_ack_iq(m); |
|
64 |
|
65 for (child = jn->content; child; child = child->next) { |
|
66 cn = (JingleContent *)(child->data); |
|
67 |
|
68 xmlns = lm_message_node_get_attribute(cn->description, "xmlns"); |
|
69 appfuncs = jingle_get_appfuncs(xmlns); |
|
70 if (appfuncs == NULL) continue; |
|
71 |
|
72 xmlns = lm_message_node_get_attribute(cn->transport, "xmlns"); |
|
73 transfuncs = jingle_get_transportfuncs(xmlns); |
|
74 if (appfuncs == NULL) continue; |
|
75 |
|
76 description = appfuncs->check(cn, &err); |
|
77 if (description == NULL || err != NULL) continue; |
|
78 transport = transfuncs->check(cn, &err); |
|
79 if (transport == NULL || err != NULL) continue; |
|
80 session_add_content(sess, cn, ACTIVE); |
|
81 } |
|
82 } |
|
83 |
|
84 void handle_content_reject(LmMessage *m, JingleNode *jn) |
|
85 { |
|
86 GError *err = NULL; |
|
87 GSList *child = NULL; |
|
88 JingleContent *cn; |
|
89 JingleAppFuncs *appfuncs; |
|
90 JingleTransportFuncs *transfuncs; |
|
91 gconstpointer description, transport; |
|
92 const gchar *xmlns; |
|
93 JingleSession *sess; |
|
94 |
|
95 if (!check_contents(jn, &err)) { |
|
96 scr_log_print(LPRINT_DEBUG, "jingle: One of the content element was invalid (%s)", |
|
97 err->message); |
|
98 jingle_send_iq_error(m, "cancel", "bad-request", NULL); |
|
99 return; |
|
100 } |
|
101 |
|
102 /* it's better if there is at least one content elem */ |
|
103 if (g_slist_length(jn->content) < 1) { |
|
104 jingle_send_iq_error(m, "cancel", "bad-request", NULL); |
|
105 return; |
|
106 } |
|
107 |
|
108 // if a session with the same sid doesn't already exists |
|
109 if ((sess = session_find(jn)) == NULL) { |
|
110 jingle_send_iq_error(m, "cancel", "unexpected-request", "out-of-order"); |
|
111 return; |
|
112 } |
|
113 |
|
114 jingle_ack_iq(m); |
|
115 |
|
116 for (child = jn->content; child; child = child->next) { |
|
117 cn = (JingleContent *)(child->data); |
|
118 session_remove_sessioncontent(sess, cn->name); |
|
119 } |
|
120 |
|
121 // If there is nothing more to do, close the session |
|
122 if (g_slist_length(sess->content) == 0) { |
|
123 jingle_send_session_terminate(jn, "success"); |
|
124 session_delete(sess); |
|
125 return; |
|
126 } |
|
127 } |
|
128 |
|
129 void handle_content_remove(LmMessage *m, JingleNode *jn) |
|
130 { |
|
131 GError *err = NULL; |
|
132 GSList *child = NULL; |
|
133 JingleContent *cn; |
|
134 JingleAppFuncs *appfuncs; |
|
135 JingleTransportFuncs *transfuncs; |
|
136 gconstpointer description, transport; |
|
137 const gchar *xmlns; |
|
138 JingleSession *sess; |
|
139 |
|
140 if (!check_contents(jn, &err)) { |
|
141 scr_log_print(LPRINT_DEBUG, "jingle: One of the content element was invalid (%s)", |
|
142 err->message); |
|
143 jingle_send_iq_error(m, "cancel", "bad-request", NULL); |
|
144 return; |
|
145 } |
|
146 |
|
147 /* it's better if there is at least one content elem */ |
|
148 if (g_slist_length(jn->content) < 1) { |
|
149 jingle_send_iq_error(m, "cancel", "bad-request", NULL); |
|
150 return; |
|
151 } |
|
152 |
|
153 // if a session with the same sid doesn't already exists |
|
154 if ((sess = session_find(jn)) == NULL) { |
|
155 jingle_send_iq_error(m, "cancel", "unexpected-request", "out-of-order"); |
|
156 return; |
|
157 } |
|
158 |
|
159 jingle_ack_iq(m); |
|
160 |
|
161 for (child = jn->content; child; child = child->next) { |
|
162 cn = (JingleContent *)(child->data); |
|
163 session_remove_sessioncontent(sess, cn->name); |
|
164 } |
|
165 } |
32 |
166 |
33 /* The session-initiate action is used to request negotiation of a new Jingle |
167 /* The session-initiate action is used to request negotiation of a new Jingle |
34 * session. When sending a session-initiate with one <content/> element, the |
168 * session. When sending a session-initiate with one <content/> element, the |
35 * value of the <content/> element's 'disposition' attribute MUST be "session" |
169 * value of the <content/> element's 'disposition' attribute MUST be "session" |
36 * (if there are multiple <content/> elements then at least one MUST have a |
170 * (if there are multiple <content/> elements then at least one MUST have a |
37 * disposition of "session"); if this rule is violated, the responder MUST |
171 * disposition of "session"); if this rule is violated, the responder MUST |
38 * return a <bad-request/> error to the initiator. |
172 * return a <bad-request/> error to the initiator. |
39 */ |
173 */ |
40 |
|
41 void handle_content_add(LmMessage *m, JingleNode *jn) |
|
42 { |
|
43 GError *err = NULL; |
|
44 GSList *child = NULL; |
|
45 JingleContent *cn; |
|
46 JingleAppFuncs *appfuncs; |
|
47 JingleTransportFuncs *transfuncs; |
|
48 gconstpointer description, transport; |
|
49 const gchar *xmlns; |
|
50 JingleSession *sess; |
|
51 |
|
52 if (!check_contents(jn, &err)) { |
|
53 scr_log_print(LPRINT_DEBUG, "jingle: One of the content element was invalid (%s)", |
|
54 err->message); |
|
55 jingle_send_iq_error(m, "cancel", "bad-request", NULL); |
|
56 return; |
|
57 } |
|
58 |
|
59 /* it's better if there is at least one content elem */ |
|
60 if (g_slist_length(jn->content) < 1) { |
|
61 jingle_send_iq_error(m, "cancel", "bad-request", NULL); |
|
62 return; |
|
63 } |
|
64 |
|
65 // if a session with the same sid doesn't already exists |
|
66 if ((sess = session_find(jn)) == NULL) { |
|
67 jingle_send_iq_error(m, "cancel", "unexpected-request", "out-of-order"); |
|
68 return; |
|
69 } |
|
70 |
|
71 jingle_ack_iq(m); |
|
72 |
|
73 for (child = jn->content; child; child = child->next) { |
|
74 cn = (JingleContent *)(child->data); |
|
75 |
|
76 xmlns = lm_message_node_get_attribute(cn->description, "xmlns"); |
|
77 appfuncs = jingle_get_appfuncs(xmlns); |
|
78 if (appfuncs == NULL) continue; |
|
79 |
|
80 xmlns = lm_message_node_get_attribute(cn->transport, "xmlns"); |
|
81 transfuncs = jingle_get_transportfuncs(xmlns); |
|
82 if (appfuncs == NULL) continue; |
|
83 |
|
84 description = appfuncs->check(cn, &err); |
|
85 if (description == NULL || err != NULL) continue; |
|
86 transport = transfuncs->check(cn, &err); |
|
87 if (transport == NULL || err != NULL) continue; |
|
88 session_add_content(sess, cn); |
|
89 } |
|
90 } |
|
91 |
|
92 void handle_content_remove(LmMessage *m, JingleNode *jn) |
|
93 { |
|
94 GError *err = NULL; |
|
95 GSList *child = NULL; |
|
96 JingleContent *cn; |
|
97 JingleAppFuncs *appfuncs; |
|
98 JingleTransportFuncs *transfuncs; |
|
99 gconstpointer description, transport; |
|
100 const gchar *xmlns; |
|
101 JingleSession *sess; |
|
102 |
|
103 if (!check_contents(jn, &err)) { |
|
104 scr_log_print(LPRINT_DEBUG, "jingle: One of the content element was invalid (%s)", |
|
105 err->message); |
|
106 jingle_send_iq_error(m, "cancel", "bad-request", NULL); |
|
107 return; |
|
108 } |
|
109 |
|
110 /* it's better if there is at least one content elem */ |
|
111 if (g_slist_length(jn->content) < 1) { |
|
112 jingle_send_iq_error(m, "cancel", "bad-request", NULL); |
|
113 return; |
|
114 } |
|
115 |
|
116 // if a session with the same sid doesn't already exists |
|
117 if ((sess = session_find(jn)) == NULL) { |
|
118 jingle_send_iq_error(m, "cancel", "unexpected-request", "out-of-order"); |
|
119 return; |
|
120 } |
|
121 |
|
122 jingle_ack_iq(m); |
|
123 |
|
124 for (child = jn->content; child; child = child->next) { |
|
125 cn = (JingleContent *)(child->data); |
|
126 |
|
127 xmlns = lm_message_node_get_attribute(cn->description, "xmlns"); |
|
128 appfuncs = jingle_get_appfuncs(xmlns); |
|
129 if (appfuncs == NULL) continue; |
|
130 |
|
131 xmlns = lm_message_node_get_attribute(cn->transport, "xmlns"); |
|
132 transfuncs = jingle_get_transportfuncs(xmlns); |
|
133 if (appfuncs == NULL) continue; |
|
134 |
|
135 description = appfuncs->check(cn, &err); |
|
136 if (description == NULL || err != NULL) continue; |
|
137 transport = transfuncs->check(cn, &err); |
|
138 if (transport == NULL || err != NULL) continue; |
|
139 session_add_content(sess, cn); |
|
140 } |
|
141 } |
|
142 |
|
143 void handle_session_initiate(LmMessage *m, JingleNode *jn) |
174 void handle_session_initiate(LmMessage *m, JingleNode *jn) |
144 { |
175 { |
145 GError *err = NULL; |
176 GError *err = NULL; |
146 GSList *child = NULL; |
177 GSList *child = NULL; |
147 gboolean valid_disposition = FALSE; |
178 gboolean valid_disposition = FALSE; |