Coverage Report

Created: 2025-07-18 06:32

/src/opensips/parser/parse_call_info.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (C) 2010 VoIP Embedded Inc. <http://www.voipembedded.com/>
3
 *
4
 *
5
 * This file is part of opensips, a free SIP server.
6
 *
7
 * opensips is free software; you can redistribute it and/or modify
8
 * it under the terms of the GNU General Public License as published by
9
 * the Free Software Foundation; either version 2 of the License, or
10
 * (at your option) any later version
11
 *
12
 * opensips is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU General Public License
18
 * along with this program; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
20
 *
21
 * History:
22
 * --------
23
 * 2010-11-09 Initial revision (Ovidiu Sas)
24
 */
25
26
#include "parse_from.h"
27
#include "parse_to.h"
28
#include "parse_call_info.h"
29
#include <stdlib.h>
30
#include <string.h>
31
#include "../dprint.h"
32
#include "msg_parser.h"
33
#include "../ut.h"
34
#include "../errinfo.h"
35
#include "../mem/mem.h"
36
37
38
/*
39
 * This method is used to parse Call-Info header.
40
 *
41
 * params: msg : sip msg
42
 * returns 0 on success,
43
 *        -1 on failure.
44
 */
45
int parse_call_info_header( struct sip_msg *msg )
46
0
{
47
0
    struct call_info_body *callinfo_b, *old_callinfo_b=NULL;
48
0
    struct to_body *call_info_b;
49
0
    struct hdr_field *call_info;
50
0
    void **parsed;
51
0
    char *tmp, *end, *start;
52
0
    unsigned int len;
53
54
0
    if ( !msg->call_info &&
55
0
   (parse_headers(msg, HDR_CALL_INFO_F,0)==-1 || !msg->call_info)) {
56
0
  return -1;
57
0
    }
58
59
0
    call_info=msg->call_info;
60
61
    /* maybe the header is already parsed! */
62
0
    if (call_info->parsed)
63
0
  return 0;
64
65
0
    parsed = &(call_info->parsed);
66
67
0
    while(*parsed == NULL)
68
0
{
69
70
0
    len = call_info->body.len+1;
71
0
    start = call_info->body.s;
72
0
    end = start + len;
73
0
    LM_DBG("parsing the whole body [%.*s]\n", len, call_info->body.s);
74
75
0
    for( tmp=call_info->body.s; tmp<=end; tmp++) {
76
0
        if (*tmp == ',' || tmp==end) {
77
0
      LM_DBG("[%.*s]\n",(int)(tmp-start),start);
78
79
0
      callinfo_b = pkg_malloc(sizeof(struct call_info_body));
80
0
      if (callinfo_b == NULL) {
81
0
    LM_ERR("out of pkg_memory\n");
82
0
    goto error;
83
0
      }
84
0
      memset(callinfo_b, 0, sizeof(struct call_info_body));
85
86
      /* now parse it!! */
87
0
      call_info_b = &(callinfo_b->call_info_body);
88
0
      parse_to(start, tmp, call_info_b);
89
0
      if (call_info_b->error == PARSE_ERROR) {
90
0
    LM_ERR("bad Call-Info header\n");
91
0
    pkg_free(call_info_b);
92
0
    set_err_info(OSER_EC_PARSER, OSER_EL_MEDIUM,
93
0
        "error parsing Call-Info header");
94
0
    set_err_reply(400, "bad header");
95
0
    goto error;
96
0
      }
97
98
      /* Save the first parsed body */
99
0
      if (*parsed == NULL)
100
0
        *parsed = callinfo_b;
101
0
      else
102
0
    old_callinfo_b->next = callinfo_b;
103
104
0
      old_callinfo_b = callinfo_b;
105
106
0
      start = tmp + 1;
107
0
  }
108
0
    }
109
0
    call_info = call_info->sibling;
110
0
    LM_DBG("done ... next call_info [%p]\n", call_info);
111
0
    if (call_info == NULL) {
112
0
  break;
113
0
    }
114
0
    parsed = &(call_info->parsed);
115
0
}
116
117
0
    return 0;
118
119
0
error:
120
0
    return -1;
121
0
}
122
123
inline static void free_call_info_param_list(struct to_param *param_lst)
124
0
{
125
0
    struct to_param *foo;
126
0
    while(param_lst){
127
0
  foo=param_lst->next;
128
  //LM_DBG(".. free [%p]->[%.*s]\n", param_lst, param_lst->name.len, param_lst->name.s);
129
0
  pkg_free(param_lst);
130
0
  param_lst=foo;
131
0
    }
132
0
    return;
133
0
}
134
135
void free_call_info(struct call_info_body *callinfo_b)
136
0
{
137
0
    struct call_info_body *foo;
138
0
    while(callinfo_b){
139
  //LM_DBG("freeing callinfo\n");
140
0
  foo=callinfo_b;
141
0
  callinfo_b=callinfo_b->next;
142
0
  if (foo->call_info_body.param_lst)
143
0
      free_call_info_param_list(foo->call_info_body.param_lst);
144
  //LM_DBG(". free [%p]->[%.*s]\n", foo, foo->call_info_body.body.len, foo->call_info_body.body.s);
145
0
  pkg_free(foo);
146
  //LM_DBG("done freeing callinfo\n");
147
0
    }
148
0
    return;
149
0
}