encode_parameters.c

Go to the documentation of this file.
00001 /* $Id: encode_parameters.c 5192 2008-11-13 10:18:48Z eliasbaixas $
00002  *
00003  * Copyright (C) 2006-2007 VozTelecom Sistemas S.L
00004  *
00005  * This file is part of Kamailio, a free SIP server.
00006  *
00007  * Kamailio is free software; you can redistribute it and/or modify
00008  * it under the terms of the GNU General Public License as published by
00009  * the Free Software Foundation; either version 2 of the License, or
00010  * (at your option) any later version
00011  *
00012  * Kamailio is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License 
00018  * along with this program; if not, write to the Free Software 
00019  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00020  */
00021 
00022 /*
00023  * =====================================================================================
00024  * 
00025  *        Filename:  encode_parameters.c
00026  * 
00027  *     Description:  Functions to encode/print parameters
00028  * 
00029  *         Version:  1.0
00030  *         Created:  25/01/06 17:46:04 CET
00031  *        Revision:  none
00032  *        Compiler:  gcc
00033  * 
00034  *          Author:  Elias Baixas (EB), elias@conillera.net
00035  *         Company:  VozTele.com
00036  * 
00037  * =====================================================================================
00038  */
00039 #define _GNU_SOURCE
00040 #include <stdio.h>
00041 #include "../../str.h"
00042 #include "../../parser/parse_param.h"
00043 #include "../../parser/parse_to.h"
00044 #include "../../parser/parse_via.h"
00045 #include "../../parser/parse_disposition.h"
00046 #include "encode_parameters.h"
00047 
00048 #define REL_PTR(a,b) (unsigned char)((b)-(a))
00049 
00050 /**
00051  * Returns how many bytes in *where have been used
00052  *
00053  * TODO this is little shitty, someone should unify all the param flavours 
00054  * to a sigle universal type of parameter (to_param,param,disposition_param)
00055  * the way is done here, at least, we dont have the parameter-hanling code spread all around.
00056  */
00057 int encode_parameters(unsigned char *where,void *pars,char *hdrstart,void *_body,char to)
00058 {
00059    struct param *parametro,*params;
00060    struct to_param *toparam,*toparams;
00061    struct disposition_param *dparam,*dparams;
00062    struct via_param *vparam,*vparams;
00063    struct via_body *vbody;
00064    struct to_body *tbody;
00065    char *mylittlepointer,*paramstart; 
00066    int i,j,paramlen;
00067    i=0;
00068    if(!pars)
00069       return 0;
00070    if(to=='t'){
00071       toparams=(struct to_param*)pars;
00072       tbody=(struct to_body*)_body;
00073       for(toparam=toparams;toparam;toparam=toparam->next){
00074     where[i++]=(unsigned char)(toparam->name.s-hdrstart);
00075     if(toparam->value.s)
00076        mylittlepointer=toparam->value.s;
00077     else
00078        if(toparam->next)
00079           mylittlepointer=toparam->next->name.s;
00080        else
00081           mylittlepointer=toparam->name.s+toparam->name.len+1;
00082     where[i++]=(unsigned char)(mylittlepointer-hdrstart);
00083       }
00084       if((toparam=tbody->last_param)){
00085     if(toparam->value.s)
00086        mylittlepointer=toparam->value.s+toparam->value.len;
00087     else
00088        mylittlepointer=toparam->name.s+toparam->name.len;
00089     where[i++]=(unsigned char)(mylittlepointer-hdrstart+1);
00090       }
00091       return i;
00092    }else if(to=='n'){
00093       params=(struct param*)pars;
00094       for(parametro=reverseParameters(params);parametro;parametro=parametro->next){
00095     where[i++]=(unsigned char)(parametro->name.s-hdrstart);
00096     if(parametro->body.s)
00097        mylittlepointer=parametro->body.s;
00098     else
00099        if(parametro->next)
00100           mylittlepointer=parametro->next->name.s;
00101        else
00102           mylittlepointer=parametro->name.s+parametro->name.len+1;
00103     where[i++]=(unsigned char)(mylittlepointer-hdrstart);
00104       }
00105       /*look for the last parameter*/
00106       /*WARNING the ** parameters are in reversed order !!! */
00107       /*TODO parameter encoding logic should be moved to a specific function...*/
00108       for(parametro=params;parametro && parametro->next;parametro=parametro->next);
00109       /*printf("PARAMETRO:%.*s\n",parametro->name.len,parametro->name.s);*/
00110       if(parametro){
00111     if(parametro->body.s)
00112        mylittlepointer=parametro->body.s+parametro->body.len;
00113     else
00114        mylittlepointer=parametro->name.s+parametro->name.len;
00115     where[i++]=(unsigned char)(mylittlepointer-hdrstart+1);
00116       }
00117       return i;
00118    }else if(to=='d'){
00119       dparams=(struct disposition_param*)pars;
00120       for(dparam=dparams;dparam;dparam=dparam->next){
00121     where[i++]=(unsigned char)(dparam->name.s-hdrstart);
00122     if(dparam->body.s)
00123        mylittlepointer=dparam->body.s;
00124     else
00125        if(dparam->next)
00126           mylittlepointer=dparam->next->name.s;
00127        else
00128           mylittlepointer=dparam->name.s+dparam->name.len+1;
00129     where[i++]=(unsigned char)(mylittlepointer-hdrstart);
00130       }
00131       /*WARNING the ** parameters are in reversed order !!! */
00132       /*TODO parameter encoding logic should be moved to a specific function...*/
00133       for(dparam=dparams;dparam && dparam->next;dparam=dparam->next);
00134       if(dparam){
00135     if(dparam->body.s)
00136        mylittlepointer=dparam->body.s+dparam->body.len;
00137     else
00138        mylittlepointer=dparam->name.s+dparam->name.len;
00139     where[i++]=(unsigned char)(mylittlepointer-hdrstart+1);
00140       }
00141       return i;
00142    }else if(to=='v'){
00143       vparams=(struct via_param*)pars;
00144       vbody=(struct via_body*)_body;
00145       for(vparam=vparams;vparam;vparam=vparam->next){
00146     where[i++]=REL_PTR(hdrstart,vparam->name.s);
00147     if(vparam->value.s)
00148        mylittlepointer=vparam->value.s;
00149     else
00150        if(vparam->next)
00151           mylittlepointer=vparam->next->name.s;
00152        else
00153           mylittlepointer=vparam->name.s+vparam->name.len+1;
00154     where[i++]=REL_PTR(hdrstart,mylittlepointer);
00155       }
00156       if((vparam=vbody->last_param)){
00157     if(vparam->value.s)
00158        mylittlepointer=vparam->value.s+vparam->value.len;
00159     else
00160        mylittlepointer=vparam->name.s+vparam->name.len;
00161     where[i++]=REL_PTR(hdrstart,mylittlepointer+1);
00162       }
00163       return i;
00164    }else if(to=='u'){
00165       paramlen=*((int*)_body);
00166       paramstart=(char *)pars;
00167       j=i=0;
00168       if(paramstart==0 || paramlen==0)
00169     return 0;
00170       /*the first parameter start index, I suppose paramstart points to the first
00171        letter of the first parameter: sip:elias@voztele.com;param1=true;param2=false
00172                                      paramstart points to __^                      
00173        each parameter is codified with its {param_name_start_idx,[param_value_start_idx|next_param_start_idx]} */
00174       where[j++]=paramstart-hdrstart;
00175       while(i<paramlen){
00176     i++;
00177     if(paramstart[i]==';'){/*no '=' found !*/
00178        where[j++]=(unsigned char)(&paramstart[i+1]-hdrstart);
00179        where[j++]=(unsigned char)(&paramstart[i+1]-hdrstart);
00180     }
00181     if(paramstart[i]=='='){/* '=' found, look for the next ';' and let 'i' pointing to it*/
00182        where[j++]=(unsigned char)(&paramstart[i+1]-hdrstart);
00183        for(;i<paramlen&&paramstart[i]!=';';i++);
00184        if(paramstart[i]==';')
00185           where[j++]=(unsigned char)(&paramstart[i+1]-hdrstart);
00186     }
00187       }
00188       where[j++]=(unsigned char)(&paramstart[i+1]-hdrstart);
00189       if(j%2 == 0)/*this is because maybe the LAST parameter doesn't have an '='*/
00190     where[j++]=(unsigned char)(&paramstart[i+1]-hdrstart);
00191       return j;
00192    }
00193    return 0;
00194 }
00195 
00196 /**reverses a param_t linked-list
00197  */
00198 param_t *reverseParameters(param_t *p)
00199 {
00200    param_t *previous=NULL,*tmp;
00201    while (p != NULL)
00202    {
00203       tmp = p->next;/* store the next */
00204       p->next = previous;/* next = previous */
00205       previous = p;/* previous = current */
00206       p = tmp;/* current = "the next" */
00207    }
00208    return previous;
00209 }
00210 
00211 /*prints the encoded parameters
00212  */
00213 int print_encoded_parameters(FILE *fd,unsigned char *payload,char *hdr,int paylen,char *prefix)
00214 {
00215    int i;
00216    for(i=0;i<paylen-1;i+=2){
00217       fprintf(fd,"%s[PARAMETER[%.*s]",prefix,payload[i+1]-payload[i]-1,&hdr[payload[i]]);
00218       fprintf(fd,"VALUE[%.*s]]\n",(payload[i+2]-payload[i+1])==0?0:(payload[i+2]-payload[i+1]-1),&hdr[payload[i+1]]);
00219    }
00220    return 0;
00221 }

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