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