Use GError to pass errors, rename parse.c in check.c
authorNicolas Cornu <nicolas.cornu@ensi-bourges.fr>
Tue, 01 Jun 2010 11:51:25 +0200
changeset 12 eb167636e5bc
parent 11 5ec956706f0c
child 13 4e6245ccd73c
Use GError to pass errors, rename parse.c in check.c
CMakeLists.txt
check.c
check.h
error.c
error.h
jingle.c
jingle.h
jingle_register.c
jingle_register.h
parse.c
parse.h
register.c
register.h
sessions.c
--- a/CMakeLists.txt	Tue Jun 01 09:24:02 2010 +0200
+++ b/CMakeLists.txt	Tue Jun 01 11:51:25 2010 +0200
@@ -35,7 +35,7 @@
 				 ${MCABBER_LIBRARY_DIRS})
 
 ## Target definitions
-add_library(jingle MODULE jingle.c parse.c jingle_register.c error.c)
+add_library(jingle MODULE jingle.c check.c register.c)
 
 ## Compiler setup
 configure_file(config.h.in config.h)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/check.c	Tue Jun 01 11:51:25 2010 +0200
@@ -0,0 +1,90 @@
+/*
+ * check.c
+ *
+ * Copyrigth (C) 2010 Nicolas Cornu <nicolas.cornu@ensi-bourges.fr>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA
+ */
+
+#include <glib.h>
+#include <loudmouth/loudmouth.h>
+
+#include "check.h"
+#include "jingle.h"
+
+
+const gchar *jingle_content_creator[] = {
+  "initiator",
+  "responder",
+  NULL
+};
+
+const gchar *jingle_content_senders[] = {
+  "both",
+  "initiator",
+  "none",
+  "responder",
+  NULL
+};
+
+
+/**
+ * Populate a jingle_data struct from a <jingle> element.
+ * Check if the element is in compliance with the XEP.
+ */
+gboolean check_jingle(LmMessageNode *node, JingleData *jd, GError **err)
+{
+  gint nb_reason = 0;
+  LmMessageNode *child = NULL;
+  const gchar *actionstr;
+
+  actionstr     = lm_message_node_get_attribute(node, "action");
+  jd->initiator = lm_message_node_get_attribute(node, "initiator");
+  jd->responder = lm_message_node_get_attribute(node, "responder");
+  jd->sid       = lm_message_node_get_attribute(node, "sid");
+
+  if (actionstr == NULL || jd->sid == NULL) {
+    g_set_error(err, JINGLE_CHECK_ERROR, JINGLE_CHECK_ERROR_MISSING,
+                "an attribute of the jingle element is missing");
+    return FALSE;
+  }
+
+  jd->action = jingle_action_from_str(actionstr);
+  if (jd->action == JINGLE_UNKNOWN_ACTION) {
+    g_set_error(err, JINGLE_CHECK_ERROR, JINGLE_CHECK_ERROR_BADVALUE,
+                "the action attribute is invalid");
+    return FALSE;
+  }
+
+  // check childs
+  for (child = node->children; child; child = child->next) {
+    if (!g_strcmp0(child->name, "reason"))
+      nb_reason++;
+  }
+
+  if (nb_reason > 1) {
+    g_set_error(err, JINGLE_CHECK_ERROR, JINGLE_CHECK_ERROR_BADELEM,
+                "too many reason elements");
+    return FALSE;
+  }
+
+  return TRUE;
+}
+
+GQuark jingle_check_error_quark()
+{
+  return g_quark_from_string("JINGLE_CHECK_ERROR");
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/check.h	Tue Jun 01 11:51:25 2010 +0200
@@ -0,0 +1,36 @@
+#ifndef __PARSE_H__
+#define __PARSE_H__ 1
+
+#include <glib.h>
+#include <loudmouth/loudmouth.h>
+
+#include "jingle.h"
+
+#define JINGLE_CHECK_ERROR jingle_check_error_quark()
+
+
+typedef enum {
+  JINGLE_CHECK_ERROR_MISSING,  // an element or attribute is missing
+  JINGLE_CHECK_ERROR_BADELEM,  // an element is not where it is supposed to be
+  JINGLE_CHECK_ERROR_BADVALUE  // the value of an attribute is incorrect
+} JingleCheckError;
+
+typedef struct {
+  JingleAction action;
+  const gchar* initiator; // optional
+  const gchar* responder; // optional
+  const gchar* sid;       // required
+} JingleData;
+
+typedef struct {
+  const gchar* creator;     // required (initiator, responder)
+  const gchar* disposition; // optional, default=session
+  const gchar* name;        // required
+  const gchar* senders;     // optional (both, initiator, none, responder)
+} ContentData;
+
+
+int check_jingle(LmMessageNode* node, JingleData *jd, GError **err);
+GQuark jingle_check_error_quark();
+
+#endif
--- a/error.c	Tue Jun 01 09:24:02 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-/**
- * Reply to a Jingle IQ with an error.
- */
-void jingle_error_iq(LmMessage *m, const gchar *errtype,
-    const gchar *cond, const gchar *jinglecond)
-{
-  LmMessage *r;
-  LmMessageNode *err, *tmpnode;
-
-  r = lm_message_new_iq_from_query(m, LM_MESSAGE_SUB_TYPE_ERROR);
-  err = lm_message_node_add_child(r->node, "error", NULL);
-  lm_message_node_set_attribute(err, "type", errtype);
-
-  // error condition as defined by RFC 3920bis section 8.3.3
-  tmpnode = lm_message_node_add_child(err, cond, NULL);
-  lm_message_node_set_attribute(tmpnode, "xmlns", NS_XMPP_STANZAS);
-
-  // jingle error condition as defined by XEP-0166 section 10
-  tmpnode = lm_message_node_add_child(err, jinglecond, NULL);
-  lm_message_node_set_attribute(tmpnode, "xmlns", NS_JINGLE_ERRORS);
-
-  lm_connection_send(lconnection, r, NULL);
-  lm_message_unref(r);
-}
-
-/**
- * Send a bad-request error (really usefull)
- */
-void jingle_error_bad_request(LmMessage *m)
-{
-  LmMessage *r;
-  LmMessageNode *err, *tmpnode;
-
-  r = lm_message_new_iq_from_query(m, LM_MESSAGE_SUB_TYPE_ERROR);
-  err = lm_message_node_add_child(r->node, "error", NULL);
-  lm_message_node_set_attribute(err, "type", "cancel");
-
-  // error condition as defined by RFC 3920bis section 8.3.3
-  tmpnode = lm_message_node_add_child(err, "bad-request", NULL);
-  lm_message_node_set_attribute(tmpnode, "xmlns", NS_XMPP_STANZAS);
-
-  lm_connection_send(lconnection, r, NULL);
-  lm_message_unref(r);
-}
--- a/error.h	Tue Jun 01 09:24:02 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,9 +0,0 @@
-#ifndef __ERROR_H__
-#define __ERROR_H__
-
-void jingle_error_iq(LmMessage *m, const gchar *errtype,
-    const gchar *cond, const gchar *jinglecond);
-
-void jingle_error_bad_request(LmMessage *m);
-
-#endif
--- a/jingle.c	Tue Jun 01 09:24:02 2010 +0200
+++ b/jingle.c	Tue Jun 01 11:51:25 2010 +0200
@@ -1,7 +1,7 @@
 /*
- *  jingle.c -- Base jingle functions
+ * jingle.c
  *
- * Copyrigth (C) 2010    Nicolas Cornu <nicolas.cornu@ensi-bourges.fr>
+ * Copyrigth (C) 2010 Nicolas Cornu <nicolas.cornu@ensi-bourges.fr>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -21,7 +21,6 @@
 
 #include <glib.h>
 #include <loudmouth/loudmouth.h>
-#include <string.h>
 
 #include <mcabber/xmpp.h>
 #include <mcabber/hooks.h>
@@ -31,9 +30,9 @@
 #include <mcabber/xmpp_defines.h> 
 
 #include "jingle.h"
-#include "jingle_register.h"
-#include "parse.h"
-#include "error.h"
+#include "check.h"
+#include "register.h"
+
 
 static void  jingle_register_lm_handlers(void);
 static void  jingle_unregister_lm_handlers(void);
@@ -47,6 +46,28 @@
 static guint connect_hid = 0;
 static guint disconn_hid = 0;
 
+/**
+ * Must be aligned with the values in JingleAction
+ * for easy acces.
+ */
+struct JingleActionList jingle_action_list[] = {
+  { NULL,                NULL }, // for JINGLE_UNKNOWN_ACTION
+  { "content-accept",    NULL },
+  { "content-add",       NULL },
+  { "content-modify",    NULL },
+  { "content-reject",    NULL },
+  { "content-remove",    NULL },
+  { "description-info",  NULL },
+  { "security-info",     NULL },
+  { "session-accept",    NULL },
+  { "session-info",      NULL },
+  { "session-initiate",  NULL },
+  { "session-terminate", NULL },
+  { "transport-accept",  NULL },
+  { "transport-info",    NULL },
+  { "transport-reject",  NULL },
+  { "transport-replace", NULL },
+};
 
 module_info_t info_jingle = {
   .branch          = MCABBER_BRANCH,
@@ -70,7 +91,8 @@
   if (iqtype != LM_MESSAGE_SUB_TYPE_SET)
     return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
 
-  struct jingle_data ij;
+  JingleData jd;
+  GError *error;
   LmMessageNode *root = lm_message_get_node(message)->children;
   LmMessageNode *node = lm_message_node_get_child(root, "jingle");
 
@@ -82,14 +104,21 @@
     return LM_HANDLER_RESULT_REMOVE_MESSAGE;
   }
 
-  if (parse_jingle(node, &ij) != PARSE_OK) {
-    jingle_error_bad_request(message); 
+  check_jingle(node, &jd, &error);
+  if (error != NULL) {
+    if (error->code == JINGLE_CHECK_ERROR) {
+      // request malformed, we reply with a bad-request
+      jingle_error_iq(message, "cancel", "bad-request", NULL);
+    }
     return LM_HANDLER_RESULT_REMOVE_MESSAGE;
   }
-
-  scr_log_print(LPRINT_DEBUG, "jingle: Received a jingle IQ");
-
-  jingle_error_iq(message, "cancel", "feature-not-implemented", "unsupported-info");
+  
+  scr_log_print(LPRINT_DEBUG, "jingle: Received a valid jingle IQ");
+  
+  if (jingle_action_list[jd.action].handler != NULL)
+    jingle_action_list[jd.action].handler(NULL);
+  else
+    jingle_error_iq(message, "cancel", "feature-not-implemented", "unsupported-info");
 
   return LM_HANDLER_RESULT_REMOVE_MESSAGE;
 }
@@ -110,6 +139,48 @@
   lm_message_unref(r);
 }
 
+/**
+ * Reply to a Jingle IQ with an error.
+ */
+void jingle_error_iq(LmMessage *m, const gchar *errtype,
+                     const gchar *cond, const gchar *jinglecond)
+{
+  LmMessage *r;
+  LmMessageNode *err, *tmpnode;
+
+  r = lm_message_new_iq_from_query(m, LM_MESSAGE_SUB_TYPE_ERROR);
+  err = lm_message_node_add_child(r->node, "error", NULL);
+  lm_message_node_set_attribute(err, "type", errtype);
+  
+  // error condition as defined by RFC 3920bis section 8.3.3
+  if (cond != NULL) {
+    tmpnode = lm_message_node_add_child(err, cond, NULL);
+    lm_message_node_set_attribute(tmpnode, "xmlns", NS_XMPP_STANZAS);
+  }
+  
+  // jingle error condition as defined by XEP-0166 section 10
+  if (jinglecond != NULL) {
+    tmpnode = lm_message_node_add_child(err, jinglecond, NULL);
+    lm_message_node_set_attribute(tmpnode, "xmlns", NS_JINGLE_ERRORS);
+  }
+  
+  lm_connection_send(lconnection, r, NULL);
+  lm_message_unref(r);
+}
+
+/**
+ * Find the jingle_action corresponding to a string
+ */
+JingleAction jingle_action_from_str(const gchar* string)
+{
+  guint i, actstrlen = sizeof(jingle_action_list)/sizeof(struct JingleActionList);
+  for (i = 0; i < actstrlen; i++)
+    if (!g_strcmp0(jingle_action_list[i].name, string))
+      return (JingleAction) i;
+
+  return JINGLE_UNKNOWN_ACTION;
+}
+
 static void jingle_unregister_lm_handlers(void)
 {
   if (lconnection) {
--- a/jingle.h	Tue Jun 01 09:24:02 2010 +0200
+++ b/jingle.h	Tue Jun 01 11:51:25 2010 +0200
@@ -1,13 +1,15 @@
 #ifndef __JINGLE_H__
 #define __JINGLE_H__ 1
 
+#include <glib.h>
+#include <loudmouth/loudmouth.h>
+
 #define NS_JINGLE "urn:xmpp:jingle:1"
 #define NS_JINGLE_ERRORS "urn:xmpp:jingle:errors:1"
 
-void jingle_ack_iq(LmMessage *m);
 
 typedef enum {
-  JINGLE_UNKNOWN,
+  JINGLE_UNKNOWN_ACTION,
   JINGLE_CONTENT_ACCEPT,
   JINGLE_CONTENT_ADD,
   JINGLE_CONTENT_MODIFY,
@@ -25,4 +27,14 @@
   JINGLE_TRANSPORT_REPLACE,
 } JingleAction;
 
+struct JingleActionList {
+  const gchar  *name;
+  void (*handler)(void *arg1);
+};
+
+void jingle_error_iq(LmMessage *m, const gchar *errtype,
+                     const gchar *cond, const gchar *jinglecond);
+void jingle_ack_iq(LmMessage *m);
+JingleAction jingle_action_from_str(const gchar* string);
+
 #endif
--- a/jingle_register.c	Tue Jun 01 09:24:02 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,48 +0,0 @@
-#include <string.h>
-#include <jingle.h>
-
-GHashTable *hk_jingle_apps_handler_hash = NULL;
-GHashTable *hk_jingle_transports_handler_hash = NULL;
-
-gchar* jingle_register_apps(const gchar* namespace)
-{
-  gchar* hookname = NULL;
-
-  // On l'enregistre dans la table
-  // Si la table n'est pas encore créé c'est le moment
-  if (!hk_jingle_apps_handler_hash) {
-    hk_jingle_apps_handler_hash = g_hash_table_new_full(&g_str_hash, &g_str_equal, &g_free, &g_free);
-    if (!hk_jingle_apps_hander_hash) {
-      scr_log_print(LPRINT_LOGNORM, "Couldn't create hook hash table for jingle apps!");
-      return NULL;
-    }
-  }
-
-  hookname = g_strdup_printf("%s%s", "hook_jingle_apps_", namespace);
-
-  // On insert la donnée
-  g_hash_table_insert(hk_jingle_apps_handler_hash, g_strdup(namespace), hook_name);
-
-  return hookname;
-}
-
-gchar* jingle_register_transports(const gchar* namespace) {
-  gchar* hookname = NULL;
-
-  // On l'enregistre dans la table
-  // Si la table n'est pas encore créé c'est le moment
-  if (!hk_jingle_transports_handler_hash) {
-    hk_jingle_transports_handler_hash = g_hash_table_new_full(&g_str_hash, &g_str_equal, &g_free, &g_free);
-    if (!hk_jingle_transports_handler_hash) {
-      scr_log_print(LPRINT_LOGNORM, "Couldn't create hook hash table for jingle transports!");
-      return NULL;
-    }
-  }
-
-  hookname = g_strdup_printf("%s%s", "hook_jingle_transports_", namespace);
-
-  // On insert la donnée
-  g_hash_table_insert(hk_jingle_transporst_handler_hash, g_strdup(namespace), hook_name);
-
-  return hookname;
-}
--- a/jingle_register.h	Tue Jun 01 09:24:02 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,11 +0,0 @@
-#ifndef __JINGLE_REGISTER_H__
-#define __JINGLE_REGISTER_H__
-
-gchar* jingle_resigter_apps(const gchar* namespace);
-
-gchar* jingle_register_transports(const gchar* namespace);   
-
-
-
-
-#endif
--- a/parse.c	Tue Jun 01 09:24:02 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,117 +0,0 @@
-#include <loudmouth/loudmouth.h>
-#include <string.h>
-
-#include "parse.h"
-#include "jingle.h"
-
-
-static JingleAction action_from_str(const gchar* string);
-
-
-struct JingleActionStr {
-	JingleAction  act;
-	const gchar  *name;
-} jingle_actions_str[] = {
-  { JINGLE_CONTENT_ACCEPT,    "content-accept" },
-  { JINGLE_CONTENT_ADD,       "content-add" },
-  { JINGLE_CONTENT_MODIFY,    "content-modify" },
-  { JINGLE_CONTENT_REJECT,    "content-reject" },
-  { JINGLE_CONTENT_REMOVE,    "content-remove" },
-  { JINGLE_DESCRIPTION_INFO,  "description-info" },
-  { JINGLE_SECURITY_INFO,     "security-info" },
-  { JINGLE_SESSION_ACCEPT,    "session-accept" },
-  { JINGLE_SESSION_INFO,      "session-info" },
-  { JINGLE_SESSION_INITIATE,  "session-initiate" },
-  { JINGLE_SESSION_TERMINATE, "session-terminate" },
-  { JINGLE_TRANSPORT_ACCEPT,  "transport-accept" },
-  { JINGLE_TRANSPORT_INFO,    "transport-info" },
-  { JINGLE_TRANSPORT_REJECT,  "transport-reject" },
-  { JINGLE_TRANSPORT_REPLACE, "transport-replace" },
-};
-
-const gchar *jingle_content_creator[] = {
-  "initiator",
-  "responder",
-  NULL
-};
-
-const gchar *jingle_content_senders[] = {
-  "both",
-  "initiator",
-  "none",
-  "responder",
-  NULL
-};
-
-
-/**
- * Populate a jingle_data struct from a <jingle> element.
- * Check if the element is in compliance with the XEP.
- */
-gint check_jingle(LmMessageNode *node, struct jingle_data *ij)
-{
-  int nb_reason = 0;
-  LmMessageNode *child = NULL;
-  gchar *actionstr;
-
-  actionstr     = lm_message_node_get_attribute(node, "action");
-  ij->initiator = lm_message_node_get_attribute(node, "initiator");
-  ij->responder = lm_message_node_get_attribute(node, "responder");
-  ij->sid       = lm_message_node_get_attribute(node, "sid");
-
-  if (action == NULL || ij->sid == NULL)
-    return PARSE_ERROR_REQUIRED; // those elements are required
-
-  ij->action = action_from_str(actionstr);
-  if (ij->action == JINGLE_UNKNOWN)
-    return PARSE_ERROR_RESTRICTION;
-
-  // check childs
-  for (child = node->children; child; child = child->next) {
-    if (!strcmp(child->name, "reason"))
-      nb_reason++;
-  }
-
-  if (nb_reason > 1)
-    return PARSE_ERROR_TOO_MANY_CHILDS;
-
-  return PARSE_OK;
-}
-
-gint check_content(LmMessageNode* node, struct content_data* ic)
-{
-  if (!strcmp(ic->name, "content"))
-    return PARSE_ERROR_NAME;
-
-  ic->creator     = lm_message_node_get_attribute(node, "creator");
-  ic->disposition = lm_message_node_get_attribute(node, "disposition");
-  ic->name        = lm_message_node_get_attribute(node, "name");
-  ic->senders     = lm_message_node_get_attribute(node, "senders");
-
-  if (ic->disposition == NULL)
-    ic->disposition = "session";
-
-  if (ic->creator == NULL || ic->name == NULL)
-    return PARSE_ERROR_REQUIRED;
-
-  if (!str_in_array(ic->creator, jingle_content_creator))
-    return PARSE_ERROR_RESTRICTION;
-  if (!str_in_array(ic->senders, jingle_content_senders))
-    ic->senders = NULL;
-
-  return PARSE_OK;
-}
-
-
-/**
- * Find the jingle_action corresponding to a string
- */
-static JingleAction action_from_str(const gchar* string)
-{
-  guint i, actstrlen = sizeof(jingle_actions_str)/sizeof(struct JingleActionStr);
-  for (i = 0; i < actstrlen; i++)
-    if (!g_strcmp0(jingle_actions_str[i].name, string))
-      return jingle_actions_str[i].act;
-
-  return JINGLE_UNKNOWN;
-}
--- a/parse.h	Tue Jun 01 09:24:02 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +0,0 @@
-#ifndef __PARSE_H__
-#define __PARSE_H__ 1
-
-#include <glib.h>
-#include <loudmouth/loudmouth.h>
-
-#define PARSE_OK                    0
-#define PARSE_ERROR_NAME            1
-#define PARSE_ERROR_REQUIRED        2
-#define PARSE_ERROR_RESTRICTION     3
-#define PARSE_ERROR_TOO_MANY_CHILDS 4
-
-
-struct jingle_data {
-  JingleAction action;
-  const gchar* initiator; // optional
-  const gchar* responder; // optional
-  const gchar* sid;       // required
-};
-
-struct content_data {
-  const gchar* creator;     // required (initiator, responder)
-  const gchar* disposition; // optional, default=session
-  const gchar* name;        // required
-  const gchar* senders;     // optional (both, initiator, none, responder)
-};
-
-
-int parse_jingle(LmMessageNode* node, struct jingle_data* ij);
-int parse_content(LmMessageNode* node, struct content_data* ic);
-
-gint str_in_array(const gchar* needle, const gchar** haystack);
-
-#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/register.c	Tue Jun 01 11:51:25 2010 +0200
@@ -0,0 +1,66 @@
+/*
+ * register.c
+ *
+ * Copyrigth (C) 2010 Nicolas Cornu <nicolas.cornu@ensi-bourges.fr>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA
+ */
+
+#include <glib.h>
+
+#include <mcabber/logprint.h>
+
+#include "jingle.h"
+
+GHashTable *hk_jingle_apps_handler_hash = NULL;
+GHashTable *hk_jingle_transports_handler_hash = NULL;
+
+gchar* jingle_register_apps(const gchar* namespace)
+{
+  gchar* hookname = NULL;
+
+  if (!hk_jingle_apps_handler_hash) {
+    hk_jingle_apps_handler_hash = g_hash_table_new_full(&g_str_hash, &g_str_equal, &g_free, &g_free);
+    if (!hk_jingle_apps_handler_hash) {
+      scr_log_print(LPRINT_LOGNORM, "Couldn't create hook hash table for jingle apps!");
+      return NULL;
+    }
+  }
+
+  hookname = g_strdup_printf("%s%s", "hook_jingle_apps_", namespace);
+
+  g_hash_table_insert(hk_jingle_apps_handler_hash, g_strdup(namespace), hookname);
+
+  return hookname;
+}
+
+gchar* jingle_register_transports(const gchar* namespace) {
+  gchar* hookname = NULL;
+
+  if (!hk_jingle_transports_handler_hash) {
+    hk_jingle_transports_handler_hash = g_hash_table_new_full(&g_str_hash, &g_str_equal, &g_free, &g_free);
+    if (!hk_jingle_transports_handler_hash) {
+      scr_log_print(LPRINT_LOGNORM, "Couldn't create hook hash table for jingle transports!");
+      return NULL;
+    }
+  }
+
+  hookname = g_strdup_printf("%s%s", "hook_jingle_transports_", namespace);
+
+  g_hash_table_insert(hk_jingle_transports_handler_hash, g_strdup(namespace), hookname);
+
+  return hookname;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/register.h	Tue Jun 01 11:51:25 2010 +0200
@@ -0,0 +1,7 @@
+#ifndef __JINGLE_REGISTER_H__
+#define __JINGLE_REGISTER_H__
+
+gchar* jingle_resigter_apps(const gchar* namespace);
+gchar* jingle_register_transports(const gchar* namespace);   
+
+#endif
--- a/sessions.c	Tue Jun 01 09:24:02 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,6 +0,0 @@
-// Session for manipulate sessions
-struct session_info {
-  gchar* initiator;
-
-  gchar* transport_namespace;
-}