~ubuntu-branches/ubuntu/utopic/sip-tester/utopic

« back to all changes in this revision

Viewing changes to .pc/include-limits.patch/scenario.cpp

  • Committer: Package Import Robot
  • Author(s): Mark Purcell, Paul Belanger, Mark Purcell
  • Date: 2011-11-03 21:56:17 UTC
  • mfrom: (1.1.7)
  • Revision ID: package-import@ubuntu.com-20111103215617-nnxicj1oto9e8ix5
Tags: 1:3.2-1
[ Paul Belanger ]
* New Upstream Release (Closes: #623915).
* Switch to dpkg-source 3.0 (quilt) format
* Building with PCAP play.
* Switch back to Debhelper.
* debian/patches/spelling-error-in-binary: Fix lintian warning

[ Mark Purcell ]
* Drop pabs from Uploaders: at his request
* fix debhelper-overrides-need-versioned-build-depends
* fix description-synopsis-starts-with-article

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *  This program is free software; you can redistribute it and/or modify
 
3
 *  it under the terms of the GNU General Public License as published by
 
4
 *  the Free Software Foundation; either version 2 of the License, or
 
5
 *  (at your option) any later version.
 
6
 *
 
7
 *  This program is distributed in the hope that it will be useful,
 
8
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
9
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
10
 *  GNU General Public License for more details.
 
11
 *
 
12
 *  You should have received a copy of the GNU General Public License
 
13
 *  along with this program; if not, write to the Free Software
 
14
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
15
 *
 
16
 *  Author : Richard GAYRAUD - 04 Nov 2003
 
17
 *           Olivier Jacques
 
18
 *           From Hewlett Packard Company.
 
19
 *           Shriram Natarajan
 
20
 *           Peter Higginson
 
21
 *           Venkatesh
 
22
 *           Lee Ballard
 
23
 *           Guillaume TEISSIER from FTR&D
 
24
 *           Wolfgang Beck
 
25
 *           Marc Van Diest from Belgacom
 
26
 *           Charles P. Wright from IBM Research
 
27
 *           Michael Stovenour
 
28
 */
 
29
 
 
30
#include <stdlib.h>
 
31
#include "sipp.hpp"
 
32
#include <gsl/gsl_rng.h>
 
33
#include <gsl/gsl_randist.h>
 
34
#include <gsl/gsl_cdf.h>
 
35
 
 
36
/************************ Class Constructor *************************/
 
37
 
 
38
message::message(int index, const char *desc)
 
39
{
 
40
  this->index = index;
 
41
  this->desc = desc;
 
42
  pause_distribution = NULL;
 
43
  pause_variable = -1;
 
44
  pause_desc = NULL;
 
45
  sessions = 0;
 
46
  bShouldRecordRoutes = 0;
 
47
#ifdef _USE_OPENSSL
 
48
  bShouldAuthenticate = 0;
 
49
#endif
 
50
 
 
51
  send_scheme = NULL;
 
52
  retrans_delay = 0;
 
53
  timeout = 0;
 
54
 
 
55
  recv_response = 0;
 
56
  recv_request = NULL;
 
57
  optional = 0;
 
58
  advance_state = true;
 
59
  regexp_match = 0;
 
60
  regexp_compile = NULL;
 
61
 
 
62
  /* Anyway */
 
63
  start_rtd = 0;
 
64
  stop_rtd  = 0;
 
65
  repeat_rtd = 0;
 
66
  lost = -1;
 
67
  crlf = 0;
 
68
  hide = 0;
 
69
  display_str = NULL;
 
70
  test = -1;
 
71
  condexec = -1;
 
72
  condexec_inverse = false;
 
73
  chance = 0;/* meaning always */
 
74
  next = -1;
 
75
  nextLabel = NULL;
 
76
  on_timeout = -1;
 
77
  onTimeoutLabel = NULL;
 
78
  timewait = false;
 
79
 
 
80
/* 3pcc extended mode */
 
81
  peer_dest = NULL;
 
82
  peer_src = NULL;
 
83
 
 
84
  /* Statistics */
 
85
  nb_sent = 0;
 
86
  nb_recv = 0;
 
87
  nb_sent_retrans = 0;
 
88
  nb_recv_retrans = 0;
 
89
  nb_timeout = 0;
 
90
  nb_unexp = 0;
 
91
  nb_lost = 0;
 
92
  counter = 0;
 
93
 
 
94
  M_actions = NULL;
 
95
 
 
96
  M_type = 0;
 
97
 
 
98
  M_sendCmdData = NULL;
 
99
  M_nbCmdSent   = 0;
 
100
  M_nbCmdRecv   = 0;
 
101
 
 
102
  content_length_flag = ContentLengthNoPresent;
 
103
 
 
104
  /* How to match responses to this message. */
 
105
  start_txn = 0;
 
106
  response_txn = 0;
 
107
  ack_txn = 0;
 
108
  recv_response_for_cseq_method_list = NULL;
 
109
}
 
110
 
 
111
message::~message()
 
112
{
 
113
  if(M_actions != NULL)
 
114
    delete(M_actions);
 
115
 
 
116
  if(send_scheme != NULL)
 
117
    delete send_scheme;
 
118
 
 
119
  if(recv_request != NULL)
 
120
    free (recv_request);
 
121
 
 
122
  if(regexp_compile != NULL)
 
123
    regfree(regexp_compile);
 
124
    free(regexp_compile);
 
125
 
 
126
 
 
127
  if (pause_distribution) {
 
128
    delete pause_distribution;
 
129
  }
 
130
 
 
131
  if(M_sendCmdData != NULL)
 
132
    delete M_sendCmdData;
 
133
 
 
134
  free(display_str);
 
135
  free(peer_dest);
 
136
  free(peer_src);
 
137
  free(pause_desc);
 
138
  free(recv_response_for_cseq_method_list);
 
139
}
 
140
 
 
141
/******** Global variables which compose the scenario file **********/
 
142
 
 
143
scenario      *main_scenario;
 
144
scenario      *ooc_scenario;
 
145
scenario      *display_scenario;
 
146
 
 
147
/* This mode setting refers to whether we open calls autonomously (MODE_CLIENT)
 
148
 * or in response to requests (MODE_SERVER). */
 
149
int           creationMode  = MODE_CLIENT;
 
150
/* Send mode. Do we send to a fixed address or to the last one we got. */
 
151
int           sendMode  = MODE_CLIENT;
 
152
/* This describes what our 3PCC behavior is. */
 
153
int           thirdPartyMode = MODE_3PCC_NONE;
 
154
 
 
155
/*************** Helper functions for various types *****************/
 
156
long get_long(const char *ptr, const char *what) {
 
157
  char *endptr;
 
158
  long ret;
 
159
 
 
160
  ret = strtol(ptr, &endptr, 0);
 
161
  if (*endptr) {
 
162
    ERROR("%s, \"%s\" is not a valid integer!\n", what, ptr);
 
163
  }
 
164
  return ret;
 
165
}
 
166
 
 
167
unsigned long long get_long_long(const char *ptr, const char *what) {
 
168
  char *endptr;
 
169
  unsigned long long ret;
 
170
 
 
171
  ret = strtoull(ptr, &endptr, 0);
 
172
  if (*endptr) {
 
173
    ERROR("%s, \"%s\" is not a valid integer!\n", what, ptr);
 
174
  }
 
175
  return ret;
 
176
}
 
177
 
 
178
/* This function returns a time in milliseconds from a string.
 
179
 * The multiplier is used to convert from the default input type into
 
180
 * milliseconds.  For example, for seconds you should use 1000 and for
 
181
 * milliseconds use 1. */
 
182
long get_time(const char *ptr, const char *what, int multiplier) {
 
183
  char *endptr;
 
184
  const char *p;
 
185
  long ret;
 
186
  double dret;
 
187
  int i;
 
188
 
 
189
  if (!isdigit(*ptr)) {
 
190
    ERROR("%s, \"%s\" is not a valid time!\n", what, ptr);
 
191
  }
 
192
 
 
193
  for (i = 0, p = ptr; *p; p++) {
 
194
        if (*p == ':') {
 
195
                i++;
 
196
        }
 
197
  }
 
198
 
 
199
  if (i == 1) { /* mm:ss */
 
200
    ERROR("%s, \"%s\" mm:ss not implemented yet!\n", what, ptr);
 
201
  }
 
202
  else if (i == 2) { /* hh:mm:ss */
 
203
    ERROR("%s, \"%s\" hh:mm:ss not implemented yet!\n", what, ptr);
 
204
  } else if (i != 0) {
 
205
    ERROR("%s, \"%s\" is not a valid time!\n", what, ptr);
 
206
  }
 
207
 
 
208
  dret = strtod(ptr, &endptr);
 
209
  if (*endptr) {
 
210
    if (!strcmp(endptr, "s")) { /* Seconds */
 
211
        ret = (long)(dret * 1000);
 
212
    } else if (!strcmp(endptr, "ms")) { /* Milliseconds. */
 
213
        ret = (long)dret;
 
214
    } else if (!strcmp(endptr, "m")) { /* Minutes. */
 
215
        ret = (long)(dret * 60000);
 
216
    } else if (!strcmp(endptr, "h")) { /* Hours. */
 
217
        ret = (long)(dret * 60 * 60 * 1000);
 
218
    } else {
 
219
      ERROR("%s, \"%s\" is not a valid time!\n", what, ptr);
 
220
    }
 
221
  } else {
 
222
    ret = (long)(dret * multiplier);
 
223
  }
 
224
  return ret;
 
225
}
 
226
 
 
227
double get_double(const char *ptr, const char *what) {
 
228
  char *endptr;
 
229
  double ret;
 
230
 
 
231
  ret = strtod(ptr, &endptr);
 
232
  if (*endptr) {
 
233
    ERROR("%s, \"%s\" is not a floating point number!\n", what, ptr);
 
234
  }
 
235
  return ret;
 
236
}
 
237
 
 
238
char * xp_get_string(const char *name, const char *what) {
 
239
  char *ptr;
 
240
 
 
241
  if (!(ptr = xp_get_value(name))) {
 
242
    ERROR("%s is missing the required '%s' parameter.", what, name);
 
243
  }
 
244
 
 
245
  return strdup(ptr);
 
246
}
 
247
 
 
248
double xp_get_double(const char *name, const char *what) {
 
249
  char *ptr;
 
250
  char *helptext;
 
251
  double val;
 
252
 
 
253
  if (!(ptr = xp_get_value(name))) {
 
254
    ERROR("%s is missing the required '%s' parameter.", what, name);
 
255
  }
 
256
  helptext = (char *)malloc(100 + strlen(name) + strlen(what));
 
257
  sprintf(helptext, "%s '%s' parameter", what, name);
 
258
  val = get_double(ptr, helptext);
 
259
  free(helptext);
 
260
 
 
261
  return val;
 
262
}
 
263
 
 
264
double xp_get_double(const char *name, const char *what, double defval) {
 
265
  if (!(xp_get_value(name))) {
 
266
    return defval;
 
267
  }
 
268
  return xp_get_double(name, what);
 
269
}
 
270
 
 
271
long xp_get_long(const char *name, const char *what) {
 
272
  char *ptr;
 
273
  char *helptext;
 
274
  long val;
 
275
 
 
276
  if (!(ptr = xp_get_value(name))) {
 
277
    ERROR("%s is missing the required '%s' parameter.", what, name);
 
278
  }
 
279
  helptext = (char *)malloc(100 + strlen(name) + strlen(what));
 
280
  sprintf(helptext, "%s '%s' parameter", what, name);
 
281
  val = get_long(ptr, helptext);
 
282
  free(helptext);
 
283
 
 
284
  return val;
 
285
}
 
286
 
 
287
long xp_get_long(const char *name, const char *what, long defval) {
 
288
  if (!(xp_get_value(name))) {
 
289
    return defval;
 
290
  }
 
291
  return xp_get_long(name, what);
 
292
}
 
293
 
 
294
 
 
295
double xp_get_bool(const char *name, const char *what) {
 
296
  char *ptr;
 
297
  char *helptext;
 
298
  bool val;
 
299
 
 
300
  if (!(ptr = xp_get_value(name))) {
 
301
    ERROR("%s is missing the required '%s' parameter.", what, name);
 
302
  }
 
303
  helptext = (char *)malloc(100 + strlen(name) + strlen(what));
 
304
  sprintf(helptext, "%s '%s' parameter", what, name);
 
305
  val = get_bool(ptr, helptext);
 
306
  free(helptext);
 
307
 
 
308
  return val;
 
309
}
 
310
 
 
311
double xp_get_bool(const char *name, const char *what, bool defval) {
 
312
  if (!(xp_get_value(name))) {
 
313
    return defval;
 
314
  }
 
315
  return xp_get_bool(name, what);
 
316
}
 
317
 
 
318
int scenario::get_txn(const char *txnName, const char *what, bool start, bool isInvite, bool isAck) {
 
319
  /* Check the name's validity. */
 
320
  if (txnName[0] == '\0') {
 
321
    ERROR("Variable names may not be empty for %s\n", what);
 
322
  }
 
323
  if (strcspn(txnName, "$,") != strlen(txnName)) {
 
324
    ERROR("Variable names may not contain $ or , for %s\n", what);
 
325
  }
 
326
 
 
327
  /* If this transaction has already been used, then we have nothing to do. */
 
328
  str_int_map::iterator txn_it = txnMap.find(txnName);
 
329
  if (txn_it != txnMap.end()) {
 
330
    if (start) {
 
331
      /* We need to fill in the invite field. */
 
332
      transactions[txn_it->second - 1].started++;
 
333
    } else if (isAck) {
 
334
      transactions[txn_it->second - 1].acks++;
 
335
    } else {
 
336
      transactions[txn_it->second - 1].responses++;
 
337
    }
 
338
    return txn_it->second;
 
339
  }
 
340
 
 
341
  /* Assign this variable the next slot. */
 
342
  struct txnControlInfo transaction;
 
343
 
 
344
  transaction.name = strdup(txnName);
 
345
  if (start) {
 
346
    transaction.started = 1;
 
347
    transaction.responses = 0;
 
348
    transaction.acks = 0;
 
349
    transaction.isInvite = isInvite;
 
350
  } else if (isAck) {
 
351
    /* Does not start or respond to this txn. */
 
352
    transaction.started = 0;
 
353
    transaction.responses = 0;
 
354
    transaction.acks = 1;
 
355
    transaction.isInvite = false;
 
356
  } else {
 
357
    transaction.started = 0;
 
358
    transaction.responses = 1;
 
359
    transaction.acks = 0;
 
360
    transaction.isInvite = false;
 
361
  }
 
362
 
 
363
  transactions.push_back(transaction);
 
364
  int txnNum = transactions.size();
 
365
  txnMap[txnName] = txnNum;
 
366
 
 
367
  return txnNum;
 
368
}
 
369
 
 
370
int scenario::find_var(const char *varName, const char *what) {
 
371
  return allocVars->find(varName, false);
 
372
}
 
373
 
 
374
int scenario::get_var(const char *varName, const char *what) {
 
375
  /* Check the name's validity. */
 
376
  if (varName[0] == '\0') {
 
377
    ERROR("Transaction names may not be empty for %s\n", what);
 
378
  }
 
379
  if (strcspn(varName, "$,") != strlen(varName)) {
 
380
    ERROR("Transaction names may not contain $ or , for %s\n", what);
 
381
  }
 
382
 
 
383
  return allocVars->find(varName, true);
 
384
}
 
385
 
 
386
int scenario::xp_get_var(const char *name, const char *what) {
 
387
  char *ptr;
 
388
 
 
389
  if (!(ptr = xp_get_value(name))) {
 
390
    ERROR("%s is missing the required '%s' variable parameter.", what, name);
 
391
  }
 
392
 
 
393
  return get_var(ptr, what);
 
394
}
 
395
 
 
396
int xp_get_optional(const char *name, const char *what) {
 
397
  char *ptr = xp_get_value(name);
 
398
 
 
399
  if (!(ptr = xp_get_value(name))) {
 
400
    return OPTIONAL_FALSE;
 
401
  }
 
402
 
 
403
  if(!strcmp(ptr, "true")) {
 
404
    return OPTIONAL_TRUE;
 
405
  } else if(!strcmp(ptr, "global")) {
 
406
    return OPTIONAL_GLOBAL;
 
407
  } else if(!strcmp(ptr, "false")) {
 
408
    return OPTIONAL_FALSE;
 
409
  } else {
 
410
    ERROR("Could not understand optional value for %s: %s", what, ptr);
 
411
  }
 
412
 
 
413
  return OPTIONAL_FALSE;
 
414
}
 
415
 
 
416
 
 
417
int scenario::xp_get_var(const char *name, const char *what, int defval) {
 
418
  char *ptr;
 
419
 
 
420
  if (!(ptr = xp_get_value(name))) {
 
421
        return defval;
 
422
  }
 
423
 
 
424
  return xp_get_var(name, what);
 
425
}
 
426
 
 
427
bool get_bool(const char *ptr, const char *what) {
 
428
  char *endptr;
 
429
  long ret;
 
430
 
 
431
  if (!strcmp(ptr, "true")) {
 
432
    return true;
 
433
  }
 
434
  if (!strcmp(ptr, "false")) {
 
435
    return false;
 
436
  }
 
437
 
 
438
  ret = strtol(ptr, &endptr, 0);
 
439
  if (*endptr) {
 
440
    ERROR("%s, \"%s\" is not a valid boolean!\n", what, ptr);
 
441
  }
 
442
  return ret ? true : false;
 
443
}
 
444
 
 
445
/* Pretty print a time. */
 
446
char *time_string(int ms) {
 
447
   static char tmp[20];
 
448
 
 
449
   if (ms < 10000) {
 
450
        snprintf(tmp, sizeof(tmp), "%dms", ms);
 
451
   } else if (ms < 100000) {
 
452
        snprintf(tmp, sizeof(tmp), "%.1fs", ((float)ms)/1000);
 
453
   } else {
 
454
        snprintf(tmp, sizeof(tmp), "%ds", ms/1000);
 
455
   }
 
456
 
 
457
   return tmp;
 
458
}
 
459
 
 
460
int time_string(double ms, char *res, int reslen) {
 
461
  if (ms < 10000) {
 
462
    /* Less then 10 seconds we represent accurately. */
 
463
    if ((int)(ms + 0.9999) == (int)(ms)) {
 
464
      /* We have an integer, or close enough to it. */
 
465
      return snprintf(res, reslen, "%dms", (int)ms);
 
466
    } else {
 
467
      if (ms < 1000) {
 
468
        return snprintf(res, reslen, "%.2lfms", ms);
 
469
      } else {
 
470
        return snprintf(res, reslen, "%.1lfms", ms);
 
471
      }
 
472
    }
 
473
  } else if (ms < 60000) {
 
474
    /* We round to 100ms for times less than a minute. */
 
475
    return snprintf(res, reslen, "%.1fs", ms/1000);
 
476
  } else if (ms < 60 * 60000) {
 
477
    /* We round to 1s for times more than a minute. */
 
478
    int s = (unsigned int)(ms / 1000);
 
479
    int m = s / 60;
 
480
    s %= 60;
 
481
    return snprintf(res, reslen, "%d:%02d", m, s);
 
482
  } else {
 
483
    int s = (unsigned int)(ms / 1000);
 
484
    int m = s / 60;
 
485
    int h = m / 60;
 
486
    s %= 60;
 
487
    m %= 60;
 
488
    return snprintf(res, reslen, "%d:%02d:%02d", h, m, s);
 
489
  }
 
490
}
 
491
 
 
492
char *double_time_string(double ms) {
 
493
   static char tmp[20];
 
494
 
 
495
   if (ms < 1000) {
 
496
        snprintf(tmp, sizeof(tmp), "%.2lfms", ms);
 
497
   } else if (ms < 10000) {
 
498
        snprintf(tmp, sizeof(tmp), "%.1lfms", ms);
 
499
   } else if (ms < 100000) {
 
500
        snprintf(tmp, sizeof(tmp), "%.1lfs", ms / 1000);
 
501
   } else {
 
502
        snprintf(tmp, sizeof(tmp), "%ds", (int)(ms/1000));
 
503
   }
 
504
 
 
505
   return tmp;
 
506
}
 
507
 
 
508
/* For backwards compatibility, we assign "true" to slot 1, false to 0, and
 
509
 * allow other valid integers. */
 
510
int scenario::get_rtd(const char *ptr, bool start) {
 
511
  if(!strcmp(ptr, (char *)"false"))
 
512
    return 0;
 
513
 
 
514
  if(!strcmp(ptr, (char *)"true"))
 
515
    return stats->findRtd("1", start);
 
516
 
 
517
  return stats->findRtd(ptr, start);
 
518
}
 
519
 
 
520
/* Get a counter */
 
521
int scenario::get_counter(const char *ptr, const char *what) {
 
522
  /* Check the name's validity. */
 
523
  if (ptr[0] == '\0') {
 
524
    ERROR("Counter names names may not be empty for %s\n", what);
 
525
  }
 
526
  if (strcspn(ptr, "$,") != strlen(ptr)) {
 
527
    ERROR("Counter names may not contain $ or , for %s\n", what);
 
528
  }
 
529
 
 
530
  return stats->findCounter(ptr, true);
 
531
}
 
532
 
 
533
 
 
534
/* Some validation functions. */
 
535
 
 
536
void scenario::validate_variable_usage() {
 
537
  allocVars->validate();
 
538
}
 
539
 
 
540
void scenario::validate_txn_usage() {
 
541
  for (unsigned int i = 0; i < transactions.size(); i++) {
 
542
    if(transactions[i].started == 0) {
 
543
      ERROR("Transaction %s is never started!\n", transactions[i].name);
 
544
    } else if(transactions[i].responses == 0) {
 
545
      ERROR("Transaction %s has no responses defined!\n", transactions[i].name);
 
546
    }
 
547
    if (transactions[i].isInvite && transactions[i].acks == 0) {
 
548
      ERROR("Transaction %s is an INVITE transaction without an ACK!\n", transactions[i].name);
 
549
    }
 
550
    if (!transactions[i].isInvite && (transactions[i].acks > 0)) {
 
551
      ERROR("Transaction %s is a non-INVITE transaction with an ACK!\n", transactions[i].name);
 
552
    }
 
553
  }
 
554
}
 
555
 
 
556
/* Apply the next and ontimeout labels according to our map. */
 
557
void scenario::apply_labels(msgvec v, str_int_map labels) {
 
558
  for (unsigned int i = 0; i < v.size(); i++) {
 
559
    if (v[i]->nextLabel) {
 
560
      str_int_map::iterator label_it = labels.find(v[i]->nextLabel);
 
561
      if (label_it == labels.end()) {
 
562
        ERROR("The label '%s' was not defined (index %d, next attribute)\n", v[i]->nextLabel, i);
 
563
      }
 
564
      v[i]->next = label_it->second;
 
565
    }
 
566
    if (v[i]->onTimeoutLabel) {
 
567
      str_int_map::iterator label_it = labels.find(v[i]->onTimeoutLabel);
 
568
      if (label_it == labels.end()) {
 
569
        ERROR("The label '%s' was not defined (index %d, ontimeout attribute)\n", v[i]->onTimeoutLabel, i);
 
570
      }
 
571
      v[i]->on_timeout = label_it->second;
 
572
    }
 
573
  }
 
574
}
 
575
 
 
576
int get_cr_number(char *src)
 
577
{
 
578
  int res=0;
 
579
  char *ptr = src;
 
580
  while(*ptr) {
 
581
    if(*ptr == '\n') res++;
 
582
    *ptr++;
 
583
  }
 
584
  return res;
 
585
}
 
586
 
 
587
char *clean_cdata(char *ptr, int *removed_crlf = NULL) {
 
588
  char * msg;
 
589
 
 
590
  while((*ptr == ' ') || (*ptr == '\t') || (*ptr == '\n')) ptr++;
 
591
 
 
592
  msg = (char *) malloc(strlen(ptr) + 3);
 
593
  if(!msg) { ERROR("Memory Overflow"); }
 
594
  strcpy(msg, ptr);
 
595
 
 
596
  ptr = msg + strlen(msg);
 
597
  ptr --;
 
598
 
 
599
  while((ptr >= msg) &&
 
600
      ((*ptr == ' ')  ||
 
601
       (*ptr == '\t') ||
 
602
       (*ptr == '\n'))) {
 
603
    if(*ptr == '\n' && removed_crlf) {
 
604
      (*removed_crlf)++;
 
605
    }
 
606
    *ptr-- = 0;
 
607
  }
 
608
 
 
609
  if(!strstr(msg, "\n\n")) {
 
610
    strcat(msg, "\n\n");
 
611
  }
 
612
 
 
613
  if(ptr == msg) {
 
614
    ERROR("Empty cdata in xml scenario file");
 
615
  }
 
616
  while ((ptr = strstr(msg, "\n "))) {
 
617
    memmove(ptr + 1, ptr + 2, strlen(ptr) - 1);
 
618
  }
 
619
  while ((ptr = strstr(msg, " \n"))) {
 
620
    memmove(ptr, ptr + 1, strlen(ptr));
 
621
  }
 
622
  while ((ptr = strstr(msg, "\n\t"))) {
 
623
    memmove(ptr + 1, ptr + 2, strlen(ptr) - 1);
 
624
  }
 
625
  while ((ptr = strstr(msg, "\t\n"))) {
 
626
    memmove(ptr, ptr + 1, strlen(ptr));
 
627
  }
 
628
 
 
629
  return msg;
 
630
}
 
631
 
 
632
 
 
633
 
 
634
/********************** Scenario File analyser **********************/
 
635
 
 
636
void scenario::checkOptionalRecv(char *elem, unsigned int scenario_file_cursor) {
 
637
  if (last_recv_optional) {
 
638
    ERROR("<recv> before <%s> sequence without a mandatory message. Please remove one 'optional=true' (element %d).", elem, scenario_file_cursor);
 
639
  }
 
640
  last_recv_optional = false;
 
641
}
 
642
 
 
643
scenario::scenario(char * filename, int deflt)
 
644
{
 
645
  char * elem;
 
646
  char *method_list = NULL;
 
647
  unsigned int scenario_file_cursor = 0;
 
648
  int    L_content_length = 0 ;
 
649
  char * peer; 
 
650
 
 
651
  last_recv_optional = false;
 
652
 
 
653
  if(filename) {
 
654
    if(!xp_set_xml_buffer_from_file(filename)) {
 
655
      ERROR("Unable to load or parse '%s' xml scenario file", filename);
 
656
    }
 
657
  } else {
 
658
    if(!xp_set_xml_buffer_from_string(default_scenario[deflt])) {
 
659
      ERROR("Unable to load default xml scenario file");
 
660
    }
 
661
  }
 
662
 
 
663
  stats = new CStat();
 
664
  allocVars = new AllocVariableTable(userVariables);
 
665
 
 
666
  hidedefault = false;
 
667
 
 
668
  elem = xp_open_element(0);
 
669
  if (!elem) {
 
670
    ERROR("No element in xml scenario file");
 
671
  }
 
672
  if(strcmp("scenario", elem)) {
 
673
    ERROR("No 'scenario' section in xml scenario file");
 
674
  }
 
675
 
 
676
  if(char *ptr = xp_get_value((char *)"name")) {
 
677
    name = strdup(ptr);
 
678
  } else {
 
679
    name = strdup("");
 
680
  }
 
681
 
 
682
  duration = 0;
 
683
  found_timewait = false;
 
684
 
 
685
  scenario_file_cursor = 0;
 
686
 
 
687
  while ((elem = xp_open_element(scenario_file_cursor))) {
 
688
    char * ptr;
 
689
    scenario_file_cursor ++;
 
690
 
 
691
    if(!strcmp(elem, "CallLengthRepartition")) {
 
692
      ptr = xp_get_string("value", "CallLengthRepartition");
 
693
      stats->setRepartitionCallLength(ptr);
 
694
      free(ptr);
 
695
    } else if(!strcmp(elem, "ResponseTimeRepartition")) {
 
696
      ptr = xp_get_string("value", "ResponseTimeRepartition");
 
697
      stats->setRepartitionResponseTime(ptr);
 
698
      free(ptr);
 
699
    } else if(!strcmp(elem, "Global")) {
 
700
      ptr = xp_get_string("variables", "Global");
 
701
 
 
702
      char **       currentTabVarName = NULL;
 
703
      int           currentNbVarNames;
 
704
 
 
705
      createStringTable(ptr, &currentTabVarName, &currentNbVarNames);
 
706
      for (int i = 0; i < currentNbVarNames; i++) {
 
707
        globalVariables->find(currentTabVarName[i], true);
 
708
      }
 
709
      freeStringTable(currentTabVarName, currentNbVarNames);
 
710
      free(ptr);
 
711
    } else if(!strcmp(elem, "User")) {
 
712
      ptr = xp_get_string("variables", "User");
 
713
 
 
714
      char **       currentTabVarName = NULL;
 
715
      int           currentNbVarNames;
 
716
 
 
717
      createStringTable(ptr, &currentTabVarName, &currentNbVarNames);
 
718
      for (int i = 0; i < currentNbVarNames; i++) {
 
719
        userVariables->find(currentTabVarName[i], true);
 
720
      }
 
721
      freeStringTable(currentTabVarName, currentNbVarNames);
 
722
      free(ptr);
 
723
    } else if(!strcmp(elem, "Reference")) {
 
724
      ptr = xp_get_string("variables", "Reference");
 
725
 
 
726
      char **       currentTabVarName = NULL;
 
727
      int           currentNbVarNames;
 
728
 
 
729
      createStringTable(ptr, &currentTabVarName, &currentNbVarNames);
 
730
      for (int i = 0; i < currentNbVarNames; i++) {
 
731
        int id = allocVars->find(currentTabVarName[i], false);
 
732
        if (id == -1) {
 
733
          ERROR("Could not reference non-existant variable '%s'", currentTabVarName[i]);
 
734
        }
 
735
      }
 
736
      freeStringTable(currentTabVarName, currentNbVarNames);
 
737
      free(ptr);
 
738
    } else if(!strcmp(elem, "DefaultMessage")) {
 
739
      char *id = xp_get_string("id", "DefaultMessage");
 
740
      if(!(ptr = xp_get_cdata())) {
 
741
        ERROR("No CDATA in 'send' section of xml scenario file");
 
742
      }
 
743
      char *msg = clean_cdata(ptr);
 
744
      set_default_message(id, msg);
 
745
      free(id);
 
746
      /* XXX: This should really be per scenario. */
 
747
    } else if(!strcmp(elem, "label")) {
 
748
      ptr = xp_get_string("id", "label");
 
749
      if (labelMap.find(ptr) != labelMap.end()) {
 
750
        ERROR("The label name '%s' is used twice.", ptr);
 
751
      }
 
752
      labelMap[ptr] = messages.size();
 
753
      free(ptr);
 
754
    } else if (!strcmp(elem, "init")) {
 
755
      /* We have an init section, which must be full of nops or labels. */
 
756
      int nop_cursor = 0;
 
757
      char *initelem;
 
758
      while ((initelem = xp_open_element(nop_cursor++))) {
 
759
        if (!strcmp(initelem, "nop")) {
 
760
          /* We should parse this. */
 
761
          message *nopmsg = new message(initmessages.size(), "scenario initialization");
 
762
          initmessages.push_back(nopmsg);
 
763
          nopmsg->M_type = MSG_TYPE_NOP;
 
764
          getCommonAttributes(nopmsg);
 
765
        } else if (!strcmp(initelem, "label")) {
 
766
          /* Add an init label. */
 
767
          ptr = xp_get_value((char *)"id");
 
768
          if (initLabelMap.find(ptr) != initLabelMap.end()) {
 
769
            ERROR("The label name '%s' is used twice.", ptr);
 
770
          }
 
771
          initLabelMap[ptr] = initmessages.size();
 
772
        } else {
 
773
          ERROR("Invalid element in an init stanza: '%s'", initelem);
 
774
        }
 
775
        xp_close_element();
 
776
      }
 
777
    } else { /** Message Case */
 
778
      if (found_timewait) {
 
779
        ERROR("<timewait> can only be the last message in a scenario!\n");
 
780
      }
 
781
      message *curmsg = new message(messages.size(), name ? name : "unknown scenario");
 
782
      messages.push_back(curmsg);
 
783
 
 
784
      if(!strcmp(elem, "send")) {
 
785
        checkOptionalRecv(elem, scenario_file_cursor);
 
786
        curmsg->M_type = MSG_TYPE_SEND;
 
787
        /* Sent messages descriptions */
 
788
        if(!(ptr = xp_get_cdata())) {
 
789
          ERROR("No CDATA in 'send' section of xml scenario file");
 
790
        }
 
791
 
 
792
        int removed_clrf = 0;
 
793
        char * msg = clean_cdata(ptr, &removed_clrf);
 
794
 
 
795
        L_content_length = xp_get_content_length(msg);
 
796
        switch (L_content_length) {
 
797
          case  -1 :
 
798
            // the msg does not contain content-length field
 
799
            break ;
 
800
          case  0 :
 
801
            curmsg -> content_length_flag =
 
802
              message::ContentLengthValueZero;   // Initialize to No present
 
803
            break ;
 
804
          default :
 
805
            curmsg -> content_length_flag =
 
806
              message::ContentLengthValueNoZero;   // Initialize to No present
 
807
            break ;
 
808
        }
 
809
 
 
810
        if((msg[strlen(msg) - 1] != '\n') && (removed_clrf)) {
 
811
          strcat(msg, "\n");
 
812
        }
 
813
        char *tsrc = msg;
 
814
        while(*tsrc++);
 
815
        curmsg -> send_scheme = new SendingMessage(this, msg);
 
816
        free(msg);
 
817
 
 
818
        // If this is a request we are sending, then store our transaction/method matching information.
 
819
        if (!curmsg->send_scheme->isResponse()) {
 
820
          char *method = curmsg->send_scheme->getMethod();
 
821
          bool isInvite = !strcmp(method, "INVITE");
 
822
          bool isAck = !strcmp(method, "ACK");
 
823
 
 
824
          if ((ptr = xp_get_value("start_txn"))) {
 
825
            if (isAck) {
 
826
                ERROR("An ACK message can not start a transaction!");
 
827
            }
 
828
            curmsg->start_txn = get_txn(ptr, "start transaction", true, isInvite, false);
 
829
          } else if ((ptr = xp_get_value("ack_txn"))) {
 
830
            if (!isAck) {
 
831
                ERROR("The ack_txn attribute is valid only for ACK messages!");
 
832
            }
 
833
            curmsg->ack_txn = get_txn(ptr, "ack transaction", false, false, true);
 
834
          } else {
 
835
            int len = method_list ? strlen(method_list) : 0;
 
836
            method_list = (char *)realloc(method_list, len + strlen(method) + 1);
 
837
            if (!method_list) {
 
838
                ERROR_NO("Out of memory allocating method_list!");
 
839
            }
 
840
            strcpy(method_list + len, method);
 
841
          }
 
842
        } else {
 
843
          if ((ptr = xp_get_value("start_txn"))) {
 
844
            ERROR("Responses can not start a transaction");
 
845
          }
 
846
          if ((ptr = xp_get_value("ack_txn"))) {
 
847
            ERROR("Responses can not ACK a transaction");
 
848
          }
 
849
        }
 
850
 
 
851
        if ((ptr = xp_get_value("response_txn"))) {
 
852
          ERROR("response_txn can only be used for recieved messages.");
 
853
        }
 
854
 
 
855
        curmsg -> retrans_delay = xp_get_long("retrans", "retransmission timer", 0);
 
856
        curmsg -> timeout = xp_get_long("timeout", "message send timeout", 0);
 
857
      } else if(!strcmp(elem, (char *)"recv")) {
 
858
        curmsg->M_type = MSG_TYPE_RECV;
 
859
        /* Received messages descriptions */
 
860
        if((ptr = xp_get_value((char *)"response"))) {
 
861
          curmsg ->recv_response = get_long(ptr, "response code");
 
862
          if (method_list) {
 
863
            curmsg->recv_response_for_cseq_method_list = strdup(method_list);
 
864
          }
 
865
          if ((ptr = xp_get_value("response_txn"))) {
 
866
            curmsg->response_txn = get_txn(ptr, "transaction response", false, false, false);
 
867
          }
 
868
        }
 
869
 
 
870
        if((ptr = xp_get_value((char *)"request"))) {
 
871
          curmsg -> recv_request = strdup(ptr);
 
872
          if ((ptr = xp_get_value("response_txn"))) {
 
873
            ERROR("response_txn can only be used for recieved responses.");
 
874
          }
 
875
        }
 
876
 
 
877
        curmsg->optional = xp_get_optional("optional", "recv");
 
878
        last_recv_optional = curmsg->optional;
 
879
        curmsg->advance_state = xp_get_bool("advance_state", "recv", true);
 
880
        if (!curmsg->advance_state && curmsg->optional == OPTIONAL_FALSE) {
 
881
          ERROR("advance_state is allowed only for optional messages (index = %d)\n", messages.size() - 1);
 
882
        }
 
883
 
 
884
        if (0 != (ptr = xp_get_value((char *)"regexp_match"))) {
 
885
          if(!strcmp(ptr, "true")) {
 
886
            curmsg -> regexp_match = 1;
 
887
          }
 
888
        }
 
889
 
 
890
        curmsg->timeout = xp_get_long("timeout", "message timeout", 0);
 
891
 
 
892
        /* record the route set  */
 
893
        /* TODO disallow optional and rrs to coexist? */
 
894
        if((ptr = xp_get_value((char *)"rrs"))) {
 
895
          curmsg -> bShouldRecordRoutes = get_bool(ptr, "record route set");
 
896
        }
 
897
 
 
898
        /* record the authentication credentials  */
 
899
        if((ptr = xp_get_value((char *)"auth"))) {
 
900
          bool temp = get_bool(ptr, "message authentication");
 
901
#ifdef _USE_OPENSSL
 
902
          curmsg -> bShouldAuthenticate = temp;
 
903
#else
 
904
          if (temp) {
 
905
            ERROR("Authentication requires OpenSSL support!");
 
906
          }
 
907
#endif
 
908
        }
 
909
      } else if(!strcmp(elem, "pause") || !strcmp(elem, "timewait")) {
 
910
        checkOptionalRecv(elem, scenario_file_cursor);
 
911
        curmsg->M_type = MSG_TYPE_PAUSE;
 
912
        if (!strcmp(elem, "timewait")) {
 
913
          curmsg->timewait = true;
 
914
          found_timewait = true;
 
915
        }
 
916
 
 
917
        int var;
 
918
        if ((var = xp_get_var("variable", "pause", -1)) != -1) {
 
919
          curmsg->pause_variable = var;
 
920
        } else {
 
921
          CSample *distribution = parse_distribution(true);
 
922
 
 
923
          bool sanity_check = xp_get_bool("sanity_check", "pause", true);
 
924
 
 
925
          double pause_duration = distribution->cdfInv(0.99);
 
926
          if (sanity_check && (pause_duration > INT_MAX)) {
 
927
            char percentile[100];
 
928
            char desc[100];
 
929
 
 
930
            distribution->timeDescr(desc, sizeof(desc));
 
931
            time_string(pause_duration, percentile, sizeof(percentile));
 
932
 
 
933
            ERROR("The distribution %s has a 99th percentile of %s, which is larger than INT_MAX.  You should chose different parameters.", desc, percentile);
 
934
          }
 
935
 
 
936
          curmsg->pause_distribution = distribution;
 
937
          /* Update scenario duration with max duration */
 
938
          duration += (int)pause_duration;
 
939
        }
 
940
      }
 
941
      else if(!strcmp(elem, "nop")) {
 
942
        checkOptionalRecv(elem, scenario_file_cursor);
 
943
        /* Does nothing at SIP level.  This message type can be used to handle
 
944
         * actions, increment counters, or for RTDs. */
 
945
        curmsg->M_type = MSG_TYPE_NOP;
 
946
      }
 
947
      else if(!strcmp(elem, "recvCmd")) {
 
948
        curmsg->M_type = MSG_TYPE_RECVCMD;
 
949
        curmsg->optional = xp_get_optional("optional", "recv");
 
950
        last_recv_optional = curmsg->optional;
 
951
 
 
952
        /* 3pcc extended mode */
 
953
        if((ptr = xp_get_value((char *)"src"))) {
 
954
           curmsg ->peer_src = strdup(ptr);
 
955
        } else if (extendedTwinSippMode) {
 
956
          ERROR("You must specify a 'src' for recvCmd when using extended 3pcc mode!");
 
957
        }
 
958
      } else if(!strcmp(elem, "sendCmd")) {
 
959
        checkOptionalRecv(elem, scenario_file_cursor);
 
960
        curmsg->M_type = MSG_TYPE_SENDCMD;
 
961
        /* Sent messages descriptions */
 
962
 
 
963
        /* 3pcc extended mode  */
 
964
        if((ptr = xp_get_value((char *)"dest"))) { 
 
965
           peer = strdup(ptr) ;
 
966
           curmsg ->peer_dest = peer ;
 
967
           peer_map::iterator peer_it;
 
968
           peer_it = peers.find(peer_map::key_type(peer));
 
969
           if(peer_it == peers.end())  /* the peer (slave or master)
 
970
                                          has not been added in the map
 
971
                                          (first occurence in the scenario) */
 
972
           {
 
973
             T_peer_infos infos;
 
974
             infos.peer_socket = 0;
 
975
             strcpy(infos.peer_host, get_peer_addr(peer));
 
976
             peers[std::string(peer)] = infos; 
 
977
           }
 
978
        } else if (extendedTwinSippMode) {
 
979
          ERROR("You must specify a 'dest' for sendCmd with extended 3pcc mode!");
 
980
        }
 
981
 
 
982
        if(!(ptr = xp_get_cdata())) {
 
983
          ERROR("No CDATA in 'sendCmd' section of xml scenario file");
 
984
        }
 
985
        char *msg = clean_cdata(ptr);
 
986
 
 
987
        curmsg -> M_sendCmdData = new SendingMessage(this, msg, true /* skip sanity */);
 
988
        free(msg);
 
989
      }
 
990
      else {
 
991
        ERROR("Unknown element '%s' in xml scenario file", elem);
 
992
      }
 
993
 
 
994
      getCommonAttributes(curmsg);
 
995
    } /** end * Message case */
 
996
    xp_close_element();
 
997
  } // end while
 
998
 
 
999
  free(method_list);
 
1000
 
 
1001
  str_int_map::iterator label_it = labelMap.find("_unexp.main");
 
1002
  if (label_it != labelMap.end()) {
 
1003
    unexpected_jump = label_it->second;
 
1004
  } else {
 
1005
    unexpected_jump = -1;
 
1006
  }
 
1007
  retaddr = find_var("_unexp.retaddr", "unexpected return address");
 
1008
  pausedaddr = find_var("_unexp.pausedaddr", "unexpected paused until");
 
1009
 
 
1010
  /* Patch up the labels. */
 
1011
  apply_labels(messages, labelMap);
 
1012
  apply_labels(initmessages, initLabelMap);
 
1013
 
 
1014
  /* Some post-scenario loading validation. */
 
1015
  stats->validateRtds();
 
1016
 
 
1017
  /* Make sure that all variables are used more than once. */
 
1018
  validate_variable_usage();
 
1019
 
 
1020
  /* Make sure that all started transactions have responses, and vice versa. */
 
1021
  validate_txn_usage();
 
1022
 
 
1023
  if (messages.size() == 0) {
 
1024
    ERROR("Did not find any messages inside of scenario!");
 
1025
  }
 
1026
}
 
1027
 
 
1028
void scenario::runInit() {
 
1029
  call *initcall;
 
1030
  if (initmessages.size() > 0) {
 
1031
    initcall = new call(main_scenario, NULL, NULL, "///main-init", 0, false, false, true);
 
1032
    initcall->run();
 
1033
  }
 
1034
}
 
1035
 
 
1036
void clear_int_str(int_str_map m) {
 
1037
  for(int_str_map::iterator it = m.begin(); it != m.end(); it = m.begin()) {
 
1038
    free(it->second);
 
1039
    m.erase(it);
 
1040
  }
 
1041
}
 
1042
 
 
1043
void clear_str_int(str_int_map m) {
 
1044
  for(str_int_map::iterator it = m.begin(); it != m.end(); it = m.begin()) {
 
1045
    m.erase(it);
 
1046
  }
 
1047
}
 
1048
 
 
1049
void clear_int_int(int_int_map m) {
 
1050
  for(int_int_map::iterator it = m.begin(); it != m.end(); it = m.begin()) {
 
1051
    m.erase(it);
 
1052
  }
 
1053
}
 
1054
 
 
1055
scenario::~scenario() {
 
1056
  for (msgvec::iterator i = messages.begin(); i != messages.end(); i++) {
 
1057
    delete *i;
 
1058
  }
 
1059
  messages.clear();
 
1060
 
 
1061
  free(name);
 
1062
 
 
1063
  allocVars->putTable();
 
1064
  delete stats;
 
1065
 
 
1066
  for (unsigned int i = 0; i < transactions.size(); i++) {
 
1067
    free(transactions[i].name);
 
1068
  }
 
1069
  transactions.clear();
 
1070
 
 
1071
  clear_str_int(labelMap);
 
1072
  clear_str_int(initLabelMap);
 
1073
  clear_str_int(txnMap);
 
1074
}
 
1075
 
 
1076
CSample *parse_distribution(bool oldstyle = false) {
 
1077
  CSample *distribution;
 
1078
  char *distname;
 
1079
  char *ptr;
 
1080
 
 
1081
  if(!(distname = xp_get_value("distribution"))) {
 
1082
    if (!oldstyle) {
 
1083
      ERROR("statistically distributed actions or pauses requires 'distribution' parameter");
 
1084
    }
 
1085
    if ((ptr = xp_get_value("normal"))) {
 
1086
        distname = "normal";
 
1087
    } else if ((ptr = xp_get_value("exponential"))) {
 
1088
        distname = "exponential";
 
1089
    } else if ((ptr = xp_get_value("lognormal"))) {
 
1090
        distname = "lognormal";
 
1091
    } else if ((ptr = xp_get_value("weibull"))) {
 
1092
        distname = "weibull";
 
1093
    } else if ((ptr = xp_get_value("pareto"))) {
 
1094
      distname = "pareto";
 
1095
    } else if ((ptr = xp_get_value("gamma"))) {
 
1096
      distname = "gamma";
 
1097
    } else if ((ptr = xp_get_value("min"))) {
 
1098
        distname = "uniform";
 
1099
    } else if ((ptr = xp_get_value("max"))) {
 
1100
        distname = "uniform";
 
1101
    } else if ((ptr = xp_get_value("milliseconds"))) {
 
1102
        double val = get_double(ptr, "Pause milliseconds");
 
1103
        return new CFixed(val);
 
1104
    } else {
 
1105
        return new CDefaultPause();
 
1106
    }
 
1107
  }
 
1108
 
 
1109
  if (!strcmp(distname, "fixed")) {
 
1110
    double value = xp_get_double("value", "Fixed distribution");
 
1111
    distribution = new CFixed(value);
 
1112
  } else if (!strcmp(distname, "uniform")) {
 
1113
    double min = xp_get_double("min", "Uniform distribution");
 
1114
    double max = xp_get_double("max", "Uniform distribution");
 
1115
    distribution = new CUniform(min, max);
 
1116
  } else if (!strcmp(distname, "normal")) {
 
1117
    double mean = xp_get_double("mean", "Normal distribution");
 
1118
    double stdev = xp_get_double("stdev", "Normal distribution");
 
1119
    distribution = new CNormal(mean, stdev);
 
1120
  } else if (!strcmp(distname, "lognormal")) {
 
1121
    double mean = xp_get_double("mean", "Lognormal distribution");
 
1122
    double stdev = xp_get_double("stdev", "Lognormal distribution");
 
1123
    distribution = new CLogNormal(mean, stdev);
 
1124
  } else if (!strcmp(distname, "exponential")) {
 
1125
    double mean = xp_get_double("mean", "Exponential distribution");
 
1126
    distribution = new CExponential(mean);
 
1127
  } else if (!strcmp(distname, "weibull")) {
 
1128
    double lambda = xp_get_double("lambda", "Weibull distribution");
 
1129
    double k = xp_get_double("k", "Weibull distribution");
 
1130
    distribution = new CWeibull(lambda, k);
 
1131
  } else if (!strcmp(distname, "pareto")) {
 
1132
    double k = xp_get_double("k", "Pareto distribution");
 
1133
    double xsubm = xp_get_double("x_m", "Pareto distribution");
 
1134
    distribution = new CPareto(k, xsubm);
 
1135
  } else if (!strcmp(distname, "gpareto")) {
 
1136
    double shape = xp_get_double("shape", "Generalized Pareto distribution");
 
1137
    double scale = xp_get_double("scale", "Generalized Pareto distribution");
 
1138
    double location = xp_get_double("location", "Generalized Pareto distribution");
 
1139
    distribution = new CGPareto(shape, scale, location);
 
1140
  } else if (!strcmp(distname, "gamma")) {
 
1141
    double k = xp_get_double("k", "Gamma distribution");
 
1142
    double theta = xp_get_double("theta", "Gamma distribution");
 
1143
    distribution = new CGamma(k, theta);
 
1144
  } else if (!strcmp(distname, "negbin")) {
 
1145
    double n = xp_get_double("n", "Negative Binomial distribution");
 
1146
    double p = xp_get_double("p", "Negative Binomial distribution");
 
1147
    distribution = new CNegBin(n, p);
 
1148
  } else {
 
1149
    ERROR("Unknown distribution: %s\n", ptr);
 
1150
  }
 
1151
 
 
1152
  return distribution;
 
1153
}
 
1154
 
 
1155
 
 
1156
 
 
1157
/* 3pcc extended mode:
 
1158
   get the correspondances between
 
1159
   slave and master names and their 
 
1160
   addresses */
 
1161
 
 
1162
void parse_slave_cfg()
 
1163
{
 
1164
  FILE * f;
 
1165
  char line[MAX_PEER_SIZE];
 
1166
  char * temp_peer;
 
1167
  char * temp_host;
 
1168
  char * peer_host;
 
1169
 
 
1170
  f = fopen(slave_cfg_file, "r");
 
1171
  if(f){
 
1172
     while (fgets(line, MAX_PEER_SIZE, f) != NULL)
 
1173
     {
 
1174
       if((temp_peer = strtok(line, ";"))) {
 
1175
         if((peer_host = (char *) malloc(MAX_PEER_SIZE))){
 
1176
           if((temp_host  = strtok(NULL, ";"))){
 
1177
              strcpy(peer_host, temp_host);
 
1178
              peer_addrs[std::string(temp_peer)] = peer_host;
 
1179
             }
 
1180
         }else {
 
1181
             ERROR("Cannot allocate memory!\n");
 
1182
           }
 
1183
       }
 
1184
     }
 
1185
   }else{
 
1186
     ERROR("Can not open slave_cfg file %s\n", slave_cfg_file);
 
1187
     }
 
1188
 
 
1189
}
 
1190
 
 
1191
// Determine in which mode the sipp tool has been 
 
1192
// launched (client, server, 3pcc client, 3pcc server, 3pcc extended master or slave)
 
1193
void scenario::computeSippMode()
 
1194
{
 
1195
  bool isRecvCmdFound = false;
 
1196
  bool isSendCmdFound = false;
 
1197
 
 
1198
  creationMode = -1;
 
1199
  sendMode = -1;
 
1200
  thirdPartyMode = MODE_3PCC_NONE;
 
1201
 
 
1202
  assert(messages.size() > 0);
 
1203
 
 
1204
  for(unsigned int i=0; i<messages.size(); i++)
 
1205
    {
 
1206
      switch(messages[i]->M_type)
 
1207
        {
 
1208
        case MSG_TYPE_PAUSE:
 
1209
        case MSG_TYPE_NOP:
 
1210
          /* Allow pauses or nops to go first. */
 
1211
          continue;
 
1212
        case MSG_TYPE_SEND:
 
1213
          if (sendMode == -1) {
 
1214
            sendMode = MODE_CLIENT;
 
1215
          }
 
1216
          if (creationMode == -1) {
 
1217
            creationMode = MODE_CLIENT;
 
1218
          }
 
1219
          break;
 
1220
 
 
1221
        case MSG_TYPE_RECV:
 
1222
          if (sendMode == -1) {
 
1223
            sendMode = MODE_SERVER;
 
1224
          }
 
1225
          if (creationMode == -1) {
 
1226
            creationMode = MODE_SERVER;
 
1227
          }
 
1228
          break;
 
1229
        case MSG_TYPE_SENDCMD:
 
1230
          isSendCmdFound = true;
 
1231
          if (creationMode == -1) {
 
1232
            creationMode = MODE_CLIENT;
 
1233
          }
 
1234
          if(!isRecvCmdFound) {
 
1235
            if (creationMode == MODE_SERVER) {
 
1236
              /*
 
1237
               * If it is a server already, then start it in
 
1238
               * 3PCC A passive mode
 
1239
               */
 
1240
               if(twinSippMode){
 
1241
                 thirdPartyMode = MODE_3PCC_A_PASSIVE;
 
1242
               }else if (extendedTwinSippMode){
 
1243
                 thirdPartyMode = MODE_MASTER_PASSIVE;
 
1244
               }
 
1245
            } else {
 
1246
                if(twinSippMode){
 
1247
                  thirdPartyMode = MODE_3PCC_CONTROLLER_A;
 
1248
                }else if (extendedTwinSippMode){
 
1249
                  thirdPartyMode = MODE_MASTER;
 
1250
                }
 
1251
            }
 
1252
            if((thirdPartyMode == MODE_MASTER_PASSIVE || thirdPartyMode == MODE_MASTER) && !master_name){
 
1253
              ERROR("Inconsistency between command line and scenario: master scenario but -master option not set\n");
 
1254
            }
 
1255
            if(!twinSippMode && !extendedTwinSippMode)
 
1256
              ERROR("sendCmd message found in scenario but no twin sipp"
 
1257
                    " address has been passed! Use -3pcc option or 3pcc extended mode.\n");
 
1258
          }
 
1259
          break;
 
1260
 
 
1261
        case MSG_TYPE_RECVCMD:
 
1262
          if (creationMode == -1) {
 
1263
            creationMode = MODE_SERVER;
 
1264
          }
 
1265
          isRecvCmdFound = true;
 
1266
          if(!isSendCmdFound)
 
1267
            {
 
1268
              if(twinSippMode){
 
1269
                thirdPartyMode = MODE_3PCC_CONTROLLER_B;
 
1270
              } else if(extendedTwinSippMode){
 
1271
                thirdPartyMode = MODE_SLAVE;
 
1272
                 if(!slave_number) {
 
1273
                   ERROR("Inconsistency between command line and scenario: slave scenario but -slave option not set\n");
 
1274
                 }else{
 
1275
                   thirdPartyMode = MODE_SLAVE;
 
1276
                 }
 
1277
              }
 
1278
              if(!twinSippMode && !extendedTwinSippMode)
 
1279
                ERROR("recvCmd message found in scenario but no "
 
1280
                      "twin sipp address has been passed! Use "
 
1281
                      "-3pcc option\n");
 
1282
            }
 
1283
          break;
 
1284
        default:
 
1285
          break;
 
1286
        }
 
1287
    }
 
1288
    if(creationMode == -1)
 
1289
      ERROR("Unable to determine creation mode of the tool (server, client)\n");
 
1290
    if(sendMode == -1)
 
1291
      ERROR("Unable to determine send mode of the tool (server, client)\n");
 
1292
}
 
1293
 
 
1294
void scenario::handle_rhs(CAction *tmpAction, char *what) {
 
1295
  if (xp_get_value("value")) {
 
1296
    tmpAction->setDoubleValue(xp_get_double("value", what));
 
1297
    if (xp_get_value("variable")) {
 
1298
      ERROR("Value and variable are mutually exclusive for %s action!", what);
 
1299
    }
 
1300
  } else if (xp_get_value("variable")) {
 
1301
    tmpAction->setVarInId(xp_get_var("variable", what));
 
1302
    if (xp_get_value("value")) {
 
1303
      ERROR("Value and variable are mutually exclusive for %s action!", what);
 
1304
    }
 
1305
  } else {
 
1306
    ERROR("No value or variable defined for %s action!", what);
 
1307
  }
 
1308
}
 
1309
 
 
1310
void scenario::handle_arithmetic(CAction *tmpAction, char *what) {
 
1311
  tmpAction->setVarId(xp_get_var("assign_to", what));
 
1312
  handle_rhs(tmpAction, what);
 
1313
}
 
1314
 
 
1315
void scenario::parseAction(CActions *actions) {
 
1316
  char *        actionElem;
 
1317
  unsigned int recvScenarioLen = 0;
 
1318
  char *        currentRegExp = NULL;
 
1319
  char *        buffer = NULL;
 
1320
  char **       currentTabVarName = NULL;
 
1321
  int           currentNbVarNames;
 
1322
  char * ptr;
 
1323
  int           sub_currentNbVarId;
 
1324
 
 
1325
  while((actionElem = xp_open_element(recvScenarioLen))) {
 
1326
    CAction *tmpAction = new CAction(this);
 
1327
 
 
1328
    if(!strcmp(actionElem, "ereg")) {
 
1329
      ptr = xp_get_string("regexp", "ereg");
 
1330
 
 
1331
      // keeping regexp expression in memory
 
1332
      if(currentRegExp != NULL)
 
1333
        delete[] currentRegExp;
 
1334
      currentRegExp = new char[strlen(ptr)+1];
 
1335
      buffer = new char[strlen(ptr)+1];
 
1336
      xp_replace(ptr, buffer, "&lt;", "<");
 
1337
      xp_replace(buffer, currentRegExp, "&gt;", ">");
 
1338
      if(buffer != NULL)
 
1339
        delete[] buffer;
 
1340
      tmpAction->setActionType(CAction::E_AT_ASSIGN_FROM_REGEXP);
 
1341
 
 
1342
      // warning - although these are detected for both msg and hdr
 
1343
      // they are only implemented for search_in="hdr"
 
1344
      tmpAction->setCaseIndep(xp_get_bool("case_indep", "ereg", false));
 
1345
      tmpAction->setHeadersOnly(xp_get_bool("start_line", "ereg", false));
 
1346
 
 
1347
      free(ptr);
 
1348
      if ( 0 != ( ptr = xp_get_value((char *)"search_in") ) ) {
 
1349
        tmpAction->setOccurence(1);
 
1350
 
 
1351
        if ( 0 == strcmp(ptr, (char *)"msg") ) {
 
1352
          tmpAction->setLookingPlace(CAction::E_LP_MSG);
 
1353
          tmpAction->setLookingChar (NULL);
 
1354
        } else if ( 0 == strcmp(ptr, (char *)"body") ) {
 
1355
          tmpAction->setLookingPlace(CAction::E_LP_BODY);
 
1356
          tmpAction->setLookingChar (NULL);
 
1357
        } else if (!strcmp(ptr, (char *)"var")) {
 
1358
          tmpAction->setVarInId(xp_get_var("variable", "ereg"));
 
1359
          tmpAction->setLookingPlace(CAction::E_LP_VAR);
 
1360
        } else if (!strcmp(ptr, (char *)"hdr")) {
 
1361
          ptr = xp_get_value((char *)"header");
 
1362
          if (!ptr || !strlen(ptr)) {
 
1363
            ERROR("search_in=\"hdr\" requires header field");
 
1364
          }
 
1365
          tmpAction->setLookingPlace(CAction::E_LP_HDR);
 
1366
          tmpAction->setLookingChar(ptr);
 
1367
          if (0 != (ptr = xp_get_value((char *)"occurence"))) {
 
1368
            tmpAction->setOccurence (atol(ptr));
 
1369
          }
 
1370
          if (0 != (ptr = xp_get_value((char *)"occurrence"))) {
 
1371
            tmpAction->setOccurence (atol(ptr));
 
1372
          }
 
1373
        } else {
 
1374
          ERROR("Unknown search_in value %s", ptr);
 
1375
        }
 
1376
      } else {
 
1377
        tmpAction->setLookingPlace(CAction::E_LP_MSG);
 
1378
        tmpAction->setLookingChar(NULL);
 
1379
      } // end if-else search_in
 
1380
 
 
1381
      if (xp_get_value("check_it")) {
 
1382
      tmpAction->setCheckIt(xp_get_bool("check_it", "ereg", false));
 
1383
          if (xp_get_value("check_it_inverse")) {
 
1384
              ERROR("Can not have both check_it and check_it_inverse for ereg!");
 
1385
          }
 
1386
      } else {
 
1387
          tmpAction->setCheckItInverse(xp_get_bool("check_it_inverse", "ereg", false));
 
1388
      }
 
1389
 
 
1390
      if (!(ptr = xp_get_value((char *) "assign_to"))) {
 
1391
        ERROR("assign_to value is missing");
 
1392
      }
 
1393
 
 
1394
      createStringTable(ptr, &currentTabVarName, &currentNbVarNames);
 
1395
 
 
1396
      int varId = get_var(currentTabVarName[0], "assign_to");
 
1397
      tmpAction->setVarId(varId);
 
1398
 
 
1399
      tmpAction->setRegExp(currentRegExp);
 
1400
      if (currentNbVarNames > 1 ) {
 
1401
        sub_currentNbVarId = currentNbVarNames - 1 ;
 
1402
        tmpAction->setNbSubVarId(sub_currentNbVarId);
 
1403
 
 
1404
        for(int i=1; i<= sub_currentNbVarId; i++) {
 
1405
          int varId = get_var(currentTabVarName[i], "sub expression assign_to");
 
1406
          tmpAction->setSubVarId(varId);
 
1407
        }
 
1408
      }
 
1409
 
 
1410
      freeStringTable(currentTabVarName, currentNbVarNames);
 
1411
 
 
1412
      if(currentRegExp != NULL) {
 
1413
        delete[] currentRegExp;
 
1414
      }
 
1415
      currentRegExp = NULL;
 
1416
    } /* end !strcmp(actionElem, "ereg") */ else if(!strcmp(actionElem, "log")) {
 
1417
      tmpAction->setMessage(xp_get_string("message", "log"));
 
1418
      tmpAction->setActionType(CAction::E_AT_LOG_TO_FILE);
 
1419
    } else if(!strcmp(actionElem, "warning")) {
 
1420
      tmpAction->setMessage(xp_get_string("message", "warning"));
 
1421
      tmpAction->setActionType(CAction::E_AT_LOG_WARNING);
 
1422
    } else if(!strcmp(actionElem, "error")) {
 
1423
      tmpAction->setMessage(xp_get_string("message", "error"));
 
1424
      tmpAction->setActionType(CAction::E_AT_LOG_ERROR);
 
1425
    } else if(!strcmp(actionElem, "assign")) {
 
1426
      tmpAction->setActionType(CAction::E_AT_ASSIGN_FROM_VALUE);
 
1427
      handle_arithmetic(tmpAction, "assign");
 
1428
    } else if(!strcmp(actionElem, "assignstr")) {
 
1429
      tmpAction->setActionType(CAction::E_AT_ASSIGN_FROM_STRING);
 
1430
      tmpAction->setVarId(xp_get_var("assign_to", "assignstr"));
 
1431
      tmpAction->setMessage(xp_get_string("value", "assignstr"));
 
1432
    } else if(!strcmp(actionElem, "gettimeofday")) {
 
1433
      tmpAction->setActionType(CAction::E_AT_ASSIGN_FROM_GETTIMEOFDAY);
 
1434
 
 
1435
      if (!(ptr = xp_get_value((char *) "assign_to"))) {
 
1436
        ERROR("assign_to value is missing");
 
1437
      }
 
1438
      createStringTable(ptr, &currentTabVarName, &currentNbVarNames);
 
1439
      if (currentNbVarNames != 2 ) {
 
1440
        ERROR("The gettimeofday action requires two output variables!");
 
1441
      }
 
1442
      tmpAction->setNbSubVarId(1);
 
1443
 
 
1444
      int varId = get_var(currentTabVarName[0], "gettimeofday seconds assign_to");
 
1445
      tmpAction->setVarId(varId);
 
1446
      varId = get_var(currentTabVarName[1], "gettimeofday useconds assign_to");
 
1447
      tmpAction->setSubVarId(varId);
 
1448
 
 
1449
      freeStringTable(currentTabVarName, currentNbVarNames);
 
1450
    } else if(!strcmp(actionElem, "index")) {
 
1451
      tmpAction->setVarId(xp_get_var("assign_to", "index"));
 
1452
      tmpAction->setActionType(CAction::E_AT_ASSIGN_FROM_INDEX);
 
1453
    } else if(!strcmp(actionElem, "jump")) {
 
1454
      tmpAction->setActionType(CAction::E_AT_JUMP);
 
1455
      handle_rhs(tmpAction, "jump");
 
1456
    } else if(!strcmp(actionElem, "pauserestore")) {
 
1457
      tmpAction->setActionType(CAction::E_AT_PAUSE_RESTORE);
 
1458
      handle_rhs(tmpAction, "pauserestore");
 
1459
    } else if(!strcmp(actionElem, "add")) {
 
1460
      tmpAction->setActionType(CAction::E_AT_VAR_ADD);
 
1461
      handle_arithmetic(tmpAction, "add");
 
1462
    } else if(!strcmp(actionElem, "subtract")) {
 
1463
      tmpAction->setActionType(CAction::E_AT_VAR_SUBTRACT);
 
1464
      handle_arithmetic(tmpAction, "subtract");
 
1465
    } else if(!strcmp(actionElem, "multiply")) {
 
1466
      tmpAction->setActionType(CAction::E_AT_VAR_MULTIPLY);
 
1467
      handle_arithmetic(tmpAction, "multiply");
 
1468
    } else if(!strcmp(actionElem, "divide")) {
 
1469
      tmpAction->setActionType(CAction::E_AT_VAR_DIVIDE);
 
1470
      handle_arithmetic(tmpAction, "divide");
 
1471
      if (tmpAction->getVarInId() == 0) {
 
1472
        if (tmpAction->getDoubleValue() == 0.0) {
 
1473
          ERROR("divide actions can not have a value of zero!");
 
1474
        }
 
1475
      }
 
1476
    } else if(!strcmp(actionElem, "sample")) {
 
1477
      tmpAction->setVarId(xp_get_var("assign_to", "sample"));
 
1478
      tmpAction->setActionType(CAction::E_AT_ASSIGN_FROM_SAMPLE);
 
1479
      tmpAction->setDistribution(parse_distribution());
 
1480
    } else if(!strcmp(actionElem, "todouble")) {
 
1481
      tmpAction->setActionType(CAction::E_AT_VAR_TO_DOUBLE);
 
1482
      tmpAction->setVarId(xp_get_var("assign_to", "todouble"));
 
1483
      tmpAction->setVarInId(xp_get_var("variable", "todouble"));
 
1484
    } else if(!strcmp(actionElem, "test")) {
 
1485
      tmpAction->setVarId(xp_get_var("assign_to", "test"));
 
1486
      tmpAction->setVarInId(xp_get_var("variable", "test"));
 
1487
      if (xp_get_value("value")) {
 
1488
        tmpAction->setDoubleValue(xp_get_double("value", "test"));
 
1489
        if (xp_get_value("variable2")) {
 
1490
          ERROR("Can not have both a value and a variable2 for test!");
 
1491
        }
 
1492
      } else {
 
1493
        tmpAction->setVarIn2Id(xp_get_var("variable2", "test"));
 
1494
      }
 
1495
      tmpAction->setActionType(CAction::E_AT_VAR_TEST);
 
1496
      ptr = xp_get_string("compare", "test");
 
1497
      if (!strcmp(ptr, "equal")) {
 
1498
        tmpAction->setComparator(CAction::E_C_EQ);
 
1499
      } else if (!strcmp(ptr, "not_equal")) {
 
1500
        tmpAction->setComparator(CAction::E_C_NE);
 
1501
      } else if (!strcmp(ptr, "greater_than")) {
 
1502
        tmpAction->setComparator(CAction::E_C_GT);
 
1503
      } else if (!strcmp(ptr, "less_than")) {
 
1504
        tmpAction->setComparator(CAction::E_C_LT);
 
1505
      } else if (!strcmp(ptr, "greater_than_equal")) {
 
1506
        tmpAction->setComparator(CAction::E_C_GEQ);
 
1507
      } else if (!strcmp(ptr, "less_than_equal")) {
 
1508
        tmpAction->setComparator(CAction::E_C_LEQ);
 
1509
      } else {
 
1510
        ERROR("Invalid 'compare' parameter: %s", ptr);
 
1511
      }
 
1512
      free(ptr);
 
1513
    } else if(!strcmp(actionElem, "verifyauth")) {
 
1514
#ifdef _USE_OPENSSL
 
1515
      tmpAction->setVarId(xp_get_var("assign_to", "verifyauth"));
 
1516
      tmpAction->setMessage(xp_get_string("username", "verifyauth"), 0);
 
1517
      tmpAction->setMessage(xp_get_string("password", "verifyauth"), 1);
 
1518
      tmpAction->setActionType(CAction::E_AT_VERIFY_AUTH);
 
1519
#else
 
1520
      ERROR("The verifyauth action requires OpenSSL support.");
 
1521
#endif
 
1522
    } else if(!strcmp(actionElem, "lookup")) {
 
1523
      tmpAction->setVarId(xp_get_var("assign_to", "lookup"));
 
1524
      tmpAction->setMessage(xp_get_string("file", "lookup"), 0);
 
1525
      tmpAction->setMessage(xp_get_string("key", "lookup"), 1);
 
1526
      tmpAction->setActionType(CAction::E_AT_LOOKUP);
 
1527
    } else if(!strcmp(actionElem, "insert")) {
 
1528
      tmpAction->setMessage(xp_get_string("file", "insert"), 0);
 
1529
      tmpAction->setMessage(xp_get_string("value", "insert"), 1);
 
1530
      tmpAction->setActionType(CAction::E_AT_INSERT);
 
1531
    } else if(!strcmp(actionElem, "replace")) {
 
1532
      tmpAction->setMessage(xp_get_string("file", "replace"), 0);
 
1533
      tmpAction->setMessage(xp_get_string("line", "replace"), 1);
 
1534
      tmpAction->setMessage(xp_get_string("value", "replace"), 2);
 
1535
      tmpAction->setActionType(CAction::E_AT_REPLACE);
 
1536
    } else if(!strcmp(actionElem, "setdest")) {
 
1537
      tmpAction->setMessage(xp_get_string("host", actionElem), 0);
 
1538
      tmpAction->setMessage(xp_get_string("port", actionElem), 1);
 
1539
      tmpAction->setMessage(xp_get_string("protocol", actionElem), 2);
 
1540
      tmpAction->setActionType(CAction::E_AT_SET_DEST);
 
1541
    } else if(!strcmp(actionElem, "closecon")) {
 
1542
      tmpAction->setActionType(CAction::E_AT_CLOSE_CON);
 
1543
    } else if(!strcmp(actionElem, "strcmp")) {
 
1544
      tmpAction->setVarId(xp_get_var("assign_to", "strcmp"));
 
1545
      tmpAction->setVarInId(xp_get_var("variable", "strcmp"));
 
1546
      if (xp_get_value("value")) {
 
1547
        tmpAction->setStringValue(xp_get_string("value", "strcmp"));
 
1548
        if (xp_get_value("variable2")) {
 
1549
          ERROR("Can not have both a value and a variable2 for strcmp!");
 
1550
        }
 
1551
      } else {
 
1552
        tmpAction->setVarIn2Id(xp_get_var("variable2", "strcmp"));
 
1553
      }
 
1554
      tmpAction->setActionType(CAction::E_AT_VAR_STRCMP);
 
1555
    } else if(!strcmp(actionElem, "trim")) {
 
1556
      tmpAction->setVarId(xp_get_var("assign_to", "trim"));
 
1557
      tmpAction->setActionType(CAction::E_AT_VAR_TRIM);
 
1558
    } else if(!strcmp(actionElem, "exec")) {
 
1559
      if((ptr = xp_get_value((char *)"command"))) {
 
1560
        tmpAction->setActionType(CAction::E_AT_EXECUTE_CMD);
 
1561
        tmpAction->setMessage(ptr);
 
1562
      } /* end (ptr = xp_get_value("command")  */ else if((ptr = xp_get_value((char *)"int_cmd"))) {
 
1563
        CAction::T_IntCmdType type(CAction::E_INTCMD_STOPCALL); /* assume the default */
 
1564
 
 
1565
        if (!strcmp(ptr, "stop_now")) {
 
1566
          type = CAction::E_INTCMD_STOP_NOW;
 
1567
        } else if (!strcmp(ptr, "stop_gracefully")) {
 
1568
          type = CAction::E_INTCMD_STOP_ALL;
 
1569
        } else if (!strcmp(ptr, "stop_call")) {
 
1570
          type = CAction::E_INTCMD_STOPCALL;
 
1571
        }
 
1572
 
 
1573
        /* the action is well formed, adding it in the */
 
1574
        /* tmpActionTable */
 
1575
        tmpAction->setActionType(CAction::E_AT_EXEC_INTCMD);
 
1576
        tmpAction->setIntCmd(type);
 
1577
#ifdef PCAPPLAY
 
1578
      } else if ((ptr = xp_get_value((char *) "play_pcap_audio"))) {
 
1579
        tmpAction->setPcapArgs(ptr);
 
1580
        tmpAction->setActionType(CAction::E_AT_PLAY_PCAP_AUDIO);
 
1581
        hasMedia = 1;
 
1582
      } else if ((ptr = xp_get_value((char *) "play_pcap_video"))) {
 
1583
        tmpAction->setPcapArgs(ptr);
 
1584
        tmpAction->setActionType(CAction::E_AT_PLAY_PCAP_VIDEO);
 
1585
        hasMedia = 1;
 
1586
#else
 
1587
      } else if ((ptr = xp_get_value((char *) "play_pcap_audio"))) {
 
1588
        ERROR("play_pcap_audio requires pcap support! Please recompile SIPp");
 
1589
      } else if ((ptr = xp_get_value((char *) "play_pcap_video"))) {
 
1590
        ERROR("play_pcap_video requires pcap support! Please recompile SIPp");
 
1591
#endif
 
1592
      } else {
 
1593
        ERROR("illegal <exec> in the scenario\n");
 
1594
      }
 
1595
    } else {
 
1596
      ERROR("Unknown action: %s", actionElem);
 
1597
    }
 
1598
 
 
1599
    /* If the action was not well-formed, there should have already been an
 
1600
     * ERROR declaration, thus it is safe to add it here at the end of the loop. */
 
1601
    actions->setAction(tmpAction);
 
1602
 
 
1603
    xp_close_element();
 
1604
    recvScenarioLen++;
 
1605
  } // end while
 
1606
}
 
1607
 
 
1608
// Action list for the message indexed by message_index in
 
1609
// the scenario
 
1610
void scenario::getActionForThisMessage(message *message)
 
1611
{
 
1612
  char *        actionElem;
 
1613
 
 
1614
  if(!(actionElem = xp_open_element(0))) {
 
1615
    return;
 
1616
  }
 
1617
  if(strcmp(actionElem, "action")) {
 
1618
    return;
 
1619
  }
 
1620
 
 
1621
  /* We actually have an action element. */
 
1622
  if(message->M_actions != NULL) {
 
1623
    ERROR("Duplicate action for %s index %d", message->desc, message->index);
 
1624
  }
 
1625
  message->M_actions = new CActions();
 
1626
 
 
1627
  parseAction(message->M_actions);
 
1628
  xp_close_element();
 
1629
}
 
1630
 
 
1631
void scenario::getBookKeeping(message *message) {
 
1632
  char *ptr;
 
1633
 
 
1634
  if((ptr = xp_get_value((char *)"rtd"))) {
 
1635
    message -> stop_rtd = get_rtd(ptr, false);
 
1636
  }
 
1637
  if ((ptr = xp_get_value((char *)"repeat_rtd"))) {
 
1638
    if (message -> stop_rtd) {
 
1639
      message-> repeat_rtd = get_bool(ptr, "repeat_rtd");
 
1640
    } else {
 
1641
      ERROR("There is a repeat_rtd element without an rtd element");
 
1642
    }
 
1643
  }
 
1644
 
 
1645
  if((ptr = xp_get_value((char *)"start_rtd"))) {
 
1646
    message -> start_rtd = get_rtd(ptr, true);
 
1647
  }
 
1648
 
 
1649
  if((ptr = xp_get_value((char *)"counter"))) {
 
1650
    message -> counter = get_counter(ptr, "counter");
 
1651
  }
 
1652
}
 
1653
 
 
1654
void scenario::getCommonAttributes(message *message) {
 
1655
  char *ptr;
 
1656
 
 
1657
  getBookKeeping(message);
 
1658
  getActionForThisMessage(message);
 
1659
 
 
1660
  if((ptr = xp_get_value((char *)"lost"))) {
 
1661
    message -> lost = get_double(ptr, "lost percentage");
 
1662
    lose_packets = 1;
 
1663
  }
 
1664
 
 
1665
  if((ptr = xp_get_value((char *)"crlf"))) {
 
1666
    message -> crlf = 1;
 
1667
  }
 
1668
 
 
1669
  if (xp_get_value("hiderest")) {
 
1670
    hidedefault = xp_get_bool("hiderest", "hiderest");
 
1671
  }
 
1672
  message -> hide = xp_get_bool("hide", "hide", hidedefault);
 
1673
  if((ptr = xp_get_value((char *)"display"))) {
 
1674
    message -> display_str = strdup(ptr);
 
1675
  }
 
1676
 
 
1677
  message -> condexec = xp_get_var("condexec", "condexec variable", -1);
 
1678
  message -> condexec_inverse = xp_get_bool("condexec_inverse", "condexec_inverse", false);
 
1679
 
 
1680
  if ((ptr = xp_get_value((char *)"next"))) {
 
1681
    if (found_timewait) {
 
1682
      ERROR("next labels are not allowed in <timewait> elements.");
 
1683
    }
 
1684
    message -> nextLabel = strdup(ptr);
 
1685
    message -> test = xp_get_var("test", "test variable", -1);
 
1686
    if ( 0 != ( ptr = xp_get_value((char *)"chance") ) ) {
 
1687
      float chance = get_double(ptr,"chance");
 
1688
      /* probability of branch to next */
 
1689
      if (( chance < 0.0 ) || (chance > 1.0 )) {
 
1690
        ERROR("Chance %s not in range [0..1]", ptr);
 
1691
      }
 
1692
      message -> chance = (int)((1.0-chance)*RAND_MAX);
 
1693
    }
 
1694
    else {
 
1695
      message -> chance = 0; /* always */
 
1696
    }
 
1697
  }
 
1698
 
 
1699
  if ((ptr = xp_get_value((char *)"ontimeout"))) {
 
1700
    if (found_timewait) {
 
1701
      ERROR("ontimeout labels are not allowed in <timewait> elements.");
 
1702
    }
 
1703
    message -> onTimeoutLabel = strdup(ptr);
 
1704
  }
 
1705
}
 
1706
 
 
1707
// char* manipulation : create a int[] from a char*
 
1708
// test first is the char* is formed by int separeted by coma
 
1709
// and then create the table
 
1710
 
 
1711
int isWellFormed(char * P_listeStr, int * nombre)
 
1712
{
 
1713
  char * ptr = P_listeStr;
 
1714
  int sizeOf;
 
1715
  bool isANumber;
 
1716
 
 
1717
  (*nombre) = 0;
 
1718
  sizeOf = strlen(P_listeStr);
 
1719
  // getting the number 
 
1720
  if(sizeOf > 0)
 
1721
    {
 
1722
      // is the string well formed ? [0-9] [,]
 
1723
      isANumber = false;
 
1724
      for(int i=0; i<=sizeOf; i++)
 
1725
        {
 
1726
          switch(ptr[i])
 
1727
            {
 
1728
            case ',':
 
1729
              if(isANumber == false)
 
1730
                {   
 
1731
                  return(0);
 
1732
                }
 
1733
              else
 
1734
                {
 
1735
                  (*nombre)++;             
 
1736
                } 
 
1737
              isANumber = false;
 
1738
              break;
 
1739
            case '0':
 
1740
            case '1':
 
1741
            case '2':
 
1742
            case '3':
 
1743
            case '4':
 
1744
            case '5':
 
1745
            case '6':
 
1746
            case '7':
 
1747
            case '8':
 
1748
            case '9':
 
1749
              isANumber = true;
 
1750
              break;
 
1751
            case '\t':
 
1752
            case ' ' :
 
1753
              break;
 
1754
            case '\0':
 
1755
              if(isANumber == false)
 
1756
                {   
 
1757
                  return(0);
 
1758
                }
 
1759
              else
 
1760
                {
 
1761
                  (*nombre)++;
 
1762
                } 
 
1763
              break;
 
1764
            default:
 
1765
              return(0);
 
1766
            }
 
1767
        } // end for
 
1768
    }
 
1769
  return(1);
 
1770
}
 
1771
 
 
1772
int createIntegerTable(char * P_listeStr, 
 
1773
                       unsigned int ** listeInteger, 
 
1774
                       int * sizeOfList)
 
1775
{
 
1776
  int nb=0;
 
1777
  char * ptr = P_listeStr;
 
1778
  char * ptr_prev = P_listeStr;
 
1779
  unsigned int current_int;
 
1780
 
 
1781
  if(P_listeStr){ 
 
1782
   if(isWellFormed(P_listeStr, sizeOfList) == 1)
 
1783
     {
 
1784
       (*listeInteger) = new unsigned int[(*sizeOfList)];
 
1785
       while((*ptr) != ('\0'))
 
1786
         {
 
1787
           if((*ptr) == ',')
 
1788
             {
 
1789
               sscanf(ptr_prev, "%u", &current_int);
 
1790
               if (nb<(*sizeOfList))
 
1791
                 (*listeInteger)[nb] = current_int;
 
1792
               nb++;
 
1793
               ptr_prev = ptr+1;
 
1794
             } 
 
1795
           ptr++;
 
1796
         }
 
1797
 
 
1798
       // Read the last
 
1799
       sscanf(ptr_prev, "%u", &current_int); 
 
1800
       if (nb<(*sizeOfList))
 
1801
         (*listeInteger)[nb] = current_int;
 
1802
       nb++;
 
1803
       return(1);
 
1804
     }
 
1805
   return(0);
 
1806
  }else return(0);
 
1807
}
 
1808
 
 
1809
int createStringTable(char * inputString, char *** stringList, int *sizeOfList)
 
1810
{
 
1811
  if(!inputString) {
 
1812
    return 0;
 
1813
  }
 
1814
 
 
1815
  *stringList = NULL;
 
1816
  *sizeOfList = 0;
 
1817
 
 
1818
  do
 
1819
  {
 
1820
    char *p = strchr(inputString, ',');
 
1821
    if (p) {
 
1822
      *p++ = '\0';
 
1823
    }
 
1824
 
 
1825
    *stringList = (char **)realloc(*stringList, sizeof(char *) * (*sizeOfList + 1));
 
1826
    (*stringList)[*sizeOfList] = strdup(inputString);
 
1827
    (*sizeOfList)++;
 
1828
 
 
1829
    inputString = p;
 
1830
  }
 
1831
  while (inputString);
 
1832
 
 
1833
  return 1;
 
1834
}
 
1835
 
 
1836
void freeStringTable(char ** stringList, int sizeOfList) {
 
1837
  for (int i = 0; i < sizeOfList; i++) {
 
1838
    free(stringList[i]);
 
1839
  }
 
1840
  free(stringList);
 
1841
}
 
1842
 
 
1843
/* These are the names of the scenarios, they must match the default_scenario table. */
 
1844
char *scenario_table[] = {
 
1845
        "uac",
 
1846
        "uas",
 
1847
        "regexp",
 
1848
        "3pcc-C-A",
 
1849
        "3pcc-C-B",
 
1850
        "3pcc-A",
 
1851
        "3pcc-B",
 
1852
        "branchc",
 
1853
        "branchs",
 
1854
        "uac_pcap",
 
1855
        "ooc_default",
 
1856
};
 
1857
 
 
1858
int find_scenario(const char *scenario) {
 
1859
  int i, max;
 
1860
  max = sizeof(scenario_table)/sizeof(scenario_table[0]);
 
1861
 
 
1862
  for (i = 0; i < max; i++) {
 
1863
    if (!strcmp(scenario_table[i], scenario)) {
 
1864
        return i;
 
1865
    }
 
1866
  }
 
1867
 
 
1868
  ERROR("Invalid default scenario name '%s'.\n", scenario);
 
1869
  return -1;
 
1870
}
 
1871
 
 
1872
// TIP: to integrate an existing XML scenario, use the following sed line:
 
1873
// cat ../3pcc-controller-B.xml | sed -e 's/\"/\\\"/g' -e 's/\(.*\)/\"\1\\n\"/'
 
1874
char * default_scenario [] = {
 
1875
/************* Default_scenario[0] ***************/
 
1876
(char *)
 
1877
"<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>\n"
 
1878
"<!DOCTYPE scenario SYSTEM \"sipp.dtd\">\n"
 
1879
"\n"
 
1880
"<!-- This program is free software; you can redistribute it and/or      -->\n"
 
1881
"<!-- modify it under the terms of the GNU General Public License as     -->\n"
 
1882
"<!-- published by the Free Software Foundation; either version 2 of the -->\n"
 
1883
"<!-- License, or (at your option) any later version.                    -->\n"
 
1884
"<!--                                                                    -->\n"
 
1885
"<!-- This program is distributed in the hope that it will be useful,    -->\n"
 
1886
"<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of     -->\n"
 
1887
"<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the      -->\n"
 
1888
"<!-- GNU General Public License for more details.                       -->\n"
 
1889
"<!--                                                                    -->\n"
 
1890
"<!-- You should have received a copy of the GNU General Public License  -->\n"
 
1891
"<!-- along with this program; if not, write to the                      -->\n"
 
1892
"<!-- Free Software Foundation, Inc.,                                    -->\n"
 
1893
"<!-- 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA             -->\n"
 
1894
"<!--                                                                    -->\n"
 
1895
"<!--                 Sipp default 'uac' scenario.                       -->\n"
 
1896
"<!--                                                                    -->\n"
 
1897
"\n"
 
1898
"<scenario name=\"Basic Sipstone UAC\">\n"
 
1899
"  <!-- In client mode (sipp placing calls), the Call-ID MUST be         -->\n"
 
1900
"  <!-- generated by sipp. To do so, use [call_id] keyword.                -->\n"
 
1901
"  <send retrans=\"500\">\n"
 
1902
"    <![CDATA[\n"
 
1903
"\n"
 
1904
"      INVITE sip:[service]@[remote_ip]:[remote_port] SIP/2.0\n"
 
1905
"      Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
 
1906
"      From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag00[call_number]\n"
 
1907
"      To: sut <sip:[service]@[remote_ip]:[remote_port]>\n"
 
1908
"      Call-ID: [call_id]\n"
 
1909
"      CSeq: 1 INVITE\n"
 
1910
"      Contact: sip:sipp@[local_ip]:[local_port]\n"
 
1911
"      Max-Forwards: 70\n"
 
1912
"      Subject: Performance Test\n"
 
1913
"      Content-Type: application/sdp\n"
 
1914
"      Content-Length: [len]\n"
 
1915
"\n"
 
1916
"      v=0\n"
 
1917
"      o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip]\n"
 
1918
"      s=-\n"
 
1919
"      c=IN IP[media_ip_type] [media_ip]\n"
 
1920
"      t=0 0\n"
 
1921
"      m=audio [media_port] RTP/AVP 0\n"
 
1922
"      a=rtpmap:0 PCMU/8000\n"
 
1923
"\n"
 
1924
"    ]]>\n"
 
1925
"  </send>\n"
 
1926
"\n"
 
1927
"  <recv response=\"100\"\n"
 
1928
"        optional=\"true\">\n"
 
1929
"  </recv>\n"
 
1930
"\n"
 
1931
"  <recv response=\"180\" optional=\"true\">\n"
 
1932
"  </recv>\n"
 
1933
"\n"
 
1934
"  <recv response=\"183\" optional=\"true\">\n"
 
1935
"  </recv>\n"
 
1936
"\n"
 
1937
"  <!-- By adding rrs=\"true\" (Record Route Sets), the route sets         -->\n"
 
1938
"  <!-- are saved and used for following messages sent. Useful to test   -->\n"
 
1939
"  <!-- against stateful SIP proxies/B2BUAs.                             -->\n"
 
1940
"  <recv response=\"200\" rtd=\"true\">\n"
 
1941
"  </recv>\n"
 
1942
"\n"
 
1943
"  <!-- Packet lost can be simulated in any send/recv message by         -->\n"
 
1944
"  <!-- by adding the 'lost = \"10\"'. Value can be [1-100] percent.       -->\n"
 
1945
"  <send>\n"
 
1946
"    <![CDATA[\n"
 
1947
"\n"
 
1948
"      ACK sip:[service]@[remote_ip]:[remote_port] SIP/2.0\n"
 
1949
"      Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
 
1950
"      From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag00[call_number]\n"
 
1951
"      To: sut <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param]\n"
 
1952
"      Call-ID: [call_id]\n"
 
1953
"      CSeq: 1 ACK\n"
 
1954
"      Contact: sip:sipp@[local_ip]:[local_port]\n"
 
1955
"      Max-Forwards: 70\n"
 
1956
"      Subject: Performance Test\n"
 
1957
"      Content-Length: 0\n"
 
1958
"\n"
 
1959
"    ]]>\n"
 
1960
"  </send>\n"
 
1961
"\n"
 
1962
"  <!-- This delay can be customized by the -d command-line option       -->\n"
 
1963
"  <!-- or by adding a 'milliseconds = \"value\"' option here.             -->\n"
 
1964
"  <pause/>\n"
 
1965
"\n"
 
1966
"  <!-- The 'crlf' option inserts a blank line in the statistics report. -->\n"
 
1967
"  <send retrans=\"500\">\n"
 
1968
"    <![CDATA[\n"
 
1969
"\n"
 
1970
"      BYE sip:[service]@[remote_ip]:[remote_port] SIP/2.0\n"
 
1971
"      Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
 
1972
"      From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag00[call_number]\n"
 
1973
"      To: sut <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param]\n"
 
1974
"      Call-ID: [call_id]\n"
 
1975
"      CSeq: 2 BYE\n"
 
1976
"      Contact: sip:sipp@[local_ip]:[local_port]\n"
 
1977
"      Max-Forwards: 70\n"
 
1978
"      Subject: Performance Test\n"
 
1979
"      Content-Length: 0\n"
 
1980
"\n"
 
1981
"    ]]>\n"
 
1982
"  </send>\n"
 
1983
"\n"
 
1984
"  <recv response=\"200\" crlf=\"true\">\n"
 
1985
"  </recv>\n"
 
1986
"\n"
 
1987
"  <!-- definition of the response time repartition table (unit is ms)   -->\n"
 
1988
"  <ResponseTimeRepartition value=\"10, 20, 30, 40, 50, 100, 150, 200\"/>\n"
 
1989
"\n"
 
1990
"  <!-- definition of the call length repartition table (unit is ms)     -->\n"
 
1991
"  <CallLengthRepartition value=\"10, 50, 100, 500, 1000, 5000, 10000\"/>\n"
 
1992
"\n"
 
1993
"</scenario>\n"
 
1994
"\n"
 
1995
 
1996
 
 
1997
/************* Default_scenario[1] ***************/
 
1998
(char *)
 
1999
"<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>\n"
 
2000
"<!DOCTYPE scenario SYSTEM \"sipp.dtd\">\n"
 
2001
"\n"
 
2002
"<!-- This program is free software; you can redistribute it and/or      -->\n"
 
2003
"<!-- modify it under the terms of the GNU General Public License as     -->\n"
 
2004
"<!-- published by the Free Software Foundation; either version 2 of the -->\n"
 
2005
"<!-- License, or (at your option) any later version.                    -->\n"
 
2006
"<!--                                                                    -->\n"
 
2007
"<!-- This program is distributed in the hope that it will be useful,    -->\n"
 
2008
"<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of     -->\n"
 
2009
"<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the      -->\n"
 
2010
"<!-- GNU General Public License for more details.                       -->\n"
 
2011
"<!--                                                                    -->\n"
 
2012
"<!-- You should have received a copy of the GNU General Public License  -->\n"
 
2013
"<!-- along with this program; if not, write to the                      -->\n"
 
2014
"<!-- Free Software Foundation, Inc.,                                    -->\n"
 
2015
"<!-- 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA             -->\n"
 
2016
"<!--                                                                    -->\n"
 
2017
"<!--                 Sipp default 'uas' scenario.                       -->\n"
 
2018
"<!--                                                                    -->\n"
 
2019
"\n"
 
2020
"<scenario name=\"Basic UAS responder\">\n"
 
2021
"  <!-- By adding rrs=\"true\" (Record Route Sets), the route sets         -->\n"
 
2022
"  <!-- are saved and used for following messages sent. Useful to test   -->\n"
 
2023
"  <!-- against stateful SIP proxies/B2BUAs.                             -->\n"
 
2024
"  <recv request=\"INVITE\" crlf=\"true\">\n"
 
2025
"  </recv>\n"
 
2026
"\n"
 
2027
"  <!-- The '[last_*]' keyword is replaced automatically by the          -->\n"
 
2028
"  <!-- specified header if it was present in the last message received  -->\n"
 
2029
"  <!-- (except if it was a retransmission). If the header was not       -->\n"
 
2030
"  <!-- present or if no message has been received, the '[last_*]'       -->\n"
 
2031
"  <!-- keyword is discarded, and all bytes until the end of the line    -->\n"
 
2032
"  <!-- are also discarded.                                              -->\n"
 
2033
"  <!--                                                                  -->\n"
 
2034
"  <!-- If the specified header was present several times in the         -->\n"
 
2035
"  <!-- message, all occurences are concatenated (CRLF seperated)        -->\n"
 
2036
"  <!-- to be used in place of the '[last_*]' keyword.                   -->\n"
 
2037
"\n"
 
2038
"  <send>\n"
 
2039
"    <![CDATA[\n"
 
2040
"\n"
 
2041
"      SIP/2.0 180 Ringing\n"
 
2042
"      [last_Via:]\n"
 
2043
"      [last_From:]\n"
 
2044
"      [last_To:];tag=[pid]SIPpTag01[call_number]\n"
 
2045
"      [last_Call-ID:]\n"
 
2046
"      [last_CSeq:]\n"
 
2047
"      Contact: <sip:[local_ip]:[local_port];transport=[transport]>\n"
 
2048
"      Content-Length: 0\n"
 
2049
"\n"
 
2050
"    ]]>\n"
 
2051
"  </send>\n"
 
2052
"\n"
 
2053
"  <send retrans=\"500\">\n"
 
2054
"    <![CDATA[\n"
 
2055
"\n"
 
2056
"      SIP/2.0 200 OK\n"
 
2057
"      [last_Via:]\n"
 
2058
"      [last_From:]\n"
 
2059
"      [last_To:];tag=[pid]SIPpTag01[call_number]\n"
 
2060
"      [last_Call-ID:]\n"
 
2061
"      [last_CSeq:]\n"
 
2062
"      Contact: <sip:[local_ip]:[local_port];transport=[transport]>\n"
 
2063
"      Content-Type: application/sdp\n"
 
2064
"      Content-Length: [len]\n"
 
2065
"\n"
 
2066
"      v=0\n"
 
2067
"      o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip]\n"
 
2068
"      s=-\n"
 
2069
"      c=IN IP[media_ip_type] [media_ip]\n"
 
2070
"      t=0 0\n"
 
2071
"      m=audio [media_port] RTP/AVP 0\n"
 
2072
"      a=rtpmap:0 PCMU/8000\n"
 
2073
"\n"
 
2074
"    ]]>\n"
 
2075
"  </send>\n"
 
2076
"\n"
 
2077
"  <recv request=\"ACK\"\n"
 
2078
"        optional=\"true\"\n"
 
2079
"        rtd=\"true\"\n"
 
2080
"        crlf=\"true\">\n"
 
2081
"  </recv>\n"
 
2082
"\n"
 
2083
"  <recv request=\"BYE\">\n"
 
2084
"  </recv>\n"
 
2085
"\n"
 
2086
"  <send>\n"
 
2087
"    <![CDATA[\n"
 
2088
"\n"
 
2089
"      SIP/2.0 200 OK\n"
 
2090
"      [last_Via:]\n"
 
2091
"      [last_From:]\n"
 
2092
"      [last_To:]\n"
 
2093
"      [last_Call-ID:]\n"
 
2094
"      [last_CSeq:]\n"
 
2095
"      Contact: <sip:[local_ip]:[local_port];transport=[transport]>\n"
 
2096
"      Content-Length: 0\n"
 
2097
"\n"
 
2098
"    ]]>\n"
 
2099
"  </send>\n"
 
2100
"\n"
 
2101
"  <!-- Keep the call open for a while in case the 200 is lost to be     -->\n"
 
2102
"  <!-- able to retransmit it if we receive the BYE again.               -->\n"
 
2103
"  <timewait milliseconds=\"4000\"/>\n"
 
2104
"\n"
 
2105
"\n"
 
2106
"  <!-- definition of the response time repartition table (unit is ms)   -->\n"
 
2107
"  <ResponseTimeRepartition value=\"10, 20, 30, 40, 50, 100, 150, 200\"/>\n"
 
2108
"\n"
 
2109
"  <!-- definition of the call length repartition table (unit is ms)     -->\n"
 
2110
"  <CallLengthRepartition value=\"10, 50, 100, 500, 1000, 5000, 10000\"/>\n"
 
2111
"\n"
 
2112
"</scenario>\n"
 
2113
"\n",
 
2114
 
 
2115
/************* Default_scenario[2] ***************/
 
2116
(char *)
 
2117
"<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>\n"
 
2118
"<!DOCTYPE scenario SYSTEM \"sipp.dtd\">\n"
 
2119
"\n"
 
2120
"<!-- This program is free software; you can redistribute it and/or      -->\n"
 
2121
"<!-- modify it under the terms of the GNU General Public License as     -->\n"
 
2122
"<!-- published by the Free Software Foundation; either version 2 of the -->\n"
 
2123
"<!-- License, or (at your option) any later version.                    -->\n"
 
2124
"<!--                                                                    -->\n"
 
2125
"<!-- This program is distributed in the hope that it will be useful,    -->\n"
 
2126
"<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of     -->\n"
 
2127
"<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the      -->\n"
 
2128
"<!-- GNU General Public License for more details.                       -->\n"
 
2129
"<!--                                                                    -->\n"
 
2130
"<!-- You should have received a copy of the GNU General Public License  -->\n"
 
2131
"<!-- along with this program; if not, write to the                      -->\n"
 
2132
"<!-- Free Software Foundation, Inc.,                                    -->\n"
 
2133
"<!-- 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA             -->\n"
 
2134
"<!--                                                                    -->\n"
 
2135
"<!--                 Sipp default 'regexp client' scenario.             -->\n"
 
2136
"<!--                                                                    -->\n"
 
2137
"\n"
 
2138
"<scenario name=\"Client with regexp scenario\">\n"
 
2139
"  <send retrans=\"500\">\n"
 
2140
"    <![CDATA[\n"
 
2141
"\n"
 
2142
"      INVITE sip:[service]@[remote_ip]:[remote_port] SIP/2.0\n"
 
2143
"      Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
 
2144
"      From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag02[call_number]\n"
 
2145
"      To: sut <sip:[service]@[remote_ip]:[remote_port]>\n"
 
2146
"      Call-ID: [call_id]\n"
 
2147
"      CSeq: 1 INVITE\n"
 
2148
"      Contact: sip:sipp@[local_ip]:[local_port]\n"
 
2149
"      Max-Forwards: 70\n"
 
2150
"      Subject: Performance Test\n"
 
2151
"      Content-Type: application/sdp\n"
 
2152
"      Content-Length: [len]\n"
 
2153
"\n"
 
2154
"      v=0\n"
 
2155
"      o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip]\n"
 
2156
"      s=-\n"
 
2157
"      c=IN IP[media_ip_type] [media_ip]\n"
 
2158
"      t=0 0\n"
 
2159
"      m=audio [media_port] RTP/AVP 0\n"
 
2160
"      a=rtpmap:0 PCMU/8000\n"
 
2161
"\n"
 
2162
"    ]]>\n"
 
2163
"  </send>\n"
 
2164
"\n"
 
2165
"  <recv response=\"100\"\n"
 
2166
"        optional=\"true\">\n"
 
2167
"  </recv>\n"
 
2168
"\n"
 
2169
"  <recv response=\"180\" optional=\"true\">\n"
 
2170
"  </recv>\n"
 
2171
"  <recv response=\"183\" optional=\"true\">\n"
 
2172
"  </recv>\n"
 
2173
"\n"
 
2174
"  <recv response=\"200\" start_rtd=\"true\">\n"
 
2175
"    <!-- Definition of regexp in the action tag. The regexp must follow -->\n"
 
2176
"    <!-- the Posix Extended standard (POSIX 1003.2), see:               -->\n"
 
2177
"    <!--                                                                -->\n"
 
2178
"    <!--   http://www.opengroup.org/onlinepubs/007908799/xbd/re.html    -->\n"
 
2179
"    <!--                                                                -->\n"
 
2180
"    <!-- regexp    : Contain the regexp to use for matching the         -->\n"
 
2181
"    <!--             received message                                   -->\n"
 
2182
"    <!--             MANDATORY                                          -->\n"
 
2183
"    <!-- search_in : msg (try to match against the entire message)      -->\n"
 
2184
"    <!--           : hdr (try to match against a specific SIP header    -->\n"
 
2185
"    <!--             (passed in the header tag)                         -->\n"
 
2186
"    <!--             OPTIONAL - default value : msg                     -->\n"
 
2187
"    <!-- header    : Header to try to match against.                    -->\n"
 
2188
"    <!--             Only used when the search_in tag is set to hdr     -->\n"
 
2189
"    <!--             MANDATORY IF search_in is equal to hdr             -->\n"
 
2190
"    <!-- check_it  : if set to true, the call is marked as failed if    -->\n"
 
2191
"    <!--             the regexp doesn't match.                          -->\n"
 
2192
"    <!--             OPTIONAL - default value : false                   -->\n"
 
2193
"    <!-- assign_to : contain the variable id (integer) or a list of     -->\n"
 
2194
"    <!--             variable id which will be used to store the        -->\n"
 
2195
"    <!--             result of the matching process between the regexp  -->\n"
 
2196
"    <!--             and the message. This variable can be re-used at   -->\n"
 
2197
"    <!--             a later time in the scenario using '[$n]' syntax   -->\n"
 
2198
"    <!--             where n is the variable id.                        -->\n"
 
2199
"    <!--             MANDATORY                                          -->\n"
 
2200
"    <action>\n"
 
2201
"      <ereg regexp=\"[0-9]{1,3}[.][0-9]{1,3}[.][0-9]{1,3}[.][0-9]{1,3}[:][0-9]{1,5}\" \n"
 
2202
"            search_in=\"msg\" \n"
 
2203
"            check_it=\"true\" \n"
 
2204
"            assign_to=\"1\"/>\n"
 
2205
"      <ereg regexp=\".*\" \n"
 
2206
"            search_in=\"hdr\" \n"
 
2207
"            header=\"Contact:\" \n"
 
2208
"            check_it=\"true\" \n"
 
2209
"            assign_to=\"6\"/>\n"
 
2210
"      <ereg regexp=\"o=([[:alnum:]]*) ([[:alnum:]]*) ([[:alnum:]]*)\"\n"
 
2211
"            search_in=\"msg\" \n"
 
2212
"            check_it=\"true\" \n"
 
2213
"            assign_to=\"3,4,5,8\"/>\n"
 
2214
"    </action>\n"
 
2215
"  </recv>\n"
 
2216
"\n"
 
2217
"  <send>\n"
 
2218
"    <![CDATA[\n"
 
2219
"      ACK sip:[service]@[remote_ip]:[remote_port] SIP/2.0\n"
 
2220
"      Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
 
2221
"      From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag02[call_number]\n"
 
2222
"      To: sut <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param]\n"
 
2223
"      Call-ID: [call_id]\n"
 
2224
"      CSeq: 1 ACK\n"
 
2225
"      retrievedIp: [$1]\n"
 
2226
"      retrievedContact:[$6]\n"
 
2227
"      retrievedSdpOrigin:[$3]\n"
 
2228
"      retrievedSdpOrigin-username:[$4]\n"
 
2229
"      retrievedSdpOrigin-session-id:[$5]\n"
 
2230
"      retrievedSdpOrigin-version:[$8]\n"
 
2231
"      Contact: sip:sipp@[local_ip]:[local_port]\n"
 
2232
"      Max-Forwards: 70\n"
 
2233
"      Subject: Performance Test\n"
 
2234
"      Content-Length: 0\n"
 
2235
"    ]]>\n"
 
2236
"  </send>\n"
 
2237
"\n"
 
2238
"  <!-- This delay can be customized by the -d command-line option       -->\n"
 
2239
"  <!-- or by adding a 'milliseconds = \"value\"' option here.           -->\n"
 
2240
"  <pause milliseconds = \"1000\"/>\n"
 
2241
"\n"
 
2242
"  <!-- The 'crlf' option inserts a blank line in the statistics report. -->\n"
 
2243
"  <send retrans=\"500\">\n"
 
2244
"    <![CDATA[\n"
 
2245
"\n"
 
2246
"      BYE sip:[service]@[remote_ip]:[remote_port] SIP/2.0\n"
 
2247
"      Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
 
2248
"      From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag02[call_number]\n"
 
2249
"      To: sut <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param]\n"
 
2250
"      Call-ID: [call_id]\n"
 
2251
"      CSeq: 2 BYE\n"
 
2252
"      Contact: sip:sipp@[local_ip]:[local_port]\n"
 
2253
"      Max-Forwards: 70\n"
 
2254
"      Subject: Performance Test\n"
 
2255
"      Content-Length: 0\n"
 
2256
"\n"
 
2257
"    ]]>\n"
 
2258
"  </send>\n"
 
2259
"\n"
 
2260
"  <recv response=\"200\" crlf=\"true\" rtd=\"true\">\n"
 
2261
"  </recv>\n"
 
2262
"\n"
 
2263
"  <!-- definition of the response time repartition table (unit is ms)   -->\n"
 
2264
"  <ResponseTimeRepartition value=\"1000, 1040, 1080, 1120, 1160, 1200\"/>\n"
 
2265
"\n"
 
2266
"  <!-- definition of the call length repartition table (unit is ms)     -->\n"
 
2267
"  <CallLengthRepartition value=\"1000, 1100, 1200, 1300, 1400\"/>\n"
 
2268
"\n"
 
2269
"</scenario>\n"
 
2270
"\n",
 
2271
 
 
2272
/************* Default_scenario[3] ***************/
 
2273
(char*)
 
2274
"<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>\n"
 
2275
"<!DOCTYPE scenario SYSTEM \"sipp.dtd\">\n"
 
2276
"\n"
 
2277
"<!-- This program is free software; you can redistribute it and/or      -->\n"
 
2278
"<!-- modify it under the terms of the GNU General Public License as     -->\n"
 
2279
"<!-- published by the Free Software Foundation; either version 2 of the -->\n"
 
2280
"<!-- License, or (at your option) any later version.                    -->\n"
 
2281
"<!--                                                                    -->\n"
 
2282
"<!-- This program is distributed in the hope that it will be useful,    -->\n"
 
2283
"<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of     -->\n"
 
2284
"<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the      -->\n"
 
2285
"<!-- GNU General Public License for more details.                       -->\n"
 
2286
"<!--                                                                    -->\n"
 
2287
"<!-- You should have received a copy of the GNU General Public License  -->\n"
 
2288
"<!-- along with this program; if not, write to the                      -->\n"
 
2289
"<!-- Free Software Foundation, Inc.,                                    -->\n"
 
2290
"<!-- 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA             -->\n"
 
2291
"<!--                                                                    -->\n"
 
2292
"<!--                 3PCC - Controller - A side                         -->\n"
 
2293
"<!--                                                                    -->\n"
 
2294
"<!--             A              Controller               B              -->\n"
 
2295
"<!--             |(1) INVITE no SDP  |                   |              -->\n"
 
2296
"<!--             |<==================|                   |              -->\n"
 
2297
"<!--             |(2) 200 offer1     |                   |              -->\n"
 
2298
"<!--             |==================>|                   |              -->\n"
 
2299
"<!--             |                   |(3) INVITE offer1  |              -->\n"
 
2300
"<!--             |                   |==================>|              -->\n"
 
2301
"<!--             |                   |(4) 200 OK answer1 |              -->\n"
 
2302
"<!--             |                   |<==================|              -->\n"
 
2303
"<!--             |                   |(5) ACK            |              -->\n"
 
2304
"<!--             |                   |==================>|              -->\n"
 
2305
"<!--             |(6) ACK answer1    |                   |              -->\n"
 
2306
"<!--             |<==================|                   |              -->\n"
 
2307
"<!--             |(7) RTP            |                   |              -->\n"
 
2308
"<!--             |.......................................|              -->\n"
 
2309
"<!--                                                                    -->\n"
 
2310
"\n"
 
2311
"<scenario name=\"3PCC Controller - A side\">\n"
 
2312
"  <send retrans=\"500\">\n"
 
2313
"    <![CDATA[\n"
 
2314
"\n"
 
2315
"      INVITE sip:[service]@[remote_ip]:[remote_port] SIP/2.0\n"
 
2316
"      Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
 
2317
"      From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag03[call_number]\n"
 
2318
"      To: sut <sip:[service]@[remote_ip]:[remote_port]>\n"
 
2319
"      Call-ID: [call_id]\n"
 
2320
"      CSeq: 1 INVITE\n"
 
2321
"      Contact: sip:sipp@[local_ip]:[local_port]\n"
 
2322
"      Max-Forwards: 70\n"
 
2323
"      Subject: Performance Test\n"
 
2324
"      Content-Length: 0\n"
 
2325
"\n"
 
2326
"    ]]>\n"
 
2327
"  </send>\n"
 
2328
"\n"
 
2329
"  <recv response=\"100\" optional=\"true\"> </recv>\n"
 
2330
"  <recv response=\"180\" optional=\"true\"> </recv>\n"
 
2331
"  <recv response=\"183\" optional=\"true\"> </recv>\n"
 
2332
"  <recv response=\"200\" crlf=\"true\" start_rtd=\"true\">\n"
 
2333
"    <action>\n"
 
2334
"       <ereg regexp=\"Content-Type:.*\" \n"
 
2335
"             search_in=\"msg\"  \n"
 
2336
"             assign_to=\"1\" /> \n"
 
2337
"    </action>\n"
 
2338
"  </recv>\n"
 
2339
"\n"
 
2340
"  <sendCmd>\n"
 
2341
"    <![CDATA[\n"
 
2342
"      Call-ID: [call_id]\n"
 
2343
"      [$1]\n"
 
2344
"\n"
 
2345
"     ]]>\n"
 
2346
"  </sendCmd>\n"
 
2347
"  \n"
 
2348
"  <recvCmd>\n"
 
2349
"    <action>\n"
 
2350
"       <ereg regexp=\"Content-Type:.*\"  \n"
 
2351
"             search_in=\"msg\"  \n"
 
2352
"             assign_to=\"2\" /> \n"
 
2353
"    </action>\n"
 
2354
"  \n"
 
2355
"  </recvCmd>\n"
 
2356
"  \n"
 
2357
"  <send rtd=\"true\">\n"
 
2358
"    <![CDATA[\n"
 
2359
"\n"
 
2360
"      ACK sip:[service]@[remote_ip]:[remote_port] SIP/2.0\n"
 
2361
"      Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
 
2362
"      From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag03[call_number]\n"
 
2363
"      To: sut <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param]\n"
 
2364
"      Call-ID: [call_id]\n"
 
2365
"      CSeq: 1 ACK\n"
 
2366
"      Contact: sip:sipp@[local_ip]:[local_port]\n"
 
2367
"      Max-Forwards: 70\n"
 
2368
"      Subject: Performance Test\n"
 
2369
"      [$2]\n"
 
2370
"\n"
 
2371
"    ]]>\n"
 
2372
"  </send>\n"
 
2373
"\n"
 
2374
"  <pause milliseconds=\"1000\"/>\n"
 
2375
"\n"
 
2376
"  <!-- The 'crlf' option inserts a blank line in the statistics report. -->\n"
 
2377
"  <send retrans=\"500\">\n"
 
2378
"    <![CDATA[\n"
 
2379
"\n"
 
2380
"      BYE sip:[service]@[remote_ip]:[remote_port] SIP/2.0\n"
 
2381
"      Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
 
2382
"      From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag03[call_number]\n"
 
2383
"      To: sut <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param]\n"
 
2384
"      Call-ID: [call_id]\n"
 
2385
"      CSeq: 2 BYE\n"
 
2386
"      Contact: sip:sipp@[local_ip]:[local_port]\n"
 
2387
"      Max-Forwards: 70\n"
 
2388
"      Subject: Performance Test\n"
 
2389
"      Content-Length: 0\n"
 
2390
"\n"
 
2391
"    ]]>\n"
 
2392
"  </send>\n"
 
2393
"\n"
 
2394
"  <recv response=\"200\" crlf=\"true\"> </recv>\n"
 
2395
"\n"
 
2396
"</scenario>\n"
 
2397
"\n",
 
2398
 
 
2399
/************* Default_scenario[4] ***************/
 
2400
(char*) 
 
2401
"<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>\n"
 
2402
"<!DOCTYPE scenario SYSTEM \"sipp.dtd\">\n"
 
2403
"\n"
 
2404
"<!-- This program is free software; you can redistribute it and/or      -->\n"
 
2405
"<!-- modify it under the terms of the GNU General Public License as     -->\n"
 
2406
"<!-- published by the Free Software Foundation; either version 2 of the -->\n"
 
2407
"<!-- License, or (at your option) any later version.                    -->\n"
 
2408
"<!--                                                                    -->\n"
 
2409
"<!-- This program is distributed in the hope that it will be useful,    -->\n"
 
2410
"<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of     -->\n"
 
2411
"<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the      -->\n"
 
2412
"<!-- GNU General Public License for more details.                       -->\n"
 
2413
"<!--                                                                    -->\n"
 
2414
"<!-- You should have received a copy of the GNU General Public License  -->\n"
 
2415
"<!-- along with this program; if not, write to the                      -->\n"
 
2416
"<!-- Free Software Foundation, Inc.,                                    -->\n"
 
2417
"<!-- 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA             -->\n"
 
2418
"<!--                                                                    -->\n"
 
2419
"<!--                 3PCC - Controller - B side                         -->\n"
 
2420
"<!--                                                                    -->\n"
 
2421
"<!--             A              Controller               B              -->\n"
 
2422
"<!--             |(1) INVITE no SDP  |                   |              -->\n"
 
2423
"<!--             |<==================|                   |              -->\n"
 
2424
"<!--             |(2) 200 offer1     |                   |              -->\n"
 
2425
"<!--             |==================>|                   |              -->\n"
 
2426
"<!--             |                   |(3) INVITE offer1  |              -->\n"
 
2427
"<!--             |                   |==================>|              -->\n"
 
2428
"<!--             |                   |(4) 200 OK answer1 |              -->\n"
 
2429
"<!--             |                   |<==================|              -->\n"
 
2430
"<!--             |                   |(5) ACK            |              -->\n"
 
2431
"<!--             |                   |==================>|              -->\n"
 
2432
"<!--             |(6) ACK answer1    |                   |              -->\n"
 
2433
"<!--             |<==================|                   |              -->\n"
 
2434
"<!--             |(7) RTP            |                   |              -->\n"
 
2435
"<!--             |.......................................|              -->\n"
 
2436
"<!--                                                                    -->\n"
 
2437
"\n"
 
2438
"\n"
 
2439
"<scenario name=\"3PCC Controller - B side\">\n"
 
2440
"\n"
 
2441
"<recvCmd>\n"
 
2442
"  <action>\n"
 
2443
"       <ereg regexp=\"Content-Type:.*\"  \n"
 
2444
"             search_in=\"msg\"  \n"
 
2445
"             assign_to=\"1\" /> \n"
 
2446
"  </action>\n"
 
2447
"</recvCmd>\n"
 
2448
"\n"
 
2449
"  <send retrans=\"500\">\n"
 
2450
"    <![CDATA[\n"
 
2451
"\n"
 
2452
"      INVITE sip:[service]@[remote_ip]:[remote_port] SIP/2.0\n"
 
2453
"      Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
 
2454
"      From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag04[call_number]\n"
 
2455
"      To: sut <sip:[service]@[remote_ip]:[remote_port]>\n"
 
2456
"      Call-ID: [call_id]\n"
 
2457
"      CSeq: 1 INVITE\n"
 
2458
"      Contact: sip:sipp@[local_ip]:[local_port]\n"
 
2459
"      Max-Forwards: 70\n"
 
2460
"      Subject: Performance Test\n"
 
2461
"      [$1]\n"
 
2462
"\n"
 
2463
"     ]]>\n"
 
2464
"  </send>\n"
 
2465
"\n"
 
2466
"  <recv response=\"100\" optional=\"true\"> </recv>\n"
 
2467
"  <recv response=\"180\" optional=\"true\"> </recv>\n"
 
2468
"  <recv response=\"183\" optional=\"true\"> </recv>\n"
 
2469
"  <recv response=\"200\" crlf=\"true\">\n"
 
2470
"    <action>\n"
 
2471
"       <ereg regexp=\"Content-Type:.*\"  \n"
 
2472
"             search_in=\"msg\"  \n"
 
2473
"             assign_to=\"2\" /> \n"
 
2474
"    </action>\n"
 
2475
"  </recv>\n"
 
2476
"  \n"
 
2477
"    \n"
 
2478
"  <send start_rtd=\"true\">\n"
 
2479
"    <![CDATA[\n"
 
2480
"\n"
 
2481
"      ACK sip:[service]@[remote_ip]:[remote_port] SIP/2.0\n"
 
2482
"      Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
 
2483
"      From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag04[call_number]\n"
 
2484
"      To: sut <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param]\n"
 
2485
"      Call-ID: [call_id]\n"
 
2486
"      CSeq: 1 ACK\n"
 
2487
"      Contact: sip:sipp@[local_ip]:[local_port]\n"
 
2488
"      Max-Forwards: 70\n"
 
2489
"      Subject: Performance Test\n"
 
2490
"      Content-Length: 0\n"
 
2491
"\n"
 
2492
"    ]]>\n"
 
2493
"  </send>\n"
 
2494
"\n"
 
2495
"  <sendCmd>\n"
 
2496
"    <![CDATA[\n"
 
2497
"      Call-ID: [call_id]\n"
 
2498
"      [$2]\n"
 
2499
"\n"
 
2500
"    ]]>\n"
 
2501
"  </sendCmd>\n"
 
2502
" \n"
 
2503
"  <pause milliseconds=\"1000\"/>\n"
 
2504
"\n"
 
2505
"\n"
 
2506
"  <!-- The 'crlf' option inserts a blank line in the statistics report. -->\n"
 
2507
"  <send retrans=\"500\" rtd=\"true\">\n"
 
2508
"    <![CDATA[\n"
 
2509
"\n"
 
2510
"      BYE sip:[service]@[remote_ip]:[remote_port] SIP/2.0\n"
 
2511
"      Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
 
2512
"      From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag04[call_number]\n"
 
2513
"      To: sut <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param]\n"
 
2514
"      Call-ID: [call_id]\n"
 
2515
"      CSeq: 2 BYE\n"
 
2516
"      Contact: sip:sipp@[local_ip]:[local_port]\n"
 
2517
"      Max-Forwards: 70\n"
 
2518
"      Subject: Performance Test\n"
 
2519
"      Content-Length: 0\n"
 
2520
"\n"
 
2521
"    ]]>\n"
 
2522
"  </send>\n"
 
2523
"\n"
 
2524
"  <recv response=\"200\" crlf=\"true\">\n"
 
2525
"  </recv>\n"
 
2526
"\n"
 
2527
"\n"
 
2528
"</scenario>\n"
 
2529
"\n",
 
2530
 
 
2531
/************* Default_scenario[5] ***************/
 
2532
(char*) 
 
2533
"<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>\n"
 
2534
"<!DOCTYPE scenario SYSTEM \"sipp.dtd\">\n"
 
2535
"\n"
 
2536
"<!-- This program is free software; you can redistribute it and/or      -->\n"
 
2537
"<!-- modify it under the terms of the GNU General Public License as     -->\n"
 
2538
"<!-- published by the Free Software Foundation; either version 2 of the -->\n"
 
2539
"<!-- License, or (at your option) any later version.                    -->\n"
 
2540
"<!--                                                                    -->\n"
 
2541
"<!-- This program is distributed in the hope that it will be useful,    -->\n"
 
2542
"<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of     -->\n"
 
2543
"<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the      -->\n"
 
2544
"<!-- GNU General Public License for more details.                       -->\n"
 
2545
"<!--                                                                    -->\n"
 
2546
"<!-- You should have received a copy of the GNU General Public License  -->\n"
 
2547
"<!-- along with this program; if not, write to the                      -->\n"
 
2548
"<!-- Free Software Foundation, Inc.,                                    -->\n"
 
2549
"<!-- 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA             -->\n"
 
2550
"<!--                                                                    -->\n"
 
2551
"<!--                 3PCC - A side emulator                             -->\n"
 
2552
"<!--                                                                    -->\n"
 
2553
"<!--             A              Controller               B              -->\n"
 
2554
"<!--             |(1) INVITE no SDP  |                   |              -->\n"
 
2555
"<!--             |<==================|                   |              -->\n"
 
2556
"<!--             |(2) 200 offer1     |                   |              -->\n"
 
2557
"<!--             |==================>|                   |              -->\n"
 
2558
"<!--             |                   |(3) INVITE offer1  |              -->\n"
 
2559
"<!--             |                   |==================>|              -->\n"
 
2560
"<!--             |                   |(4) 200 OK answer1 |              -->\n"
 
2561
"<!--             |                   |<==================|              -->\n"
 
2562
"<!--             |                   |(5) ACK            |              -->\n"
 
2563
"<!--             |                   |==================>|              -->\n"
 
2564
"<!--             |(6) ACK answer1    |                   |              -->\n"
 
2565
"<!--             |<==================|                   |              -->\n"
 
2566
"<!--             |(7) RTP            |                   |              -->\n"
 
2567
"<!--             |.......................................|              -->\n"
 
2568
"<!--                                                                    -->\n"
 
2569
"\n"
 
2570
"\n"
 
2571
"<scenario name=\"3PCC A side\">\n"
 
2572
"  <recv request=\"INVITE\" crlf=\"true\">\n"
 
2573
"  </recv>\n"
 
2574
"\n"
 
2575
"  <send>\n"
 
2576
"    <![CDATA[\n"
 
2577
"\n"
 
2578
"      SIP/2.0 200 OK\n"
 
2579
"      [last_Via:]\n"
 
2580
"      [last_From:]\n"
 
2581
"      [last_To:];tag=[pid]SIPpTag05[call_number]\n"
 
2582
"      [last_Call-ID:]\n"
 
2583
"      [last_CSeq:]\n"
 
2584
"      Contact: <sip:[local_ip]:[local_port];transport=[transport]>\n"
 
2585
"      Content-Type: application/sdp\n"
 
2586
"      Content-Length: [len]\n"
 
2587
"\n"
 
2588
"      v=0\n"
 
2589
"      o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip]\n"
 
2590
"      s=-\n"
 
2591
"      c=IN IP[media_ip_type] [media_ip]\n"
 
2592
"      t=0 0\n"
 
2593
"      m=audio [media_port] RTP/AVP 0\n"
 
2594
"      a=rtpmap:0 PCMU/8000\n"
 
2595
"\n"
 
2596
"    ]]>\n"
 
2597
"  </send>\n"
 
2598
"\n"
 
2599
"  <recv request=\"ACK\" rtd=\"true\" crlf=\"true\"> </recv>\n"
 
2600
"\n"
 
2601
"  <!-- RTP flow starts from here! -->\n"
 
2602
"\n"
 
2603
"  <recv request=\"BYE\" crlf=\"true\"> </recv>\n"
 
2604
"\n"
 
2605
"  <send>\n"
 
2606
"    <![CDATA[\n"
 
2607
"\n"
 
2608
"      SIP/2.0 200 OK\n"
 
2609
"      [last_Via:]\n"
 
2610
"      [last_From:]\n"
 
2611
"      [last_To:]\n"
 
2612
"      [last_Call-ID:]\n"
 
2613
"      [last_CSeq:]\n"
 
2614
"      Contact: <sip:[local_ip]:[local_port];transport=[transport]>\n"
 
2615
"      Content-Length: 0\n"
 
2616
"\n"
 
2617
"    ]]>\n"
 
2618
"  </send>\n"
 
2619
"\n"
 
2620
"  <!-- Keep the call open for a while in case the 200 is lost to be     -->\n"
 
2621
"  <!-- able to retransmit it if we receive the BYE again.               -->\n"
 
2622
"  <timewait milliseconds=\"2000\"/>\n"
 
2623
"\n"
 
2624
"</scenario>\n"
 
2625
"\n",
 
2626
 
 
2627
/************* Default_scenario[6] ***************/
 
2628
(char*) 
 
2629
"<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>\n"
 
2630
"<!DOCTYPE scenario SYSTEM \"sipp.dtd\">\n"
 
2631
"\n"
 
2632
"<!-- This program is free software; you can redistribute it and/or      -->\n"
 
2633
"<!-- modify it under the terms of the GNU General Public License as     -->\n"
 
2634
"<!-- published by the Free Software Foundation; either version 2 of the -->\n"
 
2635
"<!-- License, or (at your option) any later version.                    -->\n"
 
2636
"<!--                                                                    -->\n"
 
2637
"<!-- This program is distributed in the hope that it will be useful,    -->\n"
 
2638
"<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of     -->\n"
 
2639
"<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the      -->\n"
 
2640
"<!-- GNU General Public License for more details.                       -->\n"
 
2641
"<!--                                                                    -->\n"
 
2642
"<!-- You should have received a copy of the GNU General Public License  -->\n"
 
2643
"<!-- along with this program; if not, write to the                      -->\n"
 
2644
"<!-- Free Software Foundation, Inc.,                                    -->\n"
 
2645
"<!-- 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA             -->\n"
 
2646
"<!--                                                                    -->\n"
 
2647
"<!--                 3PCC - B side emulator                             -->\n"
 
2648
"<!--                                                                    -->\n"
 
2649
"<!--             A              Controller               B              -->\n"
 
2650
"<!--             |(1) INVITE no SDP  |                   |              -->\n"
 
2651
"<!--             |<==================|                   |              -->\n"
 
2652
"<!--             |(2) 200 offer1     |                   |              -->\n"
 
2653
"<!--             |==================>|                   |              -->\n"
 
2654
"<!--             |                   |(3) INVITE offer1  |              -->\n"
 
2655
"<!--             |                   |==================>|              -->\n"
 
2656
"<!--             |                   |(4) 200 OK answer1 |              -->\n"
 
2657
"<!--             |                   |<==================|              -->\n"
 
2658
"<!--             |                   |(5) ACK            |              -->\n"
 
2659
"<!--             |                   |==================>|              -->\n"
 
2660
"<!--             |(6) ACK answer1    |                   |              -->\n"
 
2661
"<!--             |<==================|                   |              -->\n"
 
2662
"<!--             |(7) RTP            |                   |              -->\n"
 
2663
"<!--             |.......................................|              -->\n"
 
2664
"<!--                                                                    -->\n"
 
2665
"\n"
 
2666
"\n"
 
2667
"\n"
 
2668
"<scenario name=\"3PCC B side\">\n"
 
2669
"  <recv request=\"INVITE\" crlf=\"true\"> </recv>\n"
 
2670
"\n"
 
2671
"  <send>\n"
 
2672
"    <![CDATA[\n"
 
2673
"\n"
 
2674
"      SIP/2.0 200 OK\n"
 
2675
"      [last_Via:]\n"
 
2676
"      [last_From:]\n"
 
2677
"      [last_To:];tag=[pid]SIPpTag06[call_number]\n"
 
2678
"      [last_Call-ID:]\n"
 
2679
"      [last_CSeq:]\n"
 
2680
"      Contact: <sip:[local_ip]:[local_port];transport=[transport]>\n"
 
2681
"      Content-Type: application/sdp\n"
 
2682
"      Content-Length: [len]\n"
 
2683
"\n"
 
2684
"      v=0\n"
 
2685
"      o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip]\n"
 
2686
"      s=-\n"
 
2687
"      c=IN IP[media_ip_type] [media_ip]\n"
 
2688
"      t=0 0\n"
 
2689
"      m=audio [media_port] RTP/AVP 0\n"
 
2690
"      a=rtpmap:0 PCMU/8000\n"
 
2691
"\n"
 
2692
"    ]]>\n"
 
2693
"  </send>\n"
 
2694
"\n"
 
2695
"  <recv request=\"ACK\" rtd=\"true\" crlf=\"true\"> </recv>\n"
 
2696
"\n"
 
2697
"  <!-- RTP flow starts from here! -->\n"
 
2698
"\n"
 
2699
"  <recv request=\"BYE\"> </recv>\n"
 
2700
"\n"
 
2701
"  <send>\n"
 
2702
"    <![CDATA[\n"
 
2703
"\n"
 
2704
"      SIP/2.0 200 OK\n"
 
2705
"      [last_Via:]\n"
 
2706
"      [last_From:]\n"
 
2707
"      [last_To:]\n"
 
2708
"      [last_Call-ID:]\n"
 
2709
"      [last_CSeq:]\n"
 
2710
"      Contact: <sip:[local_ip]:[local_port];transport=[transport]>\n"
 
2711
"      Content-Length: 0\n"
 
2712
"\n"
 
2713
"    ]]>\n"
 
2714
"  </send>\n"
 
2715
"\n"
 
2716
"  <!-- Keep the call open for a while in case the 200 is lost to be     -->\n"
 
2717
"  <!-- able to retransmit it if we receive the BYE again.               -->\n"
 
2718
"  <timewait milliseconds=\"2000\"/>\n"
 
2719
"\n"
 
2720
"</scenario>\n",
 
2721
 
 
2722
/************* Default_scenario[7] ***************/
 
2723
(char*)
 
2724
"<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>\n"
 
2725
"<!DOCTYPE scenario SYSTEM \"sipp.dtd\">\n"
 
2726
"\n"
 
2727
"<!-- This program is free software; you can redistribute it and/or      -->\n"
 
2728
"<!-- modify it under the terms of the GNU General Public License as     -->\n"
 
2729
"<!-- published by the Free Software Foundation; either version 2 of the -->\n"
 
2730
"<!-- License, or (at your option) any later version.                    -->\n"
 
2731
"<!--                                                                    -->\n"
 
2732
"<!-- This program is distributed in the hope that it will be useful,    -->\n"
 
2733
"<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of     -->\n"
 
2734
"<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the      -->\n"
 
2735
"<!-- GNU General Public License for more details.                       -->\n"
 
2736
"<!--                                                                    -->\n"
 
2737
"<!-- You should have received a copy of the GNU General Public License  -->\n"
 
2738
"<!-- along with this program; if not, write to the                      -->\n"
 
2739
"<!-- Free Software Foundation, Inc.,                                    -->\n"
 
2740
"<!-- 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA             -->\n"
 
2741
"<!--                                                                    -->\n"
 
2742
"<!--                 Sipp default 'branchc' scenario.                   -->\n"
 
2743
"<!--                                                                    -->\n"
 
2744
"\n"
 
2745
"<scenario name=\"branch_client\">\n"
 
2746
"  <send retrans=\"500\">\n"
 
2747
"    <![CDATA[\n"
 
2748
"\n"
 
2749
"      REGISTER sip:CA.cym.com SIP/2.0\n"
 
2750
"      Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
 
2751
"      From: ua1 <sip:ua1@nnl.cym:[local_port]>;tag=[pid]SIPpTag07[call_number]\n"
 
2752
"      To: ua1 <sip:ua1@nnl.cym:[local_port]>\n"
 
2753
"      Call-ID: [call_id]\n"
 
2754
"      CSeq: 1 REGISTER\n"
 
2755
"      Contact: sip:ua1@[local_ip]:[local_port]\n"
 
2756
"      Content-Length: 0\n"
 
2757
"      Expires: 300\n"
 
2758
"\n"
 
2759
"    ]]>\n"
 
2760
"  </send>\n"
 
2761
"\n"
 
2762
"  <!-- simple case - just jump over a line   -->\n"
 
2763
"  <recv response=\"200\" rtd=\"true\" next=\"5\">\n"
 
2764
"  </recv>\n"
 
2765
"\n"
 
2766
"  <recv response=\"200\">\n"
 
2767
"  </recv>\n"
 
2768
"\n"
 
2769
"  <label id=\"5\"/>\n"
 
2770
"\n"
 
2771
"  <send retrans=\"500\">\n"
 
2772
"    <![CDATA[\n"
 
2773
"\n"
 
2774
"      INVITE sip:ua2@CA.cym.com SIP/2.0\n"
 
2775
"      Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
 
2776
"      From: ua[call_number] <sip:ua1@nnl.cym:[local_port]>;tag=[pid]SIPpTag07b[call_number]\n"
 
2777
"      To: ua2 <sip:ua2@nnl.cym:[remote_port]>\n"
 
2778
"      Call-ID: [call_id]\n"
 
2779
"      CSeq: 1 INVITE\n"
 
2780
"      Contact: sip:ua1@[local_ip]:[local_port]\n"
 
2781
"      Max-Forwards: 70\n"
 
2782
"      Subject: Performance Test\n"
 
2783
"      Content-Type: application/sdp\n"
 
2784
"      Content-Length: [len]\n"
 
2785
"\n"
 
2786
"      v=0\n"
 
2787
"      o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip]\n"
 
2788
"      s=-\n"
 
2789
"      c=IN IP[media_ip_type] [media_ip]\n"
 
2790
"      t=0 0\n"
 
2791
"      m=audio [media_port] RTP/AVP 0\n"
 
2792
"      a=rtpmap:0 PCMU/8000\n"
 
2793
"\n"
 
2794
"    ]]>\n"
 
2795
"  </send>\n"
 
2796
"\n"
 
2797
"  <recv response=\"100\" optional=\"true\">\n"
 
2798
"  </recv>\n"
 
2799
"\n"
 
2800
"  <recv response=\"180\" optional=\"true\">\n"
 
2801
"  </recv>\n"
 
2802
"\n"
 
2803
"  <recv response=\"183\" optional=\"true\">\n"
 
2804
"  </recv>\n"
 
2805
"\n"
 
2806
"  <!-- Do something different on an optional receive   -->\n"
 
2807
"  <recv response=\"403\" optional=\"true\" next=\"1\">\n"
 
2808
"  </recv>\n"
 
2809
"\n"
 
2810
"  <recv response=\"200\">\n"
 
2811
"    <action>\n"
 
2812
"      <ereg regexp=\"ua25\"\n"
 
2813
"            search_in=\"hdr\"\n"
 
2814
"            header=\"From: \"\n"
 
2815
"            assign_to=\"8\"/>\n"
 
2816
"    </action>\n"
 
2817
"  </recv>\n"
 
2818
"\n"
 
2819
"  <!-- set variable 8 above on 25th call, send the ACK but skip the pause for it   -->\n"
 
2820
"  <send next=\"1\" test=\"8\">\n"
 
2821
"    <![CDATA[\n"
 
2822
"\n"
 
2823
"      ACK sip:ua2@CA.cym.com SIP/2.0\n"
 
2824
"      Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
 
2825
"      From: ua1 <sip:ua1@nnl.cym:[local_port]>;tag=[pid]SIPpTag07b[call_number]\n"
 
2826
"      To: ua2 <sip:ua2@nnl.cym:[remote_port]>[peer_tag_param]\n"
 
2827
"      Call-ID: [call_id]\n"
 
2828
"      CSeq: 1 ACK\n"
 
2829
"      Contact: sip:ua1@[local_ip]:[local_port]\n"
 
2830
"      Max-Forwards: 70\n"
 
2831
"      Subject: Performance Test\n"
 
2832
"      Content-Length: 0\n"
 
2833
"\n"
 
2834
"    ]]>\n"
 
2835
"  </send>\n"
 
2836
"\n"
 
2837
"  <pause milliseconds=\"5000\"/>\n"
 
2838
"\n"
 
2839
"  <label id=\"1\"/>\n"
 
2840
"\n"
 
2841
"  <send retrans=\"500\">\n"
 
2842
"    <![CDATA[\n"
 
2843
"\n"
 
2844
"      BYE sip:ua2@CA.cym.com SIP/2.0\n"
 
2845
"      Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
 
2846
"      From: ua1 <sip:ua1@nnl.cym:[local_port]>;tag=[pid]SIPpTag07b[call_number]\n"
 
2847
"      To: ua2 <sip:ua2@nnl.cym:[remote_port]>[peer_tag_param]\n"
 
2848
"      Call-ID: [call_id]\n"
 
2849
"      CSeq: 2 BYE\n"
 
2850
"      Contact: sip:ua1@[local_ip]:[local_port]\n"
 
2851
"      Max-Forwards: 70\n"
 
2852
"      Subject: Performance Test\n"
 
2853
"      Content-Length: 0\n"
 
2854
"\n"
 
2855
"    ]]>\n"
 
2856
"  </send>\n"
 
2857
"\n"
 
2858
"  <recv response=\"200\" crlf=\"true\">\n"
 
2859
"  </recv>\n"
 
2860
"\n"
 
2861
"  <pause milliseconds=\"4000\"/>\n"
 
2862
"\n"
 
2863
"  <!-- definition of the response time repartition table (unit is ms)   -->\n"
 
2864
"  <ResponseTimeRepartition value=\"10, 20, 30, 40, 50, 100, 150, 200\"/>\n"
 
2865
"\n"
 
2866
"  <!-- definition of the call length repartition table (unit is ms)     -->\n"
 
2867
"  <CallLengthRepartition value=\"10, 50, 100, 500, 1000, 5000, 10000\"/>\n"
 
2868
"\n"
 
2869
"</scenario>\n"
 
2870
"\n",
 
2871
 
 
2872
/************* Default_scenario[8] ***************/
 
2873
(char*)
 
2874
"<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>\n"
 
2875
"<!DOCTYPE scenario SYSTEM \"sipp.dtd\">\n"
 
2876
"\n"
 
2877
"<!-- This program is free software; you can redistribute it and/or      -->\n"
 
2878
"<!-- modify it under the terms of the GNU General Public License as     -->\n"
 
2879
"<!-- published by the Free Software Foundation; either version 2 of the -->\n"
 
2880
"<!-- License, or (at your option) any later version.                    -->\n"
 
2881
"<!--                                                                    -->\n"
 
2882
"<!-- This program is distributed in the hope that it will be useful,    -->\n"
 
2883
"<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of     -->\n"
 
2884
"<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the      -->\n"
 
2885
"<!-- GNU General Public License for more details.                       -->\n"
 
2886
"<!--                                                                    -->\n"
 
2887
"<!-- You should have received a copy of the GNU General Public License  -->\n"
 
2888
"<!-- along with this program; if not, write to the                      -->\n"
 
2889
"<!-- Free Software Foundation, Inc.,                                    -->\n"
 
2890
"<!-- 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA             -->\n"
 
2891
"<!--                                                                    -->\n"
 
2892
"<!--                 Sipp default 'branchs' scenario.                   -->\n"
 
2893
"<!--                                                                    -->\n"
 
2894
"\n"
 
2895
"<scenario name=\"branch_server\">\n"
 
2896
"  <recv request=\"REGISTER\">\n"
 
2897
"  </recv>\n"
 
2898
"\n"
 
2899
"  <send>\n"
 
2900
"    <![CDATA[\n"
 
2901
"\n"
 
2902
"      SIP/2.0 200 OK\n"
 
2903
"      [last_Via:]\n"
 
2904
"      [last_From:]\n"
 
2905
"      [last_To:];tag=[pid]SIPpTag08[call_number]\n"
 
2906
"      [last_Call-ID:]\n"
 
2907
"      [last_CSeq:]\n"
 
2908
"      Contact: <sip:[local_ip]:[local_port];transport=[transport]>\n"
 
2909
"      Content-Length: 0\n"
 
2910
"      Expires: 300\n"
 
2911
"\n"
 
2912
"    ]]>\n"
 
2913
"  </send>\n"
 
2914
"\n"
 
2915
"  <!-- Set variable 3 if the ua is of the form ua2... -->\n"
 
2916
"  <recv request=\"INVITE\" crlf=\"true\">\n"
 
2917
"    <action>\n"
 
2918
"      <ereg regexp=\"ua2\"\n"
 
2919
"            search_in=\"hdr\"\n"
 
2920
"            header=\"From: \"\n"
 
2921
"            assign_to=\"3\"/>\n"
 
2922
"    </action>\n"
 
2923
"  </recv>\n"
 
2924
"\n"
 
2925
"  <!-- send 180 then trying if variable 3 is set -->\n"
 
2926
"  <send next=\"1\" test=\"3\">\n"
 
2927
"    <![CDATA[\n"
 
2928
"\n"
 
2929
"      SIP/2.0 180 Ringing\n"
 
2930
"      [last_Via:]\n"
 
2931
"      [last_From:]\n"
 
2932
"      [last_To:];tag=[pid]SIPpTag08b[call_number]\n"
 
2933
"      [last_Call-ID:]\n"
 
2934
"      [last_CSeq:]\n"
 
2935
"      Contact: <sip:[local_ip]:[local_port];transport=[transport]>\n"
 
2936
"      Content-Length: 0\n"
 
2937
"\n"
 
2938
"    ]]>\n"
 
2939
"  </send>\n"
 
2940
"\n"
 
2941
"  <!-- if not, send a 403 error then skip to wait for a BYE -->\n"
 
2942
"  <send next=\"2\">\n"
 
2943
"    <![CDATA[\n"
 
2944
"\n"
 
2945
"      SIP/2.0 403 Error\n"
 
2946
"      [last_Via:]\n"
 
2947
"      [last_From:]\n"
 
2948
"      [last_To:];tag=[pid]SIPpTag08b[call_number]\n"
 
2949
"      [last_Call-ID:]\n"
 
2950
"      [last_CSeq:]\n"
 
2951
"      Contact: <sip:[local_ip]:[local_port];transport=[transport]>\n"
 
2952
"      Content-Length: 0\n"
 
2953
"\n"
 
2954
"    ]]>\n"
 
2955
"  </send>\n"
 
2956
"\n"
 
2957
"  <label id=\"1\"/>\n"
 
2958
"\n"
 
2959
"  <send>\n"
 
2960
"    <![CDATA[\n"
 
2961
"\n"
 
2962
"      SIP/2.0 100 Trying\n"
 
2963
"      [last_Via:]\n"
 
2964
"      [last_From:]\n"
 
2965
"      [last_To:];tag=[pid]SIPpTag08b[call_number]\n"
 
2966
"      [last_Call-ID:]\n"
 
2967
"      [last_CSeq:]\n"
 
2968
"      Contact: <sip:[local_ip]:[local_port];transport=[transport]>\n"
 
2969
"      Content-Length: 0\n"
 
2970
"\n"
 
2971
"    ]]>\n"
 
2972
"  </send>\n"
 
2973
"\n"
 
2974
"  <send retrans=\"500\">\n"
 
2975
"    <![CDATA[\n"
 
2976
"\n"
 
2977
"      SIP/2.0 200 OK\n"
 
2978
"      [last_Via:]\n"
 
2979
"      [last_From:]\n"
 
2980
"      [last_To:];tag=[pid]SIPpTag08b[call_number]\n"
 
2981
"      [last_Call-ID:]\n"
 
2982
"      [last_CSeq:]\n"
 
2983
"      Contact: <sip:[local_ip]:[local_port];transport=[transport]>\n"
 
2984
"      Content-Type: application/sdp\n"
 
2985
"      Content-Length: [len]\n"
 
2986
"\n"
 
2987
"      v=0\n"
 
2988
"      o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip]\n"
 
2989
"      s=-\n"
 
2990
"      c=IN IP[media_ip_type] [media_ip]\n"
 
2991
"      t=0 0\n"
 
2992
"      m=audio [media_port] RTP/AVP 0\n"
 
2993
"      a=rtpmap:0 PCMU/8000\n"
 
2994
"\n"
 
2995
"    ]]>\n"
 
2996
"  </send>\n"
 
2997
"\n"
 
2998
"  <recv request=\"ACK\"\n"
 
2999
"        optional=\"true\"\n"
 
3000
"        rtd=\"true\"\n"
 
3001
"        crlf=\"true\">\n"
 
3002
"  </recv>\n"
 
3003
"\n"
 
3004
"  <label id=\"2\"/>\n"
 
3005
"\n"
 
3006
"  <recv request=\"BYE\">\n"
 
3007
"  </recv>\n"
 
3008
"\n"
 
3009
"  <send>\n"
 
3010
"    <![CDATA[\n"
 
3011
"\n"
 
3012
"      SIP/2.0 200 OK\n"
 
3013
"      [last_Via:]\n"
 
3014
"      [last_From:]\n"
 
3015
"      [last_To:]\n"
 
3016
"      [last_Call-ID:]\n"
 
3017
"      [last_CSeq:]\n"
 
3018
"      Contact: <sip:[local_ip]:[local_port];transport=[transport]>\n"
 
3019
"      Content-Length: 0\n"
 
3020
"\n"
 
3021
"    ]]>\n"
 
3022
"  </send>\n"
 
3023
"\n"
 
3024
"  <!-- Keep the call open for a while in case the 200 is lost to be     -->\n"
 
3025
"  <!-- able to retransmit it if we receive the BYE again.               -->\n"
 
3026
"  <timewait milliseconds=\"4000\"/>\n"
 
3027
"\n"
 
3028
"  <!-- Definition of the response time repartition table (unit is ms)   -->\n"
 
3029
"  <ResponseTimeRepartition value=\"10, 20, 30, 40, 50, 100, 150, 200\"/>\n"
 
3030
"\n"
 
3031
"  <!-- Definition of the call length repartition table (unit is ms)     -->\n"
 
3032
"  <CallLengthRepartition value=\"10, 50, 100, 500, 1000, 5000, 10000\"/>\n"
 
3033
"\n"
 
3034
"</scenario>\n"
 
3035
"\n",
 
3036
 
 
3037
/* Although this scenario will not work without pcap play enabled, there is no
 
3038
 * harm in including it in the binary anyway, because the user could have
 
3039
 * dumped it and passed it with -sf. */
 
3040
 
 
3041
/************* Default_scenario[9] ***************/
 
3042
(char*)
 
3043
"<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>\n"
 
3044
"<!DOCTYPE scenario SYSTEM \"sipp.dtd\">\n"
 
3045
"\n"
 
3046
"<!-- This program is free software; you can redistribute it and/or      -->\n"
 
3047
"<!-- modify it under the terms of the GNU General Public License as     -->\n"
 
3048
"<!-- published by the Free Software Foundation; either version 2 of the -->\n"
 
3049
"<!-- License, or (at your option) any later version.                    -->\n"
 
3050
"<!--                                                                    -->\n"
 
3051
"<!-- This program is distributed in the hope that it will be useful,    -->\n"
 
3052
"<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of     -->\n"
 
3053
"<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the      -->\n"
 
3054
"<!-- GNU General Public License for more details.                       -->\n"
 
3055
"<!--                                                                    -->\n"
 
3056
"<!-- You should have received a copy of the GNU General Public License  -->\n"
 
3057
"<!-- along with this program; if not, write to the                      -->\n"
 
3058
"<!-- Free Software Foundation, Inc.,                                    -->\n"
 
3059
"<!-- 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA             -->\n"
 
3060
"<!--                                                                    -->\n"
 
3061
"<!--                 Sipp 'uac' scenario with pcap (rtp) play           -->\n"
 
3062
"<!--                                                                    -->\n"
 
3063
"\n"
 
3064
"<scenario name=\"UAC with media\">\n"
 
3065
"  <!-- In client mode (sipp placing calls), the Call-ID MUST be         -->\n"
 
3066
"  <!-- generated by sipp. To do so, use [call_id] keyword.                -->\n"
 
3067
"  <send retrans=\"500\">\n"
 
3068
"    <![CDATA[\n"
 
3069
"\n"
 
3070
"      INVITE sip:[service]@[remote_ip]:[remote_port] SIP/2.0\n"
 
3071
"      Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
 
3072
"      From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag09[call_number]\n"
 
3073
"      To: sut <sip:[service]@[remote_ip]:[remote_port]>\n"
 
3074
"      Call-ID: [call_id]\n"
 
3075
"      CSeq: 1 INVITE\n"
 
3076
"      Contact: sip:sipp@[local_ip]:[local_port]\n"
 
3077
"      Max-Forwards: 70\n"
 
3078
"      Subject: Performance Test\n"
 
3079
"      Content-Type: application/sdp\n"
 
3080
"      Content-Length: [len]\n"
 
3081
"\n"
 
3082
"      v=0\n"
 
3083
"      o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip]\n"
 
3084
"      s=-\n"
 
3085
"      c=IN IP[local_ip_type] [local_ip]\n"
 
3086
"      t=0 0\n"
 
3087
"      m=audio [auto_media_port] RTP/AVP 8 101\n"
 
3088
"      a=rtpmap:8 PCMA/8000\n"
 
3089
"      a=rtpmap:101 telephone-event/8000\n"
 
3090
"      a=fmtp:101 0-11,16\n"
 
3091
"\n"
 
3092
"    ]]>\n"
 
3093
"  </send>\n"
 
3094
"\n"
 
3095
"  <recv response=\"100\" optional=\"true\">\n"
 
3096
"  </recv>\n"
 
3097
"\n"
 
3098
"  <recv response=\"180\" optional=\"true\">\n"
 
3099
"  </recv>\n"
 
3100
"\n"
 
3101
"  <!-- By adding rrs=\"true\" (Record Route Sets), the route sets         -->\n"
 
3102
"  <!-- are saved and used for following messages sent. Useful to test   -->\n"
 
3103
"  <!-- against stateful SIP proxies/B2BUAs.                             -->\n"
 
3104
"  <recv response=\"200\" rtd=\"true\" crlf=\"true\">\n"
 
3105
"  </recv>\n"
 
3106
"\n"
 
3107
"  <!-- Packet lost can be simulated in any send/recv message by         -->\n"
 
3108
"  <!-- by adding the 'lost = \"10\"'. Value can be [1-100] percent.       -->\n"
 
3109
"  <send>\n"
 
3110
"    <![CDATA[\n"
 
3111
"\n"
 
3112
"      ACK sip:[service]@[remote_ip]:[remote_port] SIP/2.0\n"
 
3113
"      Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
 
3114
"      From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag09[call_number]\n"
 
3115
"      To: sut <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param]\n"
 
3116
"      Call-ID: [call_id]\n"
 
3117
"      CSeq: 1 ACK\n"
 
3118
"      Contact: sip:sipp@[local_ip]:[local_port]\n"
 
3119
"      Max-Forwards: 70\n"
 
3120
"      Subject: Performance Test\n"
 
3121
"      Content-Length: 0\n"
 
3122
"\n"
 
3123
"    ]]>\n"
 
3124
"  </send>\n"
 
3125
"\n"
 
3126
"  <!-- Play a pre-recorded PCAP file (RTP stream)                       -->\n"
 
3127
"  <nop>\n"
 
3128
"    <action>\n"
 
3129
"      <exec play_pcap_audio=\"pcap/g711a.pcap\"/>\n"
 
3130
"    </action>\n"
 
3131
"  </nop>\n"
 
3132
"\n"
 
3133
"  <!-- Pause 8 seconds, which is approximately the duration of the      -->\n"
 
3134
"  <!-- PCAP file                                                        -->\n"
 
3135
"  <pause milliseconds=\"8000\"/>\n"
 
3136
"\n"
 
3137
"  <!-- Play an out of band DTMF '1'                                     -->\n"
 
3138
"  <nop>\n"
 
3139
"    <action>\n"
 
3140
"      <exec play_pcap_audio=\"pcap/dtmf_2833_1.pcap\"/>\n"
 
3141
"    </action>\n"
 
3142
"  </nop>\n"
 
3143
"\n"
 
3144
"  <pause milliseconds=\"1000\"/>\n"
 
3145
"\n"
 
3146
"  <!-- The 'crlf' option inserts a blank line in the statistics report. -->\n"
 
3147
"  <send retrans=\"500\">\n"
 
3148
"    <![CDATA[\n"
 
3149
"\n"
 
3150
"      BYE sip:[service]@[remote_ip]:[remote_port] SIP/2.0\n"
 
3151
"      Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
 
3152
"      From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag09[call_number]\n"
 
3153
"      To: sut <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param]\n"
 
3154
"      Call-ID: [call_id]\n"
 
3155
"      CSeq: 2 BYE\n"
 
3156
"      Contact: sip:sipp@[local_ip]:[local_port]\n"
 
3157
"      Max-Forwards: 70\n"
 
3158
"      Subject: Performance Test\n"
 
3159
"      Content-Length: 0\n"
 
3160
"\n"
 
3161
"    ]]>\n"
 
3162
"  </send>\n"
 
3163
"\n"
 
3164
"  <recv response=\"200\" crlf=\"true\">\n"
 
3165
"  </recv>\n"
 
3166
"\n"
 
3167
"  <!-- definition of the response time repartition table (unit is ms)   -->\n"
 
3168
"  <ResponseTimeRepartition value=\"10, 20, 30, 40, 50, 100, 150, 200\"/>\n"
 
3169
"\n"
 
3170
"  <!-- definition of the call length repartition table (unit is ms)     -->\n"
 
3171
"  <CallLengthRepartition value=\"10, 50, 100, 500, 1000, 5000, 10000\"/>\n"
 
3172
"\n"
 
3173
"</scenario>\n"
 
3174
"\n",
 
3175
"<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>\n"
 
3176
"<!DOCTYPE scenario SYSTEM \"sipp.dtd\">\n"
 
3177
"\n"
 
3178
"<!-- This program is free software; you can redistribute it and/or      -->\n"
 
3179
"<!-- modify it under the terms of the GNU General Public License as     -->\n"
 
3180
"<!-- published by the Free Software Foundation; either version 2 of the -->\n"
 
3181
"<!-- License, or (at your option) any later version.                    -->\n"
 
3182
"<!--                                                                    -->\n"
 
3183
"<!-- This program is distributed in the hope that it will be useful,    -->\n"
 
3184
"<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of     -->\n"
 
3185
"<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the      -->\n"
 
3186
"<!-- GNU General Public License for more details.                       -->\n"
 
3187
"<!--                                                                    -->\n"
 
3188
"<!-- You should have received a copy of the GNU General Public License  -->\n"
 
3189
"<!-- along with this program; if not, write to the                      -->\n"
 
3190
"<!-- Free Software Foundation, Inc.,                                    -->\n"
 
3191
"<!-- 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA             -->\n"
 
3192
"<!--                                                                    -->\n"
 
3193
"<!--                 Sipp default 'uas' scenario.                       -->\n"
 
3194
"<!--                                                                    -->\n"
 
3195
"\n"
 
3196
"<scenario name=\"Out-of-call UAS\">\n"
 
3197
"  <recv request=\".*\" regexp_match=\"true\" />\n"
 
3198
"\n"
 
3199
"  <send>\n"
 
3200
"    <![CDATA[\n"
 
3201
"      SIP/2.0 200 OK\n"
 
3202
"      [last_Via:]\n"
 
3203
"      [last_From:]\n"
 
3204
"      [last_To:]\n"
 
3205
"      [last_Call-ID:]\n"
 
3206
"      [last_CSeq:]\n"
 
3207
"      Contact: <sip:[local_ip]:[local_port];transport=[transport]>\n"
 
3208
"      Content-Length: 0\n"
 
3209
"\n"
 
3210
"    ]]>\n"
 
3211
"  </send>\n"
 
3212
"\n"
 
3213
"  <!-- Keep the call open for a while in case the 200 is lost to be     -->\n"
 
3214
"  <!-- able to retransmit it if we receive the BYE again.               -->\n"
 
3215
"  <timewait milliseconds=\"4000\"/>\n"
 
3216
"\n"
 
3217
"\n"
 
3218
"  <!-- definition of the response time repartition table (unit is ms)   -->\n"
 
3219
"  <ResponseTimeRepartition value=\"10, 20, 30, 40, 50, 100, 150, 200\"/>\n"
 
3220
"\n"
 
3221
"  <!-- definition of the call length repartition table (unit is ms)     -->\n"
 
3222
"  <CallLengthRepartition value=\"10, 50, 100, 500, 1000, 5000, 10000\"/>\n"
 
3223
"\n"
 
3224
"</scenario>\n",
 
3225
};