Coverage Report

Created: 2025-07-09 06:29

/src/opensips/parser/parse_event.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Event header field body parser.
3
 * The parser was written for Presence Agent module only.
4
 * it recognize presence package only, no sub-packages, no parameters
5
 * It should be replaced by a more generic parser if sub-packages or
6
 * parameters should be parsed too.
7
 *
8
 * Copyright (C) 2001-2003 FhG Fokus
9
 *
10
 * This file is part of opensips, a free SIP server.
11
 *
12
 * opensips is free software; you can redistribute it and/or modify
13
 * it under the terms of the GNU General Public License as published by
14
 * the Free Software Foundation; either version 2 of the License, or
15
 * (at your option) any later version
16
 *
17
 * opensips is distributed in the hope that it will be useful,
18
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20
 * GNU General Public License for more details.
21
 *
22
 * You should have received a copy of the GNU General Public License
23
 * along with this program; if not, write to the Free Software
24
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
25
 *
26
 * History:
27
 * --------
28
 * 2003-04-26 ZSW (jiri)
29
 */
30
31
32
#include <string.h>        /* memset */
33
#include <stdio.h>         /* printf */
34
#include "../mem/mem.h"    /* pkg_malloc, pkg_free */
35
#include "../dprint.h"
36
#include "../trim.h"       /* trim_leading */
37
#include "../ut.h"
38
#include "../errinfo.h"
39
#include "parse_event.h"
40
41
42
0
#define PRES_STR "presence"
43
0
#define PRES_STR_LEN 8
44
45
0
#define PRES_WINFO_STR "presence.winfo"
46
0
#define PRES_WINFO_STR_LEN 14
47
48
0
#define PRES_XCAP_DIFF_STR "xcap-diff"
49
0
#define PRES_XCAP_DIFF_STR_LEN 9
50
51
0
#define PRES_SIP_PROFILE_STR "sip-profile"
52
0
#define PRES_SIP_PROFILE_STR_LEN 11
53
54
0
#define MWI_STR "message-summary"
55
0
#define MWI_STR_LEN 15
56
57
0
#define DIALOG_STR "dialog"
58
0
#define DIALOG_STR_LEN 6
59
60
#define DIALOG_SLA_STR "dialog;sla"
61
#define DIALOG_SLA_STR_LEN 10
62
63
0
#define CALL_INFO_STR "call-info"
64
0
#define CALL_INFO_STR_LEN 9
65
66
0
#define LINE_SEIZE_STR "line-seize"
67
0
#define LINE_SEIZE_STR_LEN 10
68
69
0
#define AS_FEATURE_STR "as-feature-event"
70
0
#define AS_FEATURE_LEN 16
71
72
0
#define REFER_STR "refer"
73
0
#define REFER_STR_LEN 5
74
75
0
#define REG_STR "reg"
76
0
#define REG_STR_LEN 3
77
78
79
static inline char* skip_token(char* _b, int _l)
80
0
{
81
0
  int i = 0;
82
83
0
  for(i = 0; i < _l; i++) {
84
0
    switch(_b[i]) {
85
0
    case ' ':
86
0
    case '\r':
87
0
    case '\n':
88
0
    case '\t':
89
0
    case ';':
90
0
      return _b + i;
91
0
    }
92
0
  }
93
94
0
  return _b + _l;
95
0
}
96
97
98
int event_parser(char* _s, int _l, event_t* _e)
99
0
{
100
0
  str tmp;
101
0
  char* end;
102
0
  param_hooks_t phooks;
103
104
0
  tmp.s = _s;
105
0
  tmp.len = _l;
106
107
0
  trim_leading(&tmp);
108
109
0
  if (tmp.len == 0) {
110
0
    LM_ERR("empty body\n");
111
0
    goto parse_error;
112
0
  }
113
114
0
  _e->text.s = tmp.s;
115
116
0
  end = skip_token(tmp.s, tmp.len);
117
118
0
  _e->text.len = end - tmp.s;
119
120
0
  if ((_e->text.len == PRES_STR_LEN) &&
121
0
    !strncasecmp(PRES_STR, tmp.s, _e->text.len)) {
122
0
    _e->parsed = EVENT_PRESENCE;
123
0
  } else if ((_e->text.len == PRES_XCAP_DIFF_STR_LEN) &&
124
0
       !strncasecmp(PRES_XCAP_DIFF_STR, tmp.s, _e->text.len)) {
125
0
    _e->parsed = EVENT_XCAP_DIFF;
126
0
  } else if ((_e->text.len == PRES_WINFO_STR_LEN) &&
127
0
       !strncasecmp(PRES_WINFO_STR, tmp.s, _e->text.len)) {
128
0
    _e->parsed = EVENT_PRESENCE_WINFO;
129
0
  } else if ((_e->text.len == PRES_SIP_PROFILE_STR_LEN) &&
130
0
       !strncasecmp(PRES_SIP_PROFILE_STR, tmp.s, _e->text.len)) {
131
0
    _e->parsed = EVENT_SIP_PROFILE;
132
0
  } else if ((_e->text.len == DIALOG_STR_LEN) &&
133
0
       !strncasecmp(DIALOG_STR, tmp.s, _e->text.len)) {
134
0
    _e->parsed = EVENT_DIALOG;
135
0
  } else if ((_e->text.len == MWI_STR_LEN) &&
136
0
       !strncasecmp(MWI_STR, tmp.s, _e->text.len)) {
137
0
    _e->parsed = EVENT_MWI;
138
0
  } else if ((_e->text.len == CALL_INFO_STR_LEN) &&
139
0
       !strncasecmp(CALL_INFO_STR, tmp.s, _e->text.len)) {
140
0
    _e->parsed = EVENT_CALL_INFO;
141
0
  } else if ((_e->text.len == LINE_SEIZE_STR_LEN) &&
142
0
       !strncasecmp(LINE_SEIZE_STR, tmp.s, _e->text.len)) {
143
0
    _e->parsed = EVENT_LINE_SEIZE;
144
0
  } else if ((_e->text.len == AS_FEATURE_LEN) &&
145
0
       !strncasecmp(AS_FEATURE_STR, tmp.s, _e->text.len)) {
146
0
    _e->parsed = EVENT_AS_FEATURE;
147
0
  } else if ((_e->text.len == REFER_STR_LEN) &&
148
0
       !strncasecmp(REFER_STR, tmp.s, _e->text.len)) {
149
0
    _e->parsed = EVENT_REFER;
150
0
  } else if ((_e->text.len == REG_STR_LEN) &&
151
0
       !strncasecmp(REG_STR, tmp.s, _e->text.len)) {
152
0
    _e->parsed = EVENT_REG;
153
0
  } else {
154
0
    _e->parsed = EVENT_OTHER;
155
0
  }
156
157
0
  if( (_e->text.len < tmp.len) && (*end)== ';')
158
0
  {
159
0
    str params_str;
160
0
    params_str.s = end+1;
161
0
    params_str.len = tmp.len- _e->text.len- 1;
162
163
0
    if (parse_params(&params_str, CLASS_ANY, &phooks, &_e->params)<0)
164
0
      goto parse_error;
165
166
0
    if(_e->parsed == EVENT_DIALOG && _e->params!= NULL
167
0
    && _e->params->name.len== 3 &&
168
0
    strncasecmp(_e->params->name.s, "sla", 3)== 0 )
169
0
    {
170
0
      _e->parsed = EVENT_DIALOG_SLA;
171
0
    }
172
0
  } else {
173
0
    _e->params= NULL;
174
0
  }
175
176
0
  return 0;
177
178
0
parse_error:
179
0
  return -1;
180
0
}
181
182
183
/*
184
 * Parse Event header field body
185
 */
186
int parse_event(struct hdr_field* _h)
187
0
{
188
0
  event_t* e;
189
190
0
  if (_h->parsed != 0) {
191
0
    return 0;
192
0
  }
193
194
0
  e = (event_t*)pkg_malloc(sizeof(event_t));
195
0
  if (e == 0) {
196
0
    LM_ERR("no pkg memory left\n");
197
0
    return -1;
198
0
  }
199
200
0
  memset(e, 0, sizeof(event_t));
201
202
0
  if (event_parser(_h->body.s, _h->body.len, e) < 0) {
203
0
    LM_ERR("event_parser failed\n");
204
0
    pkg_free(e);
205
0
    set_err_info(OSER_EC_PARSER, OSER_EL_MEDIUM,
206
0
      "error parsing EVENT header");
207
0
    set_err_reply(400, "bad headers");
208
0
    return -2;
209
0
  }
210
211
0
  _h->parsed = (void*)e;
212
0
  return 0;
213
0
}
214
215
216
/*
217
 * Free all memory
218
 */
219
void free_event(event_t** _e)
220
0
{
221
0
  if (*_e)
222
0
  {
223
0
    if((*_e)->params)
224
0
      free_params((*_e)->params);
225
0
    pkg_free(*_e);
226
0
  }
227
0
  *_e = 0;
228
0
}
229
230
231
/*
232
 * Print structure, for debugging only
233
 */
234
void print_event(event_t* _e)
235
0
{
236
0
  printf("===Event===\n");
237
0
  printf("text  : \'%.*s\'\n", _e->text.len, ZSW(_e->text.s));
238
0
  printf("parsed: %s\n",
239
0
         (_e->parsed == EVENT_PRESENCE) ? ("EVENT_PRESENCE") : ("EVENT_OTHER"));
240
0
  printf("===/Event===\n");
241
0
}