RTS API Documentation  1.10.11
switch_core_session.c
Go to the documentation of this file.
1 /*
2  * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
3  * Copyright (C) 2005-2021, Anthony Minessale II <anthm@freeswitch.org>
4  *
5  * Version: MPL 1.1
6  *
7  * The contents of this file are subject to the Mozilla Public License Version
8  * 1.1 (the "License"); you may not use this file except in compliance with
9  * the License. You may obtain a copy of the License at
10  * http://www.mozilla.org/MPL/
11  *
12  * Software distributed under the License is distributed on an "AS IS" basis,
13  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14  * for the specific language governing rights and limitations under the
15  * License.
16  *
17  * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
18  *
19  * The Initial Developer of the Original Code is
20  * Anthony Minessale II <anthm@freeswitch.org>
21  * Portions created by the Initial Developer are Copyright (C)
22  * the Initial Developer. All Rights Reserved.
23  *
24  * Contributor(s):
25  *
26  * Anthony Minessale II <anthm@freeswitch.org>
27  * Michael Jerris <mike@jerris.com>
28  * Paul D. Tinsley <pdt at jackhammer.org>
29  * Joseph Sullivan <jossulli@amazon.com>
30  *
31  *
32  * switch_core_session.c -- Main Core Library (session routines)
33  *
34  */
35 
36 #include "switch.h"
37 #include "switch_core.h"
39 
40 #define DEBUG_THREAD_POOL
41 
43 
45 {
46  int i = (int) target;
47 
48  if (i == 0 || i == 1) {
49  if (dmachine) {
50  switch_ivr_dmachine_set_target(dmachine, target);
51  }
52  session->dmachine[i] = dmachine;
53  }
54 }
55 
57 {
58  int i = (int) target;
59 
60  if (i == 0 || i == 1) {
61  return session->dmachine[i];
62  }
63 
64  return NULL;
65 }
66 
67 
69 {
70  if (session->endpoint_interface->io_routines->get_jb) {
71  return session->endpoint_interface->io_routines->get_jb(session, type);
72  }
73 
74  return NULL;
75 }
76 
78 {
79  session->soft_lock = sec;
80 }
81 
83 {
84  session->soft_lock = 0;
85 }
86 
88 
89 {
90  switch_codec_implementation_t read_impl = { 0 };
91  int interval;
92 
93  switch_core_session_get_read_impl(session, &read_impl);
94  interval = read_impl.microseconds_per_packet / 1000;
95  data->session = session;
96 
97  if (switch_core_codec_init(&data->codec,
98  "L16",
99  NULL,
100  NULL,
101  read_impl.actual_samples_per_second,
102  interval,
105  SWITCH_LOG_DEBUG, "Codec Activated L16@%uhz %dms\n", read_impl.actual_samples_per_second, interval);
106 
107  memset(&data->write_frame, 0, sizeof(data->write_frame));
108 
109  data->write_frame.codec = &data->codec;
110  data->write_frame.data = data->frame_data;
111  data->write_frame.buflen = sizeof(data->frame_data);
112  data->write_frame.datalen = 0;
113  switch_core_session_set_read_codec(session, &data->codec);
114  return SWITCH_STATUS_SUCCESS;
115  }
116 
117  return SWITCH_STATUS_FALSE;
118 }
119 
120 
121 SWITCH_DECLARE(switch_core_session_t *) switch_core_session_perform_locate(const char *uuid_str, const char *file, const char *func, int line)
122 {
123  switch_core_session_t *session = NULL;
124 
125  if (uuid_str) {
127  if ((session = switch_core_hash_find(session_manager.session_table, uuid_str))) {
128  /* Acquire a read lock on the session */
129 #ifdef SWITCH_DEBUG_RWLOCKS
130  if (switch_core_session_perform_read_lock(session, file, func, line) != SWITCH_STATUS_SUCCESS) {
131 #if EMACS_CC_MODE_IS_BUGGY
132  }
133 #endif
134 #else
136 #endif
137  /* not available, forget it */
138  session = NULL;
139  }
140  }
142  }
143 
144  /* if its not NULL, now it's up to you to rwunlock this */
145  return session;
146 }
147 
148 
149 
150 
151 
152 SWITCH_DECLARE(switch_core_session_t *) switch_core_session_perform_force_locate(const char *uuid_str, const char *file, const char *func, int line)
153 {
154  switch_core_session_t *session = NULL;
155  switch_status_t status;
156 
157  if (uuid_str) {
159  if ((session = switch_core_hash_find(session_manager.session_table, uuid_str))) {
160  /* Acquire a read lock on the session */
161 
162  if (switch_test_flag(session, SSF_DESTROYED)) {
163  status = SWITCH_STATUS_FALSE;
164 #ifdef SWITCH_DEBUG_RWLOCKS
165  switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, uuid_str, SWITCH_LOG_ERROR, "%s %s Read lock FAIL\n",
167 #endif
168  } else {
170 #ifdef SWITCH_DEBUG_RWLOCKS
171  switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, uuid_str, SWITCH_LOG_ERROR, "%s %s Read lock ACQUIRED\n",
173 #endif
174  }
175 
176  if (status != SWITCH_STATUS_SUCCESS) {
177  /* not available, forget it */
178  session = NULL;
179  }
180  }
182  }
183 
184  /* if its not NULL, now it's up to you to rwunlock this */
185  return session;
186 }
187 
188 
190  const char *file, const char *func, int line)
191 {
192  const char *uuid;
193  char uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1];
194 
195  if ((uuid = switch_channel_get_partner_uuid_copy(session->channel, uuid_str, sizeof(uuid_str)))) {
196  if ((*partner = switch_core_session_perform_locate(uuid, file, func, line))) {
197  return SWITCH_STATUS_SUCCESS;
198  }
199  }
200 
201  *partner = NULL;
202  return SWITCH_STATUS_FALSE;
203 }
204 
205 
206 struct str_node {
207  char *str;
208  struct str_node *next;
209 };
210 
212 {
214  void *val;
215  switch_core_session_t *session;
217  struct str_node *head = NULL, *np;
218  uint32_t r = 0;
219 
221 
222  if (!vars || !vars->headers)
223  return r;
224 
227  switch_core_hash_this(hi, NULL, NULL, &val);
228  if (val) {
229  session = (switch_core_session_t *) val;
232  if ((ans && (type & SHT_ANSWERED)) || (!ans && (type & SHT_UNANSWERED))) {
233  np = switch_core_alloc(pool, sizeof(*np));
234  np->str = switch_core_strdup(pool, session->uuid_str);
235  np->next = head;
236  head = np;
237  }
239  }
240  }
241  }
243 
244  for(np = head; np; np = np->next) {
245  if ((session = switch_core_session_locate(np->str))) {
246  const char *this_value;
247  if (switch_channel_up_nosig(session->channel)) {
248  /* check if all conditions are satisfied */
249  int do_hangup = 1;
251  for (hp = vars->headers; hp; hp = hp->next) {
252  const char *var_name = hp->name;
253  const char *var_value = hp->value;
254  if (!(this_value = switch_channel_get_variable(session->channel, var_name)) || (strcmp(this_value, var_value))) {
255  do_hangup = 0;
256  break;
257  }
258  }
259  if (do_hangup) {
260  switch_channel_hangup(session->channel, cause);
261  r++;
262  }
263  }
265  }
266  }
267 
269 
270  return r;
271 }
272 
273 SWITCH_DECLARE(uint32_t) switch_core_session_hupall_matching_var_ans(const char *var_name, const char *var_val, switch_call_cause_t cause,
274  switch_hup_type_t type)
275 {
276  switch_event_t *vars;
277  int r = 0;
278 
279  if (!var_val || !var_name)
280  return r;
281 
283  switch_event_add_header_string(vars, SWITCH_STACK_BOTTOM, var_name, var_val);
284  r = switch_core_session_hupall_matching_vars_ans(vars, cause, type);
285  switch_event_destroy(&vars);
286  return r;
287 }
288 
290 {
292  void *val;
293  switch_core_session_t *session;
295  struct str_node *head = NULL, *np;
296  switch_console_callback_match_t *my_matches = NULL;
297  const char *like = NULL;
298 
299  if (var_val && *var_val == '~') {
300  like = var_val + 1;
301  }
302 
304 
307  switch_core_hash_this(hi, NULL, NULL, &val);
308  if (val) {
309  session = (switch_core_session_t *) val;
311  np = switch_core_alloc(pool, sizeof(*np));
312  np->str = switch_core_strdup(pool, session->uuid_str);
313  np->next = head;
314  head = np;
316  }
317  }
318  }
320 
321  for(np = head; np; np = np->next) {
322  if ((session = switch_core_session_locate(np->str))) {
323  const char *this_val;
324  if (switch_channel_up_nosig(session->channel) &&
325  (this_val = switch_channel_get_variable_dup(session->channel, var_name, SWITCH_FALSE, -1)) &&
326  (!var_val || (like && switch_stristr(like, var_val)) || !strcmp(this_val, var_val))) {
327  switch_console_push_match(&my_matches, (const char *) np->str);
328  }
330  }
331  }
332 
334 
335 
336  return my_matches;
337 }
338 
340 {
342  void *val;
343  switch_core_session_t *session;
345  struct str_node *head = NULL, *np;
346 
348 
351  switch_core_hash_this(hi, NULL, NULL, &val);
352  if (val) {
353  session = (switch_core_session_t *) val;
355  if (session->endpoint_interface == endpoint_interface) {
356  np = switch_core_alloc(pool, sizeof(*np));
357  np->str = switch_core_strdup(pool, session->uuid_str);
358  np->next = head;
359  head = np;
360  }
362  }
363  }
364  }
366 
367  for(np = head; np; np = np->next) {
368  if ((session = switch_core_session_locate(np->str))) {
369  switch_channel_hangup(session->channel, cause);
371  }
372  }
373 
375 
376 }
377 
379 {
381  void *val;
382  switch_core_session_t *session;
384  struct str_node *head = NULL, *np;
385 
387 
388 
391  switch_core_hash_this(hi, NULL, NULL, &val);
392  if (val) {
393  session = (switch_core_session_t *) val;
395  np = switch_core_alloc(pool, sizeof(*np));
396  np->str = switch_core_strdup(pool, session->uuid_str);
397  np->next = head;
398  head = np;
400  }
401  }
402  }
404 
405  for(np = head; np; np = np->next) {
406  if ((session = switch_core_session_locate(np->str))) {
407  switch_channel_hangup(session->channel, cause);
409  }
410  }
411 
413 
414 }
415 
416 
418 {
420  void *val;
421  switch_core_session_t *session;
422  switch_console_callback_match_t *my_matches = NULL;
423 
426  switch_core_hash_this(hi, NULL, NULL, &val);
427  if (val) {
428  session = (switch_core_session_t *) val;
430  switch_console_push_match(&my_matches, session->uuid_str);
432  }
433  }
434  }
436 
437  return my_matches;
438 }
439 
441 {
442  switch_core_session_t *session = NULL;
444 
446  if ((session = switch_core_hash_find(session_manager.session_table, uuid_str)) != 0) {
447  /* Acquire a read lock on the session or forget it the channel is dead */
449  if (switch_channel_up_nosig(session->channel)) {
450  status = switch_core_session_receive_message(session, message);
451  }
453  }
454  }
456 
457  return status;
458 }
459 
461 {
462  switch_core_session_t *session = NULL;
464 
466  if ((session = switch_core_hash_find(session_manager.session_table, uuid_str)) != 0) {
467  /* Acquire a read lock on the session or forget it the channel is dead */
469  if (switch_channel_up_nosig(session->channel)) {
470  status = switch_core_session_queue_event(session, event);
471  }
473  }
474  }
476 
477  return status;
478 }
479 
480 
482 {
483  if ((int)index >= SWITCH_CORE_SESSION_MAX_PRIVATES) {
484  return NULL;
485  }
486 
487  switch_assert(session != NULL);
488  return session->private_info[index];
489 }
490 
491 
493 {
494  switch_assert(session != NULL);
495 
496  if ((int)index >= SWITCH_CORE_SESSION_MAX_PRIVATES) {
497  return SWITCH_STATUS_FALSE;
498  }
499 
500  session->private_info[index] = private_info;
501  return SWITCH_STATUS_SUCCESS;
502 }
503 
505 {
506  session->streams[session->stream_count++] = private_info;
507  return session->stream_count - 1;
508 }
509 
511 {
512  return session->streams[index];
513 }
514 
515 
517 {
518  return session->stream_count;
519 }
520 
522  const char *endpoint_name,
523  switch_caller_profile_t *caller_profile,
524  switch_core_session_t **new_session,
526  switch_originate_flag_t flags, switch_call_cause_t *cancel_cause)
527 {
529  switch_endpoint_interface_t *endpoint_interface;
530  switch_channel_t *channel = NULL;
531  switch_caller_profile_t *outgoing_profile = caller_profile;
533  const char *forwardvar;
534  int forwardval = 70;
535 
536  if ((endpoint_interface = switch_loadable_module_get_endpoint_interface(endpoint_name)) == 0) {
537  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Could not locate channel type %s\n", endpoint_name);
539  }
540 
541  if (!endpoint_interface->io_routines->outgoing_channel) {
542  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Could not locate outgoing channel interface for %s\n", endpoint_name);
544  }
545 
546  if (session) {
547  channel = switch_core_session_get_channel(session);
548 
549  switch_assert(channel != NULL);
550 
552  if (!zstr(forwardvar)) {
553  forwardval = atoi(forwardvar) - 1;
554  }
555  if (forwardval <= 0) {
557  }
558 
559  if (caller_profile) {
560  const char *eani = NULL, *eaniii = NULL;
561  const char *ecaller_id_name = NULL, *ecaller_id_number = NULL;
562 
563  if (!(flags & SOF_NO_EFFECTIVE_ANI)) {
564  eani = switch_channel_get_variable(channel, "effective_ani");
565  }
566 
567  if (!(flags & SOF_NO_EFFECTIVE_ANIII)) {
568  eaniii = switch_channel_get_variable(channel, "effective_aniii");
569  }
570 
571  if (!(flags & SOF_NO_EFFECTIVE_CID_NAME)) {
572  ecaller_id_name = switch_channel_get_variable(channel, "effective_caller_id_name");
573  }
574 
575  if (!(flags & SOF_NO_EFFECTIVE_CID_NUM)) {
576  ecaller_id_number = switch_channel_get_variable(channel, "effective_caller_id_number");
577  }
578 
579  if (eani || eaniii || ecaller_id_name || ecaller_id_number) {
580  outgoing_profile = switch_caller_profile_clone(session, caller_profile);
581 
582  if (eani) {
583  outgoing_profile->ani = eani;
584  }
585  if (eaniii) {
586  outgoing_profile->aniii = eaniii;
587  }
588  if (ecaller_id_name) {
589  outgoing_profile->caller_id_name = ecaller_id_name;
590  }
591  if (ecaller_id_number) {
592  outgoing_profile->caller_id_number = ecaller_id_number;
593  }
594  }
595  }
596  if (!outgoing_profile) {
597  outgoing_profile = switch_channel_get_caller_profile(channel);
598  }
599  }
600 
601  if ((cause =
602  endpoint_interface->io_routines->outgoing_channel(session, var_event, outgoing_profile, new_session, pool, flags,
603  cancel_cause)) != SWITCH_CAUSE_SUCCESS) {
604  UNPROTECT_INTERFACE(endpoint_interface);
605  return cause;
606  }
607 
608  if (session) {
609  for (ptr = session->event_hooks.outgoing_channel; ptr; ptr = ptr->next) {
610  if (ptr->outgoing_channel(session, var_event, caller_profile, *new_session, flags) != SWITCH_STATUS_SUCCESS) {
611  break;
612  }
613  }
614  }
615 
616  if (!*new_session) {
618  "Outgoing method for endpoint: [%s] returned: [%s] but there is no new session!\n", endpoint_name,
619  switch_channel_cause2str(cause));
620  UNPROTECT_INTERFACE(endpoint_interface);
622  } else {
623  switch_caller_profile_t *profile = NULL, *cloned_profile = NULL;
624  switch_event_t *event;
625  switch_channel_t *peer_channel = switch_core_session_get_channel(*new_session);
626  const char *use_uuid;
627  const char *use_external_id;
628  switch_core_session_t *other_session = NULL;
629 
630  switch_assert(peer_channel);
631 
632  if (channel && switch_true(switch_channel_get_variable(channel, "session_copy_loglevel"))) {
633  (*new_session)->loglevel = session->loglevel;
634  }
635 
636 
637  if ((use_uuid = switch_event_get_header(var_event, "origination_uuid"))) {
638  use_uuid = switch_core_session_strdup(*new_session, use_uuid);
639  if (switch_core_session_set_uuid(*new_session, use_uuid) == SWITCH_STATUS_SUCCESS) {
640  switch_event_del_header(var_event, "origination_uuid");
641  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(*new_session), SWITCH_LOG_DEBUG, "%s set UUID=%s\n", switch_channel_get_name(peer_channel),
642  use_uuid);
643  } else {
644  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(*new_session), SWITCH_LOG_CRIT, "%s set UUID=%s FAILED\n",
645  switch_channel_get_name(peer_channel), use_uuid);
646  }
647  }
648 
649  if ((use_external_id = switch_event_get_header(var_event, "origination_external_id"))) {
650  if (switch_core_session_set_external_id(*new_session, use_external_id) == SWITCH_STATUS_SUCCESS) {
651  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(*new_session), SWITCH_LOG_DEBUG, "%s set external_id=%s\n", switch_channel_get_name(peer_channel),
652  use_external_id);
653  switch_event_del_header(var_event, "origination_external_id");
654  } else {
655  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(*new_session), SWITCH_LOG_CRIT, "%s set external_id=%s FAILED\n",
656  switch_channel_get_name(peer_channel), use_external_id);
657  }
658  }
659 
660  if (!channel && var_event) {
661  const char *other_uuid;
662 
663  if ((other_uuid = switch_event_get_header(var_event, "origination_aleg_uuid")) && (other_session = switch_core_session_locate(other_uuid))) {
664  channel = switch_core_session_get_channel(other_session);
665  session = other_session;
666  }
667  }
668 
669  if (channel) {
670  const char *val;
671  switch_codec_t *vid_read_codec = NULL, *read_codec = switch_core_session_get_read_codec(session);
672  const char *ep = NULL, *max_forwards = switch_core_session_sprintf(session, "%d", forwardval);
673 
674  switch_channel_set_variable(peer_channel, SWITCH_MAX_FORWARDS_VARIABLE, max_forwards);
675 
676  profile = switch_channel_get_caller_profile(channel);
677 
678  vid_read_codec = switch_core_session_get_video_read_codec(session);
679 
680  ep = switch_channel_get_variable(channel, "ep_codec_string");
681 
682  if (read_codec && read_codec->implementation && switch_core_codec_ready(read_codec)) {
683  char rc[80] = "", vrc[80] = "", tmp[160] = "";
684 
685  switch_codec2str(read_codec, rc, sizeof(rc));
686  if (vid_read_codec && vid_read_codec->implementation && switch_core_codec_ready(vid_read_codec)) {
687  vrc[0] = ',';
688  switch_codec2str(vid_read_codec, vrc + 1, sizeof(vrc) - 1);
690  }
691 
692  switch_snprintf(tmp, sizeof(tmp), "%s%s", rc, vrc);
694  } else if (ep) {
696  }
697 
698 
700  switch_channel_set_flag(peer_channel, CF_WANT_MSRPS);
701  } else if (switch_channel_test_flag(channel, CF_MSRP) || switch_channel_test_flag(channel, CF_WANT_MSRP)) {
702  switch_channel_set_flag(peer_channel, CF_WANT_MSRP);
703  }
704 
706  switch_channel_set_flag(peer_channel, CF_WANT_RTT);
707  }
708 
709 
712  // Needed by 3PCC proxy so that aleg can find bleg to pass SDP to, when final ACK arrives.
714 
717  }
718 
719  if ((val = switch_channel_get_variable(channel, SWITCH_R_SDP_VARIABLE))) {
720  switch_channel_pass_sdp(channel, peer_channel, val);
721  }
722 
723  if (switch_channel_test_flag(channel, CF_PROXY_MODE)) {
724  if (switch_channel_test_cap(peer_channel, CC_BYPASS_MEDIA)) {
725  switch_channel_set_flag(peer_channel, CF_PROXY_MODE);
726  } else {
728  "%s does not support the proxy feature, disabling.\n", switch_channel_get_name(peer_channel));
730  }
731  }
732 
734  if (switch_channel_test_cap(peer_channel, CC_PROXY_MEDIA)) {
736  if (switch_channel_test_flag(channel, CF_VIDEO)) {
737  switch_channel_set_flag(peer_channel, CF_VIDEO);
738  }
739  } else {
741  "%s does not support the proxy feature, disabling.\n", switch_channel_get_name(peer_channel));
743  }
744  }
745 
746  if (profile) {
747  if ((cloned_profile = switch_caller_profile_clone(*new_session, profile)) != 0) {
748  switch_channel_set_originator_caller_profile(peer_channel, cloned_profile);
749  }
750  }
751 
752 
753  if ((profile = switch_channel_get_caller_profile(peer_channel))) {
754  if ((cloned_profile = switch_caller_profile_clone(session, profile)) != 0) {
755  switch_channel_set_origination_caller_profile(channel, cloned_profile);
756  }
757  }
758 
759  }
760 
761  if (other_session) {
762  switch_core_session_rwunlock(other_session);
763  channel = NULL;
764  session = NULL;
765  }
766 
767 
769  switch_channel_event_set_data(peer_channel, event);
770  switch_event_fire(&event);
771  }
772  }
773 
774  UNPROTECT_INTERFACE(endpoint_interface);
775  return cause;
776 }
777 
778 static const char *message_names[] = {
779  "REDIRECT_AUDIO",
780  "TRANSMIT_TEXT",
781  "ANSWER",
782  "ACKNOWLEDGE_CALL",
783  "PROGRESS",
784  "BRIDGE",
785  "UNBRIDGE",
786  "TRANSFER",
787  "RINGING",
788  "ALERTING",
789  "MEDIA",
790  "3P_MEDIA",
791  "NOMEDIA",
792  "3P_NOMEDIA",
793  "HOLD",
794  "UNHOLD",
795  "REDIRECT",
796  "RESPOND",
797  "BROADCAST",
798  "MEDIA_REDIRECT",
799  "DEFLECT",
800  "VIDEO_REFRESH_REQ",
801  "DISPLAY",
802  "MEDIA_PARAMS",
803  "TRANSCODING_NECESSARY",
804  "AUDIO_SYNC",
805  "VIDEO_SYNC",
806  "REQUEST_IMAGE_MEDIA",
807  "UUID_CHANGE",
808  "SIMPLIFY",
809  "DEBUG_MEDIA",
810  "PROXY_MEDIA",
811  "APPLICATION_EXEC",
812  "APPLICATION_EXEC_COMPLETE",
813  "PHONE_EVENT",
814  "T38_DESCRIPTION",
815  "UDPTL_MODE",
816  "CLEAR_PROGRESS",
817  "JITTER_BUFFER",
818  "RECOVERY_REFRESH",
819  "SIGNAL_DATA",
820  "MESSAGE",
821  "INFO",
822  "AUDIO_DATA",
823  "BLIND_TRANSFER_RESPONSE",
824  "STUN_ERROR",
825  "MEDIA_RENEG",
826  "KEEPALIVE",
827  "HARD_MUTE",
828  "BITRATE_REQ",
829  "BITRATE_ACK",
830  "CODEC_DEBUG_REQ",
831  "CODEC_SPECIFIC_REQ",
832  "REFER_EVENT",
833  "ANSWER_EVENT",
834  "PROGRESS_EVENT",
835  "RING_EVENT",
836  "RESAMPLE_EVENT",
837  "HEARTBEAT_EVENT",
838  "SESSION_ID",
839  "PROMPT",
840  "INVALID"
841 };
842 
845  const char *file, const char *func, int line)
846 {
849 
850  switch_assert(session != NULL);
851 
854  status = session->endpoint_interface->io_routines->receive_message(session, message);
855  }
856 
858  return status;
859  }
860 
861  if ((status = switch_core_session_read_lock_hangup(session)) != SWITCH_STATUS_SUCCESS) {
862  return status;
863  }
864 
865  if (!message->_file) {
866  message->_file = file;
867  }
868 
869  if (!message->_func) {
870  message->_func = func;
871  }
872 
873  if (!message->_line) {
874  message->_line = line;
875  }
876 
877  if (message->message_id > SWITCH_MESSAGE_INVALID-1) {
878  message->message_id = SWITCH_MESSAGE_INVALID-1;
879  }
880 
881  switch_log_printf(SWITCH_CHANNEL_ID_LOG, message->_file, message->_func, message->_line,
882  switch_core_session_get_uuid(session), SWITCH_LOG_DEBUG1, "%s receive message [%s]\n",
884 
885 
888  }
889 
890  if (message->message_id == SWITCH_MESSAGE_INDICATE_MEDIA) {
892  }
893 
895  char *arg = NULL;
896 
897  if (zstr(message->string_array_arg[0]) && !zstr(message->string_arg)) {
898  arg = switch_core_session_strdup(session, message->string_arg);
899  switch_separate_string(arg, '|', (char **)message->string_array_arg, 2);
900  }
901 
902  if (!zstr(message->string_array_arg[0])) {
903  switch_channel_set_variable(session->channel, "last_sent_callee_id_name", message->string_array_arg[0]);
904  }
905 
906  if (!zstr(message->string_array_arg[1])) {
907  switch_channel_set_variable(session->channel, "last_sent_callee_id_number", message->string_array_arg[1]);
908  }
909 
910 
912  switch_log_printf(SWITCH_CHANNEL_ID_LOG, message->_file, message->_func, message->_line,
913  switch_core_session_get_uuid(session), SWITCH_LOG_DEBUG1, "Ignoring display update.\n");
914  status = SWITCH_STATUS_SUCCESS;
915  goto end;
916  }
917 
918  }
919 
920  if (switch_channel_down_nosig(session->channel)) {
921  switch_log_printf(SWITCH_CHANNEL_ID_LOG, message->_file, message->_func, message->_line,
922  switch_core_session_get_uuid(session), SWITCH_LOG_DEBUG, "%s skip receive message [%s] (channel is hungup already)\n",
924 
925  } else {
926  if (session->media_handle) {
927  status = switch_core_media_receive_message(session, message);
928  }
929  if (status == SWITCH_STATUS_SUCCESS) {
931  status = session->endpoint_interface->io_routines->receive_message(session, message);
932  }
933  }
934  }
935 
936  if (status == SWITCH_STATUS_SUCCESS) {
937  for (ptr = session->event_hooks.receive_message; ptr; ptr = ptr->next) {
938  if ((status = ptr->receive_message(session, message)) != SWITCH_STATUS_SUCCESS) {
939  break;
940  }
941  }
942 
943 
944  if (message->message_id == SWITCH_MESSAGE_INDICATE_BRIDGE &&
946  switch_core_session_t *other_session;
947  const char *uuid = switch_channel_get_variable(session->channel, "blind_transfer_uuid");
948 
950 
951  if (!zstr(uuid) && (other_session = switch_core_session_locate(uuid))) {
952  switch_core_session_message_t msg = { 0 };
954  msg.from = __FILE__;
955  msg.numeric_arg = 1;
956  switch_core_session_receive_message(other_session, &msg);
957  switch_core_session_rwunlock(other_session);
958  }
959  }
960  }
961 
962 
963  message->_file = NULL;
964  message->_func = NULL;
965  message->_line = 0;
966 
967  if (switch_channel_up_nosig(session->channel)) {
971  }
972 
973  switch (message->message_id) {
992  break;
993  default:
994  break;
995  }
996  }
997 
998  end:
999 
1000  if (message->message_id == SWITCH_MESSAGE_INDICATE_MEDIA) {
1002  }
1003 
1006 
1007  return status;
1008 }
1009 
1011 {
1012  switch_core_session_message_t msg = { 0 };
1013  switch_core_session_t *other_session;
1014  const char *uuid;
1017 
1018  if (((uuid = switch_channel_get_partner_uuid(channel))) && (other_session = switch_core_session_locate(uuid))) {
1019  msg.message_id = indication;
1020  msg.from = __FILE__;
1021  status = switch_core_session_receive_message(other_session, &msg);
1022  switch_core_session_rwunlock(other_session);
1023  } else {
1024  status = SWITCH_STATUS_FALSE;
1025  }
1026 
1027  return status;
1028 }
1029 
1031 {
1033 
1034  if ((msg = malloc(sizeof(*msg)))) {
1035  memset(msg, 0, sizeof(*msg));
1036  msg->message_id = indication;
1037  msg->from = __FILE__;
1039 
1041  return SWITCH_STATUS_SUCCESS;
1042  }
1043 
1044  free(msg);
1045  }
1046 
1047  return SWITCH_STATUS_FALSE;
1048 }
1049 
1051 {
1053 
1054  switch_assert(session != NULL);
1055 
1056  if (session->message_queue) {
1057  if (switch_queue_trypush(session->message_queue, message) == SWITCH_STATUS_SUCCESS) {
1058  status = SWITCH_STATUS_SUCCESS;
1059  }
1060 
1062 
1064 
1065  }
1066 
1067  return status;
1068 }
1069 
1071 {
1072  switch_core_session_message_t *to_free = *message;
1073  int i;
1074  char *s;
1075 
1076  *message = NULL;
1077 
1078  if (switch_test_flag(to_free, SCSMF_DYNAMIC)) {
1079  s = (char *) to_free->string_arg;
1080  switch_safe_free(s);
1081  switch_safe_free(to_free->pointer_arg);
1082 
1083  for (i = 0; i < MESSAGE_STRING_ARG_MAX; i++) {
1084  s = (char *) to_free->string_array_arg[i];
1085  switch_safe_free(s);
1086  }
1087 
1088  switch_safe_free(to_free);
1089  }
1090 }
1091 
1093 {
1095  void *pop;
1096 
1097  switch_assert(session != NULL);
1098 
1099  if (session->message_queue) {
1100  if ((status = (switch_status_t) switch_queue_trypop(session->message_queue, &pop)) == SWITCH_STATUS_SUCCESS) {
1101  *message = (switch_core_session_message_t *) pop;
1102  if ((*message)->delivery_time && (*message)->delivery_time > switch_epoch_time_now(NULL)) {
1103  switch_core_session_queue_message(session, *message);
1104  *message = NULL;
1105  status = SWITCH_STATUS_FALSE;
1106  }
1107  }
1108  }
1109 
1110  return status;
1111 }
1112 
1114 {
1115  void *pop;
1117 
1118  switch_assert(session != NULL);
1119 
1120  if (session->message_queue) {
1121  while (switch_queue_trypop(session->message_queue, &pop) == SWITCH_STATUS_SUCCESS) {
1122  message = (switch_core_session_message_t *) pop;
1123  switch_ivr_process_indications(session, message);
1125  }
1126  }
1127 
1128  return SWITCH_STATUS_SUCCESS;
1129 }
1130 
1132 {
1134 
1135  switch_assert(session != NULL);
1136 
1137  if (session->signal_data_queue) {
1138  if (switch_queue_push(session->signal_data_queue, signal_data) == SWITCH_STATUS_SUCCESS) {
1139  status = SWITCH_STATUS_SUCCESS;
1140  }
1141 
1143 
1145 
1146  }
1147 
1148  return status;
1149 }
1150 
1152 {
1154  void *pop;
1155 
1156  switch_assert(session != NULL);
1157 
1158  if (session->signal_data_queue) {
1159  if ((status = (switch_status_t) switch_queue_trypop(session->signal_data_queue, &pop)) == SWITCH_STATUS_SUCCESS) {
1160  *signal_data = pop;
1161  }
1162  }
1163 
1164  return status;
1165 }
1166 
1168 {
1171 
1172  switch_assert(session != NULL);
1173 
1174  /* Acquire a read lock on the session or forget it the channel is dead */
1176  if (switch_channel_up_nosig(session->channel)) {
1177  if (session->endpoint_interface->io_routines->receive_event) {
1178  status = session->endpoint_interface->io_routines->receive_event(session, *event);
1179  }
1180 
1181  if (status == SWITCH_STATUS_SUCCESS) {
1182  for (ptr = session->event_hooks.receive_event; ptr; ptr = ptr->next) {
1183  if ((status = ptr->receive_event(session, *event)) != SWITCH_STATUS_SUCCESS) {
1184  break;
1185  }
1186  }
1187  }
1188 
1189  if (status == SWITCH_STATUS_BREAK) {
1190  status = SWITCH_STATUS_SUCCESS;
1191  }
1192 
1193  if (status == SWITCH_STATUS_SUCCESS) {
1194  switch_event_destroy(event);
1195  }
1196  }
1198  }
1199 
1201 
1202  return status;
1203 }
1204 
1206 {
1208 
1209  switch_assert(session != NULL);
1210 
1211  if (session->event_queue) {
1212  if (switch_queue_trypush(session->event_queue, *event) == SWITCH_STATUS_SUCCESS) {
1213  *event = NULL;
1214  status = SWITCH_STATUS_SUCCESS;
1215 
1217  }
1218  }
1219 
1220  return status;
1221 }
1222 
1224 {
1225  int x = 0;
1226 
1227  if (session->private_event_queue) {
1228  x += switch_queue_size(session->private_event_queue);
1229  }
1230 
1231  if (session->message_queue) {
1232  x += switch_queue_size(session->message_queue);
1233  }
1234 
1235  return x;
1236 }
1237 
1239 {
1240  if (session->event_queue) {
1241  return switch_queue_size(session->event_queue);
1242  }
1243 
1244  return 0;
1245 }
1246 
1248 {
1250  void *pop;
1251 
1252  switch_assert(session != NULL);
1253 
1254  if (session->event_queue && (force || !switch_channel_test_flag(session->channel, CF_DIVERT_EVENTS))) {
1255  if ((status = (switch_status_t) switch_queue_trypop(session->event_queue, &pop)) == SWITCH_STATUS_SUCCESS) {
1256  *event = (switch_event_t *) pop;
1257  }
1258  }
1259 
1260  return status;
1261 }
1262 
1264 {
1266  switch_queue_t *queue;
1267 
1268  switch_assert(session != NULL);
1269  switch_assert(event != NULL);
1270 
1271  if (session->private_event_queue) {
1272  queue = priority ? session->private_event_queue_pri : session->private_event_queue;
1273 
1274  (*event)->event_id = SWITCH_EVENT_PRIVATE_COMMAND;
1275  if (switch_queue_trypush(queue, *event) == SWITCH_STATUS_SUCCESS) {
1276  *event = NULL;
1278  status = SWITCH_STATUS_SUCCESS;
1279  }
1280  }
1281 
1282  return status;
1283 }
1284 
1285 #define check_media(session) \
1286  { \
1287  if (switch_channel_test_flag(session->channel, CF_BROADCAST_DROP_MEDIA)) { \
1288  switch_channel_clear_flag(session->channel, CF_BROADCAST_DROP_MEDIA); \
1289  switch_ivr_nomedia(session->uuid_str, SMF_REBRIDGE); \
1290  } \
1291  } \
1292 
1294 {
1296  uint32_t count = 0;
1297 
1298  if (session->private_event_queue) {
1299 
1300  if (!switch_channel_test_flag(channel, CF_EVENT_LOCK)) {
1301  count = switch_queue_size(session->private_event_queue);
1302  }
1303 
1305  count += switch_queue_size(session->private_event_queue_pri);
1306  }
1307 
1308  if (count == 0) {
1309  check_media(session);
1310  }
1311  }
1312 
1313  return count;
1314 }
1315 
1317 {
1319  void *pop;
1321  switch_queue_t *queue;
1322 
1323  if (session->private_event_queue) {
1325  queue = session->private_event_queue_pri;
1326 
1328  return SWITCH_STATUS_FALSE;
1329  }
1330  } else {
1331  queue = session->private_event_queue;
1332 
1333  if (switch_channel_test_flag(channel, CF_EVENT_LOCK)) {
1334  return SWITCH_STATUS_FALSE;
1335  }
1336  }
1337 
1338  if ((status = (switch_status_t) switch_queue_trypop(queue, &pop)) == SWITCH_STATUS_SUCCESS) {
1339  *event = (switch_event_t *) pop;
1340  } else {
1341  check_media(session);
1342  }
1343  }
1344 
1345  return status;
1346 }
1347 
1349 {
1350  int x = 0;
1351  void *pop;
1352 
1353  if (session->private_event_queue) {
1355  if (pop) {
1356  switch_event_t *event = (switch_event_t *) pop;
1357  switch_event_destroy(&event);
1358  }
1359  x++;
1360  }
1362  if (pop) {
1363  switch_event_t *event = (switch_event_t *) pop;
1364  switch_event_destroy(&event);
1365  }
1366  x++;
1367  }
1368  check_media(session);
1369  }
1370 
1371  return x;
1372 }
1373 
1375 {
1377 
1380  switch_core_session_reset(session, flush_dtmf, reset_read_codec);
1382  status = SWITCH_STATUS_SUCCESS;
1383  }
1384 
1386  }
1387 
1388  return status;
1389 }
1390 
1392 {
1394 
1395  if (reset_read_codec) {
1396  switch_core_session_set_read_codec(session, NULL);
1397  if (session->sdata && switch_core_codec_ready(&session->sdata->codec)) {
1399  }
1400  }
1401 
1402  /* clear resamplers */
1407  /* clear indications */
1409 
1410  /* wipe these, they will be recreated if need be */
1414 
1418 
1419  if (flush_dtmf) {
1420  while (switch_channel_has_dtmf(channel)) {
1421  switch_channel_flush_dtmf(channel);
1422  }
1423  }
1424 
1428 }
1429 
1430 
1432 {
1433  switch_assert(session->channel);
1434  return session->channel;
1435 }
1436 
1438 {
1439  return session->mutex;
1440 }
1441 
1443 {
1444  switch_status_t status;
1445  int tries = 0;
1446 
1447  /* If trylock fails the signal is already awake so we needn't bother ..... or do we????*/
1448 
1449  top:
1450 
1451  status = switch_mutex_trylock(session->mutex);
1452 
1453  if (status == SWITCH_STATUS_SUCCESS) {
1454  switch_thread_cond_signal(session->cond);
1455  switch_mutex_unlock(session->mutex);
1456  } else {
1458  /* We've beat them for sure, as soon as we release this lock, they will be checking their queue on the next line. */
1461  } else {
1462  /* What luck! The channel has already started going to sleep *after* we checked if we need to wake it up.
1463  It will miss any messages in its queue because they were inserted after *it* checked its queue. (catch-22)
1464  So, it's not asleep yet, but it's too late for us to be sure they know we want them to stay awake and check its queue again.
1465  Now *we* need to sleep instead but just for 1ms so we can circle back and try again.
1466  This is so rare (yet possible) to happen that we can be fairly certian it will not happen 2x in a row but we'll try 10x just in case.
1467  */
1468  if (++tries < 10) {
1469  switch_cond_next();
1470  goto top;
1471  }
1472  }
1473  }
1474 
1475  return status;
1476 }
1477 
1479 {
1482 
1484 
1485  if (session->endpoint_interface->io_routines->state_change) {
1486  status = session->endpoint_interface->io_routines->state_change(session);
1487  }
1488 
1489  if (status == SWITCH_STATUS_SUCCESS) {
1490  for (ptr = session->event_hooks.state_change; ptr; ptr = ptr->next) {
1491  if (ptr->state_change(session) != SWITCH_STATUS_SUCCESS) {
1492  break;
1493  }
1494  }
1495  }
1497 }
1498 
1500 {
1501  return switch_test_flag(session, SSF_THREAD_RUNNING) ? 1 : 0;
1502 }
1503 
1505 {
1506  return switch_test_flag(session, SSF_THREAD_STARTED) ? 1 : 0;
1507 }
1508 
1510 {
1511  int doit = 0;
1512 
1514  if (session_manager.session_count == 0) {
1515  doit = 1;
1516  } else {
1518  }
1520 
1521  if (doit) {
1522  switch_time_sync();
1523  }
1524 
1525  return doit;
1526 
1527 }
1528 
1529 SWITCH_DECLARE(void) switch_core_session_perform_destroy(switch_core_session_t **session, const char *file, const char *func, int line)
1530 {
1532  switch_event_t *event;
1533  switch_endpoint_interface_t *endpoint_interface = (*session)->endpoint_interface;
1534  int i;
1535 
1536 
1538 
1539  if (switch_core_session_running(*session) && !switch_test_flag((*session), SSF_DESTROYABLE)) {
1541  "Cowardly ignoring an attempt to call destroy on a running session.\n");
1542  }
1543 
1544  switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, switch_core_session_get_uuid(*session), SWITCH_LOG_NOTICE, "Close Channel %s [%s]\n",
1545  switch_channel_get_name((*session)->channel), switch_channel_state_name(switch_channel_get_state((*session)->channel)));
1546 
1547 
1548  if ((*session)->text_buffer) {
1549  switch_buffer_destroy(&(*session)->text_buffer);
1550  }
1551 
1552  if ((*session)->text_line_buffer) {
1553  switch_buffer_destroy(&(*session)->text_line_buffer);
1554  }
1555 
1557 
1560 
1561  switch_scheduler_del_task_group((*session)->uuid_str);
1562 
1564  switch_core_hash_delete(session_manager.session_table, (*session)->uuid_str);
1565  if ((*session)->external_id) {
1566  switch_core_hash_delete(session_manager.session_table, (*session)->external_id);
1567  }
1570  if (session_manager.session_count == 0) {
1572  switch_time_sync();
1574  }
1575  }
1576  }
1578 
1579  if ((*session)->plc) {
1580  switch_plc_free((*session)->plc);
1581  (*session)->plc = NULL;
1582  }
1583 
1585  switch_channel_event_set_data((*session)->channel, event);
1586  switch_event_fire(&event);
1587  }
1588 
1590 
1591  switch_buffer_destroy(&(*session)->raw_read_buffer);
1592  switch_buffer_destroy(&(*session)->raw_write_buffer);
1594  switch_channel_uninit((*session)->channel);
1595 
1596  for (i = 0; i < 2; i++) {
1597  if ((*session)->dmachine[i]) {
1598  switch_ivr_dmachine_destroy(&(*session)->dmachine[i]);
1599  }
1600  }
1601 
1602  if ((*session)->event_queue) {
1603  void *pop;
1604  while (switch_queue_trypop((*session)->event_queue, &pop) == SWITCH_STATUS_SUCCESS) {
1605  if (pop) {
1606  switch_event_t *event = (switch_event_t *) pop;
1607  switch_event_destroy(&event);
1608  }
1609  }
1610  }
1611 
1612  pool = (*session)->pool;
1613  //#ifndef NDEBUG
1614  //memset(*session, 0, sizeof(switch_core_session_t));
1615  //#endif
1616  *session = NULL;
1618 
1619  UNPROTECT_INTERFACE(endpoint_interface);
1620 }
1621 
1622 
1623 
1624 SWITCH_STANDARD_SCHED_FUNC(sch_heartbeat_callback)
1625 {
1626  switch_event_t *event;
1627  switch_core_session_t *session;
1628  char *uuid = task->cmd_arg;
1629  switch_core_session_message_t msg = { 0 };
1630 
1631  if ((session = switch_core_session_locate(uuid))) {
1633  switch_channel_event_set_data(session->channel, event);
1634  switch_event_fire(&event);
1635 
1636  /* reschedule this task */
1637  task->runtime = switch_epoch_time_now(NULL) + session->track_duration;
1638 
1640  msg.numeric_arg = session->track_duration;
1641  switch_core_session_receive_message(session, &msg);
1642 
1644  }
1645 }
1646 
1648 {
1649  if (session->track_id) {
1651  session->track_id = 0;
1652  }
1653 }
1654 
1656 {
1657  time_t when;
1658 
1660  if (switch_true(switch_channel_get_variable(session->channel, "heartbeat_fire_on_set"))) {
1661  when = switch_epoch_time_now(NULL);
1662  } else {
1663  when = switch_epoch_time_now(NULL) + session->track_duration;
1664  }
1665 
1666  session->track_id = switch_scheduler_add_task(when, sch_heartbeat_callback, (char *) __SWITCH_FUNC__,
1668 }
1669 
1671 {
1672  switch_assert(session != NULL);
1673 
1674  if (!seconds) {
1675  seconds = 60;
1676  }
1677 
1678  session->track_duration = seconds;
1679 
1681  switch_true(switch_channel_get_variable_dup(session->channel, "heartbeat_use_scheduler", SWITCH_FALSE, -1)) ||
1682  switch_true(switch_channel_get_variable_dup(session->channel, "bypass_media", SWITCH_FALSE, -1)) ||
1683  switch_true(switch_channel_get_variable_dup(session->channel, "bypass_media_after_bridge", SWITCH_FALSE, -1))) {
1684  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "%s using scheduler due to bypass media or media is not established.\n",
1685  switch_channel_get_name(session->channel));
1686  switch_core_session_sched_heartbeat(session, seconds);
1687  return;
1688  }
1689 
1690  if (switch_true(switch_channel_get_variable(session->channel, "heartbeat_fire_on_set"))) {
1691  session->read_frame_count = 0;
1692  } else {
1693  session->read_frame_count = (session->read_impl.samples_per_second / session->read_impl.samples_per_packet) * seconds;
1694  }
1695 
1697 
1698  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "%s setting session heartbeat to %u second(s).\n",
1699  switch_channel_get_name(session->channel), seconds);
1700 
1701 }
1702 
1704 {
1706  switch_assert(session != NULL);
1707  session->read_frame_count = 0;
1708  session->track_duration = 0;
1709 
1710 }
1711 
1713 {
1715 }
1716 
1718 {
1719  switch_core_session_t *session = obj;
1720  switch_event_t *event;
1721  char *event_str = NULL;
1722  const char *val;
1723 
1724  session->thread = thread;
1725  session->thread_id = switch_thread_self();
1726 
1727  switch_core_session_run(session);
1729 
1730  if (session->soft_lock) {
1731  uint32_t loops = session->soft_lock * 10;
1732 
1733  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Session %" SWITCH_SIZE_T_FMT " (%s) Soft-Locked, "
1734  "Waiting %u for external entities\n",
1735  session->id, switch_channel_get_name(session->channel), session->soft_lock);
1736 
1737  while(--loops > 0) {
1738  if (!session->soft_lock) break;
1739  switch_yield(100000);
1740  }
1741 
1742  }
1743 
1744  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Session %" SWITCH_SIZE_T_FMT " (%s) Locked, Waiting on external entities\n",
1745  session->id, switch_channel_get_name(session->channel));
1747  switch_set_flag(session, SSF_DESTROYED);
1748 
1749  if ((val = switch_channel_get_variable(session->channel, "memory_debug")) && switch_true(val)) {
1751  switch_channel_event_set_data(session->channel, event);
1752  switch_event_serialize(event, &event_str, SWITCH_FALSE);
1753  switch_assert(event_str);
1755  free(event_str);
1756  switch_event_destroy(&event);
1757  }
1758  }
1759 
1761 
1763  session->id, switch_channel_get_name(session->channel));
1764 
1765  switch_set_flag(session, SSF_DESTROYABLE);
1766  switch_core_session_destroy(&session);
1767  return NULL;
1768 }
1769 
1773 
1775 {
1777  switch_memory_pool_t *pool = node->pool;
1778 #ifdef DEBUG_THREAD_POOL
1779  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10, "Worker Thread %ld Started\n", (long) (intptr_t) thread);
1780 #endif
1781  for (;;) {
1782  void *pop;
1784  if (check_status == SWITCH_STATUS_SUCCESS) {
1786 
1787 #ifdef DEBUG_THREAD_POOL
1788  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10, "Worker Thread %ld Processing\n", (long) (intptr_t) thread);
1789 #endif
1790  td->running = 1;
1791  td->func(thread, td->obj);
1792  td->running = 0;
1793 
1794  if (td->pool) {
1795  switch_memory_pool_t *pool = td->pool;
1796  td = NULL;
1798  } else if (td->alloc) {
1799  free(td);
1800  }
1801 #ifdef DEBUG_THREAD_POOL
1802  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10, "Worker Thread %ld Done Processing\n", (long)(intptr_t) thread);
1803 #endif
1807  } else {
1810  if (!--session_manager.running) {
1812  }
1814  break;
1815  }
1817  }
1818  }
1819 #ifdef DEBUG_THREAD_POOL
1820  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10, "Worker Thread %ld Ended\n", (long)(intptr_t) thread);
1821 #endif
1823  return NULL;
1824 }
1825 
1826 static void thread_launch_failure(void)
1827 {
1828  uint32_t sess_count;
1829 
1831 
1832  sess_count = switch_core_session_count();
1833 
1834  if (sess_count > 110) {
1835 
1836  switch_core_session_limit(sess_count - 10);
1837  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "LUKE: I'm hit, but not bad.\n");
1839  "LUKE'S VOICE: Artoo, see what you can do with it. Hang on back there....\n"
1840  "Green laserfire moves past the beeping little robot as his head turns. "
1841  "After a few beeps and a twist of his mechanical arm,\n"
1842  "Artoo reduces the max sessions to %d thus, saving the switch from certain doom.\n", sess_count - 10);
1843 
1844  }
1845 
1847 }
1848 
1850 {
1855  return SWITCH_STATUS_SUCCESS;
1856  }
1859 
1860  {
1862  switch_threadattr_t *thd_attr;
1865 
1867  node = switch_core_alloc(pool, sizeof(*node));
1868  node->pool = pool;
1869 
1870  switch_threadattr_create(&thd_attr, node->pool);
1871  switch_threadattr_detach_set(thd_attr, 1);
1874 
1877  if (!--session_manager.running) {
1879  }
1881  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Thread Failure!\n");
1883  status = SWITCH_STATUS_GENERR;
1885  } else {
1886  status = SWITCH_STATUS_SUCCESS;
1887  }
1888  }
1889  return status;
1890 }
1891 
1892 
1894 {
1897 
1898  switch_assert(tdp);
1899 
1900  td = *tdp;
1901  *tdp = NULL;
1902 
1904  check_queue();
1905 
1906  return status;
1907 }
1908 
1910 {
1911  while(!td->running && --ms > 0) {
1912  switch_cond_next();
1913  }
1914 
1915  return ms > 0 ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_TIMEOUT;
1916 }
1917 
1919 {
1922 
1923  switch_mutex_lock(session->mutex);
1924  if (switch_test_flag(session, SSF_THREAD_RUNNING)) {
1925  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Cannot double-launch thread!\n");
1926  } else if (switch_test_flag(session, SSF_THREAD_STARTED)) {
1927  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Cannot launch thread again after it has already been run!\n");
1928  } else {
1931  td = switch_core_session_alloc(session, sizeof(*td));
1932  td->obj = session;
1935  check_queue();
1936  }
1937  switch_mutex_unlock(session->mutex);
1938 
1939  return status;
1940 }
1941 
1943 {
1946  switch_threadattr_t *thd_attr;
1947 
1949  status = SWITCH_STATUS_INUSE;
1950  goto end;
1951  }
1952 
1953 
1956  }
1957 
1958  switch_mutex_lock(session->mutex);
1959 
1960  if (switch_test_flag(session, SSF_THREAD_RUNNING)) {
1961  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Cannot double-launch thread!\n");
1962  } else if (switch_test_flag(session, SSF_THREAD_STARTED)) {
1963  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Cannot launch thread again after it has already been run!\n");
1964  } else {
1967 
1968  switch_threadattr_create(&thd_attr, session->pool);
1969  switch_threadattr_detach_set(thd_attr, 1);
1971 
1972  if (switch_thread_create(&thread, thd_attr, switch_core_session_thread, session, session->pool) == SWITCH_STATUS_SUCCESS) {
1974  status = SWITCH_STATUS_SUCCESS;
1975  } else {
1978  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Cannot create thread!\n");
1980  }
1981  }
1982 
1983  switch_mutex_unlock(session->mutex);
1984 
1985  end:
1986 
1987  return status;
1988 }
1989 
1991 {
1992  const char *buf = NULL;
1993 
1994  if (session->text_buffer) {
1995  switch_mutex_lock(session->text_mutex);
1996  buf = (const char *)switch_core_session_strdup(session, (const char *) switch_buffer_get_head_pointer(session->text_buffer));
1997  switch_mutex_unlock(session->text_mutex);
1998  }
1999 
2000  return buf;
2001 }
2002 
2004 {
2006  switch_threadattr_t *thd_attr = NULL;
2007  switch_threadattr_create(&thd_attr, session->pool);
2008  switch_threadattr_detach_set(thd_attr, 1);
2009 
2011  if (switch_thread_create(&thread, thd_attr, func, obj, session->pool) != SWITCH_STATUS_SUCCESS) {
2012  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Cannot create thread!\n");
2014  }
2015 
2016 }
2017 
2019 {
2020  switch_event_t *event;
2021  switch_core_session_message_t msg = { 0 };
2022  switch_caller_profile_t *profile;
2023 
2024  switch_assert(use_uuid);
2025 
2026  if (!strcmp(use_uuid, session->uuid_str)) {
2027  return SWITCH_STATUS_SUCCESS;
2028  }
2029 
2030 
2033  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Duplicate UUID!\n");
2035  return SWITCH_STATUS_FALSE;
2036  }
2037 
2039  msg.from = switch_channel_get_name(session->channel);
2040  msg.string_array_arg[0] = session->uuid_str;
2041  msg.string_array_arg[1] = use_uuid;
2042  switch_core_session_receive_message(session, &msg);
2043 
2044  if ((profile = switch_channel_get_caller_profile(session->channel))) {
2045  profile->uuid = switch_core_strdup(profile->pool, use_uuid);
2046  }
2047 
2048  switch_channel_set_variable(session->channel, "uuid", use_uuid);
2049  switch_channel_set_variable(session->channel, "call_uuid", use_uuid);
2050 
2052  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Old-Unique-ID", session->uuid_str);
2054  switch_set_string(session->uuid_str, use_uuid);
2057  switch_channel_event_set_data(session->channel, event);
2058  switch_event_fire(&event);
2059 
2060 
2061  return SWITCH_STATUS_SUCCESS;
2062 }
2063 
2065 {
2066  switch_assert(use_external_id);
2067 
2068  if (session->external_id && !strcmp(use_external_id, session->external_id)) {
2069  return SWITCH_STATUS_SUCCESS;
2070  }
2071 
2072 
2074  if (strcmp(use_external_id, session->uuid_str) && switch_core_hash_find(session_manager.session_table, use_external_id)) {
2075  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Duplicate External ID!\n");
2077  return SWITCH_STATUS_FALSE;
2078  }
2079 
2080  switch_channel_set_variable(session->channel, "session_external_id", use_external_id);
2081 
2082  if (session->external_id && strcmp(session->external_id, session->uuid_str)) {
2084  }
2085 
2086  session->external_id = switch_core_session_strdup(session, use_external_id);
2087 
2088  if (strcmp(session->external_id, session->uuid_str)) {
2090  }
2092 
2093  return SWITCH_STATUS_SUCCESS;
2094 }
2095 
2096 static char *xml_find_var(switch_xml_t vars, const char *name)
2097 {
2098  switch_xml_t var;
2099  if ((var = switch_xml_child(vars, name)) && var->txt) {
2100  return var->txt;
2101  }
2102 
2103  return NULL;
2104 }
2105 
2106 static void parse_array(const char *str, uint32_t *array, int32_t array_len)
2107 {
2108  char *p, *v, *dup, *next = NULL;
2109 
2110  if (zstr(str)) {
2111  return;
2112  }
2113 
2114  dup = strdup(str);
2115 
2116  p = dup;
2117  while (p) {
2118  if ((next = strchr(p, ';'))) {
2119  *next++ = '\0';
2120  }
2121 
2122  if ((v = strchr(p, '='))) {
2123  *v++ = '\0';
2124  }
2125 
2126  if (p && v) {
2127  int x = 0, y = 0;
2128 
2129  x = atoi(p);
2130  y = atoi(v);
2131 
2132  if (x < array_len) {
2133  array[x] = y;
2134  }
2135  }
2136 
2137  p = next;
2138 
2139  }
2140 
2141  free(dup);
2142 }
2143 
2146 {
2147  switch_core_session_t *session;
2148  switch_channel_t *channel;
2149  switch_xml_t tag, tag2, tag3, vars, callflow;
2151  char *flag_str = NULL, *cap_str = NULL, *direction_s = NULL, *uuid = NULL;
2152  uint32_t flags[CF_FLAG_MAX] = { 0 };
2153  uint32_t caps[CC_FLAG_MAX] = { 0 };
2154  int i;
2155 
2156  vars = switch_xml_child(xml, "variables");
2157  uuid = xml_find_var(vars, "uuid");
2158 
2159  if ((tag = switch_xml_child(xml, "channel_data"))) {
2160  direction_s = xml_find_var(tag, "direction");
2161  direction = !strcmp(direction_s, "outbound") ? SWITCH_CALL_DIRECTION_OUTBOUND : SWITCH_CALL_DIRECTION_INBOUND;
2162  flag_str = xml_find_var(tag, "flags");
2163  cap_str = xml_find_var(tag, "caps");
2164  }
2165 
2166  parse_array(flag_str, flags, CF_FLAG_MAX);
2167  parse_array(cap_str, caps, CC_FLAG_MAX);
2168 
2169  flags[CF_RECOVERING] = 0;
2170  flags[CF_RECOVERING_BRIDGE] = 0;
2171  flags[CF_TRACKED] = 0;
2172  flags[CF_TRANSFER] = 0;
2173  flags[CF_ACCEPT_CNG] = 0;
2174  flags[CF_REDIRECT] = 0;
2175  flags[CF_BRIDGED] = 0;
2176  flags[CF_HOLD] = 0;
2177  flags[CF_SERVICE] = 0;
2178  flags[CF_TAGGED] = 0;
2179  flags[CF_WINNER] = 0;
2180  flags[CF_EARLY_OK] = 0;
2181  flags[CF_CONTROLLED] = 0;
2182  flags[CF_SUSPEND] = 0;
2183  flags[CF_EVENT_PARSE] = 0;
2184  flags[CF_GEN_RINGBACK] = 0;
2185  flags[CF_BREAK] = 0;
2186  flags[CF_BROADCAST] = 0;
2187  flags[CF_UNICAST] = 0;
2188  flags[CF_EVENT_LOCK] = 0;
2189  flags[CF_EVENT_LOCK_PRI] = 0;
2190  flags[CF_RESET] = 0;
2191  flags[CF_ORIGINATING] = 0;
2192  flags[CF_STOP_BROADCAST] = 0;
2193  flags[CF_INNER_BRIDGE] = 0;
2194  flags[CF_REQ_MEDIA] = 0;
2195  flags[CF_PAUSE_BUGS] = 0;
2196  flags[CF_DIVERT_EVENTS] = 0;
2197  flags[CF_BLOCK_STATE] = 0;
2198  flags[CF_FS_RTP] = 0;
2199  flags[CF_REPORTING] = 0;
2200  flags[CF_PARK] = 0;
2201  flags[CF_TIMESTAMP_SET] = 0;
2202  flags[CF_ORIGINATOR] = 0;
2203  flags[CF_XFER_ZOMBIE] = 0;
2204  flags[CF_MEDIA_ACK] = 0;
2205  flags[CF_THREAD_SLEEPING] = 0;
2206  flags[CF_DISABLE_RINGBACK] = 0;
2207  flags[CF_NOT_READY] = 0;
2208  flags[CF_SIGNAL_BRIDGE_TTL] = 0;
2209  flags[CF_MEDIA_BRIDGE_TTL] = 0;
2210  flags[CF_BYPASS_MEDIA_AFTER_BRIDGE] = 0;
2211  flags[CF_LEG_HOLDING] = 0;
2212  flags[CF_BROADCAST_DROP_MEDIA] = 0;
2213  flags[CF_EARLY_HANGUP] = 0;
2214  flags[CF_MEDIA_SET] = 0;
2215  flags[CF_CONSUME_ON_ORIGINATE] = 0;
2216  flags[CF_PASSTHRU_PTIME_MISMATCH] = 0;
2217  flags[CF_BRIDGE_NOWRITE] = 0;
2218  flags[CF_RECOVERED] = 0;
2219  flags[CF_JITTERBUFFER] = 0;
2220  flags[CF_JITTERBUFFER_PLC] = 0;
2221  flags[CF_DIALPLAN] = 0;
2222  flags[CF_BLOCK_BROADCAST_UNTIL_MEDIA] = 0;
2223  flags[CF_CNG_PLC] = 0;
2224  flags[CF_ATTENDED_TRANSFER] = 0;
2225  flags[CF_LAZY_ATTENDED_TRANSFER] = 0;
2226  flags[CF_SIGNAL_DATA] = 0;
2227  flags[CF_SIMPLIFY] = 0;
2228  flags[CF_VIDEO_READY] = 0;
2229  flags[CF_VIDEO_DECODED_READ] = 0;
2230 
2231  if (!(session = switch_core_session_request_uuid(endpoint_interface, direction, SOF_NO_LIMITS, pool, uuid))) {
2232  return NULL;
2233  }
2234 
2235  channel = switch_core_session_get_channel(session);
2236 
2237  for (i = 0; i < CF_FLAG_MAX; i++) {
2238  if (flags[i]) {
2239  switch_channel_set_flag_value(channel, i, flags[i]);
2240  }
2241  }
2242 
2243  for (i = 0; i < CC_FLAG_MAX; i++) {
2244  if (caps[i]) {
2245  switch_channel_set_cap_value(channel, i, caps[i]);
2246  }
2247  }
2248 
2249  if ((tag2 = switch_xml_child(xml, "variables"))) {
2250  for (tag = tag2->child; tag; tag = tag->sibling) {
2251  if (tag->name && tag->txt) {
2252  char *p = strdup(tag->txt);
2253  char *val = p;
2254  switch_url_decode(val);
2255  switch_channel_set_variable(channel, tag->name, val);
2256  if (!strcasecmp(tag->name, "channel_name")) {
2257  switch_channel_set_name(channel, val);
2258  }
2259  free(p);
2260  }
2261  }
2262  }
2263 
2264  if ((callflow = switch_xml_child(xml, "callflow"))) {
2265  if ((tag2 = switch_xml_child(callflow, "caller_profile"))) {
2266  switch_caller_profile_t *caller_profile;
2267  char *tmp;
2268 
2269  caller_profile = switch_caller_profile_new(switch_core_session_get_pool(session),
2270  xml_find_var(tag2, "username"),
2271  xml_find_var(tag2, "dialplan"),
2272  xml_find_var(tag2, "caller_id_name"),
2273  xml_find_var(tag2, "caller_id_number"),
2274  xml_find_var(tag2, "network_addr"),
2275  xml_find_var(tag2, "ani"),
2276  xml_find_var(tag2, "aniii"),
2277  xml_find_var(tag2, "rdnis"),
2278  xml_find_var(tag2, "source"),
2279  xml_find_var(tag2, "context"), xml_find_var(tag2, "destination_number"));
2280 
2281  if ((tmp = xml_find_var(tag2, "callee_id_name"))) {
2282  caller_profile->callee_id_name = switch_core_session_strdup(session, tmp);
2283  }
2284 
2285  if ((tmp = xml_find_var(tag2, "callee_id_number"))) {
2286  caller_profile->callee_id_number = switch_core_session_strdup(session, tmp);
2287  }
2288 
2289  if ((tag3 = switch_xml_child(callflow, "times"))) {
2290  caller_profile->times = (switch_channel_timetable_t *) switch_core_session_alloc(session, sizeof(*caller_profile->times));
2291 
2292  caller_profile->times->resurrected = switch_time_now();
2293 
2294  for (tag3 = tag3->child; tag3; tag3 = tag3->sibling) {
2295  int64_t v;
2296 
2297  if (tag3->name && tag3->txt) {
2298  v = atoll(tag3->txt);
2299  if (!strcmp(tag3->name, "created_time")) {
2300  caller_profile->times->created = v;
2301  } else if (!strcmp(tag3->name, "profile_created_time")) {
2302  caller_profile->times->profile_created = v;
2303  } else if (!strcmp(tag3->name, "progress_time")) {
2304  caller_profile->times->progress = v;
2305  } else if (!strcmp(tag3->name, "progress_media_time")) {
2306  caller_profile->times->progress_media = v;
2307  } else if (!strcmp(tag3->name, "answered_time")) {
2308  caller_profile->times->answered = v;
2309  } else if (!strcmp(tag3->name, "hangup_time")) {
2310  caller_profile->times->hungup = v;
2311  } else if (!strcmp(tag3->name, "transfer_time")) {
2312  caller_profile->times->transferred = v;
2313  }
2314  }
2315 
2316  }
2317  }
2318 
2319  switch_channel_set_caller_profile(channel, caller_profile);
2320  if ((tag = switch_xml_child(tag2, "originator")) && (tag = tag->child)) {
2321  caller_profile = switch_caller_profile_new(switch_core_session_get_pool(session),
2322  xml_find_var(tag, "username"),
2323  xml_find_var(tag, "dialplan"),
2324  xml_find_var(tag, "caller_id_name"),
2325  xml_find_var(tag, "caller_id_number"),
2326  xml_find_var(tag, "network_addr"),
2327  xml_find_var(tag, "ani"),
2328  xml_find_var(tag, "aniii"),
2329  xml_find_var(tag, "rdnis"),
2330  xml_find_var(tag, "source"),
2331  xml_find_var(tag, "context"), xml_find_var(tag, "destination_number"));
2332 
2333  switch_channel_set_originator_caller_profile(channel, caller_profile);
2334  }
2335 
2336  if ((tag = switch_xml_child(tag2, "originatee")) && (tag = tag->child)) {
2337  caller_profile = switch_caller_profile_new(switch_core_session_get_pool(session),
2338  xml_find_var(tag, "username"),
2339  xml_find_var(tag, "dialplan"),
2340  xml_find_var(tag, "caller_id_name"),
2341  xml_find_var(tag, "caller_id_number"),
2342  xml_find_var(tag, "network_addr"),
2343  xml_find_var(tag, "ani"),
2344  xml_find_var(tag, "aniii"),
2345  xml_find_var(tag, "rdnis"),
2346  xml_find_var(tag, "source"),
2347  xml_find_var(tag, "context"), xml_find_var(tag, "destination_number"));
2348 
2349  switch_channel_set_originatee_caller_profile(channel, caller_profile);
2350  }
2351 
2352  }
2353 
2354 
2356  }
2357 
2358 
2359  if (!channel || !switch_channel_get_caller_profile(channel)) {
2360  if (session) {
2361  switch_core_session_destroy(&session);
2362  }
2363  }
2364 
2365 
2366  return session;
2367 }
2368 
2369 
2370 
2372  *endpoint_interface,
2373  switch_call_direction_t direction,
2374  switch_originate_flag_t originate_flags,
2375  switch_memory_pool_t **pool, const char *use_uuid)
2376 {
2377  switch_memory_pool_t *usepool;
2378  switch_core_session_t *session;
2379  switch_uuid_t uuid;
2380  uint32_t count = 0;
2381  int32_t sps = 0;
2382 
2383 
2385  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "The system cannot create any inbound sessions at this time.\n");
2386  return NULL;
2387  }
2388 
2390  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "The system cannot create any outbound sessions at this time.\n");
2391  return NULL;
2392  }
2393 
2394  if (!switch_core_ready() || endpoint_interface == NULL) {
2395  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "The system cannot create any sessions at this time.\n");
2396  return NULL;
2397  }
2398 
2400  return NULL;
2401  }
2402 
2403  PROTECT_INTERFACE(endpoint_interface);
2404 
2406  if (use_uuid && switch_core_hash_find(session_manager.session_table, use_uuid)) {
2408  UNPROTECT_INTERFACE(endpoint_interface);
2409  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Duplicate UUID!\n");
2410 
2411  return NULL;
2412  }
2413 
2414  if (!(originate_flags & SOF_NO_LIMITS)) {
2417  sps = --runtime.sps;
2419 
2420  if (sps <= 0) {
2423  UNPROTECT_INTERFACE(endpoint_interface);
2424  return NULL;
2425  }
2426 
2427  if ((count + 1) > session_manager.session_limit) {
2430  UNPROTECT_INTERFACE(endpoint_interface);
2431  return NULL;
2432  }
2433  }
2434 
2435 
2436  if (pool && *pool) {
2437  usepool = *pool;
2438  *pool = NULL;
2439  } else {
2440  switch_core_new_memory_pool(&usepool);
2441  }
2442 
2443  session = switch_core_alloc(usepool, sizeof(*session));
2444  session->pool = usepool;
2445 
2446  switch_core_memory_pool_set_data(session->pool, "__session", session);
2447 
2448  if (switch_channel_alloc(&session->channel, direction, session->pool) != SWITCH_STATUS_SUCCESS) {
2449  abort();
2450  }
2451 
2452  switch_channel_init(session->channel, session, CS_NEW, 0);
2453 
2454  if (direction == SWITCH_CALL_DIRECTION_OUTBOUND) {
2456  }
2457 
2458  /* The session *IS* the pool you may not alter it because you have no idea how
2459  its all private it will be passed to the thread run function */
2460 
2461  if (use_uuid) {
2462  switch_set_string(session->uuid_str, use_uuid);
2463  } else {
2464  switch_uuid_get(&uuid);
2465  switch_uuid_format(session->uuid_str, &uuid);
2466  }
2467 
2468  switch_channel_set_variable(session->channel, "uuid", session->uuid_str);
2469  switch_channel_set_variable(session->channel, "call_uuid", session->uuid_str);
2470 
2471  session->endpoint_interface = endpoint_interface;
2472  session->raw_write_frame.data = session->raw_write_buf;
2473  session->raw_write_frame.buflen = sizeof(session->raw_write_buf);
2474  session->raw_read_frame.data = session->raw_read_buf;
2475  session->raw_read_frame.buflen = sizeof(session->raw_read_buf);
2476 
2477 
2478  session->enc_write_frame.data = session->enc_write_buf;
2479  session->enc_write_frame.buflen = sizeof(session->enc_write_buf);
2480  session->enc_read_frame.data = session->enc_read_buf;
2481  session->enc_read_frame.buflen = sizeof(session->enc_read_buf);
2482 
2483  switch_mutex_init(&session->mutex, SWITCH_MUTEX_NESTED, session->pool);
2490  switch_thread_rwlock_create(&session->bug_rwlock, session->pool);
2491  switch_thread_cond_create(&session->cond, session->pool);
2492  switch_thread_rwlock_create(&session->rwlock, session->pool);
2493  switch_thread_rwlock_create(&session->io_rwlock, session->pool);
2499 
2501  session->id = session_manager.session_id++;
2503 
2506  }
2509  }
2510 
2512 
2513  switch_channel_set_variable_printf(session->channel, "session_id", "%u", session->id);
2514 
2515  return session;
2516 }
2517 
2519 {
2521 }
2522 
2524 {
2525  return session->id;
2526 }
2527 
2529 {
2533  return session_manager.session_id;
2534 }
2535 
2537 {
2538  return session_manager.session_id;
2539 }
2540 
2541 
2544 {
2545  switch_endpoint_interface_t *endpoint_interface;
2546  switch_core_session_t *session;
2547 
2548  if ((endpoint_interface = switch_loadable_module_get_endpoint_interface(endpoint_name)) == 0) {
2549  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not locate channel type %s\n", endpoint_name);
2550  return NULL;
2551  }
2552 
2553  session = switch_core_session_request(endpoint_interface, direction, SOF_NONE, pool);
2554 
2555  UNPROTECT_INTERFACE(endpoint_interface);
2556 
2557  return session;
2558 }
2559 
2560 #ifndef SWITCH_PREFIX_DIR
2561 #define SWITCH_PREFIX_DIR "."
2562 #endif
2563 
2565 {
2566  switch_assert(a != NULL);
2567  switch_assert(b != NULL);
2568 
2569  return (uint8_t) (a->endpoint_interface == b->endpoint_interface);
2570 }
2571 
2573 {
2574  switch_assert(session != NULL);
2575  switch_assert(endpoint_interface != NULL);
2576 
2577  return (uint8_t) (session->endpoint_interface == endpoint_interface);
2578 }
2579 
2581 {
2582  if (!session) return NULL;
2583  return session->uuid_str;
2584 }
2585 
2587 {
2588  if (!session) return NULL;
2589  return session->external_id;
2590 }
2591 
2592 SWITCH_DECLARE(uint32_t) switch_core_session_limit(uint32_t new_limit)
2593 {
2594  if (new_limit) {
2595  session_manager.session_limit = new_limit;
2596  }
2597 
2599 }
2600 
2601 SWITCH_DECLARE(double) switch_core_min_idle_cpu(double new_limit)
2602 {
2603  if (new_limit >= 0) {
2604  runtime.min_idle_time = new_limit;
2605  }
2606 
2607  return runtime.min_idle_time;
2608 }
2609 
2610 
2612 {
2613  return runtime.profile_time;
2614 }
2615 
2617 {
2618  if (new_limit) {
2619  runtime.sps_total = new_limit;
2620  }
2621 
2622  return runtime.sps_total;
2623 }
2624 
2626 {
2627  memset(&session_manager, 0, sizeof(session_manager));
2635 }
2636 
2638 {
2645 }
2646 
2648 {
2649  return session->app_log;
2650 }
2651 
2653 {
2654  switch_application_interface_t *application_interface;
2656 
2657  switch_assert(flags);
2658 
2659  *flags = 0;
2660 
2661  if ((application_interface = switch_loadable_module_get_application_interface(app)) == 0) {
2662  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Application %s\n", app);
2663  goto end;
2664  } else if (application_interface->flags) {
2665  *flags = application_interface->flags;
2666  status = SWITCH_STATUS_SUCCESS;
2667  }
2668 
2669  UNPROTECT_INTERFACE(application_interface);
2670 
2671  end:
2672 
2673  return status;
2674 
2675 }
2676 
2678 {
2679  switch_event_t *execute_event;
2680  char *ap, *arp;
2681 
2682  if (!arg && strstr(app, "::")) {
2683  ap = switch_core_session_strdup(session, app);
2684  app = ap;
2685 
2686  if ((arp = strstr(ap, "::"))) {
2687  *arp = '\0';
2688  arg = arp + 2;
2689  }
2690  }
2691 
2693  switch_event_add_header_string(execute_event, SWITCH_STACK_BOTTOM, "call-command", "execute");
2694  switch_event_add_header_string(execute_event, SWITCH_STACK_BOTTOM, "execute-app-name", app);
2695 
2696  if (arg) {
2697  switch_event_add_header_string(execute_event, SWITCH_STACK_BOTTOM, "execute-app-arg", arg);
2698  }
2699 
2702  }
2703 
2704  switch_event_add_header_string(execute_event, SWITCH_STACK_BOTTOM, "event-lock", "true");
2705  switch_core_session_queue_private_event(session, &execute_event, SWITCH_FALSE);
2706 
2707  return SWITCH_STATUS_SUCCESS;
2708  }
2709 
2710  return SWITCH_STATUS_FALSE;
2711 }
2712 
2714 {
2717  //switch_channel_clear_flag(session->channel, CF_VIDEO_DECODED_READ);
2722 }
2723 
2725  const char *arg, int32_t *flags)
2726 {
2727  switch_application_interface_t *application_interface;
2729 
2732 
2733  if (switch_channel_down_nosig(session->channel)) {
2734  char *p;
2735  if (!arg && (p = strstr(app, "::"))) {
2736  *p++ = '0';
2737  *p++ = '0';
2738  arg = p;
2739 
2740  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "%s ASYNC CALL CONVERTED TO INLINE %s(%s)\n",
2741  switch_channel_get_name(session->channel), app, switch_str_nil(arg));
2742  }
2743 
2744  if ((application_interface = switch_loadable_module_get_application_interface(app)) == 0) {
2745  return SWITCH_STATUS_FALSE;
2746  }
2747 
2748  if (switch_test_flag(application_interface, SAF_ZOMBIE_EXEC)) {
2749  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s ZOMBIE EXEC %s(%s)\n",
2750  switch_channel_get_name(session->channel), app, switch_str_nil(arg));
2751  goto exec;
2752  }
2753 
2755  "%s Channel is hungup and application '%s' does not have the zombie_exec flag.\n",
2756  switch_channel_get_name(session->channel), app);
2757 
2759  }
2760 
2761  if (!arg && strstr(app, "::")) {
2762  return switch_core_session_execute_application_async(session, app, arg);
2763  }
2764 
2765  if ((application_interface = switch_loadable_module_get_application_interface(app)) == 0) {
2766  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Invalid Application %s\n", app);
2769  }
2770 
2771  if (!application_interface->application_function) {
2772  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "No Function for %s\n", app);
2775  }
2776 
2777  if (flags && application_interface->flags) {
2778  *flags = application_interface->flags;
2779  }
2780 
2781  if (!switch_test_flag(application_interface, SAF_SUPPORT_NOMEDIA) && (switch_channel_test_flag(session->channel, CF_VIDEO))) {
2783  }
2784 
2785  if (switch_channel_test_flag(session->channel, CF_PROXY_MODE) && !switch_test_flag(application_interface, SAF_SUPPORT_NOMEDIA)) {
2786  switch_ivr_media(session->uuid_str, SMF_NONE);
2787  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Application %s Requires media on channel %s!\n",
2788  app, switch_channel_get_name(session->channel));
2789  } else if (!switch_test_flag(application_interface, SAF_SUPPORT_NOMEDIA) && !switch_channel_media_ready(session->channel)) {
2791  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Application %s Requires media! pre_answering channel %s\n",
2792  app, switch_channel_get_name(session->channel));
2794  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Well, that didn't work very well did it? ...\n");
2796  }
2797  } else {
2798  uint32_t ready = 0, sanity = 2000;
2799 
2800  do {
2801  sanity--;
2802  ready = switch_channel_media_up(session->channel);
2803  switch_cond_next();
2804  } while(!ready && sanity);
2805 
2806  if (!ready) {
2808  "Cannot execute app '%s' media required on an outbound channel that does not have media established\n", app);
2810  }
2811  }
2812  }
2813 
2814  if (switch_channel_text_only(session->channel) &&
2815  !switch_test_flag(application_interface, SAF_SUPPORT_NOMEDIA) &&
2816  !switch_test_flag(application_interface, SAF_SUPPORT_TEXT_ONLY)) {
2817  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Application %s does not support text-only mode on channel %s!\n",
2818  app, switch_channel_get_name(session->channel));
2821  }
2822 
2823  exec:
2824 
2825  switch_core_session_exec(session, application_interface, arg);
2826 
2827  done:
2828 
2829  UNPROTECT_INTERFACE(application_interface);
2830 
2831  return status;
2832 }
2833 
2835  const switch_application_interface_t *application_interface, const char *arg)
2836 {
2837  switch_app_log_t *log, *lp;
2838  switch_event_t *event;
2839  const char *var;
2841  char *expanded = NULL;
2842  const char *app, *app_uuid_var, *app_uuid_name;
2843  switch_core_session_message_t msg = { 0 };
2844  char delim = ',';
2845  int scope = 0;
2846  char uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1];
2847  char *app_uuid = uuid_str;
2848  switch_bool_t expand_variables = !switch_true(switch_channel_get_variable(session->channel, "app_disable_expand_variables"));
2849 
2850  if ((app_uuid_var = switch_channel_get_variable(channel, "app_uuid"))) {
2851  app_uuid = (char *)app_uuid_var;
2852  switch_channel_set_variable(channel, "app_uuid", NULL);
2853  } else {
2854  switch_uuid_str(uuid_str, sizeof(uuid_str));
2855  }
2856 
2857  if((app_uuid_name = switch_channel_get_variable(channel, "app_uuid_name"))) {
2858  switch_channel_set_variable(channel, "app_uuid_name", NULL);
2859  }
2860 
2861  switch_assert(application_interface);
2862 
2863  app = application_interface->interface_name;
2864 
2865  if (arg) {
2866  if (expand_variables) {
2867  expanded = switch_channel_expand_variables(session->channel, arg);
2868  } else {
2869  expanded = (char *)arg;
2870  }
2871  }
2872 
2873  if (expand_variables && expanded && *expanded == '%' && (*(expanded+1) == '[' || *(expanded+2) == '[')) {
2874  char *p, *dup;
2875  switch_event_t *ovars = NULL;
2876 
2877  p = expanded + 1;
2878 
2879  if (*p != '[') {
2880  delim = *p;
2881  p++;
2882  }
2883 
2884  dup = strdup(p);
2885 
2886  if (expanded != arg) {
2887  switch_safe_free(expanded);
2888  }
2889 
2890  switch_event_create_brackets(dup, '[', ']', delim, &ovars, &expanded, SWITCH_TRUE);
2891  free(dup);
2892 
2893  switch_channel_set_scope_variables(session->channel, &ovars);
2894  scope = 1;
2895  }
2896 
2897 
2899  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "EXECUTE [depth=%d] %s %s(%s)\n",
2900  switch_core_session_stack_count(session, 0), switch_channel_get_name(session->channel), app, switch_str_nil(expanded));
2901  } else {
2902  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_INFO, "EXECUTE [depth=%d] %s %s(%s)\n",
2903  switch_core_session_stack_count(session, 0), switch_channel_get_name(session->channel), app, switch_str_nil(expanded));
2904  }
2905 
2906  if ((var = switch_channel_get_variable(session->channel, "verbose_presence")) && switch_true(var)) {
2907  char *myarg = NULL;
2908  if (expanded) {
2909  myarg = switch_mprintf("%s(%s)", app, expanded);
2910  } else if (!zstr(arg)) {
2911  myarg = switch_mprintf("%s(%s)", app, arg);
2912  } else {
2913  myarg = switch_mprintf("%s", app);
2914  }
2915  if (myarg) {
2916  switch_channel_presence(session->channel, "unknown", myarg, NULL);
2917  switch_safe_free(myarg);
2918  }
2919  }
2920 
2921  if (!(var = switch_channel_get_variable(session->channel, SWITCH_DISABLE_APP_LOG_VARIABLE)) || (!(switch_true(var)))) {
2922  log = switch_core_session_alloc(session, sizeof(*log));
2923 
2924  log->app = switch_core_session_strdup(session, application_interface->interface_name);
2925  if (expanded) {
2926  log->arg = switch_core_session_strdup(session, expanded);
2927  }
2928 
2929  log->stamp = switch_time_now();
2930 
2931  for (lp = session->app_log; lp && lp->next; lp = lp->next);
2932 
2933  if (lp) {
2934  lp->next = log;
2935  } else {
2936  session->app_log = log;
2937  }
2938  }
2939 
2943 
2945  switch_channel_event_set_data(session->channel, event);
2946  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Application", application_interface->interface_name);
2947  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Application-Data", expanded);
2948  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Application-UUID", app_uuid);
2949  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Application-UUID-Name", app_uuid_name);
2950  switch_event_fire(&event);
2951  }
2952 
2954 
2955  switch_assert(application_interface->application_function);
2956 
2958 
2959  msg.from = __FILE__;
2961  msg.string_array_arg[0] = application_interface->interface_name;
2962  msg.string_array_arg[1] = expanded;
2963  switch_core_session_receive_message(session, &msg);
2964 
2965  application_interface->application_function(session, expanded);
2966 
2969  switch_channel_event_set_data(session->channel, event);
2970  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Application", application_interface->interface_name);
2971  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Application-Data", expanded);
2972  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Application-Response", resp ? resp : "_none_");
2973  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Application-UUID", app_uuid);
2974  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Application-UUID-Name", app_uuid_name);
2975  switch_event_fire(&event);
2976  }
2977 
2979  switch_core_session_receive_message(session, &msg);
2980 
2981  if (expanded != arg) {
2982  switch_safe_free(expanded);
2983  }
2984 
2985  if (scope) {
2987  }
2988 
2989  return SWITCH_STATUS_SUCCESS;
2990 }
2991 
2993 {
2994  uint32_t stack_count = 0;
2996  if (x > 0) session->stack_count++;
2997  else if (x < 0) session->stack_count--;
2998 
2999  stack_count = session->stack_count;
3001  return stack_count;
3002 }
3003 
3005  const char *context)
3006 {
3007  char *dp[25];
3008  char *dpstr;
3009  int argc, x;
3010  uint32_t stack_count = 0;
3011  switch_caller_profile_t *profile, *new_profile, *pp = NULL;
3013  switch_dialplan_interface_t *dialplan_interface = NULL;
3014  switch_caller_extension_t *extension = NULL;
3016 
3017  if (!(profile = switch_channel_get_caller_profile(channel))) {
3018  return SWITCH_STATUS_FALSE;
3019  }
3020 
3021  if ((stack_count = switch_core_session_stack_count(session, 0)) > SWITCH_MAX_STACKS) {
3022  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Error %s too many stacked extensions [depth=%d]\n",
3023  switch_channel_get_name(session->channel), stack_count);
3024  return SWITCH_STATUS_FALSE;
3025  }
3026 
3027  switch_core_session_stack_count(session, 1);
3028 
3029  new_profile = switch_caller_profile_clone(session, profile);
3030  new_profile->destination_number = switch_core_strdup(new_profile->pool, exten);
3031  new_profile->times = (switch_channel_timetable_t *) switch_core_session_alloc(session, sizeof(*new_profile->times));
3032  *new_profile->times = *profile->times;
3033 
3034 
3035  if (!zstr(dialplan)) {
3036  new_profile->dialplan = switch_core_strdup(new_profile->pool, dialplan);
3037  }
3038 
3039  if (!zstr(context)) {
3040  new_profile->context = switch_core_strdup(new_profile->pool, context);
3041  }
3042 
3043  dpstr = switch_core_session_strdup(session, new_profile->dialplan);
3044 
3045  switch_channel_set_hunt_caller_profile(channel, new_profile);
3046  argc = switch_separate_string(dpstr, ',', dp, (sizeof(dp) / sizeof(dp[0])));
3047  for (x = 0; x < argc; x++) {
3048  char *dpname = dp[x];
3049  char *dparg = NULL;
3050 
3051  if (dpname) {
3052  if ((dparg = strchr(dpname, ':'))) {
3053  *dparg++ = '\0';
3054  }
3055  } else {
3056  continue;
3057  }
3058 
3059  if (!(dialplan_interface = switch_loadable_module_get_dialplan_interface(dpname))) {
3060  continue;
3061  }
3062 
3063  extension = dialplan_interface->hunt_function(session, dparg, new_profile);
3064  UNPROTECT_INTERFACE(dialplan_interface);
3065 
3066  if (extension) {
3067  break;
3068  }
3069  }
3070 
3071  if (!extension) {
3072  status = SWITCH_STATUS_FALSE;
3073  goto done;
3074  }
3075 
3076  new_profile->caller_extension = extension;
3077 
3078  if (profile->caller_extension) {
3079  for (pp = profile->caller_extension->children; pp && pp->next; pp = pp->next);
3080 
3081  if (pp) {
3082  pp->next = new_profile;
3083  } else {
3084  profile->caller_extension->children = new_profile;
3085  }
3086  }
3087 
3088  while (switch_channel_ready(channel) && extension->current_application) {
3089  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Execute [depth=%d] %s(%s)\n",
3090  switch_core_session_stack_count(session, 0),
3092 
3096  goto done;
3097  }
3098 
3099  extension->current_application = extension->current_application->next;
3100  }
3101 
3102  done:
3104 
3105  switch_core_session_stack_count(session, -1);
3106  return status;
3107 }
3108 
3110 {
3111  switch_assert(session != NULL);
3112  session->loglevel = loglevel;
3113  return SWITCH_STATUS_SUCCESS;
3114 }
3115 
3117 {
3118  switch_assert(session != NULL);
3119  return session->loglevel;
3120 }
3121 
3123 {
3124  stream->write_function(stream, "Thread pool: running:%d busy:%d popping:%d\n",
3126 }
3127 
3129 {
3130  if (session->sdata) {
3131  if (session->sdata && switch_core_codec_ready(&session->sdata->codec)) {
3133  }
3134  memset(session->sdata, 0, sizeof(*session->sdata));
3135  } else {
3136  session->sdata = switch_core_session_alloc(session, sizeof(*session->sdata));
3137  }
3138 
3139  switch_core_session_set_codec_slin(session, session->sdata);
3140 }
3141 
3143 {
3145  session->io_override = ior;
3146  return SWITCH_STATUS_SUCCESS;
3147  }
3148 
3149  return SWITCH_STATUS_FALSE;
3150 }
3151 
3152 
3153 /* For Emacs:
3154  * Local Variables:
3155  * mode:c
3156  * indent-tabs-mode:t
3157  * tab-width:4
3158  * c-basic-offset:4
3159  * End:
3160  * For VIM:
3161  * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
3162  */
switch_status_t switch_channel_set_variable_printf(switch_channel_t *channel, const char *varname, const char *fmt,...)
switch_xml_t sibling
Definition: switch_xml.h:93
switch_mutex_t * codec_init_mutex
void switch_channel_set_cap_value(switch_channel_t *channel, switch_channel_cap_t cap, uint32_t value)
#define __SWITCH_FUNC__
switch_console_callback_match_t * switch_core_session_findall(void)
uint32_t switch_core_sessions_per_second(uint32_t new_limit)
switch_time_t stamp
Definition: switch_core.h:62
switch_channel_state_t switch_channel_get_state(switch_channel_t *channel)
Get the current state of a channel in the state engine.
#define switch_event_fire(event)
Fire an event filling in most of the arguements with obvious values.
Definition: switch_event.h:413
#define switch_channel_hangup(channel, hangup_cause)
Hangup a channel flagging it&#39;s state machine to end.
#define switch_core_media_gen_key_frame(_session)
void switch_time_sync(void)
Definition: switch_time.c:609
unsigned int switch_queue_size(switch_queue_t *queue)
Definition: switch_apr.c:1238
void switch_core_session_set_dmachine(switch_core_session_t *session, switch_ivr_dmachine_t *dmachine, switch_digit_action_target_t target)
#define SWITCH_MUTEX_DEFAULT
Definition: switch_apr.h:317
#define switch_core_new_memory_pool(p)
Create a new sub memory pool from the core&#39;s master pool.
Definition: switch_core.h:633
A module interface to implement an application.
switch_core_session_t * switch_core_session_request_uuid(switch_endpoint_interface_t *endpoint_interface, switch_call_direction_t direction, switch_originate_flag_t originate_flags, switch_memory_pool_t **pool, const char *use_uuid)
struct switch_session_manager session_manager
char * switch_core_session_sprintf(_In_ switch_core_session_t *session, _In_z_ _Printf_format_string_ const char *fmt,...)
printf-style style printing routine. The data is output to a string allocated from the session ...
char * name
Definition: switch_xml.h:81
switch_status_t switch_thread_cond_create(switch_thread_cond_t **cond, switch_memory_pool_t *pool)
Definition: switch_apr.c:373
switch_audio_resampler_t * write_resampler
void * switch_core_session_get_private_class(switch_core_session_t *session, switch_pvt_class_t index)
static switch_bool_t switch_true(const char *expr)
Evaluate the truthfullness of a string expression.
Definition: switch_utils.h:519
#define SWITCH_CHANNEL_SESSION_LOG(x)
An Abstract Representation of a dialplan extension.
switch_queue_t * event_queue
Call Specific Data.
Definition: switch_caller.h:73
switch_thread_rwlock_t * bug_rwlock
#define switch_set_flag(obj, flag)
Set a flag on an arbitrary object.
Definition: switch_utils.h:700
uint32_t switch_scheduler_del_task_group(const char *group)
Delete a scheduled task based on the group name.
switch_status_t switch_core_session_dequeue_event(switch_core_session_t *session, switch_event_t **event, switch_bool_t force)
#define SWITCH_THREAD_FUNC
#define SWITCH_ORIGINATOR_VARIABLE
Definition: switch_types.h:205
struct str_node * next
int switch_core_session_add_stream(switch_core_session_t *session, void *private_info)
switch_core_session_message_types_t message_id
Definition: switch_core.h:183
switch_status_t switch_channel_alloc(_In_ switch_channel_t **channel, _In_ switch_call_direction_t direction, _In_ switch_memory_pool_t *pool)
Allocate a new channel.
switch_status_t switch_core_session_set_codec_slin(switch_core_session_t *session, switch_slin_data_t *data)
#define SWITCH_CHANNEL_LOG
struct switch_io_event_hook_outgoing_channel * next
switch_status_t switch_mutex_trylock(switch_mutex_t *lock)
Definition: switch_apr.c:318
switch_status_t switch_core_hash_destroy(_Inout_ switch_hash_t **hash)
Destroy an existing hash table.
void * switch_core_hash_find(_In_ switch_hash_t *hash, _In_z_ const char *key)
Retrieve data from a given hash.
uint8_t raw_read_buf[SWITCH_RECOMMENDED_BUFFER_SIZE]
switch_status_t switch_core_session_pass_indication(switch_core_session_t *session, switch_core_session_message_types_t indication)
#define switch_event_del_header(_e, _h)
Definition: switch_event.h:212
static const char * message_names[]
Abstraction of an module endpoint interface This is the glue between the abstract idea of a "channel"...
const char * switch_core_session_get_external_id(switch_core_session_t *session)
switch_mutex_t * codec_write_mutex
switch_status_t switch_ivr_process_indications(switch_core_session_t *session, switch_core_session_message_t *message)
Definition: switch_ivr.c:813
const char * switch_channel_get_partner_uuid(switch_channel_t *channel)
int switch_core_test_flag(int flag)
Definition: switch_core.c:1792
#define switch_core_hash_init(_hash)
Definition: switch_core.h:1431
const char * switch_channel_cause2str(_In_ switch_call_cause_t cause)
return a cause string for a given cause
switch_frame_t enc_read_frame
#define SWITCH_MAX_STACKS
Definition: switch_types.h:583
const char * switch_channel_get_partner_uuid_copy(switch_channel_t *channel, char *buf, switch_size_t blen)
void switch_channel_flush_dtmf(_In_ switch_channel_t *channel)
switch_queue_t * thread_queue
switch_buffer_t * raw_write_buffer
#define MESSAGE_STRING_ARG_MAX
Definition: switch_core.h:177
switch_mutex_t * stack_count_mutex
switch_status_t switch_queue_pop_timeout(switch_queue_t *queue, void **data, switch_interval_time_t timeout)
Definition: switch_apr.c:1248
switch_call_direction_t
Definition: switch_types.h:303
switch_mutex_t * codec_read_mutex
void switch_core_session_unsched_heartbeat(switch_core_session_t *session)
void switch_channel_event_set_data(_In_ switch_channel_t *channel, _In_ switch_event_t *event)
Add information about a given channel to an event object.
switch_xml_t child
Definition: switch_xml.h:97
switch_pvt_class_t
Definition: switch_types.h:258
switch_codec_t * switch_core_session_get_video_read_codec(_In_ switch_core_session_t *session)
Retrieve the video_read codec from a given session.
switch_bool_t
Definition: switch_types.h:437
switch_mutex_t * switch_core_session_get_mutex(switch_core_session_t *session)
Signal a session&#39;s state machine thread that a state change has occured.
Node in which to store state change callback hooks.
switch_status_t switch_event_create_brackets(char *data, char a, char b, char c, switch_event_t **event, char **new_data, switch_bool_t dup)
#define switch_channel_presence(_a, _b, _c, _d)
switch_status_t switch_core_session_message_send(const char *uuid_str, switch_core_session_message_t *message)
#define switch_core_strdup(_pool, _todup)
Copy a string using memory allocation from a given pool.
Definition: switch_core.h:733
switch_status_t switch_core_session_set_read_codec(_In_ switch_core_session_t *session, switch_codec_t *codec)
Assign the read codec to a given session.
const cJSON *const b
Definition: switch_cJSON.h:243
Node in which to store custom receive message callback hooks.
void switch_core_session_init(switch_memory_pool_t *pool)
const char * external_id
uint8_t switch_core_session_check_interface(switch_core_session_t *session, const switch_endpoint_interface_t *endpoint_interface)
Checks if a session is using a specific endpoint.
int switch_core_session_sync_clock(void)
switch_status_t switch_threadattr_stacksize_set(switch_threadattr_t *attr, switch_size_t stacksize)
Definition: switch_apr.c:683
void switch_core_session_raw_read(switch_core_session_t *session)
switch_status_t switch_core_media_bug_flush_all(_In_ switch_core_session_t *session)
Flush the read/write buffers for all media bugs on the session.
struct switch_io_event_hook_receive_event * next
#define switch_core_destroy_memory_pool(p)
Returns a subpool back to the main pool.
Definition: switch_core.h:642
switch_memory_pool_t * pool
void switch_ivr_dmachine_set_target(switch_ivr_dmachine_t *dmachine, switch_digit_action_target_t target)
Representation of an event.
Definition: switch_event.h:80
#define switch_codec2str(codec, buf, len)
Definition: switch_utils.h:293
#define switch_channel_ready(_channel)
switch_io_routines_t * io_routines
void * streams[SWITCH_MAX_STREAMS]
switch_core_session_t * switch_core_session_request_xml(switch_endpoint_interface_t *endpoint_interface, switch_memory_pool_t **pool, switch_xml_t xml)
An event Header.
Definition: switch_event.h:65
switch_core_session_t * switch_core_session_request_by_name(const char *endpoint_name, switch_call_direction_t direction, switch_memory_pool_t **pool)
switch_status_t switch_core_session_read_lock(_In_ switch_core_session_t *session)
Acquire a read lock on the session.
void switch_core_session_free_message(switch_core_session_message_t **message)
switch_status_t switch_queue_trypop(switch_queue_t *queue, void **data)
Definition: switch_apr.c:1264
switch_core_session_message_types_t
Possible types of messages for inter-session communication.
switch_caller_profile_t * switch_caller_profile_clone(_In_ switch_core_session_t *session, _In_ switch_caller_profile_t *tocopy)
Clone an existing caller profile object.
switch_digit_action_target_t
Definition: switch_types.h:283
void switch_channel_set_caller_profile(switch_channel_t *channel, switch_caller_profile_t *caller_profile)
Set the given channel&#39;s caller profile.
switch_io_receive_event_t receive_event
switch_status_t switch_core_session_set_private_class(switch_core_session_t *session, void *private_info, switch_pvt_class_t index)
#define switch_channel_media_ready(_channel)
switch_status_t switch_thread_pool_wait(switch_thread_data_t *td, int ms)
static void parse_array(const char *str, uint32_t *array, int32_t array_len)
switch_status_t switch_thread_cond_timedwait(switch_thread_cond_t *cond, switch_mutex_t *mutex, switch_interval_time_t timeout)
Definition: switch_apr.c:383
switch_status_t switch_core_session_perform_receive_message(switch_core_session_t *session, switch_core_session_message_t *message, const char *file, const char *func, int line)
static switch_status_t check_queue(void)
switch_receive_event_hook_t receive_event
switch_status_t switch_core_session_queue_indication(switch_core_session_t *session, switch_core_session_message_types_t indication)
switch_status_t switch_core_session_wake_session_thread(switch_core_session_t *session)
void switch_core_session_debug_pool(switch_stream_handle_t *stream)
switch_hup_type_t
Definition: switch_core.h:985
switch_codec_implementation_t read_impl
A representation of an XML tree.
Definition: switch_xml.h:79
switch_memory_pool_t * pool
Definition: switch_core.h:71
switch_status_t switch_core_codec_destroy(switch_codec_t *codec)
Destroy an initalized codec handle.
struct switch_caller_profile * next
Abstract interface to a dialplan module.
switch_mutex_t * throttle_mutex
const char * switch_channel_get_variable_dup(switch_channel_t *channel, const char *varname, switch_bool_t dup, int idx)
Retrieve a variable from a given channel.
const char * string_array_arg[MESSAGE_STRING_ARG_MAX]
Definition: switch_core.h:211
static void *SWITCH_THREAD_FUNC switch_core_session_thread(switch_thread_t *thread, void *obj)
const char * switch_channel_state_name(_In_ switch_channel_state_t state)
Render the name of the provided state enum.
switch_app_log_t * switch_core_session_get_app_log(switch_core_session_t *session)
uint32_t switch_originate_flag_t
Definition: switch_types.h:335
switch_queue_t * signal_data_queue
switch_caller_profile_t * switch_caller_profile_new(_In_ switch_memory_pool_t *pool, _In_opt_z_ const char *username, _In_opt_z_ const char *dialplan, _In_opt_z_ const char *caller_id_name, _In_opt_z_ const char *caller_id_number, _In_opt_z_ const char *network_addr, _In_opt_z_ const char *ani, _In_opt_z_ const char *aniii, _In_opt_z_ const char *rdnis, _In_opt_z_ const char *source, _In_opt_z_ const char *context, _In_opt_z_ const char *destination_number)
Create a new caller profile object.
const char * dialplan
Definition: switch_caller.h:77
switch_status_t switch_core_session_execute_exten(switch_core_session_t *session, const char *exten, const char *dialplan, const char *context)
switch_status_t switch_core_session_set_external_id(switch_core_session_t *session, const char *use_external_id)
A table of i/o routines that an endpoint interface can implement.
switch_status_t switch_ivr_media(const char *uuid, switch_media_flag_t flags)
Signal a session to request direct media access to it&#39;s remote end.
Definition: switch_ivr.c:1773
switch_status_t switch_core_session_execute_application_async(switch_core_session_t *session, const char *app, const char *arg)
void switch_resample_destroy(switch_audio_resampler_t **resampler)
Destroy an existing resampler handle.
static switch_thread_t * thread
Definition: switch_log.c:486
int switch_snprintf(_Out_z_cap_(len) char *buf, _In_ switch_size_t len, _In_z_ _Printf_format_string_ const char *format,...)
struct switch_runtime runtime
Definition: switch_core.c:86
unsigned int switch_core_session_started(switch_core_session_t *session)
uint32_t switch_channel_test_flag(switch_channel_t *channel, switch_channel_flag_t flag)
Test for presence of given flag on a given channel.
void switch_core_session_hupall(switch_call_cause_t cause)
uint32_t switch_scheduler_add_task(time_t task_runtime, switch_scheduler_func_t func, const char *desc, const char *group, uint32_t cmd_id, void *cmd_arg, switch_scheduler_flag_t flags)
Schedule a task in the future.
void switch_core_session_soft_lock(switch_core_session_t *session, uint32_t sec)
Node in which to store custom receive message callback hooks.
switch_thread_cond_t * cond
void switch_channel_set_scope_variables(switch_channel_t *channel, switch_event_t **event)
switch_core_session_t * session
SWITCH_BEGIN_EXTERN_C int switch_status_is_timeup(int status)
Definition: switch_apr.c:95
switch_buffer_t * text_buffer
switch_codec_t * codec
Definition: switch_frame.h:56
A message object designed to allow unlike technologies to exchange data.
Definition: switch_core.h:179
void switch_channel_set_origination_caller_profile(switch_channel_t *channel, switch_caller_profile_t *caller_profile)
Set the given channel&#39;s origination caller profile.
switch_console_callback_match_t * switch_core_session_findall_matching_var(const char *var_name, const char *var_val)
#define SWITCH_DISABLE_APP_LOG_VARIABLE
Definition: switch_types.h:232
switch_media_handle_t * media_handle
#define SWITCH_ORIGINATE_SIGNAL_BOND_VARIABLE
Definition: switch_types.h:204
#define zstr(x)
Definition: switch_utils.h:314
switch_codec_t * switch_core_session_get_read_codec(_In_ switch_core_session_t *session)
Retrieve the read codec from a given session.
switch_size_t switch_core_session_id(void)
Provide the current session_id.
struct switch_caller_application * next
switch_status_t switch_core_session_perform_get_partner(switch_core_session_t *session, switch_core_session_t **partner, const char *file, const char *func, int line)
Get the session&#39;s partner (the session its bridged to)
uint32_t switch_core_session_hupall_matching_var_ans(const char *var_name, const char *var_val, switch_call_cause_t cause, switch_hup_type_t type)
switch_channel_t * switch_core_session_get_channel(switch_core_session_t *session)
switch_io_event_hooks_t event_hooks
char * txt
Definition: switch_xml.h:85
switch_status_t switch_mutex_unlock(switch_mutex_t *lock)
Definition: switch_apr.c:313
#define SWITCH_MESSAGE_QUEUE_LEN
switch_status_t switch_core_session_get_read_impl(switch_core_session_t *session, switch_codec_implementation_t *impp)
#define switch_core_session_execute_application(_a, _b, _c)
Execute an application on a session.
Definition: switch_core.h:1129
void switch_core_recovery_track(switch_core_session_t *session)
uint8_t switch_core_session_compare(switch_core_session_t *a, switch_core_session_t *b)
Checks if 2 sessions are using the same endpoint module.
#define UNPROTECT_INTERFACE(_it)
#define SWITCH_ORIGINATOR_CODEC_VARIABLE
Definition: switch_types.h:206
#define switch_clear_flag(obj, flag)
Clear a flag on an arbitrary object while locked.
Definition: switch_utils.h:724
switch_receive_message_hook_t receive_message
#define SWITCH_MUTEX_NESTED
Definition: switch_apr.h:318
void switch_core_session_reset(switch_core_session_t *session, switch_bool_t flush_dtmf, switch_bool_t reset_read_codec)
int switch_plc_free(switch_plc_state_t *s)
switch_queue_t * private_event_queue
static char * xml_find_var(switch_xml_t vars, const char *name)
void switch_core_session_enable_heartbeat(switch_core_session_t *session, uint32_t seconds)
switch_status_t switch_core_session_get_app_flags(const char *app, int32_t *flags)
switch_status_t switch_threadattr_detach_set(switch_threadattr_t *attr, int32_t on)
Definition: switch_apr.c:678
const switch_codec_implementation_t * implementation
double switch_core_idle_cpu(void)
void * private_info[SWITCH_CORE_SESSION_MAX_PRIVATES]
uint32_t buflen
Definition: switch_frame.h:70
int32_t sessions_peak_fivemin
switch_byte_t switch_byte_t * buf
#define SWITCH_PROCESS_CDR_VARIABLE
Definition: switch_types.h:179
uint32_t switch_core_session_private_event_count(switch_core_session_t *session)
#define switch_yield(ms)
Wait a desired number of microseconds and yield the CPU.
Definition: switch_utils.h:998
unsigned int switch_separate_string(_In_ char *buf, char delim, _Post_count_(return) char **array, unsigned int arraylen)
Separate a string into an array based on a character delimiter.
switch_channel_t * channel
switch_status_t switch_core_session_thread_pool_launch(switch_core_session_t *session)
switch_audio_resampler_t * read_resampler
switch_dialplan_hunt_function_t hunt_function
uint32_t datalen
Definition: switch_frame.h:68
switch_core_session_t * switch_core_session_perform_force_locate(const char *uuid_str, const char *file, const char *func, int line)
switch_mutex_t * frame_read_mutex
switch_status_t switch_core_session_queue_event(switch_core_session_t *session, switch_event_t **event)
void switch_core_session_disable_heartbeat(switch_core_session_t *session)
switch_application_interface_t * switch_loadable_module_get_application_interface(const char *name)
Retrieve the application interface by it&#39;s registered name.
switch_core_session_t * switch_core_session_perform_locate(const char *uuid_str, const char *file, const char *func, int line)
switch_status_t switch_mutex_lock(switch_mutex_t *lock)
Definition: switch_apr.c:308
const char * callee_id_number
Definition: switch_caller.h:89
uint8_t enc_write_buf[SWITCH_RECOMMENDED_BUFFER_SIZE]
switch_status_t switch_core_session_dequeue_signal_data(switch_core_session_t *session, void **signal_data)
switch_status_t switch_core_session_thread_launch(switch_core_session_t *session)
#define switch_core_session_request_video_refresh(_s)
Definition: switch_core.h:2881
#define switch_core_alloc(_pool, _mem)
Allocate memory directly from a memory pool.
Definition: switch_core.h:684
uint32_t switch_scheduler_del_task_id(uint32_t task_id)
Delete a scheduled task.
#define switch_channel_get_variable(_c, _v)
int index
Definition: switch_cJSON.h:160
#define SWITCH_THREAD_STACKSIZE
Definition: switch_types.h:584
uint32_t switch_core_session_messages_waiting(switch_core_session_t *session)
switch_status_t switch_event_add_header_string(switch_event_t *event, switch_stack_t stack, const char *header_name, const char *data)
Add a string header to an event.
switch_thread_t * thread
void switch_core_session_perform_destroy(switch_core_session_t **session, const char *file, const char *func, int line)
void switch_core_session_sched_heartbeat(switch_core_session_t *session, uint32_t seconds)
const char * caller_id_name
Definition: switch_caller.h:79
#define switch_safe_free(it)
Free a pointer and set it to NULL unless it already is NULL.
Definition: switch_utils.h:885
switch_status_t switch_thread_rwlock_tryrdlock(switch_thread_rwlock_t *rwlock)
Definition: switch_apr.c:255
switch_thread_start_t func
Definition: switch_core.h:67
struct switch_caller_profile * children
uint32_t switch_core_session_flush_private_events(switch_core_session_t *session)
Flush the private event queue of a session.
static void *SWITCH_THREAD_FUNC switch_core_session_thread_pool_worker(switch_thread_t *thread, void *obj)
switch_status_t switch_channel_pass_sdp(switch_channel_t *from_channel, switch_channel_t *to_channel, const char *sdp)
void switch_console_push_match(switch_console_callback_match_t **matches, const char *new_val)
switch_status_t switch_mutex_init(switch_mutex_t **lock, unsigned int flags, switch_memory_pool_t *pool)
Definition: switch_apr.c:293
SWITCH_STANDARD_SCHED_FUNC(sch_heartbeat_callback)
switch_application_function_t application_function
void switch_channel_set_flag_value(switch_channel_t *channel, switch_channel_flag_t flag, uint32_t value)
Set given flag(s) on a given channel.
#define SWITCH_ORIGINATOR_VIDEO_CODEC_VARIABLE
Definition: switch_types.h:207
void switch_core_session_launch_thread(switch_core_session_t *session, switch_thread_start_t func, void *obj)
switch_status_t switch_core_session_exec(switch_core_session_t *session, const switch_application_interface_t *application_interface, const char *arg)
switch_status_t switch_core_session_receive_event(switch_core_session_t *session, switch_event_t **event)
#define switch_channel_text_only(_channel)
switch_mutex_t * resample_mutex
#define switch_channel_down_nosig(_channel)
switch_queue_t * message_queue
#define SWITCH_CURRENT_APPLICATION_RESPONSE_VARIABLE
Definition: switch_types.h:134
void switch_core_hash_this(_In_ switch_hash_index_t *hi, _Out_opt_ptrdiff_cap_(klen) const void **key, _Out_opt_ switch_ssize_t *klen, _Out_ void **val)
Gets the key and value of the current hash element.
#define SWITCH_IGNORE_DISPLAY_UPDATES_VARIABLE
Definition: switch_types.h:127
switch_mutex_t * text_mutex
switch_io_routines_t * io_override
switch_time_t profile_created
uintptr_t switch_size_t
switch_thread_cond_t * cond
#define switch_core_session_destroy(session)
Destroy a session and return the memory pool to the core.
Definition: switch_core.h:817
switch_hash_index_t * switch_core_hash_next(_In_ switch_hash_index_t **hi)
Gets the next element of a hashtable.
#define switch_core_session_request(_ep, _d, _f, _p)
Definition: switch_core.h:803
void switch_channel_set_originator_caller_profile(switch_channel_t *channel, switch_caller_profile_t *caller_profile)
Set the given channel&#39;s originator caller profile.
#define switch_core_codec_init(_codec, _codec_name, _modname, _fmtp, _rate, _ms, _channels, _flags, _codec_settings, _pool)
Initialize a codec handle.
Definition: switch_core.h:1693
switch_io_state_change_t state_change
char uuid_str[SWITCH_UUID_FORMATTED_LENGTH+1]
switch_thread_rwlock_t * io_rwlock
char * switch_url_decode(char *s)
switch_mutex_t * session_hash_mutex
void switch_cond_next(void)
Definition: switch_time.c:658
struct switch_io_event_hook_receive_message * next
switch_size_t switch_core_session_id_dec(void)
uint32_t switch_core_session_count(void)
Provide the total number of sessions.
#define SWITCH_CURRENT_APPLICATION_DATA_VARIABLE
Definition: switch_types.h:133
double switch_core_min_idle_cpu(double new_limit)
switch_buffer_t * raw_read_buffer
switch_memory_pool_t * memory_pool
void switch_channel_set_hunt_caller_profile(switch_channel_t *channel, switch_caller_profile_t *caller_profile)
switch_call_cause_t
switch_caller_application_t * current_application
char frame_data[SWITCH_RECOMMENDED_BUFFER_SIZE]
void * switch_core_hash_delete(_In_ switch_hash_t *hash, _In_z_ const char *key)
Delete data from a hash based on desired key.
switch_status_t switch_core_session_override_io_routines(switch_core_session_t *session, switch_io_routines_t *ior)
#define switch_core_session_receive_message(_session, _message)
Definition: switch_core.h:1247
void switch_core_session_rwunlock(_In_ switch_core_session_t *session)
Unlock a read or write lock on as given session.
void switch_core_session_video_reset(switch_core_session_t *session)
switch_status_t switch_core_session_flush_message(switch_core_session_t *session)
switch_status_t switch_channel_set_variable_var_check(switch_channel_t *channel, const char *varname, const char *value, switch_bool_t var_check)
uint32_t switch_channel_test_cap(switch_channel_t *channel, switch_channel_cap_t cap)
switch_state_change_hook_t state_change
#define switch_str_nil(s)
Make a null string a blank string instead.
Definition: switch_utils.h:993
#define SWITCH_CORE_SESSION_MAX_PRIVATES
Definition: switch_types.h:239
struct fspr_thread_mutex_t switch_mutex_t
Definition: switch_apr.h:314
switch_frame_t raw_read_frame
#define SWITCH_CHANNEL_SESSION_LOG_CLEAN(x)
switch_status_t switch_thread_cond_signal(switch_thread_cond_t *cond)
Definition: switch_apr.c:394
switch_status_t switch_core_media_receive_message(switch_core_session_t *session, switch_core_session_message_t *msg)
int switch_thread_equal(switch_thread_id_t tid1, switch_thread_id_t tid2)
Compare two thread ids.
Definition: switch_apr.c:111
void *(SWITCH_THREAD_FUNC * switch_thread_start_t)(switch_thread_t *, void *)
Definition: switch_apr.h:950
switch_status_t switch_core_session_execute_application_get_flags(switch_core_session_t *session, const char *app, const char *arg, int32_t *flags)
switch_status_t switch_core_session_dequeue_message(switch_core_session_t *session, switch_core_session_message_t **message)
void switch_core_session_run(_In_ switch_core_session_t *session)
Start the session&#39;s state machine.
void switch_uuid_format(char *buffer, const switch_uuid_t *uuid)
Definition: switch_apr.c:1140
#define switch_channel_expand_variables(_channel, _in)
#define SWITCH_R_SDP_VARIABLE
Definition: switch_types.h:197
switch_queue_t * private_event_queue_pri
struct switch_io_event_hook_state_change * next
switch_stream_handle_write_function_t write_function
uint32_t switch_core_session_event_count(switch_core_session_t *session)
int switch_core_session_get_stream_count(switch_core_session_t *session)
#define SWITCH_EVENT_QUEUE_LEN
switch_memory_pool_t * pool
#define SWITCH_SIZE_T_FMT
void switch_channel_uninit(switch_channel_t *channel)
Uninitalize a channel.
switch_status_t
Common return values.
unsigned int switch_core_session_running(switch_core_session_t *session)
#define switch_goto_status(_status, _label)
Definition: switch_utils.h:287
void * switch_core_session_get_stream(switch_core_session_t *session, int index)
switch_status_t switch_core_session_read_lock_hangup(_In_ switch_core_session_t *session)
Acquire a read lock on the session.
switch_dialplan_interface_t * switch_loadable_module_get_dialplan_interface(const char *name)
Retrieve the dialplan interface by it&#39;s registered name.
const cJSON *const target
Node in which to store custom receive message callback hooks.
switch_endpoint_interface_t * switch_loadable_module_get_endpoint_interface(const char *name)
Retrieve the endpoint interface by it&#39;s registered name.
switch_memory_pool_t * pool
char * switch_uuid_str(char *buf, switch_size_t len)
void switch_core_session_write_lock(_In_ switch_core_session_t *session)
Acquire a write lock on the session.
struct switch_event_header * next
Definition: switch_event.h:76
uint8_t enc_read_buf[SWITCH_RECOMMENDED_BUFFER_SIZE]
#define SWITCH_SIGNAL_BOND_VARIABLE
Definition: switch_types.h:203
#define check_media(session)
void switch_core_session_signal_state_change(switch_core_session_t *session)
void switch_channel_set_originatee_caller_profile(switch_channel_t *channel, switch_caller_profile_t *caller_profile)
Set the given channel&#39;s originatee caller profile.
switch_hash_t * session_table
switch_size_t switch_channel_has_dtmf(_In_ switch_channel_t *channel)
Test for presence of DTMF on a given channel.
void switch_core_memory_pool_set_data(switch_memory_pool_t *pool, const char *key, void *data)
#define switch_core_hash_insert(_h, _k, _d)
Definition: switch_core.h:1479
#define switch_core_session_locate(uuid_str)
Locate a session based on it&#39;s uuid.
Definition: switch_core.h:932
Main Library Header.
#define switch_core_media_bug_remove_all(_s)
Definition: switch_core.h:405
switch_ivr_dmachine_t * switch_core_session_get_dmachine(switch_core_session_t *session, switch_digit_action_target_t target)
#define switch_event_create(event, id)
Create a new event assuming it will not be custom event and therefore hiding the unused parameters...
Definition: switch_event.h:384
switch_bool_t switch_core_ready_outbound(void)
Determines if the core is ready to place outbound calls.
Definition: switch_core.c:3008
#define SWITCH_DECLARE(type)
switch_frame_t enc_write_frame
void switch_uuid_get(switch_uuid_t *uuid)
Definition: switch_apr.c:1152
switch_size_t switch_core_session_get_id(switch_core_session_t *session)
#define switch_event_get_header(_e, _h)
Definition: switch_event.h:172
#define switch_channel_set_flag(_c, _f)
switch_xml_t switch_xml_child(_In_ switch_xml_t xml, _In_z_ const char *name)
returns the first child tag (one level deeper) with the given name or NULL \ if not found ...
switch_status_t switch_channel_set_name(switch_channel_t *channel, const char *name)
Assign a name to a given channel.
switch_io_receive_message_t receive_message
switch_call_direction_t switch_channel_direction(switch_channel_t *channel)
#define switch_set_string(_dst, _src)
Definition: switch_utils.h:734
switch_status_t switch_queue_trypush(switch_queue_t *queue, void *data)
Definition: switch_apr.c:1279
struct switch_channel_timetable * times
switch_status_t switch_channel_state_thread_trylock(switch_channel_t *channel)
void switch_core_memory_pool_tag(switch_memory_pool_t *pool, const char *tag)
uint32_t switch_core_session_hupall_matching_vars_ans(switch_event_t *vars, switch_call_cause_t cause, switch_hup_type_t type)
switch_io_outgoing_channel_t outgoing_channel
void switch_core_session_hupall_endpoint(const switch_endpoint_interface_t *endpoint_interface, switch_call_cause_t cause)
Hangup all sessions that belong to an endpoint.
switch_mutex_t * mutex
void switch_core_session_soft_unlock(switch_core_session_t *session)
time_t switch_epoch_time_now(time_t *t)
Get the current epoch time.
Definition: switch_time.c:322
const char * caller_id_number
Definition: switch_caller.h:81
switch_status_t switch_queue_term(switch_queue_t *queue)
Definition: switch_apr.c:1274
#define switch_core_session_alloc(_session, _memory)
Allocate memory from a session&#39;s pool.
Definition: switch_core.h:696
switch_ivr_dmachine_t * dmachine[2]
switch_status_t switch_queue_push(switch_queue_t *queue, void *data)
Definition: switch_apr.c:1253
const char * switch_core_session_get_text_buffer(switch_core_session_t *session)
switch_status_t switch_thread_rwlock_create(switch_thread_rwlock_t **rwlock, switch_memory_pool_t *pool)
Definition: switch_apr.c:235
#define switch_test_flag(obj, flag)
Test for the existance of a flag on an arbitary object.
Definition: switch_utils.h:693
switch_status_t switch_core_session_try_reset(switch_core_session_t *session, switch_bool_t flush_dtmf, switch_bool_t reset_read_codec)
Reset the buffers and resampler on a session, fail if can not lock codec mutexes. ...
static switch_bool_t switch_core_codec_ready(switch_codec_t *codec)
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
const char * switch_stristr(const char *instr, const char *str)
#define SWITCH_CURRENT_APPLICATION_VARIABLE
Definition: switch_types.h:142
switch_status_t switch_threadattr_create(switch_threadattr_t **new_attr, switch_memory_pool_t *pool)
Definition: switch_apr.c:665
switch_status_t switch_thread_create(switch_thread_t **new_thread, switch_threadattr_t *attr, switch_thread_start_t func, void *data, switch_memory_pool_t *cont)
Definition: switch_apr.c:698
A table of settings and callbacks that define a paticular implementation of a codec.
#define PROTECT_INTERFACE(_it)
switch_endpoint_interface_t * endpoint_interface
struct switch_thread_pool_node_s switch_thread_pool_node_t
int count
Definition: switch_cJSON.h:204
struct fspr_pool_t switch_memory_pool_t
const char *const name
Definition: switch_cJSON.h:250
#define switch_channel_up_nosig(_channel)
switch_status_t switch_core_session_queue_signal_data(switch_core_session_t *session, void *signal_data)
switch_status_t switch_queue_create(switch_queue_t **queue, unsigned int queue_capacity, switch_memory_pool_t *pool)
Definition: switch_apr.c:1233
#define switch_core_session_strdup(_session, _todup)
Copy a string using memory allocation from a session&#39;s pool.
Definition: switch_core.h:719
switch_log_level_t loglevel
switch_thread_id_t switch_thread_self(void)
Definition: switch_apr.c:102
switch_status_t switch_ivr_deactivate_unicast(switch_core_session_t *session)
Definition: switch_ivr.c:371
static void thread_launch_failure(void)
void switch_event_destroy(switch_event_t **event)
Destroy an event.
uint8_t raw_write_buf[SWITCH_RECOMMENDED_BUFFER_SIZE]
void switch_channel_state_thread_unlock(switch_channel_t *channel)
switch_status_t switch_core_session_event_send(const char *uuid_str, switch_event_t **event)
switch_status_t switch_core_session_queue_message(switch_core_session_t *session, switch_core_session_message_t *message)
switch_log_level_t switch_core_session_get_loglevel(switch_core_session_t *session)
Get the log level for a session.
void switch_channel_clear_flag(switch_channel_t *channel, switch_channel_flag_t flag)
Clear given flag(s) from a channel.
switch_slin_data_t * sdata
switch_thread_id_t thread_id
void switch_ivr_dmachine_destroy(switch_ivr_dmachine_t **dmachine)
#define switch_assert(expr)
struct fspr_thread_t switch_thread_t
Definition: switch_apr.h:941
#define SWITCH_MAX_FORWARDS_VARIABLE
Definition: switch_types.h:226
#define switch_channel_set_variable(_channel, _var, _val)
switch_mutex_t * mutex
switch_time_t switch_time_now(void)
Definition: switch_apr.c:325
switch_frame_t raw_write_frame
switch_status_t switch_channel_init(switch_channel_t *channel, switch_core_session_t *session, switch_channel_state_t state, switch_channel_flag_t flag)
Connect a newly allocated channel to a session object and setup it&#39;s initial state.
switch_status_t switch_core_session_set_loglevel(switch_core_session_t *session, switch_log_level_t loglevel)
Sets the log level for a session.
#define switch_channel_pre_answer(channel)
Indicate progress on a channel to attempt early media.
switch_bool_t switch_core_session_in_thread(switch_core_session_t *session)
switch_caller_profile_t * switch_channel_get_caller_profile(switch_channel_t *channel)
Retrieve the given channel&#39;s caller profile.
#define switch_core_session_kill_channel(session, sig)
Send a signal to a channel.
Definition: switch_core.h:1393
switch_status_t switch_event_serialize(switch_event_t *event, char **str, switch_bool_t encode)
switch_bool_t switch_core_ready_inbound(void)
Determines if the core is ready to take inbound calls.
Definition: switch_core.c:3003
void switch_buffer_destroy(switch_buffer_t **buffer)
Destroy the buffer.
char * switch_channel_get_name(switch_channel_t *channel)
Retrieve the name of a given channel.
#define switch_core_hash_first(_h)
Definition: switch_core.h:1592
switch_bool_t switch_core_ready(void)
Determines if the core is ready to take calls.
Definition: switch_core.c:2998
switch_thread_rwlock_t * rwlock
SWITCH_BEGIN_EXTERN_C char * switch_mprintf(const char *zFormat,...)
memset(buf, 0, buflen)
#define switch_channel_media_up(_channel)
uint32_t switch_core_session_limit(uint32_t new_limit)
Core Library.
void * switch_buffer_get_head_pointer(switch_buffer_t *buffer)
Definition: switch_buffer.c:57
const char * callee_id_name
Definition: switch_caller.h:87
switch_memory_pool_t * switch_core_session_get_pool(_In_ switch_core_session_t *session)
Retrieve the memory pool from a session.
switch_time_t progress_media
switch_app_log_t * app_log
switch_call_cause_t switch_core_session_outgoing_channel(switch_core_session_t *session, switch_event_t *var_event, const char *endpoint_name, switch_caller_profile_t *caller_profile, switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags, switch_call_cause_t *cancel_cause)
switch_log_level_t
Log Level Enumeration.
void switch_core_session_destroy_state(switch_core_session_t *session)
#define SWITCH_UUID_FORMATTED_LENGTH
Definition: switch_apr.h:545
switch_event_header_t * headers
Definition: switch_event.h:90
switch_outgoing_channel_hook_t outgoing_channel
struct switch_app_log * next
Definition: switch_core.h:63
struct switch_caller_extension * caller_extension
switch_status_t switch_core_session_dequeue_private_event(switch_core_session_t *session, switch_event_t **event)
void switch_ivr_clear_speech_cache(switch_core_session_t *session)
void switch_core_session_uninit(void)
char * switch_core_session_get_uuid(switch_core_session_t *session)
switch_status_t switch_core_session_set_uuid(switch_core_session_t *session, const char *use_uuid)
switch_status_t switch_core_session_queue_private_event(switch_core_session_t *session, switch_event_t **event, switch_bool_t priority)
switch_status_t switch_thread_pool_launch_thread(switch_thread_data_t **tdp)
switch_memory_pool_t * pool
uint32_t switch_core_session_stack_count(switch_core_session_t *session, int x)
switch_jb_t * switch_core_session_get_jb(switch_core_session_t *session, switch_media_type_t type)
switch_media_type_t
switch_status_t switch_threadattr_priority_set(switch_threadattr_t *attr, switch_thread_priority_t priority)
Definition: switch_apr.c:688