comparison libpurple/protocols/jabber/jingle/jingle.c @ 26363:925af7142249

Restructure Jingle action handlers to only require modification in one place.
author Mike Ruprecht <maiku@soc.pidgin.im>
date Tue, 17 Mar 2009 02:15:09 +0000
parents 0a5737e1e969
children 583d211a956a
comparison
equal deleted inserted replaced
26362:02861ee5b29b 26363:925af7142249
28 #include <string.h> 28 #include <string.h>
29 #include "session.h" 29 #include "session.h"
30 #include "iceudp.h" 30 #include "iceudp.h"
31 #include "rawudp.h" 31 #include "rawudp.h"
32 #include "rtp.h" 32 #include "rtp.h"
33
34 const gchar *
35 jingle_get_action_name(JingleActionType action)
36 {
37 switch (action) {
38 case JINGLE_CONTENT_ACCEPT:
39 return "content-accept";
40 case JINGLE_CONTENT_ADD:
41 return "content-add";
42 case JINGLE_CONTENT_MODIFY:
43 return "content-modify";
44 case JINGLE_CONTENT_REJECT:
45 return "content-reject";
46 case JINGLE_CONTENT_REMOVE:
47 return "content-remove";
48 case JINGLE_DESCRIPTION_INFO:
49 return "description-info";
50 case JINGLE_SESSION_ACCEPT:
51 return "session-accept";
52 case JINGLE_SESSION_INFO:
53 return "session-info";
54 case JINGLE_SESSION_INITIATE:
55 return "session-initiate";
56 case JINGLE_SESSION_TERMINATE:
57 return "session-terminate";
58 case JINGLE_TRANSPORT_ACCEPT:
59 return "transport-accept";
60 case JINGLE_TRANSPORT_INFO:
61 return "transport-info";
62 case JINGLE_TRANSPORT_REJECT:
63 return "transport-reject";
64 case JINGLE_TRANSPORT_REPLACE:
65 return "transport-replace";
66 default:
67 return "unknown-type";
68 }
69 }
70
71 JingleActionType
72 jingle_get_action_type(const gchar *action)
73 {
74 if (!strcmp(action, "content-accept"))
75 return JINGLE_CONTENT_ACCEPT;
76 else if (!strcmp(action, "content-add"))
77 return JINGLE_CONTENT_ADD;
78 else if (!strcmp(action, "content-modify"))
79 return JINGLE_CONTENT_MODIFY;
80 else if (!strcmp(action, "content-reject"))
81 return JINGLE_CONTENT_REJECT;
82 else if (!strcmp(action, "content-remove"))
83 return JINGLE_CONTENT_REMOVE;
84 else if (!strcmp(action, "description-info"))
85 return JINGLE_DESCRIPTION_INFO;
86 else if (!strcmp(action, "session-accept"))
87 return JINGLE_SESSION_ACCEPT;
88 else if (!strcmp(action, "session-info"))
89 return JINGLE_SESSION_INFO;
90 else if (!strcmp(action, "session-initiate"))
91 return JINGLE_SESSION_INITIATE;
92 else if (!strcmp(action, "session-terminate"))
93 return JINGLE_SESSION_TERMINATE;
94 else if (!strcmp(action, "transport-accept"))
95 return JINGLE_TRANSPORT_ACCEPT;
96 else if (!strcmp(action, "transport-info"))
97 return JINGLE_TRANSPORT_INFO;
98 else if (!strcmp(action, "transport-reject"))
99 return JINGLE_TRANSPORT_REJECT;
100 else if (!strcmp(action, "transport-replace"))
101 return JINGLE_TRANSPORT_REPLACE;
102 else
103 return JINGLE_UNKNOWN_TYPE;
104 }
105 33
106 GType 34 GType
107 jingle_get_type(const gchar *type) 35 jingle_get_type(const gchar *type)
108 { 36 {
109 if (!strcmp(type, JINGLE_TRANSPORT_RAWUDP)) 37 if (!strcmp(type, JINGLE_TRANSPORT_RAWUDP))
129 else 57 else
130 return G_TYPE_NONE; 58 return G_TYPE_NONE;
131 } 59 }
132 60
133 static void 61 static void
62 jingle_handle_unknown_type(JingleSession *session, xmlnode *jingle)
63 {
64 /* Send error */
65 }
66
67 static void
134 jingle_handle_content_accept(JingleSession *session, xmlnode *jingle) 68 jingle_handle_content_accept(JingleSession *session, xmlnode *jingle)
135 { 69 {
136 xmlnode *content = xmlnode_get_child(jingle, "content"); 70 xmlnode *content = xmlnode_get_child(jingle, "content");
137 jabber_iq_send(jingle_session_create_ack(session, jingle)); 71 jabber_iq_send(jingle_session_create_ack(session, jingle));
138 72
372 306
373 jingle_content_set_pending_transport(content, transport); 307 jingle_content_set_pending_transport(content, transport);
374 } 308 }
375 } 309 }
376 310
311 typedef struct {
312 const char *name;
313 void (*handler)(JingleSession*, xmlnode*);
314 } JingleAction;
315
316 static const JingleAction jingle_actions[] = {
317 {"unknown-type", jingle_handle_unknown_type},
318 {"content-accept", jingle_handle_content_accept},
319 {"content-add", jingle_handle_content_add},
320 {"content-modify", jingle_handle_content_modify},
321 {"content-reject", jingle_handle_content_reject},
322 {"content-remove", jingle_handle_content_remove},
323 {"description-info", jingle_handle_description_info},
324 {"session-accept", jingle_handle_session_accept},
325 {"session-info", jingle_handle_session_info},
326 {"session-initiate", jingle_handle_session_initiate},
327 {"session-terminate", jingle_handle_session_terminate},
328 {"transport-accept", jingle_handle_transport_accept},
329 {"transport-info", jingle_handle_transport_info},
330 {"transport-reject", jingle_handle_transport_reject},
331 {"transport-replace", jingle_handle_transport_replace},
332 };
333
334 const gchar *
335 jingle_get_action_name(JingleActionType action)
336 {
337 return jingle_actions[action].name;
338 }
339
340 JingleActionType
341 jingle_get_action_type(const gchar *action)
342 {
343 static const int num_actions =
344 sizeof(jingle_actions)/sizeof(JingleAction);
345 /* Start at 1 to skip the unknown-action type */
346 int i = 1;
347 for (; i < num_actions; ++i) {
348 if (!strcmp(action, jingle_actions[i].name))
349 return i;
350 }
351 return JINGLE_UNKNOWN_TYPE;
352 }
377 353
378 void 354 void
379 jingle_parse(JabberStream *js, xmlnode *packet) 355 jingle_parse(JabberStream *js, xmlnode *packet)
380 { 356 {
381 const gchar *type = xmlnode_get_attrib(packet, "type"); 357 const gchar *type = xmlnode_get_attrib(packet, "type");
382 xmlnode *jingle; 358 xmlnode *jingle;
383 const gchar *action; 359 const gchar *action;
384 const gchar *sid; 360 const gchar *sid;
361 JingleActionType action_type;
385 JingleSession *session; 362 JingleSession *session;
386 363
387 if (!type || strcmp(type, "set")) { 364 if (!type || strcmp(type, "set")) {
388 /* send iq error here */ 365 /* send iq error here */
389 return; 366 return;
397 374
398 if (!(action = xmlnode_get_attrib(jingle, "action"))) { 375 if (!(action = xmlnode_get_attrib(jingle, "action"))) {
399 /* send iq error here */ 376 /* send iq error here */
400 return; 377 return;
401 } 378 }
379
380 action_type = jingle_get_action_type(action);
402 381
403 purple_debug_info("jabber", "got Jingle package action = %s\n", 382 purple_debug_info("jabber", "got Jingle package action = %s\n",
404 action); 383 action);
405 384
406 if (!(sid = xmlnode_get_attrib(jingle, "sid"))) { 385 if (!(sid = xmlnode_get_attrib(jingle, "sid"))) {
413 purple_debug_error("jingle", "jabber_jingle_session_parse couldn't find session\n"); 392 purple_debug_error("jingle", "jabber_jingle_session_parse couldn't find session\n");
414 /* send iq error here */ 393 /* send iq error here */
415 return; 394 return;
416 } 395 }
417 396
418 if (!strcmp(action, "session-initiate")) { 397 if (action_type == JINGLE_SESSION_INITIATE) {
419 if (session) { 398 if (session) {
420 /* This should only happen if you start a session with yourself */ 399 /* This should only happen if you start a session with yourself */
421 purple_debug_error("jingle", "Jingle session with " 400 purple_debug_error("jingle", "Jingle session with "
422 "id={%s} already exists\n", sid); 401 "id={%s} already exists\n", sid);
423 /* send iq error */ 402 /* send iq error */
403 return;
424 } else if ((session = jingle_session_find_by_jid(js, 404 } else if ((session = jingle_session_find_by_jid(js,
425 xmlnode_get_attrib(packet, "from")))) { 405 xmlnode_get_attrib(packet, "from")))) {
426 purple_debug_fatal("jingle", "Jingle session with " 406 purple_debug_fatal("jingle", "Jingle session with "
427 "jid={%s} already exists\n", 407 "jid={%s} already exists\n",
428 xmlnode_get_attrib(packet, "from")); 408 xmlnode_get_attrib(packet, "from"));
430 return; 410 return;
431 } else { 411 } else {
432 session = jingle_session_create(js, sid, 412 session = jingle_session_create(js, sid,
433 xmlnode_get_attrib(packet, "to"), 413 xmlnode_get_attrib(packet, "to"),
434 xmlnode_get_attrib(packet, "from"), FALSE); 414 xmlnode_get_attrib(packet, "from"), FALSE);
435 jingle_handle_session_initiate(session, jingle); 415 }
436 } 416 }
437 } else if (!strcmp(action, "content-accept")) { 417
438 jingle_handle_content_accept(session, jingle); 418 jingle_actions[action_type].handler(session, jingle);
439 } else if (!strcmp(action, "content-add")) {
440 jingle_handle_content_add(session, jingle);
441 } else if (!strcmp(action, "content-modify")) {
442 jingle_handle_content_modify(session, jingle);
443 } else if (!strcmp(action, "content-reject")) {
444 jingle_handle_content_reject(session, jingle);
445 } else if (!strcmp(action, "content-remove")) {
446 jingle_handle_content_remove(session, jingle);
447 } else if (!strcmp(action, "description-info")) {
448 jingle_handle_description_info(session, jingle);
449 } else if (!strcmp(action, "session-accept")) {
450 jingle_handle_session_accept(session, jingle);
451 } else if (!strcmp(action, "session-info")) {
452 jingle_handle_session_info(session, jingle);
453 } else if (!strcmp(action, "session-terminate")) {
454 jingle_handle_session_terminate(session, jingle);
455 } else if (!strcmp(action, "transport-accept")) {
456 jingle_handle_transport_accept(session, jingle);
457 } else if (!strcmp(action, "transport-info")) {
458 jingle_handle_transport_info(session, jingle);
459 } else if (!strcmp(action, "transport-reject")) {
460 jingle_handle_transport_reject(session, jingle);
461 } else if (!strcmp(action, "transport-replace")) {
462 jingle_handle_transport_replace(session, jingle);
463 }
464 } 419 }
465 420
466 static void 421 static void
467 jingle_terminate_sessions_gh(gpointer key, gpointer value, gpointer user_data) 422 jingle_terminate_sessions_gh(gpointer key, gpointer value, gpointer user_data)
468 { 423 {