parse.c
changeset 6 a035ec60dc7f
parent 5 2155c65c7455
child 8 2dc0ecb57c0d
equal deleted inserted replaced
5:2155c65c7455 6:a035ec60dc7f
     1 #include <loudmouth/loudmouth.h>
     1 #include <loudmouth/loudmouth.h>
     2 #include <string.h>
     2 #include <string.h>
     3 
     3 
     4 #include "parse.h"
     4 #include "parse.h"
       
     5 #include "jingle.h"
     5 
     6 
     6 int parse_jingle(LmMessageNode *node, struct info_jingle *ij)
     7 const gchar *jingle_actions[] = {
       
     8   "content-accept",
       
     9   "content-add",
       
    10   "content-modify",
       
    11   "content-reject",
       
    12   "content-remove",
       
    13   "description-info",
       
    14   "security-info",
       
    15   "session-accept",
       
    16   "session-info",
       
    17   "session-initiate",
       
    18   "session-terminate",
       
    19   "transport-accept",
       
    20   "transport-info",
       
    21   "transport-reject",
       
    22   "transport-replace",
       
    23   NULL
       
    24 };
       
    25 
       
    26 const gchar *jingle_content_creator[] = {
       
    27   "initiator",
       
    28   "responder",
       
    29   NULL
       
    30 };
       
    31 
       
    32 const gchar *jingle_content_senders[] = {
       
    33   "both",
       
    34   "initiator",
       
    35   "none",
       
    36   "responder",
       
    37   NULL
       
    38 };
       
    39 
       
    40 /**
       
    41  * Populate a jingle_data struct from a <jingle> element.
       
    42  * Check if the element is in compliance with the XEP.
       
    43  */
       
    44 int check_jingle(LmMessageNode *node, struct jingle_data *ij)
     7 {
    45 {
     8   int nb_reason = 0;
    46   int nb_reason = 0;
     9   LmMessageNode *child = NULL;
    47   LmMessageNode *child = NULL;
    10   
       
    11   if (!strcmp(ij->name, "jingle"))
       
    12     return PARSE_ERROR_NAME;
       
    13 
    48 
    14   ij->action    = g_strdup(lm_message_node_get_attribute(node, "action"));
    49   ij->action    = lm_message_node_get_attribute(node, "action");
    15   ij->initiator = g_strdup(lm_message_node_get_attribute(node, "initiator"));
    50   ij->initiator = lm_message_node_get_attribute(node, "initiator");
    16   ij->responder = g_strdup(lm_message_node_get_attribute(node, "responder"));
    51   ij->responder = lm_message_node_get_attribute(node, "responder");
    17   ij->sid       = g_strdup(lm_message_node_get_attribute(node, "sid"));
    52   ij->sid       = lm_message_node_get_attribute(node, "sid");
    18    
    53 
    19   // check required
       
    20   if (ij->action == NULL || ij->sid == NULL)
    54   if (ij->action == NULL || ij->sid == NULL)
    21     return PARSE_ERROR_REQUIRED;
    55     return PARSE_ERROR_REQUIRED; // those elements are required
    22     
    56 
    23   // check restrictions
    57   if (!str_in_array(ij->action, jingle_actions))
    24   if (!check_restriction(ij->action, {"content-accept", "content-add",
       
    25   "content-modify", "content-reject", "content-remove", "description-info",
       
    26   "security-info", "session-accept", "session-info", "session-initiate",
       
    27   "session-terminate", "transport-accept", "transport-info", "transport-reject",
       
    28   "transport-replace", NULL}))
       
    29    return PARSE_ERROR_RESTRICTION;
    58    return PARSE_ERROR_RESTRICTION;
    30   
    59 
    31   // check childs
    60   // check childs
    32   for (child = node->children; child; child = child->next) {
    61   for (child = node->children; child; child = child->next) {
    33     if (!strcmp(child->name, "reason"))
    62     if (!strcmp(child->name, "reason"))
    34       nb_reason++;
    63       nb_reason++;
    35   }
    64   }
    36   
    65 
    37   if (reason > 1)
    66   if (nb_reason > 1)
    38     return PARSE_ERROR_TOO_MANY_CHILDS;
    67     return PARSE_ERROR_TOO_MANY_CHILDS;
    39     
    68 
    40   return PARSE_OK;
    69   return PARSE_OK;
    41 }
    70 }
    42 
    71 
    43 
    72 int parse_content(LmMessageNode* node, struct content_data* ic)
    44 void free_jingle(struct info_jingle *ij)
       
    45 {
       
    46   g_free(ij->action);
       
    47   g_free(ij->initiator);
       
    48   g_free(ij->responder);
       
    49   g_free(ij->sid);
       
    50 }
       
    51 
       
    52 
       
    53 int parse_content(LmMessageNode* node, struct info_content* ic)
       
    54 {
    73 {
    55   if (!strcmp(ic->name, "content"))
    74   if (!strcmp(ic->name, "content"))
    56     return PARSE_ERROR_NAME;
    75     return PARSE_ERROR_NAME;
    57 
    76 
    58   ic->creator     = g_strdup(lm_message_node_get_attribute(node, "creator"));
    77   ic->creator     = lm_message_node_get_attribute(node, "creator");
    59   ic->disposition = g_strdup(lm_message_node_get_attribute(node, "disposition"));
    78   ic->disposition = lm_message_node_get_attribute(node, "disposition");
    60   ic->name        = g_strdup(lm_message_node_get_attribute(node, "name"));
    79   ic->name        = lm_message_node_get_attribute(node, "name");
    61   ic->senders     = g_strdup(lm_message_node_get_attribute(node, "senders"));
    80   ic->senders     = lm_message_node_get_attribute(node, "senders");
    62 
    81 
    63   // Put default if none
       
    64   if (ic->disposition == NULL)
    82   if (ic->disposition == NULL)
    65     ic->disposition = g_strdup("session");
    83     ic->disposition = "session";
    66 
    84 
    67   // check required
       
    68   if (ic->creator == NULL || ic->name == NULL)
    85   if (ic->creator == NULL || ic->name == NULL)
    69     return PARSE_ERROR_REQUIRED;
    86     return PARSE_ERROR_REQUIRED;
    70 
    87 
    71   // check restrictions
    88   if (!str_in_array(ic->creator, jingle_content_creator))
    72   if (!check_restriction(ic->creator, {"initiator", "responder", NULL}))
       
    73     return PARSE_ERROR_RESTRICTION;
    89     return PARSE_ERROR_RESTRICTION;
    74   if (!check_restriction(ic->senders, {"both", "initiator", "none", "responder", NULL}))
    90   if (!str_in_array(ic->senders, jingle_content_senders))
    75     ic->senders = NULL; // because it's optional
    91     ic->senders = NULL;
    76     
    92 
    77   return PARSE_OK;
    93   return PARSE_OK;
    78 }
    94 }
    79 
    95 
       
    96 /**
       
    97  * Check if needle exists in haystack.
       
    98  * The last element of haystack must be NULL.
       
    99  */
       
   100 gint str_in_array(const gchar* needle, const gchar** haystack)
       
   101 {
       
   102   const gchar* value;
       
   103   gint found = 0;
       
   104   for (value = haystack[0]; value && !found; value++)
       
   105     if (!g_strcmp0(needle, value))
       
   106       found = 1;
    80 
   107 
    81 void free_content(struct info_content *ic)
       
    82 {
       
    83   g_free(ic->creator);
       
    84   g_free(ic->disposition);
       
    85   g_free(ic->name);
       
    86   g_free(ic->senders);
       
    87 }
       
    88 
       
    89 
       
    90 int check_restriction(const gchar* name, const gchar** values)
       
    91 {
       
    92   const char* value;
       
    93   int found = 0;
       
    94   value = values[0];
       
    95   while (value && !found) {
       
    96     if (!strcmp(name, value))
       
    97       found = 1;
       
    98     value++;
       
    99   }
       
   100   return found;
   108   return found;
   101 }
   109 }