Parent Directory
|
Revision Log
Revision 89 - (view) (download)
| 1 : | jhermanski | 89 | /* |
| 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 : | * From Hewlett Packard Company. | ||
| 18 : | */ | ||
| 19 : | |||
| 20 : | #ifndef __CALL__ | ||
| 21 : | #define __CALL__ | ||
| 22 : | |||
| 23 : | #include <map> | ||
| 24 : | #include <list> | ||
| 25 : | #include <sys/types.h> | ||
| 26 : | #include <sys/socket.h> | ||
| 27 : | #include <string.h> | ||
| 28 : | #include "scenario.hpp" | ||
| 29 : | #ifdef _USE_OPENSSL | ||
| 30 : | #include "sslcommon.h" | ||
| 31 : | #endif | ||
| 32 : | #ifdef PCAPPLAY | ||
| 33 : | #include "send_packets.h" | ||
| 34 : | #endif | ||
| 35 : | |||
| 36 : | #ifndef MAX | ||
| 37 : | #define MAX(a, b) ((a) > (b) ? (a) : (b)) | ||
| 38 : | #endif | ||
| 39 : | #define MAX_HEADER_LEN 2049 | ||
| 40 : | #define UDP_MAX_RETRANS_INVITE_TRANSACTION 5 | ||
| 41 : | #define UDP_MAX_RETRANS_NON_INVITE_TRANSACTION 9 | ||
| 42 : | #define UDP_MAX_RETRANS MAX(UDP_MAX_RETRANS_INVITE_TRANSACTION, UDP_MAX_RETRANS_NON_INVITE_TRANSACTION) | ||
| 43 : | #define MAX_SUB_MESSAGE_LENGTH 2049 | ||
| 44 : | #define DEFAULT_T2_TIMER_VALUE 4000 | ||
| 45 : | #define SIP_TRANSACTION_TIMEOUT 32000 | ||
| 46 : | |||
| 47 : | #ifdef __HPUX | ||
| 48 : | extern int createAuthHeader(char * user, char * password, char * method, char * uri, char * msgbody, char * auth, char * aka_OP, char * aka_AMF, char * aka_K, char * result); | ||
| 49 : | #else | ||
| 50 : | extern "C" { extern int createAuthHeader(char * user, char * password, char * method, char * uri, char * msgbody, char * auth, char * aka_OP, char * aka_AMF, char * aka_K, char * result); } | ||
| 51 : | #endif | ||
| 52 : | |||
| 53 : | /* Forward declaration of call, so that we can define the call_list iterator | ||
| 54 : | * that is referenced from call. */ | ||
| 55 : | class call; | ||
| 56 : | |||
| 57 : | typedef std::list<call *> call_list; | ||
| 58 : | |||
| 59 : | /* This arrangement of wheels lets us support up to 32 bit timers. | ||
| 60 : | * | ||
| 61 : | * If we were to put a minimum bound on timer_resol (or do some kind of dynamic | ||
| 62 : | * allocation), then we could reduce the level one order by a factor of | ||
| 63 : | * timer_resol. */ | ||
| 64 : | #define LEVEL_ONE_ORDER 12 | ||
| 65 : | #define LEVEL_TWO_ORDER 10 | ||
| 66 : | #define LEVEL_THREE_ORDER 10 | ||
| 67 : | #define LEVEL_ONE_SLOTS (1 << LEVEL_ONE_ORDER) | ||
| 68 : | #define LEVEL_TWO_SLOTS (1 << LEVEL_TWO_ORDER) | ||
| 69 : | #define LEVEL_THREE_SLOTS (1 << LEVEL_THREE_ORDER) | ||
| 70 : | |||
| 71 : | /* A time wheel structure as defined in Varghese and Lauck's 1996 journal | ||
| 72 : | * article (based on their 1987 SOSP paper). */ | ||
| 73 : | class timewheel { | ||
| 74 : | public: | ||
| 75 : | timewheel(); | ||
| 76 : | |||
| 77 : | int expire_paused_calls(); | ||
| 78 : | /* Add a paused call and increment count. */ | ||
| 79 : | void add_paused_call(call *call, bool increment); | ||
| 80 : | void remove_paused_call(call *call); | ||
| 81 : | int size(); | ||
| 82 : | |||
| 83 : | private: | ||
| 84 : | /* How many calls are in this wheel. */ | ||
| 85 : | int count; | ||
| 86 : | |||
| 87 : | unsigned int wheel_base; | ||
| 88 : | |||
| 89 : | /* The actual wheels. */ | ||
| 90 : | call_list wheel_one[LEVEL_ONE_SLOTS]; | ||
| 91 : | call_list wheel_two[LEVEL_TWO_SLOTS]; | ||
| 92 : | call_list wheel_three[LEVEL_THREE_SLOTS]; | ||
| 93 : | |||
| 94 : | /* Calls that are paused indefinitely. */ | ||
| 95 : | call_list forever_list; | ||
| 96 : | |||
| 97 : | /* Turn a call into a list (based on wakeup). */ | ||
| 98 : | call_list *call2list(call *call); | ||
| 99 : | }; | ||
| 100 : | |||
| 101 : | class call { | ||
| 102 : | public: | ||
| 103 : | char * id; | ||
| 104 : | unsigned int number; | ||
| 105 : | unsigned int tdm_map_number; | ||
| 106 : | |||
| 107 : | int msg_index; | ||
| 108 : | |||
| 109 : | /* Last message sent from scenario step (retransmitions do not | ||
| 110 : | * change this index. Only message sent from the scenario | ||
| 111 : | * are kept in this index.) */ | ||
| 112 : | int last_send_index; | ||
| 113 : | char * last_send_msg; | ||
| 114 : | |||
| 115 : | /* How long until sending this message times out. */ | ||
| 116 : | unsigned int send_timeout; | ||
| 117 : | |||
| 118 : | /* Last received message (expected, not optional, and not | ||
| 119 : | * retransmitted) and the associated hash. Stills setted until a new | ||
| 120 : | * scenario steps sends a message */ | ||
| 121 : | unsigned long last_recv_hash; | ||
| 122 : | int last_recv_index; | ||
| 123 : | char * last_recv_msg; | ||
| 124 : | |||
| 125 : | /* Recv message characteristics when we sent a valid message | ||
| 126 : | * (scneario, no retrans) just after a valid reception. This was | ||
| 127 : | * a cause relationship, so the next time this cookie will be recvd, | ||
| 128 : | * we will retransmit the same message we sent this time */ | ||
| 129 : | unsigned long recv_retrans_hash; | ||
| 130 : | unsigned int recv_retrans_recv_index; | ||
| 131 : | unsigned int recv_retrans_send_index; | ||
| 132 : | unsigned int recv_timeout; | ||
| 133 : | |||
| 134 : | /* holds the route set */ | ||
| 135 : | char * dialog_route_set; | ||
| 136 : | char * next_req_url; | ||
| 137 : | |||
| 138 : | /* cseq value for [cseq] keyword */ | ||
| 139 : | unsigned int cseq; | ||
| 140 : | |||
| 141 : | #ifdef PCAPPLAY | ||
| 142 : | int hasMediaInformation; | ||
| 143 : | pthread_t media_thread; | ||
| 144 : | play_args_t play_args_a; | ||
| 145 : | play_args_t play_args_v; | ||
| 146 : | #endif | ||
| 147 : | |||
| 148 : | |||
| 149 : | #ifdef _USE_OPENSSL | ||
| 150 : | /* holds the auth header and if the challenge was 401 or 407 */ | ||
| 151 : | char * dialog_authentication; | ||
| 152 : | int dialog_challenge_type; | ||
| 153 : | #endif | ||
| 154 : | |||
| 155 : | unsigned int next_retrans; | ||
| 156 : | int nb_retrans; | ||
| 157 : | unsigned int nb_last_delay; | ||
| 158 : | |||
| 159 : | unsigned int paused_until; | ||
| 160 : | |||
| 161 : | unsigned long start_time; | ||
| 162 : | unsigned long long start_time_rtd[MAX_RTD_INFO_LENGTH]; | ||
| 163 : | |||
| 164 : | bool rtd_done[MAX_RTD_INFO_LENGTH]; | ||
| 165 : | |||
| 166 : | char *peer_tag; | ||
| 167 : | |||
| 168 : | struct sipp_socket *call_remote_socket; | ||
| 169 : | int call_port; | ||
| 170 : | |||
| 171 : | void * comp_state; | ||
| 172 : | |||
| 173 : | int deleted; | ||
| 174 : | |||
| 175 : | bool call_established; // == true when the call is established | ||
| 176 : | // ie ACK received or sent | ||
| 177 : | // => init to false | ||
| 178 : | bool count_in_stats; // == true if normal call to be counted | ||
| 179 : | // in statistics | ||
| 180 : | bool ack_is_pending; // == true if an ACK is pending | ||
| 181 : | // Needed to avoid abortCall sending a | ||
| 182 : | // CANCEL instead of BYE in some extreme | ||
| 183 : | // cases for 3PCC scenario. | ||
| 184 : | // => init to false | ||
| 185 : | |||
| 186 : | /* Call Variable Table */ | ||
| 187 : | CCallVariable ** M_callVariableTable; | ||
| 188 : | |||
| 189 : | /* result of execute action */ | ||
| 190 : | enum T_ActionResult | ||
| 191 : | { | ||
| 192 : | E_AR_NO_ERROR = 0, | ||
| 193 : | E_AR_REGEXP_DOESNT_MATCH, | ||
| 194 : | E_AR_STOP_CALL, | ||
| 195 : | E_AR_HDR_NOT_FOUND | ||
| 196 : | }; | ||
| 197 : | |||
| 198 : | /* Store the last action result to allow */ | ||
| 199 : | /* call to continue and mark it as failed */ | ||
| 200 : | T_ActionResult last_action_result; | ||
| 201 : | |||
| 202 : | call(char * id, int userId, bool ipv6); | ||
| 203 : | call (char *id, int userId, bool ipv6 , bool isAutomatic); | ||
| 204 : | ~call(); | ||
| 205 : | |||
| 206 : | /* rc == true means call not deleted by processing */ | ||
| 207 : | bool run(); | ||
| 208 : | void formatNextReqUrl (char* next_req_url); | ||
| 209 : | void computeRouteSetAndRemoteTargetUri (char* rrList, char* contact, bool bRequestIncoming); | ||
| 210 : | bool matches_scenario(unsigned int index, int reply_code, char * request, char * responsecseqmethod); | ||
| 211 : | bool process_incoming(char * msg); | ||
| 212 : | |||
| 213 : | T_ActionResult executeAction(char * msg, int scenarioIndex); | ||
| 214 : | void extractSubMessage(char * msg, char * matchingString, char* result, bool case_indep, | ||
| 215 : | int occurrence, bool headers); | ||
| 216 : | bool rejectCall(); | ||
| 217 : | double get_rhs(CAction *currentAction); | ||
| 218 : | |||
| 219 : | // P_index use for message index in scenario and ctrl of CRLF | ||
| 220 : | // P_index = -2 No ctrl of CRLF | ||
| 221 : | // P_index = -1 Add crlf to end of message | ||
| 222 : | char* createSendingMessage(SendingMessage *src, int P_index); | ||
| 223 : | char* createSendingMessage(char * src, int P_index, bool skip_sanity = false); | ||
| 224 : | |||
| 225 : | // method for the management of unexpected messages | ||
| 226 : | bool abortCall(); // call aborted with BYE or CANCEL | ||
| 227 : | bool checkInternalCmd(char* cmd); // check of specific internal command | ||
| 228 : | // received from the twin socket | ||
| 229 : | // used for example to cancel the call | ||
| 230 : | // of the third party | ||
| 231 : | bool check_peer_src(char* msg, | ||
| 232 : | int search_index); // 3pcc extended mode:check if | ||
| 233 : | // the twin message received | ||
| 234 : | // comes from the expected sender | ||
| 235 : | void sendBuffer(char *buf); // send a message out of a scenario | ||
| 236 : | // execution | ||
| 237 : | int checkAutomaticResponseMode(char * P_recv); | ||
| 238 : | bool automaticResponseMode(int P_case, char* P_recv); | ||
| 239 : | |||
| 240 : | #ifdef __3PCC__ | ||
| 241 : | int sendCmdMessage(int index); // 3PCC | ||
| 242 : | bool process_twinSippCom(char * msg); // 3PCC | ||
| 243 : | |||
| 244 : | int sendCmdBuffer(char* cmd); // for 3PCC, send a command out of a | ||
| 245 : | // scenario execution | ||
| 246 : | |||
| 247 : | #endif | ||
| 248 : | |||
| 249 : | static void readInputFileContents(const char* fileName); | ||
| 250 : | static void dumpFileContents(void); | ||
| 251 : | |||
| 252 : | void getFieldFromInputFile(const char* fileName, int field, char*& dest); | ||
| 253 : | void getFieldFromInputFile(const char* keyword, char*& dest); | ||
| 254 : | |||
| 255 : | /* Associate/Dissociate this call with a socket. */ | ||
| 256 : | struct sipp_socket *associate_socket(struct sipp_socket *socket); | ||
| 257 : | struct sipp_socket *dissociate_socket(); | ||
| 258 : | |||
| 259 : | /* Associate a user with this call. */ | ||
| 260 : | void setUser(int userId); | ||
| 261 : | |||
| 262 : | /* Is this call paused or running? */ | ||
| 263 : | bool running; | ||
| 264 : | /* If we are running, the iterator to remove us from the running list. */ | ||
| 265 : | call_list::iterator runit; | ||
| 266 : | /* If we are paused, the iterator to remove us from the paused list. */ | ||
| 267 : | call_list::iterator pauseit; | ||
| 268 : | |||
| 269 : | private: | ||
| 270 : | /* rc == true means call not deleted by processing */ | ||
| 271 : | bool next(); | ||
| 272 : | bool process_unexpected(char * msg); | ||
| 273 : | void do_bookkeeping(int index); | ||
| 274 : | |||
| 275 : | void extract_cseq_method (char* responseCseq, char* msg); | ||
| 276 : | |||
| 277 : | int send_raw(char * msg, int index); | ||
| 278 : | char * send_scene(int index, int *send_status); | ||
| 279 : | void connect_socket_if_needed(); | ||
| 280 : | |||
| 281 : | char * compute_cseq(char * src); | ||
| 282 : | char * get_header_field_code(char * msg, char * code); | ||
| 283 : | char * get_last_header(char * name); | ||
| 284 : | char * get_header_content(char* message, char * name); | ||
| 285 : | char * get_header(char* message, char * name, bool content); | ||
| 286 : | char * get_first_line(char* message); | ||
| 287 : | char * get_last_request_uri(); | ||
| 288 : | |||
| 289 : | typedef std::map <std::string, int> file_line_map; | ||
| 290 : | file_line_map *m_lineNumber; | ||
| 291 : | int userId; | ||
| 292 : | |||
| 293 : | bool use_ipv6; | ||
| 294 : | struct sipp_socket *call_socket; | ||
| 295 : | |||
| 296 : | void get_remote_media_addr(char * message); | ||
| 297 : | |||
| 298 : | #ifdef _USE_OPENSSL | ||
| 299 : | SSL_CTX *m_ctx_ssl ; | ||
| 300 : | BIO *m_bio ; | ||
| 301 : | #endif | ||
| 302 : | }; | ||
| 303 : | |||
| 304 : | /* Call contexts interface */ | ||
| 305 : | |||
| 306 : | typedef std::pair<std::string, call *> string_call_pair; | ||
| 307 : | typedef std::map<std::string, call *> call_map; | ||
| 308 : | call_map * get_calls(); | ||
| 309 : | call_list * get_running_calls(); | ||
| 310 : | |||
| 311 : | /* These are wrappers for various circumstances. */ | ||
| 312 : | call * add_call(int userId, bool ipv6); | ||
| 313 : | call * add_call(char * call_id , bool ipv6, int userId); | ||
| 314 : | call * add_call(char * call_id , struct sipp_socket *socket); | ||
| 315 : | call * add_call(char * call_id , struct sipp_socket *socket, bool isAutomatic); | ||
| 316 : | /* This is the core function. */ | ||
| 317 : | call * add_call(char * call_id , bool ipv6, int userId, bool isAutomatic); | ||
| 318 : | |||
| 319 : | call * get_call(char *); | ||
| 320 : | void delete_call(char *); | ||
| 321 : | void delete_calls(void); | ||
| 322 : | |||
| 323 : | void add_running_call(call *call); | ||
| 324 : | bool remove_running_call(call *call); | ||
| 325 : | int expire_paused_calls(); | ||
| 326 : | int paused_calls_count(); | ||
| 327 : | void remove_paused_call(call *call); | ||
| 328 : | |||
| 329 : | typedef std::pair<struct sipp_socket *,call_map *> socket_map_pair; | ||
| 330 : | |||
| 331 : | typedef std::map<struct sipp_socket *, void *> socket_call_map_map; | ||
| 332 : | call_list *get_calls_for_socket(struct sipp_socket *socket); | ||
| 333 : | void add_call_to_socket(struct sipp_socket *socket, call *call); | ||
| 334 : | void remove_call_from_socket(struct sipp_socket *socket, call *call); | ||
| 335 : | |||
| 336 : | #endif |
| No admin address has been configured | ViewVC Help |
| Powered by ViewVC 1.0.8 |