mi_func.c

Go to the documentation of this file.
00001 /*
00002  * $Id: mi_func.c 5404 2008-12-30 21:25:29Z miconda $
00003  *
00004  * pua_mi module - MI pua module
00005  *
00006  * Copyright (C) 2006 Voice Sistem S.R.L.
00007  *
00008  * This file is part of Kamailio, a free SIP server.
00009  *
00010  * Kamailio is free software; you can redistribute it and/or modify
00011  * it under the terms of the GNU General Public License as published by
00012  * the Free Software Foundation; either version 2 of the License, or
00013  * (at your option) any later version
00014  *
00015  * Kamailio is distributed in the hope that it will be useful,
00016  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018  * GNU General Public License for more details.
00019  *
00020  * You should have received a copy of the GNU General Public License 
00021  * along with this program; if not, write to the Free Software 
00022  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00023  */
00024  
00025 #include <stdio.h>
00026 #include <stdlib.h>
00027 
00028 #include "../../parser/parse_expires.h"
00029 #include "../../parser/parse_uri.h"
00030 #include  "../../mem/mem.h"
00031 #include "../../mi/mi.h"
00032 #include "../../ut.h"
00033 #include "../../cmpapi.h"
00034 
00035 #include "../pua/pua_bind.h"
00036 #include "../pua/pua.h"
00037 #include "pua_mi.h"
00038 
00039 /*
00040  * mi cmd: pua_publish
00041  *    <presentity_uri> 
00042  *    <expires>
00043  *    <event package>
00044  *    <content_type>     - body type if body of a type different from default
00045  *                            event content-type or . 
00046  *    <ETag>             - ETag that publish should match or . if no ETag
00047  *    <extra_headers>    - extra headers to be added to the request or .
00048  *    <publish_body>     - may not be present in case of update for expire
00049  */
00050 
00051 struct mi_root* mi_pua_publish(struct mi_root* cmd, void* param)
00052 {
00053    int exp;
00054    struct mi_node* node= NULL;
00055    str pres_uri, expires;
00056    str body= {0, 0};
00057    struct sip_uri uri;
00058    publ_info_t publ;
00059    str event;
00060    str content_type;
00061    str etag;
00062    str extra_headers;
00063    int result;
00064    int sign= 1;
00065 
00066    LM_DBG("start\n");
00067 
00068    node = cmd->node.kids;
00069    if(node == NULL)
00070       return 0;
00071 
00072    /* Get presentity URI */
00073    pres_uri = node->value;
00074    if(pres_uri.s == NULL || pres_uri.s== 0)
00075    {
00076       LM_ERR("empty uri\n");
00077       return init_mi_tree(404, "Empty presentity URI", 20);
00078    }
00079    if(parse_uri(pres_uri.s, pres_uri.len, &uri)<0 )
00080    {
00081       LM_ERR("bad uri\n");
00082       return init_mi_tree(404, "Bad presentity URI", 18);
00083    }
00084    LM_DBG("pres_uri '%.*s'\n", pres_uri.len, pres_uri.s);
00085 
00086    node = node->next;
00087    if(node == NULL)
00088       return 0;
00089 
00090    /* Get expires */
00091    expires= node->value;
00092    if(expires.s== NULL || expires.len== 0)
00093    {
00094       LM_ERR("empty expires parameter\n");
00095       return init_mi_tree(400, "Empty expires parameter", 23);
00096    }
00097    if(expires.s[0]== '-')
00098    {
00099       sign= -1;
00100       expires.s++;
00101       expires.len--;
00102    }
00103    if( str2int(&expires, (unsigned int*) &exp)< 0)
00104    {
00105       LM_ERR("invalid expires parameter\n" );
00106       goto error;
00107    }
00108    
00109    exp= exp* sign;
00110 
00111    LM_DBG("expires '%d'\n", exp);
00112 
00113    node = node->next;
00114    if(node == NULL)
00115       return 0;
00116 
00117    /* Get event */
00118    event= node->value;
00119    if(event.s== NULL || event.len== 0)
00120    {
00121       LM_ERR("empty event parameter\n");
00122       return init_mi_tree(400, "Empty event parameter", 21);
00123    }
00124    LM_DBG("event '%.*s'\n",
00125        event.len, event.s);
00126 
00127    node = node->next;
00128    if(node == NULL)
00129       return 0;
00130 
00131    /* Get content type */
00132    content_type= node->value;
00133    if(content_type.s== NULL || content_type.len== 0)
00134    {
00135       LM_ERR("empty content type\n");
00136       return init_mi_tree(400, "Empty content type parameter", 28);
00137    }
00138    LM_DBG("content type '%.*s'\n",
00139        content_type.len, content_type.s);
00140 
00141    node = node->next;
00142    if(node == NULL)
00143       return 0;
00144 
00145    /* Get etag */
00146    etag= node->value;
00147    if(etag.s== NULL || etag.len== 0)
00148    {
00149       LM_ERR("empty etag parameter\n");
00150       return init_mi_tree(400, "Empty etag parameter", 20);
00151    }
00152    LM_DBG("etag '%.*s'\n", etag.len, etag.s);
00153 
00154    node = node->next;
00155    if(node == NULL)
00156       return 0;
00157 
00158    /* Get extra_headers */
00159    extra_headers = node->value;
00160    if(extra_headers.s== NULL || extra_headers.len== 0)
00161    {
00162       LM_ERR("empty extra_headers parameter\n");
00163       return init_mi_tree(400, "Empty extra_headers", 19);
00164    }
00165    LM_DBG("extra_headers '%.*s'\n",
00166        extra_headers.len, extra_headers.s);
00167 
00168    node = node->next;
00169 
00170    /* Get body */
00171    if(node == NULL )
00172    {
00173       body.s= NULL;
00174       body.len= 0;
00175    }
00176    else
00177    {
00178       if(node->next!=NULL)
00179          return init_mi_tree(400, "Too many parameters", 19);
00180 
00181       body= node->value;
00182       if(body.s == NULL || body.s== 0)
00183       {
00184          LM_ERR("empty body parameter\n");
00185          return init_mi_tree(400, "Empty body parameter", 20);
00186       }
00187    }
00188    LM_DBG("body '%.*s'\n", body.len, body.s);
00189 
00190    /* Check that body is NULL if content type is . */
00191    if(body.s== NULL && (content_type.len!= 1 || content_type.s[0]!= '.'))
00192    {
00193       LM_ERR("body is missing, but content type is not .\n");
00194       return init_mi_tree(400, "Body parameter is missing", 25);
00195    }
00196 
00197    /* Create the publ_info_t structure */
00198    memset(&publ, 0, sizeof(publ_info_t));
00199    
00200    publ.pres_uri= &pres_uri;
00201    if(body.s)
00202    {
00203       publ.body= &body;
00204    }
00205    
00206    publ.event= get_event_flag(&event);
00207    if(publ.event< 0)
00208    {
00209       LM_ERR("unkown event\n");
00210       return init_mi_tree(400, "Unknown event", 13);
00211    }
00212    if(content_type.len!= 1)
00213    {
00214       publ.content_type= content_type;
00215    }  
00216    
00217    if(! (etag.len== 1 && etag.s[0]== '.'))
00218    {
00219       publ.etag= &etag;
00220    }  
00221    publ.expires= exp;
00222 
00223    if (!(extra_headers.len == 1 && extra_headers.s[0] == '.')) {
00224        publ.extra_headers = &extra_headers;
00225    }
00226 
00227    if (cmd->async_hdl!=NULL)
00228    {
00229       publ.source_flag= MI_ASYN_PUBLISH;
00230       publ.cb_param= (void*)cmd->async_hdl;
00231    }  
00232    else
00233       publ.source_flag|= MI_PUBLISH;
00234 
00235    LM_DBG("send publish\n");
00236 
00237    result= pua_send_publish(&publ);
00238 
00239    if(result< 0)
00240    {
00241       LM_ERR("sending publish failed\n");
00242       return init_mi_tree(500, "MI/PUBLISH failed", 17);
00243    }  
00244    if(result== 418)
00245       return init_mi_tree(418, "Wrong ETag", 10);
00246    
00247    if (cmd->async_hdl==NULL)
00248          return init_mi_tree( 202, "Accepted", 8);
00249    else
00250          return MI_ROOT_ASYNC_RPL;
00251 
00252 error:
00253 
00254    return 0;
00255 }
00256 
00257 int mi_publ_rpl_cback( ua_pres_t* hentity, struct sip_msg* reply)
00258 {
00259    struct mi_root *rpl_tree= NULL;
00260    struct mi_handler* mi_hdl= NULL;
00261    struct hdr_field* hdr= NULL;
00262    int statuscode;
00263    int lexpire;
00264    int found;
00265    str etag;
00266    str reason= {0, 0};
00267 
00268    if(reply== NULL || hentity== NULL || hentity->cb_param== NULL)
00269    {
00270       LM_ERR("NULL parameter\n");
00271       return -1;
00272    }
00273    if(reply== FAKED_REPLY)
00274    {
00275       statuscode= 408;
00276       reason.s= "Request Timeout";
00277       reason.len= strlen(reason.s);
00278    }
00279    else
00280    {
00281       statuscode= reply->first_line.u.reply.statuscode;
00282       reason= reply->first_line.u.reply.reason;
00283    }
00284 
00285    mi_hdl = (struct mi_handler *)(hentity->cb_param);
00286    
00287    rpl_tree = init_mi_tree( 200, MI_OK_S, MI_OK_LEN);
00288    if (rpl_tree==0)
00289       goto done;
00290    
00291    addf_mi_node_child( &rpl_tree->node, 0, 0, 0, "%d %.*s",
00292       statuscode, reason.len, reason.s);
00293    
00294    
00295    if(statuscode== 200)
00296    {
00297       /* extract ETag and expires */
00298       lexpire = ((exp_body_t*)reply->expires->parsed)->val;
00299       LM_DBG("lexpire= %d\n", lexpire);
00300       
00301       hdr = reply->headers;
00302       found = 0;
00303       while (hdr!= NULL)
00304       {
00305          if(cmp_hdrname_strzn(&hdr->name, "SIP-ETag",8)==0)
00306          {
00307             found = 1;
00308             break;
00309          }
00310          hdr = hdr->next;
00311       }
00312       if(found== 0) /* must find SIP-Etag header field in 200 OK msg*/
00313       {
00314          LM_ERR("SIP-ETag header field not found\n");
00315          goto error;
00316       }
00317       etag= hdr->body;
00318          
00319       addf_mi_node_child( &rpl_tree->node, 0, "ETag", 4, "%.*s", etag.len, etag.s);
00320       
00321       addf_mi_node_child( &rpl_tree->node, 0, "Expires", 7, "%d", lexpire);
00322    }  
00323 
00324 done:
00325    if ( statuscode >= 200) 
00326    {
00327       mi_hdl->handler_f( rpl_tree, mi_hdl, 1);
00328    }
00329    else 
00330    {
00331       mi_hdl->handler_f( rpl_tree, mi_hdl, 0 );
00332    }
00333    return 0;
00334 
00335 error:
00336    return  -1;
00337 }
00338 
00339 
00340 /*Command parameters:
00341  * pua_subscribe
00342  *    <presentity_uri>
00343  *    <watcher_uri>
00344  *    <event_package>
00345  *    <expires>
00346  * */
00347 
00348 
00349 struct mi_root* mi_pua_subscribe(struct mi_root* cmd, void* param)
00350 {
00351    int exp= 0;
00352    str pres_uri, watcher_uri, expires;
00353    struct mi_node* node= NULL;
00354    struct mi_root* rpl= NULL;
00355    struct sip_uri uri;
00356    subs_info_t subs;
00357    int sign= 1;
00358    str event;
00359 
00360    node = cmd->node.kids;
00361    if(node == NULL)
00362       return 0;
00363 
00364    pres_uri= node->value;
00365    if(pres_uri.s == NULL || pres_uri.s== 0)
00366    {
00367       return init_mi_tree(400, "Bad uri", 7);
00368    }
00369    if(parse_uri(pres_uri.s, pres_uri.len, &uri)<0 )
00370    {
00371       LM_ERR("bad uri\n"); 
00372       return init_mi_tree(400, "Bad uri", 7);
00373    }
00374 
00375    node = node->next;
00376    if(node == NULL)
00377       return 0;
00378 
00379    watcher_uri= node->value;
00380    if(watcher_uri.s == NULL || watcher_uri.s== 0)
00381    {
00382       return init_mi_tree(400, "Bad uri", 7);
00383    }
00384    if(parse_uri(watcher_uri.s, watcher_uri.len, &uri)<0 )
00385    {
00386       LM_ERR("bad uri\n"); 
00387       return init_mi_tree(400, "Bad uri", 7);
00388    }
00389 
00390    /* Get event */
00391    node = node->next;
00392    if(node == NULL)
00393       return 0;
00394 
00395    event= node->value;
00396    if(event.s== NULL || event.len== 0)
00397    {
00398       LM_ERR("empty event parameter\n");
00399       return init_mi_tree(400, "Empty event parameter", 21);
00400    }
00401    LM_DBG("event '%.*s'\n", event.len, event.s);
00402 
00403    node = node->next;
00404    if(node == NULL || node->next!=NULL)
00405    {
00406       LM_ERR("Too much or too many parameters\n");
00407       return 0;
00408    }
00409 
00410    expires= node->value;
00411    if(expires.s== NULL || expires.len== 0)
00412    {
00413       LM_ERR("Bad expires parameter\n");
00414       return init_mi_tree(400, "Bad expires", 11);
00415    }     
00416    if(expires.s[0]== '-')
00417    {
00418       sign= -1;
00419       expires.s++;
00420       expires.len--;
00421    }
00422    if( str2int(&expires, (unsigned int*) &exp)< 0)
00423    {
00424       LM_ERR("invalid expires parameter\n" );
00425       goto error;
00426    }
00427    
00428    exp= exp* sign;
00429 
00430    LM_DBG("expires '%d'\n", exp);
00431    
00432    memset(&subs, 0, sizeof(subs_info_t));
00433    
00434    subs.pres_uri= &pres_uri;
00435 
00436    subs.watcher_uri= &watcher_uri;
00437 
00438    subs.contact= &watcher_uri;
00439    
00440    subs.expires= exp;
00441    subs.source_flag |= MI_SUBSCRIBE;
00442    subs.event= get_event_flag(&event);
00443    if(subs.event< 0)
00444    {
00445       LM_ERR("unkown event\n");
00446       return init_mi_tree(400, "Unknown event", 13);
00447    }
00448 
00449    if(pua_send_subscribe(&subs)< 0)
00450    {
00451       LM_ERR("while sending subscribe\n");
00452       goto error;
00453    }
00454    
00455    rpl= init_mi_tree(202, "accepted", 8);
00456    if(rpl == NULL)
00457       return 0;
00458    
00459    return rpl;
00460 
00461 error:
00462 
00463    return 0;
00464 
00465 }
00466 

Generated on Wed May 23 20:00:27 2012 for Kamailio - The Open Source SIP Server by  doxygen 1.5.6