jingle/check.c
changeset 14 77966ed56e14
child 16 cb085682970f
equal deleted inserted replaced
13:4e6245ccd73c 14:77966ed56e14
       
     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 }