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  switch_core_codec_lock_full(session);
1396 
1397  if (reset_read_codec) {
1398  switch_core_session_set_read_codec(session, NULL);
1399  if (session->sdata && switch_core_codec_ready(&session->sdata->codec)) {
1401  }
1402  }
1403 
1404  /* clear resamplers */
1409  /* clear indications */
1411 
1412  /* wipe these, they will be recreated if need be */
1416 
1420 
1421  if (flush_dtmf) {
1422  while (switch_channel_has_dtmf(channel)) {
1423  switch_channel_flush_dtmf(channel);
1424  }
1425  }
1426 
1430 
1432 }
1433 
1434 
1436 {
1437  switch_assert(session->channel);
1438  return session->channel;
1439 }
1440 
1442 {
1443  return session->mutex;
1444 }
1445 
1447 {
1448  switch_status_t status;
1449  int tries = 0;
1450 
1451  /* If trylock fails the signal is already awake so we needn't bother ..... or do we????*/
1452 
1453  top:
1454 
1455  status = switch_mutex_trylock(session->mutex);
1456 
1457  if (status == SWITCH_STATUS_SUCCESS) {
1458  switch_thread_cond_signal(session->cond);
1459  switch_mutex_unlock(session->mutex);
1460  } else {
1462  /* We've beat them for sure, as soon as we release this lock, they will be checking their queue on the next line. */
1465  } else {
1466  /* What luck! The channel has already started going to sleep *after* we checked if we need to wake it up.
1467  It will miss any messages in its queue because they were inserted after *it* checked its queue. (catch-22)
1468  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.
1469  Now *we* need to sleep instead but just for 1ms so we can circle back and try again.
1470  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.
1471  */
1472  if (++tries < 10) {
1473  switch_cond_next();
1474  goto top;
1475  }
1476  }
1477  }
1478 
1479  return status;
1480 }
1481 
1483 {
1486 
1488 
1489  if (session->endpoint_interface->io_routines->state_change) {
1490  status = session->endpoint_interface->io_routines->state_change(session);
1491  }
1492 
1493  if (status == SWITCH_STATUS_SUCCESS) {
1494  for (ptr = session->event_hooks.state_change; ptr; ptr = ptr->next) {
1495  if (ptr->state_change(session) != SWITCH_STATUS_SUCCESS) {
1496  break;
1497  }
1498  }
1499  }
1501 }
1502 
1504 {
1505  return switch_test_flag(session, SSF_THREAD_RUNNING) ? 1 : 0;
1506 }
1507 
1509 {
1510  return switch_test_flag(session, SSF_THREAD_STARTED) ? 1 : 0;
1511 }
1512 
1514 {
1515  int doit = 0;
1516 
1518  if (session_manager.session_count == 0) {
1519  doit = 1;
1520  } else {
1522  }
1524 
1525  if (doit) {
1526  switch_time_sync();
1527  }
1528 
1529  return doit;
1530 
1531 }
1532 
1533 SWITCH_DECLARE(void) switch_core_session_perform_destroy(switch_core_session_t **session, const char *file, const char *func, int line)
1534 {
1536  switch_event_t *event;
1537  switch_endpoint_interface_t *endpoint_interface = (*session)->endpoint_interface;
1538  int i;
1539 
1540 
1542 
1543  if (switch_core_session_running(*session) && !switch_test_flag((*session), SSF_DESTROYABLE)) {
1545  "Cowardly ignoring an attempt to call destroy on a running session.\n");
1546  }
1547 
1548  switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, switch_core_session_get_uuid(*session), SWITCH_LOG_NOTICE, "Close Channel %s [%s]\n",
1549  switch_channel_get_name((*session)->channel), switch_channel_state_name(switch_channel_get_state((*session)->channel)));
1550 
1551 
1552  if ((*session)->text_buffer) {
1553  switch_buffer_destroy(&(*session)->text_buffer);
1554  }
1555 
1556  if ((*session)->text_line_buffer) {
1557  switch_buffer_destroy(&(*session)->text_line_buffer);
1558  }
1559 
1561 
1564 
1565  switch_scheduler_del_task_group((*session)->uuid_str);
1566 
1568  switch_core_hash_delete(session_manager.session_table, (*session)->uuid_str);
1569  if ((*session)->external_id) {
1570  switch_core_hash_delete(session_manager.session_table, (*session)->external_id);
1571  }
1574  if (session_manager.session_count == 0) {
1576  switch_time_sync();
1578  }
1579  }
1580  }
1582 
1583  if ((*session)->plc) {
1584  switch_plc_free((*session)->plc);
1585  (*session)->plc = NULL;
1586  }
1587 
1589  switch_channel_event_set_data((*session)->channel, event);
1590  switch_event_fire(&event);
1591  }
1592 
1594 
1595  switch_buffer_destroy(&(*session)->raw_read_buffer);
1596  switch_buffer_destroy(&(*session)->raw_write_buffer);
1598  switch_channel_uninit((*session)->channel);
1599 
1600  for (i = 0; i < 2; i++) {
1601  if ((*session)->dmachine[i]) {
1602  switch_ivr_dmachine_destroy(&(*session)->dmachine[i]);
1603  }
1604  }
1605 
1606  if ((*session)->event_queue) {
1607  void *pop;
1608  while (switch_queue_trypop((*session)->event_queue, &pop) == SWITCH_STATUS_SUCCESS) {
1609  if (pop) {
1610  switch_event_t *event = (switch_event_t *) pop;
1611  switch_event_destroy(&event);
1612  }
1613  }
1614  }
1615 
1616  pool = (*session)->pool;
1617  //#ifndef NDEBUG
1618  //memset(*session, 0, sizeof(switch_core_session_t));
1619  //#endif
1620  *session = NULL;
1622 
1623  UNPROTECT_INTERFACE(endpoint_interface);
1624 }
1625 
1626 
1627 
1628 SWITCH_STANDARD_SCHED_FUNC(sch_heartbeat_callback)
1629 {
1630  switch_event_t *event;
1631  switch_core_session_t *session;
1632  char *uuid = task->cmd_arg;
1633  switch_core_session_message_t msg = { 0 };
1634 
1635  if ((session = switch_core_session_locate(uuid))) {
1637  switch_channel_event_set_data(session->channel, event);
1638  switch_event_fire(&event);
1639 
1640  /* reschedule this task */
1641  task->runtime = switch_epoch_time_now(NULL) + session->track_duration;
1642 
1644  msg.numeric_arg = session->track_duration;
1645  switch_core_session_receive_message(session, &msg);
1646 
1648  }
1649 }
1650 
1652 {
1653  if (session->track_id) {
1655  session->track_id = 0;
1656  }
1657 }
1658 
1660 {
1661  time_t when;
1662 
1664  if (switch_true(switch_channel_get_variable(session->channel, "heartbeat_fire_on_set"))) {
1665  when = switch_epoch_time_now(NULL);
1666  } else {
1667  when = switch_epoch_time_now(NULL) + session->track_duration;
1668  }
1669 
1670  session->track_id = switch_scheduler_add_task(when, sch_heartbeat_callback, (char *) __SWITCH_FUNC__,
1672 }
1673 
1675 {
1676  switch_assert(session != NULL);
1677 
1678  if (!seconds) {
1679  seconds = 60;
1680  }
1681 
1682  session->track_duration = seconds;
1683 
1685  switch_true(switch_channel_get_variable_dup(session->channel, "heartbeat_use_scheduler", SWITCH_FALSE, -1)) ||
1686  switch_true(switch_channel_get_variable_dup(session->channel, "bypass_media", SWITCH_FALSE, -1)) ||
1687  switch_true(switch_channel_get_variable_dup(session->channel, "bypass_media_after_bridge", SWITCH_FALSE, -1))) {
1688  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "%s using scheduler due to bypass media or media is not established.\n",
1689  switch_channel_get_name(session->channel));
1690  switch_core_session_sched_heartbeat(session, seconds);
1691  return;
1692  }
1693 
1694  if (switch_true(switch_channel_get_variable(session->channel, "heartbeat_fire_on_set"))) {
1695  session->read_frame_count = 0;
1696  } else {
1697  session->read_frame_count = (session->read_impl.samples_per_second / session->read_impl.samples_per_packet) * seconds;
1698  }
1699 
1701 
1702  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "%s setting session heartbeat to %u second(s).\n",
1703  switch_channel_get_name(session->channel), seconds);
1704 
1705 }
1706 
1708 {
1710  switch_assert(session != NULL);
1711  session->read_frame_count = 0;
1712  session->track_duration = 0;
1713 
1714 }
1715 
1717 {
1719 }
1720 
1722 {
1723  switch_core_session_t *session = obj;
1724  switch_event_t *event;
1725  char *event_str = NULL;
1726  const char *val;
1727 
1728  session->thread = thread;
1729  session->thread_id = switch_thread_self();
1730 
1731  switch_core_session_run(session);
1733 
1734  if (session->soft_lock) {
1735  uint32_t loops = session->soft_lock * 10;
1736 
1737  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Session %" SWITCH_SIZE_T_FMT " (%s) Soft-Locked, "
1738  "Waiting %u for external entities\n",
1739  session->id, switch_channel_get_name(session->channel), session->soft_lock);
1740 
1741  while(--loops > 0) {
1742  if (!session->soft_lock) break;
1743  switch_yield(100000);
1744  }
1745 
1746  }
1747 
1748  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Session %" SWITCH_SIZE_T_FMT " (%s) Locked, Waiting on external entities\n",
1749  session->id, switch_channel_get_name(session->channel));
1751  switch_set_flag(session, SSF_DESTROYED);
1752 
1753  if ((val = switch_channel_get_variable(session->channel, "memory_debug")) && switch_true(val)) {
1755  switch_channel_event_set_data(session->channel, event);
1756  switch_event_serialize(event, &event_str, SWITCH_FALSE);
1757  switch_assert(event_str);
1759  free(event_str);
1760  switch_event_destroy(&event);
1761  }
1762  }
1763 
1765 
1767  session->id, switch_channel_get_name(session->channel));
1768 
1769  switch_set_flag(session, SSF_DESTROYABLE);
1770  switch_core_session_destroy(&session);
1771  return NULL;
1772 }
1773 
1777 
1779 {
1781  switch_memory_pool_t *pool = node->pool;
1782 #ifdef DEBUG_THREAD_POOL
1783  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10, "Worker Thread %ld Started\n", (long) (intptr_t) thread);
1784 #endif
1785  for (;;) {
1786  void *pop;
1788  if (check_status == SWITCH_STATUS_SUCCESS) {
1790 
1791 #ifdef DEBUG_THREAD_POOL
1792  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10, "Worker Thread %ld Processing\n", (long) (intptr_t) thread);
1793 #endif
1794  td->running = 1;
1795  td->func(thread, td->obj);
1796  td->running = 0;
1797 
1798  if (td->pool) {
1799  switch_memory_pool_t *pool = td->pool;
1800  td = NULL;
1802  } else if (td->alloc) {
1803  free(td);
1804  }
1805 #ifdef DEBUG_THREAD_POOL
1806  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10, "Worker Thread %ld Done Processing\n", (long)(intptr_t) thread);
1807 #endif
1811  } else {
1814  if (!--session_manager.running) {
1816  }
1818  break;
1819  }
1821  }
1822  }
1823 #ifdef DEBUG_THREAD_POOL
1824  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10, "Worker Thread %ld Ended\n", (long)(intptr_t) thread);
1825 #endif
1827  return NULL;
1828 }
1829 
1830 static void thread_launch_failure(void)
1831 {
1832  uint32_t sess_count;
1833 
1835 
1836  sess_count = switch_core_session_count();
1837 
1838  if (sess_count > 110) {
1839 
1840  switch_core_session_limit(sess_count - 10);
1841  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "LUKE: I'm hit, but not bad.\n");
1843  "LUKE'S VOICE: Artoo, see what you can do with it. Hang on back there....\n"
1844  "Green laserfire moves past the beeping little robot as his head turns. "
1845  "After a few beeps and a twist of his mechanical arm,\n"
1846  "Artoo reduces the max sessions to %d thus, saving the switch from certain doom.\n", sess_count - 10);
1847 
1848  }
1849 
1851 }
1852 
1854 {
1859  return SWITCH_STATUS_SUCCESS;
1860  }
1863 
1864  {
1866  switch_threadattr_t *thd_attr;
1869 
1871  node = switch_core_alloc(pool, sizeof(*node));
1872  node->pool = pool;
1873 
1874  switch_threadattr_create(&thd_attr, node->pool);
1875  switch_threadattr_detach_set(thd_attr, 1);
1878 
1881  if (!--session_manager.running) {
1883  }
1885  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Thread Failure!\n");
1887  status = SWITCH_STATUS_GENERR;
1889  } else {
1890  status = SWITCH_STATUS_SUCCESS;
1891  }
1892  }
1893  return status;
1894 }
1895 
1896 
1898 {
1901 
1902  switch_assert(tdp);
1903 
1904  td = *tdp;
1905  *tdp = NULL;
1906 
1908  check_queue();
1909 
1910  return status;
1911 }
1912 
1914 {
1915  while(!td->running && --ms > 0) {
1916  switch_cond_next();
1917  }
1918 
1919  return ms > 0 ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_TIMEOUT;
1920 }
1921 
1923 {
1926 
1927  switch_mutex_lock(session->mutex);
1928  if (switch_test_flag(session, SSF_THREAD_RUNNING)) {
1929  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Cannot double-launch thread!\n");
1930  } else if (switch_test_flag(session, SSF_THREAD_STARTED)) {
1931  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Cannot launch thread again after it has already been run!\n");
1932  } else {
1935  td = switch_core_session_alloc(session, sizeof(*td));
1936  td->obj = session;
1939  check_queue();
1940  }
1941  switch_mutex_unlock(session->mutex);
1942 
1943  return status;
1944 }
1945 
1947 {
1950  switch_threadattr_t *thd_attr;
1951 
1953  status = SWITCH_STATUS_INUSE;
1954  goto end;
1955  }
1956 
1957 
1960  }
1961 
1962  switch_mutex_lock(session->mutex);
1963 
1964  if (switch_test_flag(session, SSF_THREAD_RUNNING)) {
1965  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Cannot double-launch thread!\n");
1966  } else if (switch_test_flag(session, SSF_THREAD_STARTED)) {
1967  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Cannot launch thread again after it has already been run!\n");
1968  } else {
1971 
1972  switch_threadattr_create(&thd_attr, session->pool);
1973  switch_threadattr_detach_set(thd_attr, 1);
1975 
1976  if (switch_thread_create(&thread, thd_attr, switch_core_session_thread, session, session->pool) == SWITCH_STATUS_SUCCESS) {
1978  status = SWITCH_STATUS_SUCCESS;
1979  } else {
1982  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Cannot create thread!\n");
1984  }
1985  }
1986 
1987  switch_mutex_unlock(session->mutex);
1988 
1989  end:
1990 
1991  return status;
1992 }
1993 
1995 {
1996  const char *buf = NULL;
1997 
1998  if (session->text_buffer) {
1999  switch_mutex_lock(session->text_mutex);
2000  buf = (const char *)switch_core_session_strdup(session, (const char *) switch_buffer_get_head_pointer(session->text_buffer));
2001  switch_mutex_unlock(session->text_mutex);
2002  }
2003 
2004  return buf;
2005 }
2006 
2008 {
2010  switch_threadattr_t *thd_attr = NULL;
2011  switch_threadattr_create(&thd_attr, session->pool);
2012  switch_threadattr_detach_set(thd_attr, 1);
2013 
2015  if (switch_thread_create(&thread, thd_attr, func, obj, session->pool) != SWITCH_STATUS_SUCCESS) {
2016  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Cannot create thread!\n");
2018  }
2019 
2020 }
2021 
2023 {
2024  switch_event_t *event;
2025  switch_core_session_message_t msg = { 0 };
2026  switch_caller_profile_t *profile;
2027 
2028  switch_assert(use_uuid);
2029 
2030  if (!strcmp(use_uuid, session->uuid_str)) {
2031  return SWITCH_STATUS_SUCCESS;
2032  }
2033 
2034 
2037  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Duplicate UUID!\n");
2039  return SWITCH_STATUS_FALSE;
2040  }
2041 
2043  msg.from = switch_channel_get_name(session->channel);
2044  msg.string_array_arg[0] = session->uuid_str;
2045  msg.string_array_arg[1] = use_uuid;
2046  switch_core_session_receive_message(session, &msg);
2047 
2048  if ((profile = switch_channel_get_caller_profile(session->channel))) {
2049  profile->uuid = switch_core_strdup(profile->pool, use_uuid);
2050  }
2051 
2052  switch_channel_set_variable(session->channel, "uuid", use_uuid);
2053  switch_channel_set_variable(session->channel, "call_uuid", use_uuid);
2054 
2056  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Old-Unique-ID", session->uuid_str);
2058  switch_set_string(session->uuid_str, use_uuid);
2061  switch_channel_event_set_data(session->channel, event);
2062  switch_event_fire(&event);
2063 
2064 
2065  return SWITCH_STATUS_SUCCESS;
2066 }
2067 
2069 {
2070  switch_assert(use_external_id);
2071 
2072  if (session->external_id && !strcmp(use_external_id, session->external_id)) {
2073  return SWITCH_STATUS_SUCCESS;
2074  }
2075 
2076 
2078  if (strcmp(use_external_id, session->uuid_str) && switch_core_hash_find(session_manager.session_table, use_external_id)) {
2079  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Duplicate External ID!\n");
2081  return SWITCH_STATUS_FALSE;
2082  }
2083 
2084  switch_channel_set_variable(session->channel, "session_external_id", use_external_id);
2085 
2086  if (session->external_id && strcmp(session->external_id, session->uuid_str)) {
2088  }
2089 
2090  session->external_id = switch_core_session_strdup(session, use_external_id);
2091 
2092  if (strcmp(session->external_id, session->uuid_str)) {
2094  }
2096 
2097  return SWITCH_STATUS_SUCCESS;
2098 }
2099 
2100 static char *xml_find_var(switch_xml_t vars, const char *name)
2101 {
2102  switch_xml_t var;
2103  if ((var = switch_xml_child(vars, name)) && var->txt) {
2104  return var->txt;
2105  }
2106 
2107  return NULL;
2108 }
2109 
2110 static void parse_array(const char *str, uint32_t *array, int32_t array_len)
2111 {
2112  char *p, *v, *dup, *next = NULL;
2113 
2114  if (zstr(str)) {
2115  return;
2116  }
2117 
2118  dup = strdup(str);
2119 
2120  p = dup;
2121  while (p) {
2122  if ((next = strchr(p, ';'))) {
2123  *next++ = '\0';
2124  }
2125 
2126  if ((v = strchr(p, '='))) {
2127  *v++ = '\0';
2128  }
2129 
2130  if (p && v) {
2131  int x = 0, y = 0;
2132 
2133  x = atoi(p);
2134  y = atoi(v);
2135 
2136  if (x < array_len) {
2137  array[x] = y;
2138  }
2139  }
2140 
2141  p = next;
2142 
2143  }
2144 
2145  free(dup);
2146 }
2147 
2150 {
2151  switch_core_session_t *session;
2152  switch_channel_t *channel;
2153  switch_xml_t tag, tag2, tag3, vars, callflow;
2155  char *flag_str = NULL, *cap_str = NULL, *direction_s = NULL, *uuid = NULL;
2156  uint32_t flags[CF_FLAG_MAX] = { 0 };
2157  uint32_t caps[CC_FLAG_MAX] = { 0 };
2158  int i;
2159 
2160  vars = switch_xml_child(xml, "variables");
2161  uuid = xml_find_var(vars, "uuid");
2162 
2163  if ((tag = switch_xml_child(xml, "channel_data"))) {
2164  direction_s = xml_find_var(tag, "direction");
2165  direction = !strcmp(direction_s, "outbound") ? SWITCH_CALL_DIRECTION_OUTBOUND : SWITCH_CALL_DIRECTION_INBOUND;
2166  flag_str = xml_find_var(tag, "flags");
2167  cap_str = xml_find_var(tag, "caps");
2168  }
2169 
2170  parse_array(flag_str, flags, CF_FLAG_MAX);
2171  parse_array(cap_str, caps, CC_FLAG_MAX);
2172 
2173  flags[CF_RECOVERING] = 0;
2174  flags[CF_RECOVERING_BRIDGE] = 0;
2175  flags[CF_TRACKED] = 0;
2176  flags[CF_TRANSFER] = 0;
2177  flags[CF_ACCEPT_CNG] = 0;
2178  flags[CF_REDIRECT] = 0;
2179  flags[CF_BRIDGED] = 0;
2180  flags[CF_HOLD] = 0;
2181  flags[CF_SERVICE] = 0;
2182  flags[CF_TAGGED] = 0;
2183  flags[CF_WINNER] = 0;
2184  flags[CF_EARLY_OK] = 0;
2185  flags[CF_CONTROLLED] = 0;
2186  flags[CF_SUSPEND] = 0;
2187  flags[CF_EVENT_PARSE] = 0;
2188  flags[CF_GEN_RINGBACK] = 0;
2189  flags[CF_BREAK] = 0;
2190  flags[CF_BROADCAST] = 0;
2191  flags[CF_UNICAST] = 0;
2192  flags[CF_EVENT_LOCK] = 0;
2193  flags[CF_EVENT_LOCK_PRI] = 0;
2194  flags[CF_RESET] = 0;
2195  flags[CF_ORIGINATING] = 0;
2196  flags[CF_STOP_BROADCAST] = 0;
2197  flags[CF_INNER_BRIDGE] = 0;
2198  flags[CF_REQ_MEDIA] = 0;
2199  flags[CF_PAUSE_BUGS] = 0;
2200  flags[CF_DIVERT_EVENTS] = 0;
2201  flags[CF_BLOCK_STATE] = 0;
2202  flags[CF_FS_RTP] = 0;
2203  flags[CF_REPORTING] = 0;
2204  flags[CF_PARK] = 0;
2205  flags[CF_TIMESTAMP_SET] = 0;
2206  flags[CF_ORIGINATOR] = 0;
2207  flags[CF_XFER_ZOMBIE] = 0;
2208  flags[CF_MEDIA_ACK] = 0;
2209  flags[CF_THREAD_SLEEPING] = 0;
2210  flags[CF_DISABLE_RINGBACK] = 0;
2211  flags[CF_NOT_READY] = 0;
2212  flags[CF_SIGNAL_BRIDGE_TTL] = 0;
2213  flags[CF_MEDIA_BRIDGE_TTL] = 0;
2214  flags[CF_BYPASS_MEDIA_AFTER_BRIDGE] = 0;
2215  flags[CF_LEG_HOLDING] = 0;
2216  flags[CF_BROADCAST_DROP_MEDIA] = 0;
2217  flags[CF_EARLY_HANGUP] = 0;
2218  flags[CF_MEDIA_SET] = 0;
2219  flags[CF_CONSUME_ON_ORIGINATE] = 0;
2220  flags[CF_PASSTHRU_PTIME_MISMATCH] = 0;
2221  flags[CF_BRIDGE_NOWRITE] = 0;
2222  flags[CF_RECOVERED] = 0;
2223  flags[CF_JITTERBUFFER] = 0;
2224  flags[CF_JITTERBUFFER_PLC] = 0;
2225  flags[CF_DIALPLAN] = 0;
2226  flags[CF_BLOCK_BROADCAST_UNTIL_MEDIA] = 0;
2227  flags[CF_CNG_PLC] = 0;
2228  flags[CF_ATTENDED_TRANSFER] = 0;
2229  flags[CF_LAZY_ATTENDED_TRANSFER] = 0;
2230  flags[CF_SIGNAL_DATA] = 0;
2231  flags[CF_SIMPLIFY] = 0;
2232  flags[CF_VIDEO_READY] = 0;
2233  flags[CF_VIDEO_DECODED_READ] = 0;
2234 
2235  if (!(session = switch_core_session_request_uuid(endpoint_interface, direction, SOF_NO_LIMITS, pool, uuid))) {
2236  return NULL;
2237  }
2238 
2239  channel = switch_core_session_get_channel(session);
2240 
2241  for (i = 0; i < CF_FLAG_MAX; i++) {
2242  if (flags[i]) {
2243  switch_channel_set_flag_value(channel, i, flags[i]);
2244  }
2245  }
2246 
2247  for (i = 0; i < CC_FLAG_MAX; i++) {
2248  if (caps[i]) {
2249  switch_channel_set_cap_value(channel, i, caps[i]);
2250  }
2251  }
2252 
2253  if ((tag2 = switch_xml_child(xml, "variables"))) {
2254  for (tag = tag2->child; tag; tag = tag->sibling) {
2255  if (tag->name && tag->txt) {
2256  char *p = strdup(tag->txt);
2257  char *val = p;
2258  switch_url_decode(val);
2259  switch_channel_set_variable(channel, tag->name, val);
2260  if (!strcasecmp(tag->name, "channel_name")) {
2261  switch_channel_set_name(channel, val);
2262  }
2263  free(p);
2264  }
2265  }
2266  }
2267 
2268  if ((callflow = switch_xml_child(xml, "callflow"))) {
2269  if ((tag2 = switch_xml_child(callflow, "caller_profile"))) {
2270  switch_caller_profile_t *caller_profile;
2271  char *tmp;
2272 
2273  caller_profile = switch_caller_profile_new(switch_core_session_get_pool(session),
2274  xml_find_var(tag2, "username"),
2275  xml_find_var(tag2, "dialplan"),
2276  xml_find_var(tag2, "caller_id_name"),
2277  xml_find_var(tag2, "caller_id_number"),
2278  xml_find_var(tag2, "network_addr"),
2279  xml_find_var(tag2, "ani"),
2280  xml_find_var(tag2, "aniii"),
2281  xml_find_var(tag2, "rdnis"),
2282  xml_find_var(tag2, "source"),
2283  xml_find_var(tag2, "context"), xml_find_var(tag2, "destination_number"));
2284 
2285  if ((tmp = xml_find_var(tag2, "callee_id_name"))) {
2286  caller_profile->callee_id_name = switch_core_session_strdup(session, tmp);
2287  }
2288 
2289  if ((tmp = xml_find_var(tag2, "callee_id_number"))) {
2290  caller_profile->callee_id_number = switch_core_session_strdup(session, tmp);
2291  }
2292 
2293  if ((tag3 = switch_xml_child(callflow, "times"))) {
2294  caller_profile->times = (switch_channel_timetable_t *) switch_core_session_alloc(session, sizeof(*caller_profile->times));
2295 
2296  caller_profile->times->resurrected = switch_time_now();
2297 
2298  for (tag3 = tag3->child; tag3; tag3 = tag3->sibling) {
2299  int64_t v;
2300 
2301  if (tag3->name && tag3->txt) {
2302  v = atoll(tag3->txt);
2303  if (!strcmp(tag3->name, "created_time")) {
2304  caller_profile->times->created = v;
2305  } else if (!strcmp(tag3->name, "profile_created_time")) {
2306  caller_profile->times->profile_created = v;
2307  } else if (!strcmp(tag3->name, "progress_time")) {
2308  caller_profile->times->progress = v;
2309  } else if (!strcmp(tag3->name, "progress_media_time")) {
2310  caller_profile->times->progress_media = v;
2311  } else if (!strcmp(tag3->name, "answered_time")) {
2312  caller_profile->times->answered = v;
2313  } else if (!strcmp(tag3->name, "hangup_time")) {
2314  caller_profile->times->hungup = v;
2315  } else if (!strcmp(tag3->name, "transfer_time")) {
2316  caller_profile->times->transferred = v;
2317  }
2318  }
2319 
2320  }
2321  }
2322 
2323  switch_channel_set_caller_profile(channel, caller_profile);
2324  if ((tag = switch_xml_child(tag2, "originator")) && (tag = tag->child)) {
2325  caller_profile = switch_caller_profile_new(switch_core_session_get_pool(session),
2326  xml_find_var(tag, "username"),
2327  xml_find_var(tag, "dialplan"),
2328  xml_find_var(tag, "caller_id_name"),
2329  xml_find_var(tag, "caller_id_number"),
2330  xml_find_var(tag, "network_addr"),
2331  xml_find_var(tag, "ani"),
2332  xml_find_var(tag, "aniii"),
2333  xml_find_var(tag, "rdnis"),
2334  xml_find_var(tag, "source"),
2335  xml_find_var(tag, "context"), xml_find_var(tag, "destination_number"));
2336 
2337  switch_channel_set_originator_caller_profile(channel, caller_profile);
2338  }
2339 
2340  if ((tag = switch_xml_child(tag2, "originatee")) && (tag = tag->child)) {
2341  caller_profile = switch_caller_profile_new(switch_core_session_get_pool(session),
2342  xml_find_var(tag, "username"),
2343  xml_find_var(tag, "dialplan"),
2344  xml_find_var(tag, "caller_id_name"),
2345  xml_find_var(tag, "caller_id_number"),
2346  xml_find_var(tag, "network_addr"),
2347  xml_find_var(tag, "ani"),
2348  xml_find_var(tag, "aniii"),
2349  xml_find_var(tag, "rdnis"),
2350  xml_find_var(tag, "source"),
2351  xml_find_var(tag, "context"), xml_find_var(tag, "destination_number"));
2352 
2353  switch_channel_set_originatee_caller_profile(channel, caller_profile);
2354  }
2355 
2356  }
2357 
2358 
2360  }
2361 
2362 
2363  if (!channel || !switch_channel_get_caller_profile(channel)) {
2364  if (session) {
2365  switch_core_session_destroy(&session);
2366  }
2367  }
2368 
2369 
2370  return session;
2371 }
2372 
2373 
2374 
2376  *endpoint_interface,
2377  switch_call_direction_t direction,
2378  switch_originate_flag_t originate_flags,
2379  switch_memory_pool_t **pool, const char *use_uuid)
2380 {
2381  switch_memory_pool_t *usepool;
2382  switch_core_session_t *session;
2383  switch_uuid_t uuid;
2384  uint32_t count = 0;
2385  int32_t sps = 0;
2386 
2387 
2389  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "The system cannot create any inbound sessions at this time.\n");
2390  return NULL;
2391  }
2392 
2394  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "The system cannot create any outbound sessions at this time.\n");
2395  return NULL;
2396  }
2397 
2398  if (!switch_core_ready() || endpoint_interface == NULL) {
2399  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "The system cannot create any sessions at this time.\n");
2400  return NULL;
2401  }
2402 
2404  return NULL;
2405  }
2406 
2407  PROTECT_INTERFACE(endpoint_interface);
2408 
2410  if (use_uuid && switch_core_hash_find(session_manager.session_table, use_uuid)) {
2412  UNPROTECT_INTERFACE(endpoint_interface);
2413  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Duplicate UUID!\n");
2414 
2415  return NULL;
2416  }
2417 
2418  if (!(originate_flags & SOF_NO_LIMITS)) {
2421  sps = --runtime.sps;
2423 
2424  if (sps <= 0) {
2427  UNPROTECT_INTERFACE(endpoint_interface);
2428  return NULL;
2429  }
2430 
2431  if ((count + 1) > session_manager.session_limit) {
2434  UNPROTECT_INTERFACE(endpoint_interface);
2435  return NULL;
2436  }
2437  }
2438 
2439 
2440  if (pool && *pool) {
2441  usepool = *pool;
2442  *pool = NULL;
2443  } else {
2444  switch_core_new_memory_pool(&usepool);
2445  }
2446 
2447  session = switch_core_alloc(usepool, sizeof(*session));
2448  session->pool = usepool;
2449 
2450  switch_core_memory_pool_set_data(session->pool, "__session", session);
2451 
2452  if (switch_channel_alloc(&session->channel, direction, session->pool) != SWITCH_STATUS_SUCCESS) {
2453  abort();
2454  }
2455 
2456  switch_channel_init(session->channel, session, CS_NEW, 0);
2457 
2458  if (direction == SWITCH_CALL_DIRECTION_OUTBOUND) {
2460  }
2461 
2462  /* The session *IS* the pool you may not alter it because you have no idea how
2463  its all private it will be passed to the thread run function */
2464 
2465  if (use_uuid) {
2466  switch_set_string(session->uuid_str, use_uuid);
2467  } else {
2468  switch_uuid_get(&uuid);
2469  switch_uuid_format(session->uuid_str, &uuid);
2470  }
2471 
2472  switch_channel_set_variable(session->channel, "uuid", session->uuid_str);
2473  switch_channel_set_variable(session->channel, "call_uuid", session->uuid_str);
2474 
2475  session->endpoint_interface = endpoint_interface;
2476  session->raw_write_frame.data = session->raw_write_buf;
2477  session->raw_write_frame.buflen = sizeof(session->raw_write_buf);
2478  session->raw_read_frame.data = session->raw_read_buf;
2479  session->raw_read_frame.buflen = sizeof(session->raw_read_buf);
2480 
2481 
2482  session->enc_write_frame.data = session->enc_write_buf;
2483  session->enc_write_frame.buflen = sizeof(session->enc_write_buf);
2484  session->enc_read_frame.data = session->enc_read_buf;
2485  session->enc_read_frame.buflen = sizeof(session->enc_read_buf);
2486 
2487  switch_mutex_init(&session->mutex, SWITCH_MUTEX_NESTED, session->pool);
2494  switch_thread_rwlock_create(&session->bug_rwlock, session->pool);
2495  switch_thread_cond_create(&session->cond, session->pool);
2496  switch_thread_rwlock_create(&session->rwlock, session->pool);
2497  switch_thread_rwlock_create(&session->io_rwlock, session->pool);
2503 
2505  session->id = session_manager.session_id++;
2507 
2510  }
2513  }
2514 
2516 
2517  switch_channel_set_variable_printf(session->channel, "session_id", "%u", session->id);
2518 
2519  return session;
2520 }
2521 
2523 {
2525 }
2526 
2528 {
2529  return session->id;
2530 }
2531 
2533 {
2537  return session_manager.session_id;
2538 }
2539 
2541 {
2542  return session_manager.session_id;
2543 }
2544 
2545 
2548 {
2549  switch_endpoint_interface_t *endpoint_interface;
2550  switch_core_session_t *session;
2551 
2552  if ((endpoint_interface = switch_loadable_module_get_endpoint_interface(endpoint_name)) == 0) {
2553  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not locate channel type %s\n", endpoint_name);
2554  return NULL;
2555  }
2556 
2557  session = switch_core_session_request(endpoint_interface, direction, SOF_NONE, pool);
2558 
2559  UNPROTECT_INTERFACE(endpoint_interface);
2560 
2561  return session;
2562 }
2563 
2564 #ifndef SWITCH_PREFIX_DIR
2565 #define SWITCH_PREFIX_DIR "."
2566 #endif
2567 
2569 {
2570  switch_assert(a != NULL);
2571  switch_assert(b != NULL);
2572 
2573  return (uint8_t) (a->endpoint_interface == b->endpoint_interface);
2574 }
2575 
2577 {
2578  switch_assert(session != NULL);
2579  switch_assert(endpoint_interface != NULL);
2580 
2581  return (uint8_t) (session->endpoint_interface == endpoint_interface);
2582 }
2583 
2585 {
2586  if (!session) return NULL;
2587  return session->uuid_str;
2588 }
2589 
2591 {
2592  if (!session) return NULL;
2593  return session->external_id;
2594 }
2595 
2596 SWITCH_DECLARE(uint32_t) switch_core_session_limit(uint32_t new_limit)
2597 {
2598  if (new_limit) {
2599  session_manager.session_limit = new_limit;
2600  }
2601 
2603 }
2604 
2605 SWITCH_DECLARE(double) switch_core_min_idle_cpu(double new_limit)
2606 {
2607  if (new_limit >= 0) {
2608  runtime.min_idle_time = new_limit;
2609  }
2610 
2611  return runtime.min_idle_time;
2612 }
2613 
2614 
2616 {
2617  return runtime.profile_time;
2618 }
2619 
2621 {
2622  if (new_limit) {
2623  runtime.sps_total = new_limit;
2624  }
2625 
2626  return runtime.sps_total;
2627 }
2628 
2630 {
2631  memset(&session_manager, 0, sizeof(session_manager));
2639 }
2640 
2642 {
2649 }
2650 
2652 {
2653  return session->app_log;
2654 }
2655 
2657 {
2658  switch_application_interface_t *application_interface;
2660 
2661  switch_assert(flags);
2662 
2663  *flags = 0;
2664 
2665  if ((application_interface = switch_loadable_module_get_application_interface(app)) == 0) {
2666  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Application %s\n", app);
2667  goto end;
2668  } else if (application_interface->flags) {
2669  *flags = application_interface->flags;
2670  status = SWITCH_STATUS_SUCCESS;
2671  }
2672 
2673  UNPROTECT_INTERFACE(application_interface);
2674 
2675  end:
2676 
2677  return status;
2678 
2679 }
2680 
2682 {
2683  switch_event_t *execute_event;
2684  char *ap, *arp;
2685 
2686  if (!arg && strstr(app, "::")) {
2687  ap = switch_core_session_strdup(session, app);
2688  app = ap;
2689 
2690  if ((arp = strstr(ap, "::"))) {
2691  *arp = '\0';
2692  arg = arp + 2;
2693  }
2694  }
2695 
2697  switch_event_add_header_string(execute_event, SWITCH_STACK_BOTTOM, "call-command", "execute");
2698  switch_event_add_header_string(execute_event, SWITCH_STACK_BOTTOM, "execute-app-name", app);
2699 
2700  if (arg) {
2701  switch_event_add_header_string(execute_event, SWITCH_STACK_BOTTOM, "execute-app-arg", arg);
2702  }
2703 
2706  }
2707 
2708  switch_event_add_header_string(execute_event, SWITCH_STACK_BOTTOM, "event-lock", "true");
2709  switch_core_session_queue_private_event(session, &execute_event, SWITCH_FALSE);
2710 
2711  return SWITCH_STATUS_SUCCESS;
2712  }
2713 
2714  return SWITCH_STATUS_FALSE;
2715 }
2716 
2718 {
2721  //switch_channel_clear_flag(session->channel, CF_VIDEO_DECODED_READ);
2726 }
2727 
2729  const char *arg, int32_t *flags)
2730 {
2731  switch_application_interface_t *application_interface;
2733 
2736 
2737  if (switch_channel_down_nosig(session->channel)) {
2738  char *p;
2739  if (!arg && (p = strstr(app, "::"))) {
2740  *p++ = '0';
2741  *p++ = '0';
2742  arg = p;
2743 
2744  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "%s ASYNC CALL CONVERTED TO INLINE %s(%s)\n",
2745  switch_channel_get_name(session->channel), app, switch_str_nil(arg));
2746  }
2747 
2748  if ((application_interface = switch_loadable_module_get_application_interface(app)) == 0) {
2749  return SWITCH_STATUS_FALSE;
2750  }
2751 
2752  if (switch_test_flag(application_interface, SAF_ZOMBIE_EXEC)) {
2753  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s ZOMBIE EXEC %s(%s)\n",
2754  switch_channel_get_name(session->channel), app, switch_str_nil(arg));
2755  goto exec;
2756  }
2757 
2759  "%s Channel is hungup and application '%s' does not have the zombie_exec flag.\n",
2760  switch_channel_get_name(session->channel), app);
2761 
2763  }
2764 
2765  if (!arg && strstr(app, "::")) {
2766  return switch_core_session_execute_application_async(session, app, arg);
2767  }
2768 
2769  if ((application_interface = switch_loadable_module_get_application_interface(app)) == 0) {
2770  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Invalid Application %s\n", app);
2773  }
2774 
2775  if (!application_interface->application_function) {
2776  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "No Function for %s\n", app);
2779  }
2780 
2781  if (flags && application_interface->flags) {
2782  *flags = application_interface->flags;
2783  }
2784 
2785  if (!switch_test_flag(application_interface, SAF_SUPPORT_NOMEDIA) && (switch_channel_test_flag(session->channel, CF_VIDEO))) {
2787  }
2788 
2789  if (switch_channel_test_flag(session->channel, CF_PROXY_MODE) && !switch_test_flag(application_interface, SAF_SUPPORT_NOMEDIA)) {
2790  switch_ivr_media(session->uuid_str, SMF_NONE);
2791  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Application %s Requires media on channel %s!\n",
2792  app, switch_channel_get_name(session->channel));
2793  } else if (!switch_test_flag(application_interface, SAF_SUPPORT_NOMEDIA) && !switch_channel_media_ready(session->channel)) {
2795  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Application %s Requires media! pre_answering channel %s\n",
2796  app, switch_channel_get_name(session->channel));
2798  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Well, that didn't work very well did it? ...\n");
2800  }
2801  } else {
2802  uint32_t ready = 0, sanity = 2000;
2803 
2804  do {
2805  sanity--;
2806  ready = switch_channel_media_up(session->channel);
2807  switch_cond_next();
2808  } while(!ready && sanity);
2809 
2810  if (!ready) {
2812  "Cannot execute app '%s' media required on an outbound channel that does not have media established\n", app);
2814  }
2815  }
2816  }
2817 
2818  if (switch_channel_text_only(session->channel) &&
2819  !switch_test_flag(application_interface, SAF_SUPPORT_NOMEDIA) &&
2820  !switch_test_flag(application_interface, SAF_SUPPORT_TEXT_ONLY)) {
2821  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Application %s does not support text-only mode on channel %s!\n",
2822  app, switch_channel_get_name(session->channel));
2825  }
2826 
2827  exec:
2828 
2829  switch_core_session_exec(session, application_interface, arg);
2830 
2831  done:
2832 
2833  UNPROTECT_INTERFACE(application_interface);
2834 
2835  return status;
2836 }
2837 
2839  const switch_application_interface_t *application_interface, const char *arg)
2840 {
2841  switch_app_log_t *log, *lp;
2842  switch_event_t *event;
2843  const char *var;
2845  char *expanded = NULL;
2846  const char *app, *app_uuid_var, *app_uuid_name;
2847  switch_core_session_message_t msg = { 0 };
2848  char delim = ',';
2849  int scope = 0;
2850  char uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1];
2851  char *app_uuid = uuid_str;
2852  switch_bool_t expand_variables = !switch_true(switch_channel_get_variable(session->channel, "app_disable_expand_variables"));
2853 
2854  if ((app_uuid_var = switch_channel_get_variable(channel, "app_uuid"))) {
2855  app_uuid = (char *)app_uuid_var;
2856  switch_channel_set_variable(channel, "app_uuid", NULL);
2857  } else {
2858  switch_uuid_str(uuid_str, sizeof(uuid_str));
2859  }
2860 
2861  if((app_uuid_name = switch_channel_get_variable(channel, "app_uuid_name"))) {
2862  switch_channel_set_variable(channel, "app_uuid_name", NULL);
2863  }
2864 
2865  switch_assert(application_interface);
2866 
2867  app = application_interface->interface_name;
2868 
2869  if (arg) {
2870  if (expand_variables) {
2871  expanded = switch_channel_expand_variables(session->channel, arg);
2872  } else {
2873  expanded = (char *)arg;
2874  }
2875  }
2876 
2877  if (expand_variables && expanded && *expanded == '%' && (*(expanded+1) == '[' || *(expanded+2) == '[')) {
2878  char *p, *dup;
2879  switch_event_t *ovars = NULL;
2880 
2881  p = expanded + 1;
2882 
2883  if (*p != '[') {
2884  delim = *p;
2885  p++;
2886  }
2887 
2888  dup = strdup(p);
2889 
2890  if (expanded != arg) {
2891  switch_safe_free(expanded);
2892  }
2893 
2894  switch_event_create_brackets(dup, '[', ']', delim, &ovars, &expanded, SWITCH_TRUE);
2895  free(dup);
2896 
2897  switch_channel_set_scope_variables(session->channel, &ovars);
2898  scope = 1;
2899  }
2900 
2901 
2903  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "EXECUTE [depth=%d] %s %s(%s)\n",
2904  switch_core_session_stack_count(session, 0), switch_channel_get_name(session->channel), app, switch_str_nil(expanded));
2905  } else {
2906  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_INFO, "EXECUTE [depth=%d] %s %s(%s)\n",
2907  switch_core_session_stack_count(session, 0), switch_channel_get_name(session->channel), app, switch_str_nil(expanded));
2908  }
2909 
2910  if ((var = switch_channel_get_variable(session->channel, "verbose_presence")) && switch_true(var)) {
2911  char *myarg = NULL;
2912  if (expanded) {
2913  myarg = switch_mprintf("%s(%s)", app, expanded);
2914  } else if (!zstr(arg)) {
2915  myarg = switch_mprintf("%s(%s)", app, arg);
2916  } else {
2917  myarg = switch_mprintf("%s", app);
2918  }
2919  if (myarg) {
2920  switch_channel_presence(session->channel, "unknown", myarg, NULL);
2921  switch_safe_free(myarg);
2922  }
2923  }
2924 
2925  if (!(var = switch_channel_get_variable(session->channel, SWITCH_DISABLE_APP_LOG_VARIABLE)) || (!(switch_true(var)))) {
2926  log = switch_core_session_alloc(session, sizeof(*log));
2927 
2928  log->app = switch_core_session_strdup(session, application_interface->interface_name);
2929  if (expanded) {
2930  log->arg = switch_core_session_strdup(session, expanded);
2931  }
2932 
2933  log->stamp = switch_time_now();
2934 
2935  for (lp = session->app_log; lp && lp->next; lp = lp->next);
2936 
2937  if (lp) {
2938  lp->next = log;
2939  } else {
2940  session->app_log = log;
2941  }
2942  }
2943 
2947 
2949  switch_channel_event_set_data(session->channel, event);
2950  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Application", application_interface->interface_name);
2951  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Application-Data", expanded);
2952  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Application-UUID", app_uuid);
2953  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Application-UUID-Name", app_uuid_name);
2954  switch_event_fire(&event);
2955  }
2956 
2958 
2959  switch_assert(application_interface->application_function);
2960 
2962 
2963  msg.from = __FILE__;
2965  msg.string_array_arg[0] = application_interface->interface_name;
2966  msg.string_array_arg[1] = expanded;
2967  switch_core_session_receive_message(session, &msg);
2968 
2969  application_interface->application_function(session, expanded);
2970 
2973  switch_channel_event_set_data(session->channel, event);
2974  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Application", application_interface->interface_name);
2975  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Application-Data", expanded);
2976  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Application-Response", resp ? resp : "_none_");
2977  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Application-UUID", app_uuid);
2978  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Application-UUID-Name", app_uuid_name);
2979  switch_event_fire(&event);
2980  }
2981 
2983  switch_core_session_receive_message(session, &msg);
2984 
2985  if (expanded != arg) {
2986  switch_safe_free(expanded);
2987  }
2988 
2989  if (scope) {
2991  }
2992 
2993  return SWITCH_STATUS_SUCCESS;
2994 }
2995 
2997 {
2998  uint32_t stack_count = 0;
3000  if (x > 0) session->stack_count++;
3001  else if (x < 0) session->stack_count--;
3002 
3003  stack_count = session->stack_count;
3005  return stack_count;
3006 }
3007 
3009  const char *context)
3010 {
3011  char *dp[25];
3012  char *dpstr;
3013  int argc, x;
3014  uint32_t stack_count = 0;
3015  switch_caller_profile_t *profile, *new_profile, *pp = NULL;
3017  switch_dialplan_interface_t *dialplan_interface = NULL;
3018  switch_caller_extension_t *extension = NULL;
3020 
3021  if (!(profile = switch_channel_get_caller_profile(channel))) {
3022  return SWITCH_STATUS_FALSE;
3023  }
3024 
3025  if ((stack_count = switch_core_session_stack_count(session, 0)) > SWITCH_MAX_STACKS) {
3026  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Error %s too many stacked extensions [depth=%d]\n",
3027  switch_channel_get_name(session->channel), stack_count);
3028  return SWITCH_STATUS_FALSE;
3029  }
3030 
3031  switch_core_session_stack_count(session, 1);
3032 
3033  new_profile = switch_caller_profile_clone(session, profile);
3034  new_profile->destination_number = switch_core_strdup(new_profile->pool, exten);
3035  new_profile->times = (switch_channel_timetable_t *) switch_core_session_alloc(session, sizeof(*new_profile->times));
3036  *new_profile->times = *profile->times;
3037 
3038 
3039  if (!zstr(dialplan)) {
3040  new_profile->dialplan = switch_core_strdup(new_profile->pool, dialplan);
3041  }
3042 
3043  if (!zstr(context)) {
3044  new_profile->context = switch_core_strdup(new_profile->pool, context);
3045  }
3046 
3047  dpstr = switch_core_session_strdup(session, new_profile->dialplan);
3048 
3049  switch_channel_set_hunt_caller_profile(channel, new_profile);
3050  argc = switch_separate_string(dpstr, ',', dp, (sizeof(dp) / sizeof(dp[0])));
3051  for (x = 0; x < argc; x++) {
3052  char *dpname = dp[x];
3053  char *dparg = NULL;
3054 
3055  if (dpname) {
3056  if ((dparg = strchr(dpname, ':'))) {
3057  *dparg++ = '\0';
3058  }
3059  } else {
3060  continue;
3061  }
3062 
3063  if (!(dialplan_interface = switch_loadable_module_get_dialplan_interface(dpname))) {
3064  continue;
3065  }
3066 
3067  extension = dialplan_interface->hunt_function(session, dparg, new_profile);
3068  UNPROTECT_INTERFACE(dialplan_interface);
3069 
3070  if (extension) {
3071  break;
3072  }
3073  }
3074 
3075  if (!extension) {
3076  status = SWITCH_STATUS_FALSE;
3077  goto done;
3078  }
3079 
3080  new_profile->caller_extension = extension;
3081 
3082  if (profile->caller_extension) {
3083  for (pp = profile->caller_extension->children; pp && pp->next; pp = pp->next);
3084 
3085  if (pp) {
3086  pp->next = new_profile;
3087  } else {
3088  profile->caller_extension->children = new_profile;
3089  }
3090  }
3091 
3092  while (switch_channel_ready(channel) && extension->current_application) {
3093  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Execute [depth=%d] %s(%s)\n",
3094  switch_core_session_stack_count(session, 0),
3096 
3100  goto done;
3101  }
3102 
3103  extension->current_application = extension->current_application->next;
3104  }
3105 
3106  done:
3108 
3109  switch_core_session_stack_count(session, -1);
3110  return status;
3111 }
3112 
3114 {
3115  switch_assert(session != NULL);
3116  session->loglevel = loglevel;
3117  return SWITCH_STATUS_SUCCESS;
3118 }
3119 
3121 {
3122  switch_assert(session != NULL);
3123  return session->loglevel;
3124 }
3125 
3127 {
3128  stream->write_function(stream, "Thread pool: running:%d busy:%d popping:%d\n",
3130 }
3131 
3133 {
3134  if (session->sdata) {
3135  if (session->sdata && switch_core_codec_ready(&session->sdata->codec)) {
3137  }
3138  memset(session->sdata, 0, sizeof(*session->sdata));
3139  } else {
3140  session->sdata = switch_core_session_alloc(session, sizeof(*session->sdata));
3141  }
3142 
3143  switch_core_session_set_codec_slin(session, session->sdata);
3144 }
3145 
3147 {
3149  session->io_override = ior;
3150  return SWITCH_STATUS_SUCCESS;
3151  }
3152 
3153  return SWITCH_STATUS_FALSE;
3154 }
3155 
3156 
3157 /* For Emacs:
3158  * Local Variables:
3159  * mode:c
3160  * indent-tabs-mode:t
3161  * tab-width:4
3162  * c-basic-offset:4
3163  * End:
3164  * For VIM:
3165  * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
3166  */
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)
void switch_core_codec_unlock_full(switch_core_session_t *session)
Unlock codec read mutex and codec write mutex.
#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:587
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:307
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:262
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:441
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:287
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:339
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:2892
#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:588
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
void switch_core_codec_lock_full(switch_core_session_t *session)
Lock codec read mutex and codec write mutex using trylock in an infinite loop.
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