encode_route.c

Go to the documentation of this file.
00001 /* $Id: encode_route.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_route.c
00026  * 
00027  *     Description:  functions to encode/decode/print the route header
00028  * 
00029  *         Version:  1.0
00030  *         Created:  20/11/05 04:24:55 CET
00031  *        Revision:  none
00032  *        Compiler:  gcc
00033  * 
00034  *          Author:  Elias Baixas (EB), elias@conillera.net
00035  *         Company:  VozTele.com
00036  * 
00037  * =====================================================================================
00038  */
00039 
00040 #define _GNU_SOURCE
00041 #include <stdio.h>
00042 
00043 #include "../../parser/parse_rr.h"
00044 #include "../../parser/parse_uri.h"
00045 #include "encode_route.h"
00046 #include "encode_uri.h"
00047 #include "encode_header.h"
00048 #include "encode_parameters.h"
00049 #include "xaddress.h"
00050 
00051 
00052 #define HAS_NAME_F      0x01
00053 #define HAS_Q_F         0x02
00054 #define HAS_EXPIRES_F      0x04
00055 #define HAS_RECEIVED_F     0x08
00056 #define HAS_METHOD_F    0x10
00057 
00058 /*
00059  * encodes a (maybe aggregated) route/record-route header.
00060  * encoding is:
00061  * 1: flags
00062  * 1: number of routes present
00063  * N: fore each route present, the length of the route
00064  * N*M: the route structures concatenated
00065  */
00066 int encode_route_body(char *hdr,int hdrlen,rr_t *route_parsed,unsigned char *where)
00067 {
00068    int i=0,k,route_offset;
00069    unsigned char flags,tmp[500];
00070    rr_t *myroute;
00071    
00072    flags=0;
00073    for(route_offset=0,i=0,myroute=route_parsed;myroute;myroute=myroute->next,i++){
00074       if((k=encode_route(hdr,hdrlen,myroute,&tmp[route_offset]))<0){
00075     LM_ERR("parsing route number %d\n",i);
00076     return -1;
00077       }
00078       where[2+i]=(unsigned char)k;
00079       route_offset+=k;
00080    }
00081    where[1]=(unsigned char)i;
00082    memcpy(&where[2+i],tmp,route_offset);
00083    return 2+i+route_offset;
00084 }
00085 
00086 /* Encoder for route/record-route units (may be inside an aggegated
00087  * Route/RRoute header, see [rfc3261, 7.3.1, page 30] ).
00088  * Returns the length of the encoded structure in bytes
00089  * FORMAT (byte meanings):
00090  * 1: flags
00091  *    0x01 :   there is a Display Name
00092  * 1: length of the XURI-encoded uri in bytes.
00093  * [2]: optionally, 1 HDR-based ptr to the displayname + the length of the name
00094  * N: the XURI-encoded URI.
00095  * [N:] optionally, HDR-based pointers to the different header-parameters
00096  *
00097  */
00098 int encode_route(char *hdrstart,int hdrlen,rr_t *body,unsigned char *where)
00099 {
00100    int i=2,j=0;/* 1*flags + 1*URI_len*/
00101    unsigned char flags=0;
00102    struct sip_uri puri;
00103 
00104    if(body->nameaddr.name.s && body->nameaddr.name.len){
00105       flags|=HAS_NAME_F;
00106       where[i++]=(unsigned char)(body->nameaddr.name.s-hdrstart);
00107       where[i++]=(unsigned char)body->nameaddr.name.len;
00108    }
00109 
00110    if (parse_uri(body->nameaddr.uri.s, body->nameaddr.uri.len,&puri) < 0 ) {
00111       LM_ERR("Bad URI in address\n");
00112      return -1;
00113    }else{
00114       if((j=encode_uri2(hdrstart,hdrlen,body->nameaddr.uri,&puri,&where[i]))<0){
00115     LM_ERR("error codifying the URI\n");
00116     return -1;
00117       }else{
00118     i+=j;
00119       }
00120    }
00121    where[0]=flags;
00122    where[1]=(unsigned char)j;
00123    i+=encode_parameters(&where[i],(void *)body->params,hdrstart,body,'n');
00124    return i;
00125 }
00126 
00127 
00128 int print_encoded_route_body(FILE *fd,char *hdr,int hdrlen,unsigned char *payload,int paylen,char *prefix)
00129 {
00130    unsigned char flags, numroutes;
00131    int i,offset;
00132 
00133    flags=payload[0];
00134    fprintf(fd,"%s",prefix);
00135    for(i=0;i<paylen;i++)
00136       fprintf(fd,"%s%d%s",i==0?"ENCODED CONTACT BODY:[":":",payload[i],i==paylen-1?"]\n":"");
00137 
00138    numroutes=payload[1];
00139    if(numroutes==0){
00140       LM_ERR("no routes present?\n");
00141       return -1;
00142    }
00143    for(i=0,offset=2+numroutes;i<numroutes;i++){
00144       print_encoded_route(fd,hdr,hdrlen,&payload[offset],payload[2+i],strcat(prefix,"  "));
00145       offset+=payload[2+i];
00146       prefix[strlen(prefix)-2]=0;
00147    }
00148    return 1;
00149 }
00150 
00151 int print_encoded_route(FILE *fd,char *hdr,int hdrlen,unsigned char* payload,int paylen,char *prefix)
00152 {
00153    int i=2;/* flags + urilength */
00154    unsigned char flags=0;
00155 
00156    flags=payload[0];
00157    fprintf(fd,"%s",prefix);
00158    for(i=0;i<paylen;i++)
00159       fprintf(fd,"%s%d%s",i==0?"ENCODED ROUTE=[":":",payload[i],i==paylen-1?"]\n":"");
00160    i=2;
00161    if(flags & HAS_NAME_F){
00162       fprintf(fd,"%sNAME=[%.*s]\n",prefix,payload[i+1],&hdr[payload[i]]);
00163       i+=2;
00164    }
00165    if(print_encoded_uri(fd,&payload[i],payload[1],hdr,hdrlen,strcat(prefix,"  "))<0){
00166       prefix[strlen(prefix)-2]=0;
00167       fprintf(fd,"Error parsing URI\n");
00168       return -1;
00169    }
00170    prefix[strlen(prefix)-2]=0;
00171    print_encoded_parameters(fd,&payload[i+payload[1]],hdr,paylen-i-payload[1],prefix);
00172    /* for(i+=payload[1];i<paylen-1;i+=2){
00173       fprintf(fd,"%s[PARAMETER[%.*s]",prefix,payload[i+1]-payload[i]-1,&hdr[payload[i]]);
00174       fprintf(fd,"VALUE[%.*s]]\n",(payload[i+2]-payload[i+1])==0?0:(payload[i+2]-payload[i+1]-1),&hdr[payload[i+1]]);
00175    }*/
00176    return 0;
00177 }
00178 
00179 
00180 int dump_route_body_test(char *hdr,int hdrlen,unsigned char *payload,int paylen,FILE* fd,char segregationLevel,char *prefix)
00181 {
00182    unsigned char flags, numroutes;
00183    int i,offset;
00184 
00185    flags=payload[0];
00186    if(!segregationLevel){
00187       return dump_standard_hdr_test(hdr,hdrlen,(unsigned char*)payload,paylen,fd);
00188    }
00189 
00190    numroutes=payload[1];
00191    if(numroutes==0){
00192       LM_ERR("no routes present?\n");
00193       return -1;
00194    }
00195    if(segregationLevel & (JUNIT|SEGREGATE|ONLY_URIS)){
00196       for(i=0,offset=2+numroutes;i<numroutes;i++){
00197     dump_route_test(hdr,hdrlen,&payload[offset],payload[2+i],fd,segregationLevel,prefix);
00198     offset+=payload[2+i];
00199       }
00200    }
00201    return 1;
00202 }
00203 
00204 int dump_route_test(char *hdr,int hdrlen,unsigned char* payload,int paylen,FILE* fd,char segregationLevel,char *prefix)
00205 {
00206    int i=2;/* flags + urilength */
00207    unsigned char flags=0;
00208 
00209    if(!(segregationLevel & (ONLY_URIS|JUNIT))){
00210       return dump_standard_hdr_test(hdr,hdrlen,(unsigned char*)payload,paylen,fd);
00211    }
00212    flags=payload[0];
00213    i=2;
00214    if(flags & HAS_NAME_F){
00215       i+=2;
00216    }
00217    if((!(segregationLevel & JUNIT)) && (segregationLevel & ONLY_URIS)){
00218       return dump_standard_hdr_test(hdr,hdrlen,(unsigned char*)(payload+i),payload[1],fd);
00219    }
00220    if((segregationLevel & JUNIT) && (segregationLevel & ONLY_URIS)){
00221       return print_uri_junit_tests(hdr,hdrlen,&payload[i],payload[1],fd,1,"");
00222    }
00223    if(segregationLevel & JUNIT){
00224       i=2;
00225       fprintf(fd,"%sgetAddress.getDisplayName=(S)",prefix);
00226       if(flags & HAS_NAME_F){
00227     fprintf(fd,"%.*s\n",payload[i+1],&hdr[payload[i]]);
00228     i+=2;
00229       }else
00230     fprintf(fd,"(null)\n");
00231       return print_uri_junit_tests(hdr,hdrlen,&payload[i],payload[1],fd,0,"getAddress.getURI.");
00232    }
00233    return 0;
00234 }

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