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 * Authors : Benjamin GAUTHIER - 24 Mar 2004
17 * Joseph BANINO
18 * Olivier JACQUES
19 * Richard GAYRAUD
20 * From Hewlett Packard Company.
21 * Guillaume Teissier from FTR&D
22 */
23
24 #include "sipp.hpp"
25 #include <assert.h>
26 #ifdef PCAPPLAY
27 #include "prepare_pcap.h"
28 #endif
29
30
strIntCmd(CAction::T_IntCmdType type)31 static const char* strIntCmd(CAction::T_IntCmdType type)
32 {
33 switch (type) {
34 case CAction::E_INTCMD_STOPCALL:
35 return "stop_call";
36 case CAction::E_INTCMD_STOP_ALL:
37 return "stop_gracefully";
38 case CAction::E_INTCMD_STOP_NOW:
39 return "stop_now";
40
41 default:
42 case CAction::E_INTCMD_INVALID:
43 return "invalid";
44 }
45 return "invalid";
46 }
47
comparatorToString(T_Comparator comp)48 const char * CAction::comparatorToString(T_Comparator comp)
49 {
50 switch(comp) {
51 case E_C_EQ:
52 return "==";
53 case E_C_NE:
54 return "!=";
55 case E_C_GT:
56 return ">";
57 case E_C_LT:
58 return "<";
59 case E_C_GEQ:
60 return ">=";
61 case E_C_LEQ:
62 return "<=";
63 default:
64 return "invalid";
65 }
66 }
67
compare(VariableTable * variableTable)68 bool CAction::compare(VariableTable *variableTable)
69 {
70 double lhs = variableTable->getVar(M_varInId)->getDouble();
71 double rhs = M_varIn2Id ? variableTable->getVar(M_varIn2Id)->getDouble() : M_doubleValue;
72
73 switch(M_comp) {
74 case E_C_EQ:
75 return lhs == rhs;
76 case E_C_NE:
77 return lhs != rhs;
78 case E_C_GT:
79 return lhs > rhs;
80 case E_C_LT:
81 return lhs < rhs;
82 case E_C_GEQ:
83 return lhs >= rhs;
84 case E_C_LEQ:
85 return lhs <= rhs;
86 default:
87 ERROR("Internal error: Invalid comparison type %d", M_comp);
88 return false; /* Shut up warning. */
89 }
90 }
91
afficheInfo()92 void CAction::afficheInfo()
93 {
94 if (M_action == E_AT_ASSIGN_FROM_REGEXP) {
95 if(M_lookingPlace == E_LP_MSG) {
96 printf("Type[%d] - regexp[%s] where[%s] - checkIt[%d] - checkItInverse[%d] - $%s",
97 M_action,
98 M_regularExpression,
99 "Full Msg",
100 M_checkIt,
101 M_checkItInverse,
102 display_scenario->allocVars->getName(M_varId));
103 } else {
104 printf("Type[%d] - regexp[%s] where[%s-%s] - checkIt[%d] - checkItInverse[%d] - $%s",
105 M_action,
106 M_regularExpression,
107 "Header",
108 M_lookingChar,
109 M_checkIt,
110 M_checkItInverse, display_scenario->allocVars->getName(M_varId));
111 }
112 } else if (M_action == E_AT_EXECUTE_CMD) {
113 printf("Type[%d] - command[%-32.32s]", M_action, M_message_str[0]);
114 } else if (M_action == E_AT_EXEC_INTCMD) {
115 printf("Type[%d] - intcmd[%-32.32s]", M_action, strIntCmd(M_IntCmd));
116 } else if (M_action == E_AT_LOG_TO_FILE) {
117 printf("Type[%d] - message[%-32.32s]", M_action, M_message_str[0]);
118 } else if (M_action == E_AT_LOG_WARNING) {
119 printf("Type[%d] - warning[%-32.32s]", M_action, M_message_str[0]);
120 } else if (M_action == E_AT_LOG_ERROR) {
121 printf("Type[%d] - error[%-32.32s]", M_action, M_message_str[0]);
122 } else if (M_action == E_AT_ASSIGN_FROM_SAMPLE) {
123 char tmp[40];
124 M_distribution->textDescr(tmp, sizeof(tmp));
125 printf("Type[%d] - sample varId[%s] %s", M_action, display_scenario->allocVars->getName(M_varId), tmp);
126 } else if (M_action == E_AT_ASSIGN_FROM_VALUE) {
127 printf("Type[%d] - assign varId[%s] %lf", M_action, display_scenario->allocVars->getName(M_varId), M_doubleValue);
128 } else if (M_action == E_AT_ASSIGN_FROM_INDEX) {
129 printf("Type[%d] - assign index[%s]", M_action, display_scenario->allocVars->getName(M_varId));
130 } else if (M_action == E_AT_ASSIGN_FROM_GETTIMEOFDAY) {
131 printf("Type[%d] - assign gettimeofday[%s, %s]", M_action, display_scenario->allocVars->getName(M_varId), display_scenario->allocVars->getName(M_subVarId[0]));
132 } else if (M_action == E_AT_ASSIGN_FROM_STRING) {
133 printf("Type[%d] - string assign varId[%s] [%-32.32s]", M_action, display_scenario->allocVars->getName(M_varId), M_message_str[0]);
134 } else if (M_action == E_AT_JUMP) {
135 printf("Type[%d] - jump varInId[%s] %lf", M_action, display_scenario->allocVars->getName(M_varInId), M_doubleValue);
136 } else if (M_action == E_AT_PAUSE_RESTORE) {
137 printf("Type[%d] - restore pause varInId[%s] %lf", M_action, display_scenario->allocVars->getName(M_varInId), M_doubleValue);
138 } else if (M_action == E_AT_VAR_ADD) {
139 printf("Type[%d] - add varId[%s] %lf", M_action, display_scenario->allocVars->getName(M_varId), M_doubleValue);
140 } else if (M_action == E_AT_VAR_MULTIPLY) {
141 printf("Type[%d] - multiply varId[%s] %lf", M_action, display_scenario->allocVars->getName(M_varId), M_doubleValue);
142 } else if (M_action == E_AT_VAR_DIVIDE) {
143 printf("Type[%d] - divide varId[%s] %lf", M_action, display_scenario->allocVars->getName(M_varId), M_doubleValue);
144 } else if (M_action == E_AT_VAR_TRIM) {
145 printf("Type[%d] - trim varId[%s]", M_action, display_scenario->allocVars->getName(M_varId));
146 } else if (M_action == E_AT_VAR_TEST) {
147 printf("Type[%d] - divide varId[%s] varInId[%s] %s %lf", M_action, display_scenario->allocVars->getName(M_varId), display_scenario->allocVars->getName(M_varInId), comparatorToString(M_comp), M_doubleValue);
148 } else if (M_action == E_AT_VAR_TO_DOUBLE) {
149 printf("Type[%d] - toDouble varId[%s]", M_action, display_scenario->allocVars->getName(M_varId));
150 #ifdef PCAPPLAY
151 } else if ((M_action == E_AT_PLAY_PCAP_AUDIO) || (M_action == E_AT_PLAY_PCAP_IMAGE) || (M_action == E_AT_PLAY_PCAP_VIDEO)) {
152 printf("Type[%d] - file[%s]", M_action, M_pcapArgs->file);
153 #endif
154
155 #ifdef RTP_STREAM
156 } else if (M_action == E_AT_RTP_STREAM_PLAY) {
157 printf("Type[%d] - rtp_stream playfile file %s loop=%d payload %d bytes per packet=%d ms per packet=%d ticks per packet=%d", M_action,M_rtpstream_actinfo.filename,M_rtpstream_actinfo.loop_count,M_rtpstream_actinfo.payload_type,M_rtpstream_actinfo.bytes_per_packet,M_rtpstream_actinfo.ms_per_packet,M_rtpstream_actinfo.ticks_per_packet);
158 } else if (M_action == E_AT_RTP_STREAM_PAUSE) {
159 printf("Type[%d] - rtp_stream pause", M_action);
160 } else if (M_action == E_AT_RTP_STREAM_RESUME) {
161 printf("Type[%d] - rtp_stream resume", M_action);
162 #endif
163
164 } else {
165 printf("Type[%d] - unknown action type ... ", M_action);
166 }
167 }
168
169
getActionType()170 CAction::T_ActionType CAction::getActionType()
171 {
172 return(M_action);
173 }
getLookingPlace()174 CAction::T_LookingPlace CAction::getLookingPlace()
175 {
176 return(M_lookingPlace);
177 }
getIntCmd()178 CAction::T_IntCmdType CAction::getIntCmd ()
179 {
180 return(M_IntCmd);
181 }
getComparator()182 CAction::T_Comparator CAction::getComparator ()
183 {
184 return(M_comp);
185 }
186
getCheckIt()187 bool CAction::getCheckIt()
188 {
189 return(M_checkIt);
190 }
getCheckItInverse()191 bool CAction::getCheckItInverse()
192 {
193 return(M_checkItInverse);
194 }
getCaseIndep()195 bool CAction::getCaseIndep()
196 {
197 return(M_caseIndep);
198 }
getHeadersOnly()199 bool CAction::getHeadersOnly()
200 {
201 return(M_headersOnly);
202 }
getOccurrence()203 int CAction::getOccurrence()
204 {
205 return(M_occurrence);
206 }
getVarId()207 int CAction::getVarId()
208 {
209 return(M_varId);
210 }
getVarInId()211 int CAction::getVarInId()
212 {
213 return(M_varInId);
214 }
getVarIn2Id()215 int CAction::getVarIn2Id()
216 {
217 return(M_varIn2Id);
218 }
getLookingChar()219 char* CAction::getLookingChar()
220 {
221 return(M_lookingChar);
222 }
getMessage(int n)223 SendingMessage *CAction::getMessage(int n)
224 {
225 return(M_message[n]);
226 }
getDistribution()227 CSample* CAction::getDistribution()
228 {
229 return(M_distribution);
230 }
getDoubleValue()231 double CAction::getDoubleValue()
232 {
233 return(M_doubleValue);
234 }
getStringValue()235 char* CAction::getStringValue()
236 {
237 return(M_stringValue);
238 }
239 #ifdef PCAPPLAY
getPcapPkts()240 pcap_pkts * CAction::getPcapPkts()
241 {
242 return(M_pcapArgs);
243 }
244 #endif
245 #ifdef RTP_STREAM
getRTPStreamActInfo()246 rtpstream_actinfo_t *CAction::getRTPStreamActInfo() { return (&M_rtpstream_actinfo); }
247 #endif
248
setActionType(CAction::T_ActionType P_value)249 void CAction::setActionType (CAction::T_ActionType P_value)
250 {
251 M_action = P_value;
252 }
setLookingPlace(CAction::T_LookingPlace P_value)253 void CAction::setLookingPlace (CAction::T_LookingPlace P_value)
254 {
255 M_lookingPlace = P_value;
256 }
setCheckIt(bool P_value)257 void CAction::setCheckIt (bool P_value)
258 {
259 M_checkIt = P_value;
260 }
setCheckItInverse(bool P_value)261 void CAction::setCheckItInverse (bool P_value)
262 {
263 M_checkItInverse = P_value;
264 }
setVarId(int P_value)265 void CAction::setVarId (int P_value)
266 {
267 M_varId = P_value;
268 }
setVarInId(int P_value)269 void CAction::setVarInId (int P_value)
270 {
271 M_varInId = P_value;
272 }
setVarIn2Id(int P_value)273 void CAction::setVarIn2Id (int P_value)
274 {
275 M_varIn2Id = P_value;
276 }
setCaseIndep(bool P_value)277 void CAction::setCaseIndep (bool P_value)
278 {
279 M_caseIndep = P_value;
280 }
setOccurrence(int P_value)281 void CAction::setOccurrence (int P_value)
282 {
283 M_occurrence = P_value;
284 }
setHeadersOnly(bool P_value)285 void CAction::setHeadersOnly (bool P_value)
286 {
287 M_headersOnly = P_value;
288 }
setIntCmd(T_IntCmdType P_type)289 void CAction::setIntCmd (T_IntCmdType P_type)
290 {
291 M_IntCmd = P_type;
292 }
setComparator(T_Comparator P_value)293 void CAction::setComparator (T_Comparator P_value)
294 {
295 M_comp = P_value;
296 }
297
298 /* sample specific function. */
setDistribution(CSample * P_value)299 void CAction::setDistribution (CSample *P_value)
300 {
301 M_distribution = P_value;
302 }
303 /* assign from value specific function. */
setDoubleValue(double P_value)304 void CAction::setDoubleValue (double P_value)
305 {
306 M_doubleValue = P_value;
307 }
308
309 /* strcmp specific function. */
setStringValue(char * P_value)310 void CAction::setStringValue (char *P_value)
311 {
312 M_stringValue = P_value;
313 }
314
setSubVarId(int P_value)315 void CAction::setSubVarId (int P_value)
316 {
317 if ( M_nbSubVarId < M_maxNbSubVarId ) {
318 M_subVarId[M_nbSubVarId] = P_value;
319 M_nbSubVarId++;
320 }
321 }
322
getSubVarId(int P_index)323 int CAction::getSubVarId(int P_index)
324 {
325 return(M_subVarId[P_index]);
326 }
327
getSubVarId()328 int* CAction::getSubVarId()
329 {
330 return(M_subVarId);
331 }
332
setNbSubVarId(int P_value)333 void CAction::setNbSubVarId (int P_value)
334 {
335 M_maxNbSubVarId = P_value;
336 if(M_subVarId != NULL) {
337 delete [] M_subVarId;
338 M_subVarId = NULL;
339 }
340 M_subVarId = new int[M_maxNbSubVarId] ;
341 M_nbSubVarId = 0 ;
342 }
getNbSubVarId()343 int CAction::getNbSubVarId ()
344 {
345 return(M_nbSubVarId);
346 }
347
348
setLookingChar(const char * P_value)349 void CAction::setLookingChar(const char* P_value)
350 {
351 if(M_lookingChar != NULL) {
352 delete [] M_lookingChar;
353 M_lookingChar = NULL;
354 }
355
356 if(P_value != NULL) {
357 M_lookingChar = new char[strlen(P_value)+1];
358 strcpy(M_lookingChar, P_value);
359 }
360 }
361
setMessage(char * P_value,int n)362 void CAction::setMessage (char* P_value, int n)
363 {
364 if(M_message[n] != NULL) {
365 delete M_message[n];
366 M_message[n] = NULL;
367 }
368 free(M_message_str[n]);
369 M_message_str[n] = NULL;
370
371 if(P_value != NULL) {
372 M_message_str[n] = strdup(P_value);
373 M_message[n] = new SendingMessage(M_scenario, P_value, true /* skip sanity */);
374 }
375 }
376
setRegExp(const char * P_value)377 void CAction::setRegExp(const char *P_value)
378 {
379 int errorCode;
380
381 free(M_regularExpression);
382 M_regularExpression = strdup(P_value);
383 M_regExpSet = true;
384
385 errorCode = regcomp(&M_internalRegExp, P_value, REGEXP_PARAMS);
386 if(errorCode != 0) {
387 char buffer[MAX_HEADER_LEN];
388 regerror(errorCode, &M_internalRegExp, buffer, sizeof(buffer));
389 ERROR("recomp error : regular expression '%s' - error '%s'\n", M_regularExpression, buffer);
390 }
391 }
392
getRegularExpression()393 char *CAction::getRegularExpression()
394 {
395 if (!M_regExpSet) {
396 ERROR("Trying to get a regular expression for an action that does not have one!");
397 }
398 return M_regularExpression;
399 }
400
executeRegExp(const char * P_string,VariableTable * P_callVarTable)401 int CAction::executeRegExp(const char* P_string, VariableTable *P_callVarTable)
402 {
403 regmatch_t pmatch[10];
404 int error;
405 int nbOfMatch = 0;
406 char* result = NULL ;
407
408 if (!M_regExpSet) {
409 ERROR("Trying to perform regular expression match on action that does not have one!");
410 }
411
412 if (getNbSubVarId() > 9) {
413 ERROR("You can only have nine sub expressions!");
414 }
415
416 memset((void*)pmatch, 0, sizeof(regmatch_t)*10);
417
418 error = regexec(&M_internalRegExp, P_string, 10, pmatch, REGEXP_PARAMS);
419 if ( error == 0) {
420 CCallVariable* L_callVar = P_callVarTable->getVar(getVarId());
421
422 for(int i = 0; i <= getNbSubVarId(); i++) {
423 if(pmatch[i].rm_eo == -1) break ;
424
425 setSubString(&result, P_string, pmatch[i].rm_so, pmatch[i].rm_eo);
426 L_callVar->setMatchingValue(result);
427 nbOfMatch++;
428
429 if (i == getNbSubVarId())
430 break ;
431
432 L_callVar = P_callVarTable->getVar(getSubVarId(i));
433 }
434 }
435 return(nbOfMatch);
436 }
437
setSubString(char ** P_target,const char * P_source,int P_start,int P_stop)438 void CAction::setSubString(char** P_target, const char* P_source, int P_start, int P_stop)
439 {
440 int sizeOf;
441
442 if(P_source != NULL) {
443 sizeOf = P_stop - P_start;
444 (*P_target) = new char[sizeOf + 1];
445
446 if (sizeOf > 0) {
447 memcpy((*P_target), &(P_source[P_start]), sizeOf);
448 }
449
450 (*P_target)[sizeOf] = '\0';
451 } else {
452 *P_target = NULL ;
453 }
454 }
455
456
457 #ifdef PCAPPLAY
setPcapArgs(pcap_pkts * P_value)458 void CAction::setPcapArgs (pcap_pkts * P_value)
459 {
460 if(M_pcapArgs != NULL) {
461 free(M_pcapArgs);
462 M_pcapArgs = NULL;
463 }
464
465 if(P_value != NULL) {
466 M_pcapArgs = (pcap_pkts *)malloc(sizeof(*M_pcapArgs));
467 memcpy(M_pcapArgs, P_value, sizeof(*M_pcapArgs));
468 }
469 }
470
setPcapArgs(const char * P_value)471 void CAction::setPcapArgs(const char* P_value)
472 {
473 if(M_pcapArgs != NULL) {
474 free(M_pcapArgs);
475 M_pcapArgs = NULL;
476 }
477
478 if(P_value != NULL) {
479 M_pcapArgs = (pcap_pkts *) malloc(sizeof(*M_pcapArgs));
480 if (parse_play_args(P_value, M_pcapArgs) == -1) {
481 ERROR("Play pcap error");
482 }
483 if (access(M_pcapArgs->file, F_OK)) {
484 ERROR("Cannot read file %s\n", M_pcapArgs->file);
485 }
486 }
487 }
488 #endif
489
490 #ifdef RTP_STREAM
setRTPStreamActInfo(const char * P_value)491 void CAction::setRTPStreamActInfo(const char* P_value)
492 {
493 char *ParamString;
494 char *NextComma;
495
496 if (strlen(P_value)>=sizeof (M_rtpstream_actinfo.filename)) {
497 ERROR("Filename %s is too long, maximum supported length %zu\n", P_value,
498 sizeof(M_rtpstream_actinfo.filename) - 1);
499 }
500 strcpy (M_rtpstream_actinfo.filename,P_value);
501 ParamString= strchr(M_rtpstream_actinfo.filename,',');
502 NextComma= NULL;
503
504 M_rtpstream_actinfo.loop_count= 1;
505 if (ParamString) {
506 /* we have a loop count parameter */
507 *(ParamString++)= 0;
508 NextComma= strchr (ParamString,',');
509 if (NextComma) {
510 *(NextComma++)= 0;
511 }
512 M_rtpstream_actinfo.loop_count= atoi(ParamString);
513 ParamString= NextComma;
514 }
515
516 M_rtpstream_actinfo.payload_type= rtp_default_payload;
517 if (ParamString) {
518 /* we have a payload type parameter */
519 NextComma= strchr (ParamString,',');
520 if (NextComma) {
521 *(NextComma++)= 0;
522 }
523 M_rtpstream_actinfo.payload_type= atoi(ParamString);
524 }
525
526 /* Setup based on what we know of payload types */
527 switch (M_rtpstream_actinfo.payload_type) {
528 case 0: M_rtpstream_actinfo.ms_per_packet= 20;
529 M_rtpstream_actinfo.bytes_per_packet= 160;
530 M_rtpstream_actinfo.ticks_per_packet= 160;
531 break;
532
533 case 8: M_rtpstream_actinfo.ms_per_packet= 20;
534 M_rtpstream_actinfo.bytes_per_packet= 160;
535 M_rtpstream_actinfo.ticks_per_packet= 160;
536 break;
537
538 case 18: M_rtpstream_actinfo.ms_per_packet= 20;
539 M_rtpstream_actinfo.bytes_per_packet= 20;
540 M_rtpstream_actinfo.ticks_per_packet= 160;
541 break;
542
543 default: M_rtpstream_actinfo.ms_per_packet= -1;
544 M_rtpstream_actinfo.bytes_per_packet= -1;
545 M_rtpstream_actinfo.ticks_per_packet= -1;
546 ERROR("Unknown rtp payload type %d - cannot set playback parameters\n",M_rtpstream_actinfo.payload_type);
547 break;
548 }
549
550 if (rtpstream_cache_file(M_rtpstream_actinfo.filename)<0) {
551 ERROR("Cannot read/cache rtpstream file %s\n",M_rtpstream_actinfo.filename);
552 }
553 }
554
setRTPStreamActInfo(rtpstream_actinfo_t * P_value)555 void CAction::setRTPStreamActInfo (rtpstream_actinfo_t *P_value)
556 {
557 /* At this stage the entire rtpstream action info structure can simply be */
558 /* copied. No members need to be individually duplicated/processed. */
559 memcpy (&M_rtpstream_actinfo,P_value,sizeof(M_rtpstream_actinfo));
560 }
561 #endif
562
setScenario(scenario * P_scenario)563 void CAction::setScenario(scenario * P_scenario)
564 {
565 M_scenario = P_scenario;
566 }
567
setAction(CAction P_action)568 void CAction::setAction(CAction P_action)
569 {
570 if (P_action.getActionType() == CAction::E_AT_ASSIGN_FROM_SAMPLE) {
571 assert(P_action.getDistribution() != NULL);
572 }
573 int L_i;
574 setActionType ( P_action.getActionType() );
575 setLookingPlace ( P_action.getLookingPlace() );
576 setVarId ( P_action.getVarId() );
577 setVarInId ( P_action.getVarInId() );
578 setDoubleValue ( P_action.getDoubleValue() );
579 setDistribution ( P_action.getDistribution() );
580 setScenario ( P_action.M_scenario );
581
582 setNbSubVarId ( P_action.getNbSubVarId() );
583 for (L_i = 0; L_i < P_action.getNbSubVarId() ; L_i++ ) {
584 setSubVarId (P_action.getSubVarId(L_i));
585 }
586
587 setLookingChar ( P_action.getLookingChar() );
588 setCheckIt ( P_action.getCheckIt() );
589 setCheckItInverse ( P_action.getCheckItInverse() );
590 setCaseIndep ( P_action.getCaseIndep() );
591 setOccurrence ( P_action.getOccurrence() );
592 setHeadersOnly ( P_action.getHeadersOnly() );
593 for (L_i = 0; L_i < MAX_ACTION_MESSAGE; L_i++) {
594 setMessage(P_action.M_message_str[L_i], L_i);
595 }
596 setRegExp ( P_action.M_regularExpression);
597 setIntCmd ( P_action.M_IntCmd );
598 #ifdef PCAPPLAY
599 setPcapArgs ( P_action.M_pcapArgs );
600 #endif
601 #ifdef RTP_STREAM
602 setRTPStreamActInfo (&(P_action.M_rtpstream_actinfo));
603 #endif
604 }
605
CAction(scenario * scenario)606 CAction::CAction(scenario *scenario)
607 {
608 M_action = E_AT_NO_ACTION;
609 M_varId = 0;
610 M_varInId = 0;
611 M_varIn2Id = 0;
612
613 M_nbSubVarId = 0;
614 M_maxNbSubVarId = 0;
615 M_subVarId = NULL;
616
617 M_checkIt = false;
618 M_checkItInverse = false;
619 M_lookingPlace = E_LP_MSG;
620 M_lookingChar = NULL;
621 M_caseIndep = false;
622 M_occurrence = 1;
623 M_headersOnly = true;
624 for (int i = 0; i < MAX_ACTION_MESSAGE; i++) {
625 M_message[i] = NULL;
626 M_message_str[i] = NULL;
627 }
628 M_IntCmd = E_INTCMD_INVALID;
629 M_doubleValue = 0;
630 M_stringValue = NULL;
631 M_distribution = NULL;
632 #ifdef PCAPPLAY
633 M_pcapArgs = NULL;
634 #endif
635
636 #ifdef RTP_STREAM
637 memset(&M_rtpstream_actinfo, 0, sizeof(M_rtpstream_actinfo));
638 #endif
639
640 M_scenario = scenario;
641 M_regExpSet = false;
642 M_regularExpression = NULL;
643 }
644
~CAction()645 CAction::~CAction()
646 {
647 if(M_lookingChar != NULL) {
648 delete [] M_lookingChar;
649 M_lookingChar = NULL;
650 }
651 for (int i = 0; i < MAX_ACTION_MESSAGE; i++) {
652 if(M_message[i] != NULL) {
653 delete M_message[i];
654 M_message[i] = NULL;
655 }
656 free(M_message_str[i]);
657 M_message_str[i] = NULL;
658 }
659 if(M_subVarId != NULL) {
660 delete [] M_subVarId;
661 M_subVarId = NULL;
662 }
663 free(M_stringValue);
664 #ifdef PCAPPLAY
665 if (M_pcapArgs != NULL) {
666 free_pcaps(M_pcapArgs);
667 M_pcapArgs = NULL;
668 }
669 #endif
670 if (M_regExpSet) {
671 regfree(&M_internalRegExp);
672 free(M_regularExpression);
673 }
674 if (M_distribution) {
675 delete M_distribution;
676 }
677 }
678
679 /****************************** CActions class ************************/
680
afficheInfo()681 void CActions::afficheInfo()
682 {
683 printf("Action Size = [%d]\n", M_nbAction);
684 for(int i=0; i<M_nbAction; i++) {
685 printf("actionlist[%d] : \n", i);
686 M_actionList[i]->afficheInfo();
687 }
688 }
689
reset()690 void CActions::reset()
691 {
692 for (int i = 0; i < M_nbAction; i++) {
693 delete M_actionList[i];
694 M_actionList[i] = NULL;
695 }
696 M_nbAction = 0;
697 }
698
getActionSize()699 int CActions::getActionSize()
700 {
701 return(M_nbAction);
702 }
703
setAction(CAction * P_action)704 void CActions::setAction(CAction *P_action)
705 {
706 CAction **newActions = new CAction*[M_nbAction + 1];
707 if (!newActions) {
708 ERROR("Could not allocate new action list.");
709 }
710 for (int i = 0; i < M_nbAction; i++) {
711 newActions[i] = M_actionList[i];
712 }
713 if (M_actionList) {
714 delete [] M_actionList;
715 }
716 M_actionList = newActions;
717 M_actionList[M_nbAction] = P_action;
718 M_nbAction++;
719 }
720
getAction(int i)721 CAction* CActions::getAction(int i)
722 {
723 if(i < M_nbAction) {
724 return(M_actionList[i]);
725 } else
726 return(NULL);
727 }
728
729
CActions()730 CActions::CActions()
731 {
732 M_nbAction = 0;
733 M_actionList = NULL;
734 }
735
736
~CActions()737 CActions::~CActions()
738 {
739 for (int i = 0; i < M_nbAction; i++) {
740 delete M_actionList[i];
741 }
742 delete [] M_actionList;
743 M_actionList = NULL;
744 }
745
746 #ifdef GTEST
747 #include "gtest/gtest.h"
748
TEST(actions,MatchingRegexp)749 TEST(actions, MatchingRegexp) {
750 AllocVariableTable vt(NULL);
751 int id = vt.find("1", true);
752 int sub1_id = vt.find("2", true);
753 int sub2_id = vt.find("3", true);
754 int sub3_id = vt.find("4", true);
755 int sub4_id = vt.find("5", true);
756 CAction re(NULL);
757 re.setVarId(id);
758 re.setNbSubVarId(4);
759 re.setSubVarId(sub1_id);
760 re.setSubVarId(sub2_id);
761 re.setSubVarId(sub3_id);
762 re.setSubVarId(sub4_id);
763 re.setRegExp("(.+)(o) (.+)(d)");
764 int results = re.executeRegExp("hello world", &vt);
765
766 ASSERT_EQ(5, results);
767 ASSERT_STREQ("hello world", vt.getVar(id)->getString());
768 ASSERT_STREQ("hell", vt.getVar(sub1_id)->getString());
769 ASSERT_STREQ("o", vt.getVar(sub2_id)->getString());
770 ASSERT_STREQ("worl", vt.getVar(sub3_id)->getString());
771 ASSERT_STREQ("d", vt.getVar(sub4_id)->getString());
772 }
773
TEST(actions,NonMatchingRegexp)774 TEST(actions, NonMatchingRegexp) {
775 AllocVariableTable vt(NULL);
776 int id = vt.find("1", true);
777 int sub1_id = vt.find("2", true);
778 int sub2_id = vt.find("3", true);
779 int sub3_id = vt.find("4", true);
780 int sub4_id = vt.find("5", true);
781 CAction re(NULL);
782 re.setVarId(id);
783 re.setNbSubVarId(4);
784 re.setSubVarId(sub1_id);
785 re.setSubVarId(sub2_id);
786 re.setSubVarId(sub3_id);
787 re.setSubVarId(sub4_id);
788 re.setRegExp("(.+)(o) (.+)(d)");
789 int results = re.executeRegExp("", &vt);
790
791 ASSERT_EQ(0, results);
792 ASSERT_STREQ("", vt.getVar(id)->getString());
793 ASSERT_STREQ("", vt.getVar(sub1_id)->getString());
794 }
795
796 #endif
797