modules_k/pua_bla/notify.c

00001 /*
00002  * $Id: notify.c 1666 2007-03-02 13:40:09Z anca_vamanu $
00003  *
00004  * pua_bla module - pua Bridged Line Appearance
00005  *
00006  * Copyright (C) 2007 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  * History:
00025  * --------
00026  *  2007-03-30  initial version (anca)
00027  */
00028 #include<stdio.h>
00029 #include<stdlib.h>
00030 #include<libxml/parser.h>
00031 
00032 #include "../../parser/parse_content.h"
00033 #include "../../parser/contact/parse_contact.h"
00034 #include "../../parser/parse_from.h"
00035 #include "../../lib/kcore/cmpapi.h"
00036 #include "../pua/hash.h"
00037 #include"pua_bla.h"
00038 
00039 int bla_handle_notify(struct sip_msg* msg, char* s1, char* s2)
00040 {
00041         publ_info_t publ;
00042         struct to_body *pto = NULL, TO = {0}, *pfrom = NULL;
00043         str body;
00044         ua_pres_t dialog;
00045         unsigned int expires= 0;
00046         struct hdr_field* hdr;
00047         str subs_state;
00048         int found= 0;
00049         str extra_headers= {0, 0};
00050         static char buf[255];
00051         str contact;
00052 
00053         memset(&publ, 0, sizeof(publ_info_t));
00054         memset(&dialog, 0, sizeof(ua_pres_t));
00055  
00056         LM_DBG("start\n");
00057   
00058         if ( parse_headers(msg,HDR_EOH_F, 0)==-1 )
00059         {
00060                 LM_ERR("parsing headers\n");
00061                 return -1;
00062         }
00063   
00064         if( msg->to==NULL || msg->to->body.s==NULL)
00065         {
00066                 LM_ERR("cannot parse TO header\n");
00067                 goto error;
00068         }
00069         /* examine the to header */
00070         if(msg->to->parsed != NULL)
00071         {
00072                 pto = (struct to_body*)msg->to->parsed;
00073                 LM_DBG("'To' header ALREADY PARSED: <%.*s>\n",
00074                                 pto->uri.len, pto->uri.s );
00075         }
00076         else
00077         {
00078                 parse_to(msg->to->body.s,msg->to->body.s + msg->to->body.len + 1, &TO);
00079                 if(TO.uri.len <= 0)
00080                 {
00081                         LM_DBG("'To' header NOT parsed\n");
00082                         goto error;
00083                 }
00084                 pto = &TO;
00085         }
00086         publ.pres_uri= &pto->uri;
00087         dialog.watcher_uri= publ.pres_uri;
00088   
00089         if (pto->tag_value.s==NULL || pto->tag_value.len==0 )
00090         {
00091                 LM_ERR("NULL to_tag value\n");
00092                 goto error;
00093         }
00094         dialog.from_tag= pto->tag_value;
00095   
00096         if( msg->callid==NULL || msg->callid->body.s==NULL)
00097         {
00098                 LM_ERR("cannot parse callid header\n");
00099                 goto error;
00100         }
00101         dialog.call_id = msg->callid->body;
00102   
00103         if (!msg->from || !msg->from->body.s)
00104         {
00105                 LM_ERR("cannot find 'from' header!\n");
00106                 goto error;
00107         }
00108         if (msg->from->parsed == NULL)
00109         {
00110                 LM_DBG(" 'From' header not parsed\n");
00111                 /* parsing from header */
00112                 if ( parse_from_header( msg )<0 )
00113                 {
00114                         LM_DBG(" ERROR cannot parse From header\n");
00115                         goto error;
00116                 }
00117         }
00118         pfrom = (struct to_body*)msg->from->parsed;
00119         dialog.pres_uri= &pfrom->uri;
00120  
00121         if( pfrom->tag_value.s ==NULL || pfrom->tag_value.len == 0)
00122         {
00123                 LM_ERR("no from tag value present\n");
00124                 goto error;
00125         }
00126  
00127         dialog.to_tag= pfrom->tag_value;
00128         dialog.event= BLA_EVENT;
00129         dialog.flag= BLA_SUBSCRIBE;
00130         if(pua_is_dialog(&dialog)< 0)
00131         {
00132                 LM_ERR("Notify in a non existing dialog\n");
00133                 goto error;
00134         }
00135         LM_DBG("found a matching dialog\n");
00136  
00137         /* parse Subscription-State and extract expires if existing */
00138         hdr = msg->headers;
00139         while (hdr!= NULL)
00140         {
00141                 if(cmp_hdrname_strzn(&hdr->name, "Subscription-State",18)==0)
00142                 {
00143                         found = 1;
00144                         break;
00145                 }
00146                 hdr = hdr->next;
00147         }
00148         if(found==0 )
00149         {
00150                 LM_ERR("No Subscription-State header found\n");
00151                 goto error;
00152         }
00153         subs_state= hdr->body;
00154         if(strncmp(subs_state.s, "terminated", 10)== 0)
00155                 expires= 0;
00156         else
00157                 if(strncmp(subs_state.s, "active", 6)== 0 ||
00158                                 strncmp(subs_state.s, "pending", 7)==0 )
00159                 {
00160                         char* sep= NULL;
00161                         str exp= {0, 0};
00162                         sep= strchr(subs_state.s, ';');
00163                         if(sep== NULL)
00164                         {
00165                                 LM_ERR("No expires found in Notify\n");
00166                                 goto error;
00167                         }
00168                         if(strncmp(sep+1, "expires=", 8)!= 0)
00169                         {
00170                                 LM_ERR("No expires found in Notify\n");
00171                                 goto error;
00172                         }
00173                         exp.s= sep+ 9;
00174                         sep= exp.s;
00175                         while((*sep)>='0' && (*sep)<='9')
00176                         {
00177                                 sep++;
00178                                 exp.len++;
00179                         }
00180                         if( str2int(&exp, &expires)< 0)
00181                         {
00182                                 LM_ERR("while parsing int\n");
00183                                 goto error;
00184                         }
00185                 }
00186    
00187         if ( get_content_length(msg) == 0 )
00188         {
00189                 LM_ERR("content length= 0\n");
00190                 goto error;
00191         }
00192         else
00193         {
00194                 body.s=get_body(msg);
00195                 if (body.s== NULL)
00196                 {
00197                         LM_ERR("cannot extract body from msg\n");
00198                         goto error;
00199                 }
00200                 body.len = get_content_length( msg );
00201         }
00202         
00203         if(msg->contact== NULL || msg->contact->body.s== NULL)
00204         {
00205                 LM_ERR("no contact header found");
00206                 goto error;
00207         }
00208         if( parse_contact(msg->contact) <0 )
00209         {
00210                 LM_ERR(" cannot parse contact header\n");
00211                 goto error;
00212         }
00213 
00214         if(msg->contact->parsed == NULL)
00215         {
00216                 LM_ERR("cannot parse contact header\n");
00217                 goto error;
00218         }
00219         contact = ((contact_body_t* )msg->contact->parsed)->contacts->uri;
00220 
00221         /* build extra_headers with Sender*/
00222         extra_headers.s= buf;
00223         memcpy(extra_headers.s, header_name.s, header_name.len);
00224         extra_headers.len= header_name.len;
00225         memcpy(extra_headers.s+extra_headers.len,": ",2);
00226         extra_headers.len+= 2;
00227         memcpy(extra_headers.s+ extra_headers.len, contact.s, contact.len);
00228         extra_headers.len+= contact.len;
00229         memcpy(extra_headers.s+ extra_headers.len, CRLF, CRLF_LEN);
00230         extra_headers.len+= CRLF_LEN;
00231    
00232         publ.body= &body;
00233         publ.source_flag= BLA_PUBLISH;
00234         publ.expires= expires;
00235         publ.event= BLA_EVENT;
00236         publ.extra_headers= &extra_headers;
00237         
00238         if(pua_send_publish(&publ)< 0)
00239         {
00240                 LM_ERR("while sending Publish\n");
00241                 goto error;
00242         }
00243       
00244         xmlCleanupParser();
00245         xmlMemoryDump();
00246 
00247         free_to_params(&TO);
00248         return 1;
00249    
00250 error:
00251         free_to_params(&TO);
00252         return 0;
00253 }
00254