FreeSWITCH API Documentation  1.7.0
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-2014, 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 
194  if ((uuid = switch_channel_get_partner_uuid(session->channel))) {
195  if ((*partner = switch_core_session_perform_locate(uuid, file, func, line))) {
196  return SWITCH_STATUS_SUCCESS;
197  }
198  }
199 
200  *partner = NULL;
201  return SWITCH_STATUS_FALSE;
202 }
203 
204 
205 struct str_node {
206  char *str;
207  struct str_node *next;
208 };
209 
210 SWITCH_DECLARE(uint32_t) switch_core_session_hupall_matching_var_ans(const char *var_name, const char *var_val, switch_call_cause_t cause,
211  switch_hup_type_t type)
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 (!var_val)
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_val;
247  if (switch_channel_up_nosig(session->channel) &&
248  (this_val = switch_channel_get_variable(session->channel, var_name)) && (!strcmp(this_val, var_val))) {
249  switch_channel_hangup(session->channel, cause);
250  r++;
251  }
253  }
254  }
255 
257 
258  return r;
259 }
260 
261 
263 {
265  void *val;
266  switch_core_session_t *session;
268  struct str_node *head = NULL, *np;
269  switch_console_callback_match_t *my_matches = NULL;
270  const char *like = NULL;
271 
272  if (var_val && *var_val == '~') {
273  like = var_val + 1;
274  }
275 
277 
280  switch_core_hash_this(hi, NULL, NULL, &val);
281  if (val) {
282  session = (switch_core_session_t *) val;
284  np = switch_core_alloc(pool, sizeof(*np));
285  np->str = switch_core_strdup(pool, session->uuid_str);
286  np->next = head;
287  head = np;
289  }
290  }
291  }
293 
294  for(np = head; np; np = np->next) {
295  if ((session = switch_core_session_locate(np->str))) {
296  const char *this_val;
297  if (switch_channel_up_nosig(session->channel) &&
298  (this_val = switch_channel_get_variable_dup(session->channel, var_name, SWITCH_FALSE, -1)) &&
299  (!var_val || (like && switch_stristr(like, var_val)) || !strcmp(this_val, var_val))) {
300  switch_console_push_match(&my_matches, (const char *) np->str);
301  }
303  }
304  }
305 
307 
308 
309  return my_matches;
310 }
311 
313 {
315  void *val;
316  switch_core_session_t *session;
318  struct str_node *head = NULL, *np;
319 
321 
324  switch_core_hash_this(hi, NULL, NULL, &val);
325  if (val) {
326  session = (switch_core_session_t *) val;
328  if (session->endpoint_interface == endpoint_interface) {
329  np = switch_core_alloc(pool, sizeof(*np));
330  np->str = switch_core_strdup(pool, session->uuid_str);
331  np->next = head;
332  head = np;
333  }
335  }
336  }
337  }
339 
340  for(np = head; np; np = np->next) {
341  if ((session = switch_core_session_locate(np->str))) {
342  switch_channel_hangup(session->channel, cause);
344  }
345  }
346 
348 
349 }
350 
352 {
354  void *val;
355  switch_core_session_t *session;
357  struct str_node *head = NULL, *np;
358 
360 
361 
364  switch_core_hash_this(hi, NULL, NULL, &val);
365  if (val) {
366  session = (switch_core_session_t *) val;
368  np = switch_core_alloc(pool, sizeof(*np));
369  np->str = switch_core_strdup(pool, session->uuid_str);
370  np->next = head;
371  head = np;
373  }
374  }
375  }
377 
378  for(np = head; np; np = np->next) {
379  if ((session = switch_core_session_locate(np->str))) {
380  switch_channel_hangup(session->channel, cause);
382  }
383  }
384 
386 
387 }
388 
389 
391 {
393  void *val;
394  switch_core_session_t *session;
395  switch_console_callback_match_t *my_matches = NULL;
396 
399  switch_core_hash_this(hi, NULL, NULL, &val);
400  if (val) {
401  session = (switch_core_session_t *) val;
403  switch_console_push_match(&my_matches, session->uuid_str);
405  }
406  }
407  }
409 
410  return my_matches;
411 }
412 
414 {
415  switch_core_session_t *session = NULL;
417 
419  if ((session = switch_core_hash_find(session_manager.session_table, uuid_str)) != 0) {
420  /* Acquire a read lock on the session or forget it the channel is dead */
422  if (switch_channel_up_nosig(session->channel)) {
423  status = switch_core_session_receive_message(session, message);
424  }
426  }
427  }
429 
430  return status;
431 }
432 
434 {
435  switch_core_session_t *session = NULL;
437 
439  if ((session = switch_core_hash_find(session_manager.session_table, uuid_str)) != 0) {
440  /* Acquire a read lock on the session or forget it the channel is dead */
442  if (switch_channel_up_nosig(session->channel)) {
443  status = switch_core_session_queue_event(session, event);
444  }
446  }
447  }
449 
450  return status;
451 }
452 
453 
455 {
456  if ((int)index >= SWITCH_CORE_SESSION_MAX_PRIVATES) {
457  return NULL;
458  }
459 
460  switch_assert(session != NULL);
461  return session->private_info[index];
462 }
463 
464 
466 {
467  switch_assert(session != NULL);
468 
469  if ((int)index >= SWITCH_CORE_SESSION_MAX_PRIVATES) {
470  return SWITCH_STATUS_FALSE;
471  }
472 
473  session->private_info[index] = private_info;
474  return SWITCH_STATUS_SUCCESS;
475 }
476 
478 {
479  session->streams[session->stream_count++] = private_info;
480  return session->stream_count - 1;
481 }
482 
484 {
485  return session->streams[index];
486 }
487 
488 
490 {
491  return session->stream_count;
492 }
493 
495  const char *endpoint_name,
496  switch_caller_profile_t *caller_profile,
497  switch_core_session_t **new_session,
499  switch_originate_flag_t flags, switch_call_cause_t *cancel_cause)
500 {
503  switch_endpoint_interface_t *endpoint_interface;
504  switch_channel_t *channel = NULL;
505  switch_caller_profile_t *outgoing_profile = caller_profile;
507  const char *forwardvar;
508  int forwardval = 70;
509 
510  if ((endpoint_interface = switch_loadable_module_get_endpoint_interface(endpoint_name)) == 0) {
511  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Could not locate channel type %s\n", endpoint_name);
513  }
514 
515  if (!endpoint_interface->io_routines->outgoing_channel) {
516  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Could not locate outgoing channel interface for %s\n", endpoint_name);
518  }
519 
520  if (session) {
521  channel = switch_core_session_get_channel(session);
522 
523  switch_assert(channel != NULL);
524 
526  if (!zstr(forwardvar)) {
527  forwardval = atoi(forwardvar) - 1;
528  }
529  if (forwardval <= 0) {
531  }
532 
533  if (caller_profile) {
534  const char *eani = NULL, *eaniii = NULL;
535  const char *ecaller_id_name = NULL, *ecaller_id_number = NULL;
536 
537  if (!(flags & SOF_NO_EFFECTIVE_ANI)) {
538  eani = switch_channel_get_variable(channel, "effective_ani");
539  }
540 
541  if (!(flags & SOF_NO_EFFECTIVE_ANIII)) {
542  eaniii = switch_channel_get_variable(channel, "effective_aniii");
543  }
544 
545  if (!(flags & SOF_NO_EFFECTIVE_CID_NAME)) {
546  ecaller_id_name = switch_channel_get_variable(channel, "effective_caller_id_name");
547  }
548 
549  if (!(flags & SOF_NO_EFFECTIVE_CID_NUM)) {
550  ecaller_id_number = switch_channel_get_variable(channel, "effective_caller_id_number");
551  }
552 
553  if (eani || eaniii || ecaller_id_name || ecaller_id_number) {
554  outgoing_profile = switch_caller_profile_clone(session, caller_profile);
555 
556  if (eani) {
557  outgoing_profile->ani = eani;
558  }
559  if (eaniii) {
560  outgoing_profile->aniii = eaniii;
561  }
562  if (ecaller_id_name) {
563  outgoing_profile->caller_id_name = ecaller_id_name;
564  }
565  if (ecaller_id_number) {
566  outgoing_profile->caller_id_number = ecaller_id_number;
567  }
568  }
569  }
570  if (!outgoing_profile) {
571  outgoing_profile = switch_channel_get_caller_profile(channel);
572  }
573  }
574 
575  if ((cause =
576  endpoint_interface->io_routines->outgoing_channel(session, var_event, outgoing_profile, new_session, pool, flags,
577  cancel_cause)) != SWITCH_CAUSE_SUCCESS) {
578  UNPROTECT_INTERFACE(endpoint_interface);
579  return cause;
580  }
581 
582  if (session) {
583  for (ptr = session->event_hooks.outgoing_channel; ptr; ptr = ptr->next) {
584  if ((status = ptr->outgoing_channel(session, var_event, caller_profile, *new_session, flags)) != SWITCH_STATUS_SUCCESS) {
585  break;
586  }
587  }
588  }
589 
590  if (!*new_session) {
592  "Outgoing method for endpoint: [%s] returned: [%s] but there is no new session!\n", endpoint_name,
593  switch_channel_cause2str(cause));
594  UNPROTECT_INTERFACE(endpoint_interface);
596  } else {
597  switch_caller_profile_t *profile = NULL, *cloned_profile = NULL;
598  switch_event_t *event;
599  switch_channel_t *peer_channel = switch_core_session_get_channel(*new_session);
600  const char *use_uuid;
601 
602  switch_assert(peer_channel);
603 
604  if (channel && switch_true(switch_channel_get_variable(channel, "session_copy_loglevel"))) {
605  (*new_session)->loglevel = session->loglevel;
606  }
607 
608 
609  if ((use_uuid = switch_event_get_header(var_event, "origination_uuid"))) {
610  use_uuid = switch_core_session_strdup(*new_session, use_uuid);
611  if (switch_core_session_set_uuid(*new_session, use_uuid) == SWITCH_STATUS_SUCCESS) {
612  switch_event_del_header(var_event, "origination_uuid");
613  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(*new_session), SWITCH_LOG_DEBUG, "%s set UUID=%s\n", switch_channel_get_name(peer_channel),
614  use_uuid);
615  } else {
616  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(*new_session), SWITCH_LOG_CRIT, "%s set UUID=%s FAILED\n",
617  switch_channel_get_name(peer_channel), use_uuid);
618  }
619  }
620 
621  if (channel) {
622  const char *val;
623  switch_codec_t *vid_read_codec = NULL, *read_codec = switch_core_session_get_read_codec(session);
624  const char *ep, *max_forwards = switch_core_session_sprintf(session, "%d", forwardval);
625 
626  switch_channel_set_variable(peer_channel, SWITCH_MAX_FORWARDS_VARIABLE, max_forwards);
627 
628  profile = switch_channel_get_caller_profile(channel);
629 
630  vid_read_codec = switch_core_session_get_video_read_codec(session);
631 
632  if (read_codec && read_codec->implementation && switch_core_codec_ready(read_codec)) {
633  char rc[80] = "", vrc[80] = "", tmp[160] = "";
634 
635  switch_codec2str(read_codec, rc, sizeof(rc));
636  if (vid_read_codec && vid_read_codec->implementation && switch_core_codec_ready(vid_read_codec)) {
637  vrc[0] = ',';
638  switch_codec2str(vid_read_codec, vrc + 1, sizeof(vrc) - 1);
640  }
641 
642  switch_snprintf(tmp, sizeof(tmp), "%s%s", rc, vrc);
644  } else if ((ep = switch_channel_get_variable(channel, "ep_codec_string"))) {
646  }
647 
650  // Needed by 3PCC proxy so that aleg can find bleg to pass SDP to, when final ACK arrives.
652 
655  }
656 
657  if ((val = switch_channel_get_variable(channel, SWITCH_R_SDP_VARIABLE))) {
658  switch_channel_pass_sdp(channel, peer_channel, val);
659  }
660 
661  if (switch_channel_test_flag(channel, CF_PROXY_MODE)) {
662  if (switch_channel_test_cap(peer_channel, CC_BYPASS_MEDIA)) {
663  switch_channel_set_flag(peer_channel, CF_PROXY_MODE);
664  } else {
666  "%s does not support the proxy feature, disabling.\n", switch_channel_get_name(peer_channel));
668  }
669  }
670 
672  if (switch_channel_test_cap(peer_channel, CC_PROXY_MEDIA)) {
674  if (switch_channel_test_flag(channel, CF_VIDEO)) {
675  switch_channel_set_flag(peer_channel, CF_VIDEO);
676  }
677  } else {
679  "%s does not support the proxy feature, disabling.\n", switch_channel_get_name(peer_channel));
681  }
682  }
683 
686  }
687 
688  if (profile) {
689  if ((cloned_profile = switch_caller_profile_clone(*new_session, profile)) != 0) {
690  switch_channel_set_originator_caller_profile(peer_channel, cloned_profile);
691  }
692  }
693 
694 
695  if ((profile = switch_channel_get_caller_profile(peer_channel))) {
696  if ((cloned_profile = switch_caller_profile_clone(session, profile)) != 0) {
697  switch_channel_set_origination_caller_profile(channel, cloned_profile);
698  }
699  }
700 
701  }
702 
704  switch_channel_event_set_data(peer_channel, event);
705  switch_event_fire(&event);
706  }
707  }
708 
709  UNPROTECT_INTERFACE(endpoint_interface);
710  return cause;
711 }
712 
713 static const char *message_names[] = {
714  "REDIRECT_AUDIO",
715  "TRANSMIT_TEXT",
716  "ANSWER",
717  "PROGRESS",
718  "BRIDGE",
719  "UNBRIDGE",
720  "TRANSFER",
721  "RINGING",
722  "MEDIA",
723  "3P_MEDIA",
724  "NOMEDIA",
725  "3P_NOMEDIA",
726  "HOLD",
727  "UNHOLD",
728  "REDIRECT",
729  "RESPOND",
730  "BROADCAST",
731  "MEDIA_REDIRECT",
732  "DEFLECT",
733  "VIDEO_REFRESH_REQ",
734  "DISPLAY",
735  "TRANSCODING_NECESSARY",
736  "AUDIO_SYNC",
737  "VIDEO_SYNC",
738  "REQUEST_IMAGE_MEDIA",
739  "UUID_CHANGE",
740  "SIMPLIFY",
741  "DEBUG_MEDIA",
742  "PROXY_MEDIA",
743  "APPLICATION_EXEC",
744  "APPLICATION_EXEC_COMPLETE",
745  "PHONE_EVENT",
746  "T38_DESCRIPTION",
747  "UDPTL_MODE",
748  "CLEAR_PROGRESS",
749  "JITTER_BUFFER",
750  "RECOVERY_REFRESH",
751  "SIGNAL_DATA",
752  "MESSAGE",
753  "INFO",
754  "AUDIO_DATA",
755  "BLIND_TRANSFER_RESPONSE",
756  "STUN_ERROR",
757  "MEDIA_RENEG",
758  "KEEPALIVE",
759  "HARD_MUTE",
760  "BITRATE_REQ",
761  "BITRATE_ACK",
762  "CODEC_DEBUG_REQ",
763  "CODEC_SPECIFIC_REQ",
764  "REFER_EVENT",
765  "ANSWER_EVENT",
766  "PROGRESS_EVENT",
767  "RING_EVENT",
768  "RESAMPLE_EVENT",
769  "HEARTBEAT_EVENT",
770  "INVALID"
771 };
772 
775  const char *file, const char *func, int line)
776 {
779 
780  switch_assert(session != NULL);
781 
782  if (message->message_id == SWITCH_MESSAGE_INDICATE_SIGNAL_DATA) {
783  if (session->endpoint_interface->io_routines->receive_message) {
784  status = session->endpoint_interface->io_routines->receive_message(session, message);
785  }
786 
788  return status;
789  }
790 
791  if ((status = switch_core_session_read_lock_hangup(session)) != SWITCH_STATUS_SUCCESS) {
792  return status;
793  }
794 
795  if (!message->_file) {
796  message->_file = file;
797  }
798 
799  if (!message->_func) {
800  message->_func = func;
801  }
802 
803  if (!message->_line) {
804  message->_line = line;
805  }
806 
807  if (message->message_id > SWITCH_MESSAGE_INVALID-1) {
808  message->message_id = SWITCH_MESSAGE_INVALID-1;
809  }
810 
811  switch_log_printf(SWITCH_CHANNEL_ID_LOG, message->_file, message->_func, message->_line,
812  switch_core_session_get_uuid(session), SWITCH_LOG_DEBUG1, "%s receive message [%s]\n",
813  switch_channel_get_name(session->channel), message_names[message->message_id]);
814 
815 
816  if (message->message_id == SWITCH_MESSAGE_INDICATE_CLEAR_PROGRESS) {
817  switch_channel_clear_flag(session->channel, CF_EARLY_MEDIA);
818  }
819 
820  if (message->message_id == SWITCH_MESSAGE_INDICATE_MEDIA) {
821  switch_channel_set_flag(session->channel, CF_PROXY_OFF);
822  }
823 
824  if (message->message_id == SWITCH_MESSAGE_INDICATE_DISPLAY) {
825  char *arg = NULL;
826 
827  if (zstr(message->string_array_arg[0]) && !zstr(message->string_arg)) {
828  arg = switch_core_session_strdup(session, message->string_arg);
829  switch_separate_string(arg, '|', (char **)message->string_array_arg, 2);
830  }
831 
832  if (!zstr(message->string_array_arg[0])) {
833  switch_channel_set_variable(session->channel, "last_sent_callee_id_name", message->string_array_arg[0]);
834  }
835 
836  if (!zstr(message->string_array_arg[1])) {
837  switch_channel_set_variable(session->channel, "last_sent_callee_id_number", message->string_array_arg[1]);
838  }
839 
840 
842  switch_log_printf(SWITCH_CHANNEL_ID_LOG, message->_file, message->_func, message->_line,
843  switch_core_session_get_uuid(session), SWITCH_LOG_DEBUG1, "Ignoring display update.\n");
844  status = SWITCH_STATUS_SUCCESS;
845  goto end;
846  }
847 
848  }
849 
850  if (switch_channel_down_nosig(session->channel)) {
851  switch_log_printf(SWITCH_CHANNEL_ID_LOG, message->_file, message->_func, message->_line,
852  switch_core_session_get_uuid(session), SWITCH_LOG_DEBUG, "%s skip receive message [%s] (channel is hungup already)\n",
853  switch_channel_get_name(session->channel), message_names[message->message_id]);
854 
855  } else {
856  if (session->media_handle) {
857  status = switch_core_media_receive_message(session, message);
858  }
859  if (status == SWITCH_STATUS_SUCCESS) {
860  if (session->endpoint_interface->io_routines->receive_message) {
861  status = session->endpoint_interface->io_routines->receive_message(session, message);
862  }
863  }
864  }
865 
866  if (status == SWITCH_STATUS_SUCCESS) {
867  for (ptr = session->event_hooks.receive_message; ptr; ptr = ptr->next) {
868  if ((status = ptr->receive_message(session, message)) != SWITCH_STATUS_SUCCESS) {
869  break;
870  }
871  }
872 
873 
874  if (message->message_id == SWITCH_MESSAGE_INDICATE_BRIDGE &&
876  switch_core_session_t *other_session;
877  const char *uuid = switch_channel_get_variable(session->channel, "blind_transfer_uuid");
878 
880 
881  if (!zstr(uuid) && (other_session = switch_core_session_locate(uuid))) {
882  switch_core_session_message_t msg = { 0 };
884  msg.from = __FILE__;
885  msg.numeric_arg = 1;
886  switch_core_session_receive_message(other_session, &msg);
887  switch_core_session_rwunlock(other_session);
888  }
889  }
890  }
891 
892 
893  message->_file = NULL;
894  message->_func = NULL;
895  message->_line = 0;
896 
897  if (switch_channel_up_nosig(session->channel)) {
898  if (message->message_id == SWITCH_MESSAGE_INDICATE_BRIDGE || message->message_id == SWITCH_MESSAGE_INDICATE_UNBRIDGE) {
901  }
902 
903  switch (message->message_id) {
920  switch_channel_set_flag(session->channel, CF_VIDEO_BREAK);
922  break;
923  default:
924  break;
925  }
926  }
927 
928  end:
929 
930  if (message->message_id == SWITCH_MESSAGE_INDICATE_MEDIA) {
931  switch_channel_clear_flag(session->channel, CF_PROXY_OFF);
932  }
933 
936 
937  return status;
938 }
939 
941 {
942  switch_core_session_message_t msg = { 0 };
943  switch_core_session_t *other_session;
944  const char *uuid;
947 
948  if (((uuid = switch_channel_get_partner_uuid(channel))) && (other_session = switch_core_session_locate(uuid))) {
949  msg.message_id = indication;
950  msg.from = __FILE__;
951  status = switch_core_session_receive_message(other_session, &msg);
952  switch_core_session_rwunlock(other_session);
953  } else {
954  status = SWITCH_STATUS_FALSE;
955  }
956 
957  return status;
958 }
959 
961 {
963 
964  if ((msg = malloc(sizeof(*msg)))) {
965  memset(msg, 0, sizeof(*msg));
966  msg->message_id = indication;
967  msg->from = __FILE__;
969  switch_core_session_queue_message(session, msg);
970  return SWITCH_STATUS_SUCCESS;
971  }
972 
973  return SWITCH_STATUS_FALSE;
974 }
975 
977 {
979 
980  switch_assert(session != NULL);
981 
982  if (session->message_queue) {
983  if (switch_queue_trypush(session->message_queue, message) == SWITCH_STATUS_SUCCESS) {
984  status = SWITCH_STATUS_SUCCESS;
985  }
986 
988 
990 
991  }
992 
993  return status;
994 }
995 
997 {
998  switch_core_session_message_t *to_free = *message;
999  int i;
1000  char *s;
1001 
1002  *message = NULL;
1003 
1004  if (switch_test_flag(to_free, SCSMF_DYNAMIC)) {
1005  s = (char *) to_free->string_arg;
1006  switch_safe_free(s);
1007  switch_safe_free(to_free->pointer_arg);
1008 
1009  for (i = 0; i < MESSAGE_STRING_ARG_MAX; i++) {
1010  s = (char *) to_free->string_array_arg[i];
1011  switch_safe_free(s);
1012  }
1013 
1014  switch_safe_free(to_free);
1015  }
1016 }
1017 
1019 {
1021  void *pop;
1022 
1023  switch_assert(session != NULL);
1024 
1025  if (session->message_queue) {
1026  if ((status = (switch_status_t) switch_queue_trypop(session->message_queue, &pop)) == SWITCH_STATUS_SUCCESS) {
1027  *message = (switch_core_session_message_t *) pop;
1028  if ((*message)->delivery_time && (*message)->delivery_time > switch_epoch_time_now(NULL)) {
1029  switch_core_session_queue_message(session, *message);
1030  *message = NULL;
1031  status = SWITCH_STATUS_FALSE;
1032  }
1033  }
1034  }
1035 
1036  return status;
1037 }
1038 
1040 {
1042  void *pop;
1044 
1045  switch_assert(session != NULL);
1046 
1047 
1048  if (session->message_queue) {
1049  while ((status = (switch_status_t) switch_queue_trypop(session->message_queue, &pop)) == SWITCH_STATUS_SUCCESS) {
1050  message = (switch_core_session_message_t *) pop;
1051  switch_ivr_process_indications(session, message);
1053  }
1054  }
1055 
1056  return SWITCH_STATUS_SUCCESS;
1057 }
1058 
1060 {
1062 
1063  switch_assert(session != NULL);
1064 
1065  if (session->signal_data_queue) {
1066  if (switch_queue_push(session->signal_data_queue, signal_data) == SWITCH_STATUS_SUCCESS) {
1067  status = SWITCH_STATUS_SUCCESS;
1068  }
1069 
1071 
1073 
1074  }
1075 
1076  return status;
1077 }
1078 
1080 {
1082  void *pop;
1083 
1084  switch_assert(session != NULL);
1085 
1086  if (session->signal_data_queue) {
1087  if ((status = (switch_status_t) switch_queue_trypop(session->signal_data_queue, &pop)) == SWITCH_STATUS_SUCCESS) {
1088  *signal_data = pop;
1089  }
1090  }
1091 
1092  return status;
1093 }
1094 
1096 {
1099 
1100  switch_assert(session != NULL);
1101 
1102  /* Acquire a read lock on the session or forget it the channel is dead */
1104  if (switch_channel_up_nosig(session->channel)) {
1105  if (session->endpoint_interface->io_routines->receive_event) {
1106  status = session->endpoint_interface->io_routines->receive_event(session, *event);
1107  }
1108 
1109  if (status == SWITCH_STATUS_SUCCESS) {
1110  for (ptr = session->event_hooks.receive_event; ptr; ptr = ptr->next) {
1111  if ((status = ptr->receive_event(session, *event)) != SWITCH_STATUS_SUCCESS) {
1112  break;
1113  }
1114  }
1115  }
1116 
1117  if (status == SWITCH_STATUS_BREAK) {
1118  status = SWITCH_STATUS_SUCCESS;
1119  }
1120 
1121  if (status == SWITCH_STATUS_SUCCESS) {
1122  switch_event_destroy(event);
1123  }
1124  }
1126  }
1127 
1129 
1130  return status;
1131 }
1132 
1134 {
1136 
1137  switch_assert(session != NULL);
1138 
1139  if (session->event_queue) {
1140  if (switch_queue_trypush(session->event_queue, *event) == SWITCH_STATUS_SUCCESS) {
1141  *event = NULL;
1142  status = SWITCH_STATUS_SUCCESS;
1143 
1145  }
1146  }
1147 
1148  return status;
1149 }
1150 
1152 {
1153  int x = 0;
1154 
1155  if (session->private_event_queue) {
1156  x += switch_queue_size(session->private_event_queue);
1157  }
1158 
1159  if (session->message_queue) {
1160  x += switch_queue_size(session->message_queue);
1161  }
1162 
1163  return x;
1164 }
1165 
1167 {
1168  if (session->event_queue) {
1169  return switch_queue_size(session->event_queue);
1170  }
1171 
1172  return 0;
1173 }
1174 
1176 {
1178  void *pop;
1179 
1180  switch_assert(session != NULL);
1181 
1182  if (session->event_queue && (force || !switch_channel_test_flag(session->channel, CF_DIVERT_EVENTS))) {
1183  if ((status = (switch_status_t) switch_queue_trypop(session->event_queue, &pop)) == SWITCH_STATUS_SUCCESS) {
1184  *event = (switch_event_t *) pop;
1185  }
1186  }
1187 
1188  return status;
1189 }
1190 
1192 {
1194  switch_queue_t *queue;
1195 
1196  switch_assert(session != NULL);
1197  switch_assert(event != NULL);
1198 
1199  if (session->private_event_queue) {
1200  queue = priority ? session->private_event_queue_pri : session->private_event_queue;
1201 
1202  (*event)->event_id = SWITCH_EVENT_PRIVATE_COMMAND;
1203  if (switch_queue_trypush(queue, *event) == SWITCH_STATUS_SUCCESS) {
1204  *event = NULL;
1206  status = SWITCH_STATUS_SUCCESS;
1207  }
1208  }
1209 
1210  return status;
1211 }
1212 
1213 #define check_media(session) \
1214  { \
1215  if (switch_channel_test_flag(session->channel, CF_BROADCAST_DROP_MEDIA)) { \
1216  switch_channel_clear_flag(session->channel, CF_BROADCAST_DROP_MEDIA); \
1217  switch_ivr_nomedia(session->uuid_str, SMF_REBRIDGE); \
1218  } \
1219  } \
1220 
1222 {
1224  uint32_t count = 0;
1225 
1226  if (session->private_event_queue) {
1227 
1228  if (!switch_channel_test_flag(channel, CF_EVENT_LOCK)) {
1229  count = switch_queue_size(session->private_event_queue);
1230  }
1231 
1233  count += switch_queue_size(session->private_event_queue_pri);
1234  }
1235 
1236  if (count == 0) {
1237  check_media(session);
1238  }
1239  }
1240 
1241  return count;
1242 }
1243 
1245 {
1247  void *pop;
1249  switch_queue_t *queue;
1250 
1251  if (session->private_event_queue) {
1252  if (switch_queue_size(session->private_event_queue_pri)) {
1253  queue = session->private_event_queue_pri;
1254 
1256  return SWITCH_STATUS_FALSE;
1257  }
1258  } else {
1259  queue = session->private_event_queue;
1260 
1261  if (switch_channel_test_flag(channel, CF_EVENT_LOCK)) {
1262  return SWITCH_STATUS_FALSE;
1263  }
1264  }
1265 
1266  if ((status = (switch_status_t) switch_queue_trypop(queue, &pop)) == SWITCH_STATUS_SUCCESS) {
1267  *event = (switch_event_t *) pop;
1268  } else {
1269  check_media(session);
1270  }
1271  }
1272 
1273  return status;
1274 }
1275 
1277 {
1279  int x = 0;
1280  void *pop;
1281 
1282  if (session->private_event_queue) {
1283  while ((status = (switch_status_t) switch_queue_trypop(session->private_event_queue_pri, &pop)) == SWITCH_STATUS_SUCCESS) {
1284  if (pop) {
1285  switch_event_t *event = (switch_event_t *) pop;
1286  switch_event_destroy(&event);
1287  }
1288  x++;
1289  }
1290  while ((status = (switch_status_t) switch_queue_trypop(session->private_event_queue, &pop)) == SWITCH_STATUS_SUCCESS) {
1291  if (pop) {
1292  switch_event_t *event = (switch_event_t *) pop;
1293  switch_event_destroy(&event);
1294  }
1295  x++;
1296  }
1297  check_media(session);
1298  }
1299 
1300  return x;
1301 }
1302 
1304 {
1306  switch_size_t has;
1307 
1308  if (reset_read_codec) {
1309  switch_core_session_set_read_codec(session, NULL);
1310  if (session->sdata && switch_core_codec_ready(&session->sdata->codec)) {
1311  switch_core_codec_destroy(&session->sdata->codec);
1312  }
1313  }
1314 
1315  /* clear resamplers */
1316  switch_mutex_lock(session->resample_mutex);
1317  switch_resample_destroy(&session->read_resampler);
1318  switch_resample_destroy(&session->write_resampler);
1319  switch_mutex_unlock(session->resample_mutex);
1320  /* clear indications */
1322 
1323  /* wipe these, they will be recreated if need be */
1324  switch_mutex_lock(session->codec_write_mutex);
1325  switch_buffer_destroy(&session->raw_write_buffer);
1326  switch_mutex_unlock(session->codec_write_mutex);
1327 
1328  switch_mutex_lock(session->codec_read_mutex);
1329  switch_buffer_destroy(&session->raw_read_buffer);
1330  switch_mutex_unlock(session->codec_read_mutex);
1331 
1332  switch_mutex_lock(session->video_codec_write_mutex);
1333  switch_buffer_destroy(&session->video_raw_write_buffer);
1334  switch_mutex_unlock(session->video_codec_write_mutex);
1335 
1336  switch_mutex_lock(session->video_codec_read_mutex);
1337  switch_buffer_destroy(&session->video_raw_read_buffer);
1338  switch_mutex_unlock(session->video_codec_read_mutex);
1339 
1340  //video_raw_read_frame.data is dynamically allocated if necessary, so wipe this also
1341  switch_safe_free(session->video_raw_read_frame.data);
1342 
1343  if (flush_dtmf) {
1344  while ((has = switch_channel_has_dtmf(channel))) {
1345  switch_channel_flush_dtmf(channel);
1346  }
1347  }
1348 
1352 }
1353 
1354 
1356 {
1357  switch_assert(session->channel);
1358  return session->channel;
1359 }
1360 
1362 {
1363  return session->mutex;
1364 }
1365 
1367 {
1368  switch_status_t status;
1369  int tries = 0;
1370 
1371  /* If trylock fails the signal is already awake so we needn't bother ..... or do we????*/
1372 
1373  top:
1374 
1375  status = switch_mutex_trylock(session->mutex);
1376 
1377  if (status == SWITCH_STATUS_SUCCESS) {
1378  switch_thread_cond_signal(session->cond);
1379  switch_mutex_unlock(session->mutex);
1380  } else {
1382  /* We've beat them for sure, as soon as we release this lock, they will be checking their queue on the next line. */
1383  switch_channel_state_thread_unlock(session->channel);
1384  } else {
1385  /* What luck! The channel has already started going to sleep *after* we checked if we need to wake it up.
1386  It will miss any messages in its queue because they were inserted after *it* checked its queue. (catch-22)
1387  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.
1388  Now *we* need to sleep instead but just for 1ms so we can circle back and try again.
1389  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.
1390  */
1391  if (++tries < 10) {
1392  switch_cond_next();
1393  goto top;
1394  }
1395  }
1396  }
1397 
1398  return status;
1399 }
1400 
1402 {
1405 
1407 
1408  if (session->endpoint_interface->io_routines->state_change) {
1409  status = session->endpoint_interface->io_routines->state_change(session);
1410  }
1411 
1412  if (status == SWITCH_STATUS_SUCCESS) {
1413  for (ptr = session->event_hooks.state_change; ptr; ptr = ptr->next) {
1414  if ((status = ptr->state_change(session)) != SWITCH_STATUS_SUCCESS) {
1415  break;
1416  }
1417  }
1418  }
1420 }
1421 
1423 {
1424  return switch_test_flag(session, SSF_THREAD_RUNNING) ? 1 : 0;
1425 }
1426 
1428 {
1429  return switch_test_flag(session, SSF_THREAD_STARTED) ? 1 : 0;
1430 }
1431 
1433 {
1434  int doit = 0;
1435 
1437  if (session_manager.session_count == 0) {
1438  doit = 1;
1439  } else {
1441  }
1443 
1444  if (doit) {
1445  switch_time_sync();
1446  }
1447 
1448  return doit;
1449 
1450 }
1451 
1452 SWITCH_DECLARE(void) switch_core_session_perform_destroy(switch_core_session_t **session, const char *file, const char *func, int line)
1453 {
1455  switch_event_t *event;
1456  switch_endpoint_interface_t *endpoint_interface = (*session)->endpoint_interface;
1457  int i;
1458 
1459 
1461 
1462  if (switch_core_session_running(*session) && !switch_test_flag((*session), SSF_DESTROYABLE)) {
1464  "Cowardly ignoring an attempt to call destroy on a running session.\n");
1465  }
1466 
1467  switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, switch_core_session_get_uuid(*session), SWITCH_LOG_NOTICE, "Close Channel %s [%s]\n",
1468  switch_channel_get_name((*session)->channel), switch_channel_state_name(switch_channel_get_state((*session)->channel)));
1469 
1470 
1472 
1475 
1476  switch_scheduler_del_task_group((*session)->uuid_str);
1477 
1479  switch_core_hash_delete(session_manager.session_table, (*session)->uuid_str);
1482  if (session_manager.session_count == 0) {
1484  switch_time_sync();
1486  }
1487  }
1488  }
1490 
1491  if ((*session)->plc) {
1492  plc_free((*session)->plc);
1493  (*session)->plc = NULL;
1494  }
1495 
1497  switch_channel_event_set_data((*session)->channel, event);
1498  switch_event_fire(&event);
1499  }
1500 
1502 
1503  switch_buffer_destroy(&(*session)->raw_read_buffer);
1504  switch_buffer_destroy(&(*session)->raw_write_buffer);
1506  switch_channel_uninit((*session)->channel);
1507 
1508  for (i = 0; i < 2; i++) {
1509  if ((*session)->dmachine[i]) {
1510  switch_ivr_dmachine_destroy(&(*session)->dmachine[i]);
1511  }
1512  }
1513 
1514  pool = (*session)->pool;
1515  //#ifndef NDEBUG
1516  //memset(*session, 0, sizeof(switch_core_session_t));
1517  //#endif
1518  *session = NULL;
1520 
1521  UNPROTECT_INTERFACE(endpoint_interface);
1522 }
1523 
1524 
1525 
1526 SWITCH_STANDARD_SCHED_FUNC(sch_heartbeat_callback)
1527 {
1528  switch_event_t *event;
1529  switch_core_session_t *session;
1530  char *uuid = task->cmd_arg;
1531  switch_core_session_message_t msg = { 0 };
1532 
1533  if ((session = switch_core_session_locate(uuid))) {
1535  switch_channel_event_set_data(session->channel, event);
1536  switch_event_fire(&event);
1537 
1538  /* reschedule this task */
1539  task->runtime = switch_epoch_time_now(NULL) + session->track_duration;
1540 
1542  msg.numeric_arg = session->track_duration;
1543  switch_core_session_receive_message(session, &msg);
1544 
1546  }
1547 }
1548 
1550 {
1551  if (session->track_id) {
1552  switch_scheduler_del_task_id(session->track_id);
1553  session->track_id = 0;
1554  }
1555 }
1556 
1558 {
1559  time_t when;
1560 
1562  if (switch_true(switch_channel_get_variable(session->channel, "heartbeat_fire_on_set"))) {
1563  when = switch_epoch_time_now(NULL);
1564  } else {
1565  when = switch_epoch_time_now(NULL) + session->track_duration;
1566  }
1567 
1568  session->track_id = switch_scheduler_add_task(when, sch_heartbeat_callback, (char *) __SWITCH_FUNC__,
1570 }
1571 
1573 {
1574  switch_assert(session != NULL);
1575 
1576  if (!seconds) {
1577  seconds = 60;
1578  }
1579 
1580  session->track_duration = seconds;
1581 
1582  if (switch_channel_test_flag(session->channel, CF_PROXY_MODE) || !switch_channel_media_ready(session->channel) ||
1583  switch_true(switch_channel_get_variable_dup(session->channel, "heartbeat_use_scheduler", SWITCH_FALSE, -1)) ||
1584  switch_true(switch_channel_get_variable_dup(session->channel, "bypass_media", SWITCH_FALSE, -1)) ||
1585  switch_true(switch_channel_get_variable_dup(session->channel, "bypass_media_after_bridge", SWITCH_FALSE, -1))) {
1586  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "%s using scheduler due to bypass media or media is not established.\n",
1587  switch_channel_get_name(session->channel));
1588  switch_core_session_sched_heartbeat(session, seconds);
1589  return;
1590  }
1591 
1592  if (switch_true(switch_channel_get_variable(session->channel, "heartbeat_fire_on_set"))) {
1593  session->read_frame_count = 0;
1594  } else {
1595  session->read_frame_count = (session->read_impl.samples_per_second / session->read_impl.samples_per_packet) * seconds;
1596  }
1597 
1599 
1600  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "%s setting session heartbeat to %u second(s).\n",
1601  switch_channel_get_name(session->channel), seconds);
1602 
1603 }
1604 
1606 {
1608  switch_assert(session != NULL);
1609  session->read_frame_count = 0;
1610  session->track_duration = 0;
1611 
1612 }
1613 
1615 {
1616  return switch_thread_equal(switch_thread_self(), session->thread_id) ? SWITCH_TRUE : SWITCH_FALSE;
1617 }
1618 
1620 {
1621  switch_core_session_t *session = obj;
1622  switch_event_t *event;
1623  char *event_str = NULL;
1624  const char *val;
1625 
1626  session->thread = thread;
1627  session->thread_id = switch_thread_self();
1628 
1629  switch_core_session_run(session);
1631 
1632  if (session->soft_lock) {
1633  uint32_t loops = session->soft_lock * 10;
1634 
1635  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Session %" SWITCH_SIZE_T_FMT " (%s) Soft-Locked, "
1636  "Waiting %u for external entities\n",
1637  session->id, switch_channel_get_name(session->channel), session->soft_lock);
1638 
1639  while(--loops > 0) {
1640  if (!session->soft_lock) break;
1641  switch_yield(100000);
1642  }
1643 
1644  }
1645 
1646  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Session %" SWITCH_SIZE_T_FMT " (%s) Locked, Waiting on external entities\n",
1647  session->id, switch_channel_get_name(session->channel));
1649  switch_set_flag(session, SSF_DESTROYED);
1650 
1651  if ((val = switch_channel_get_variable(session->channel, "memory_debug")) && switch_true(val)) {
1653  switch_channel_event_set_data(session->channel, event);
1654  switch_event_serialize(event, &event_str, SWITCH_FALSE);
1655  switch_assert(event_str);
1657  free(event_str);
1658  switch_event_destroy(&event);
1659  }
1660  }
1661 
1663 
1665  session->id, switch_channel_get_name(session->channel));
1666 
1667  switch_set_flag(session, SSF_DESTROYABLE);
1668  switch_core_session_destroy(&session);
1669  return NULL;
1670 }
1671 
1675 
1677 {
1679  switch_memory_pool_t *pool = node->pool;
1680 #ifdef DEBUG_THREAD_POOL
1681  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10, "Worker Thread %ld Started\n", (long) (intptr_t) thread);
1682 #endif
1683  for (;;) {
1684  void *pop;
1686  if (check_status == SWITCH_STATUS_SUCCESS) {
1688 
1689 #ifdef DEBUG_THREAD_POOL
1690  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10, "Worker Thread %ld Processing\n", (long) (intptr_t) thread);
1691 #endif
1692  td->func(thread, td->obj);
1693 
1694  if (td->pool) {
1695  switch_memory_pool_t *pool = td->pool;
1696  td = NULL;
1698  } else if (td->alloc) {
1699  free(td);
1700  }
1701 #ifdef DEBUG_THREAD_POOL
1702  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10, "Worker Thread %ld Done Processing\n", (long)(intptr_t) thread);
1703 #endif
1707  } else {
1710  if (!--session_manager.running) {
1712  }
1714  break;
1715  }
1717  }
1718  }
1719 #ifdef DEBUG_THREAD_POOL
1720  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10, "Worker Thread %ld Ended\n", (long)(intptr_t) thread);
1721 #endif
1723  return NULL;
1724 }
1725 
1726 static void thread_launch_failure(void)
1727 {
1728  uint32_t sess_count;
1729 
1731 
1732  sess_count = switch_core_session_count();
1733 
1734  if (sess_count > 110) {
1735 
1736  switch_core_session_limit(sess_count - 10);
1737  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "LUKE: I'm hit, but not bad.\n");
1739  "LUKE'S VOICE: Artoo, see what you can do with it. Hang on back there....\n"
1740  "Green laserfire moves past the beeping little robot as his head turns. "
1741  "After a few beeps and a twist of his mechanical arm,\n"
1742  "Artoo reduces the max sessions to %d thus, saving the switch from certain doom.\n", sess_count - 10);
1743 
1744  }
1745 
1747 }
1748 
1750 {
1755  return SWITCH_STATUS_SUCCESS;
1756  }
1759 
1760  {
1762  switch_threadattr_t *thd_attr;
1765 
1767  node = switch_core_alloc(pool, sizeof(*node));
1768  node->pool = pool;
1769 
1770  switch_threadattr_create(&thd_attr, node->pool);
1771  switch_threadattr_detach_set(thd_attr, 1);
1774 
1777  if (!--session_manager.running) {
1779  }
1781  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Thread Failure!\n");
1783  status = SWITCH_STATUS_GENERR;
1785  } else {
1786  status = SWITCH_STATUS_SUCCESS;
1787  }
1788  }
1789  return status;
1790 }
1791 
1792 
1794 {
1797 
1798  switch_assert(tdp);
1799 
1800  td = *tdp;
1801  *tdp = NULL;
1802 
1804  check_queue();
1805 
1806  return status;
1807 }
1808 
1810 {
1813 
1814  switch_mutex_lock(session->mutex);
1815  if (switch_test_flag(session, SSF_THREAD_RUNNING)) {
1816  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Cannot double-launch thread!\n");
1817  } else if (switch_test_flag(session, SSF_THREAD_STARTED)) {
1818  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Cannot launch thread again after it has already been run!\n");
1819  } else {
1822  td = switch_core_session_alloc(session, sizeof(*td));
1823  td->obj = session;
1826  check_queue();
1827  }
1828  switch_mutex_unlock(session->mutex);
1829 
1830  return status;
1831 }
1832 
1833 
1835 {
1838  switch_threadattr_t *thd_attr;
1839 
1841  status = SWITCH_STATUS_INUSE;
1842  goto end;
1843  }
1844 
1845 
1848  }
1849 
1850  switch_mutex_lock(session->mutex);
1851 
1852  if (switch_test_flag(session, SSF_THREAD_RUNNING)) {
1853  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Cannot double-launch thread!\n");
1854  } else if (switch_test_flag(session, SSF_THREAD_STARTED)) {
1855  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Cannot launch thread again after it has already been run!\n");
1856  } else {
1859 
1860  switch_threadattr_create(&thd_attr, session->pool);
1861  switch_threadattr_detach_set(thd_attr, 1);
1863 
1864  if (switch_thread_create(&thread, thd_attr, switch_core_session_thread, session, session->pool) == SWITCH_STATUS_SUCCESS) {
1866  status = SWITCH_STATUS_SUCCESS;
1867  } else {
1870  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Cannot create thread!\n");
1872  }
1873  }
1874 
1875  switch_mutex_unlock(session->mutex);
1876 
1877  end:
1878 
1879  return status;
1880 }
1881 
1883 {
1885  switch_threadattr_t *thd_attr = NULL;
1886  switch_threadattr_create(&thd_attr, session->pool);
1887  switch_threadattr_detach_set(thd_attr, 1);
1888 
1890  if (switch_thread_create(&thread, thd_attr, func, obj, session->pool) != SWITCH_STATUS_SUCCESS) {
1891  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Cannot create thread!\n");
1893  }
1894 
1895 }
1896 
1898 {
1899  switch_event_t *event;
1900  switch_core_session_message_t msg = { 0 };
1901  switch_caller_profile_t *profile;
1902 
1903  switch_assert(use_uuid);
1904 
1905  if (!strcmp(use_uuid, session->uuid_str)) {
1906  return SWITCH_STATUS_SUCCESS;
1907  }
1908 
1909 
1912  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Duplicate UUID!\n");
1914  return SWITCH_STATUS_FALSE;
1915  }
1916 
1918  msg.from = switch_channel_get_name(session->channel);
1919  msg.string_array_arg[0] = session->uuid_str;
1920  msg.string_array_arg[1] = use_uuid;
1921  switch_core_session_receive_message(session, &msg);
1922 
1923  if ((profile = switch_channel_get_caller_profile(session->channel))) {
1924  profile->uuid = switch_core_strdup(profile->pool, use_uuid);
1925  }
1926 
1927  switch_channel_set_variable(session->channel, "uuid", use_uuid);
1928  switch_channel_set_variable(session->channel, "call_uuid", use_uuid);
1929 
1931  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Old-Unique-ID", session->uuid_str);
1933  switch_set_string(session->uuid_str, use_uuid);
1934  switch_core_hash_insert(session_manager.session_table, session->uuid_str, session);
1936  switch_channel_event_set_data(session->channel, event);
1937  switch_event_fire(&event);
1938 
1939 
1940  return SWITCH_STATUS_SUCCESS;
1941 }
1942 
1943 static char *xml_find_var(switch_xml_t vars, const char *name)
1944 {
1945  switch_xml_t var;
1946  if ((var = switch_xml_child(vars, name)) && var->txt) {
1947  return var->txt;
1948  }
1949 
1950  return NULL;
1951 }
1952 
1953 static void parse_array(const char *str, uint32_t *array, int32_t array_len)
1954 {
1955  char *p, *v, *dup, *next = NULL;
1956 
1957  if (zstr(str)) {
1958  return;
1959  }
1960 
1961  dup = strdup(str);
1962 
1963  p = dup;
1964  while (p) {
1965  if ((next = strchr(p, ';'))) {
1966  *next++ = '\0';
1967  }
1968 
1969  if ((v = strchr(p, '='))) {
1970  *v++ = '\0';
1971  }
1972 
1973  if (p && v) {
1974  int x = 0, y = 0;
1975 
1976  x = atoi(p);
1977  y = atoi(v);
1978 
1979  if (x < array_len) {
1980  array[x] = y;
1981  }
1982  }
1983 
1984  p = next;
1985 
1986  }
1987 
1988  free(dup);
1989 }
1990 
1993 {
1994  switch_core_session_t *session;
1995  switch_channel_t *channel;
1996  switch_xml_t tag, tag2, tag3, vars, callflow;
1998  char *flag_str = NULL, *cap_str = NULL, *direction_s = NULL, *uuid = NULL;
1999  uint32_t flags[CF_FLAG_MAX] = { 0 };
2000  uint32_t caps[CC_FLAG_MAX] = { 0 };
2001  int i;
2002 
2003  vars = switch_xml_child(xml, "variables");
2004  uuid = xml_find_var(vars, "uuid");
2005 
2006  if ((tag = switch_xml_child(xml, "channel_data"))) {
2007  direction_s = xml_find_var(tag, "direction");
2008  direction = !strcmp(direction_s, "outbound") ? SWITCH_CALL_DIRECTION_OUTBOUND : SWITCH_CALL_DIRECTION_INBOUND;
2009  flag_str = xml_find_var(tag, "flags");
2010  cap_str = xml_find_var(tag, "caps");
2011  }
2012 
2013  parse_array(flag_str, flags, CF_FLAG_MAX);
2014  parse_array(cap_str, caps, CC_FLAG_MAX);
2015 
2016  flags[CF_RECOVERING] = 0;
2017  flags[CF_RECOVERING_BRIDGE] = 0;
2018  flags[CF_TRACKED] = 0;
2019  flags[CF_TRANSFER] = 0;
2020  flags[CF_ACCEPT_CNG] = 0;
2021  flags[CF_REDIRECT] = 0;
2022  flags[CF_BRIDGED] = 0;
2023  flags[CF_HOLD] = 0;
2024  flags[CF_SERVICE] = 0;
2025  flags[CF_TAGGED] = 0;
2026  flags[CF_WINNER] = 0;
2027  flags[CF_EARLY_OK] = 0;
2028  flags[CF_CONTROLLED] = 0;
2029  flags[CF_SUSPEND] = 0;
2030  flags[CF_EVENT_PARSE] = 0;
2031  flags[CF_GEN_RINGBACK] = 0;
2032  flags[CF_BREAK] = 0;
2033  flags[CF_BROADCAST] = 0;
2034  flags[CF_UNICAST] = 0;
2035  flags[CF_EVENT_LOCK] = 0;
2036  flags[CF_EVENT_LOCK_PRI] = 0;
2037  flags[CF_RESET] = 0;
2038  flags[CF_ORIGINATING] = 0;
2039  flags[CF_STOP_BROADCAST] = 0;
2040  flags[CF_INNER_BRIDGE] = 0;
2041  flags[CF_REQ_MEDIA] = 0;
2042  flags[CF_PAUSE_BUGS] = 0;
2043  flags[CF_DIVERT_EVENTS] = 0;
2044  flags[CF_BLOCK_STATE] = 0;
2045  flags[CF_FS_RTP] = 0;
2046  flags[CF_REPORTING] = 0;
2047  flags[CF_PARK] = 0;
2048  flags[CF_TIMESTAMP_SET] = 0;
2049  flags[CF_ORIGINATOR] = 0;
2050  flags[CF_XFER_ZOMBIE] = 0;
2051  flags[CF_MEDIA_ACK] = 0;
2052  flags[CF_THREAD_SLEEPING] = 0;
2053  flags[CF_DISABLE_RINGBACK] = 0;
2054  flags[CF_NOT_READY] = 0;
2055  flags[CF_SIGNAL_BRIDGE_TTL] = 0;
2056  flags[CF_MEDIA_BRIDGE_TTL] = 0;
2057  flags[CF_BYPASS_MEDIA_AFTER_BRIDGE] = 0;
2058  flags[CF_LEG_HOLDING] = 0;
2059  flags[CF_BROADCAST_DROP_MEDIA] = 0;
2060  flags[CF_EARLY_HANGUP] = 0;
2061  flags[CF_MEDIA_SET] = 0;
2062  flags[CF_CONSUME_ON_ORIGINATE] = 0;
2063  flags[CF_PASSTHRU_PTIME_MISMATCH] = 0;
2064  flags[CF_BRIDGE_NOWRITE] = 0;
2065  flags[CF_RECOVERED] = 0;
2066  flags[CF_JITTERBUFFER] = 0;
2067  flags[CF_JITTERBUFFER_PLC] = 0;
2068  flags[CF_DIALPLAN] = 0;
2069  flags[CF_BLOCK_BROADCAST_UNTIL_MEDIA] = 0;
2070  flags[CF_CNG_PLC] = 0;
2071  flags[CF_ATTENDED_TRANSFER] = 0;
2072  flags[CF_LAZY_ATTENDED_TRANSFER] = 0;
2073  flags[CF_SIGNAL_DATA] = 0;
2074  flags[CF_SIMPLIFY] = 0;
2075  flags[CF_VIDEO_READY] = 0;
2076  flags[CF_VIDEO_DECODED_READ] = 0;
2077 
2078  if (!(session = switch_core_session_request_uuid(endpoint_interface, direction, SOF_NO_LIMITS, pool, uuid))) {
2079  return NULL;
2080  }
2081 
2082  channel = switch_core_session_get_channel(session);
2083 
2084  for (i = 0; i < CF_FLAG_MAX; i++) {
2085  if (flags[i]) {
2086  switch_channel_set_flag_value(channel, i, flags[i]);
2087  }
2088  }
2089 
2090  for (i = 0; i < CC_FLAG_MAX; i++) {
2091  if (caps[i]) {
2092  switch_channel_set_cap_value(channel, i, caps[i]);
2093  }
2094  }
2095 
2096  if ((tag2 = switch_xml_child(xml, "variables"))) {
2097  for (tag = tag2->child; tag; tag = tag->sibling) {
2098  if (tag->name && tag->txt) {
2099  char *p = strdup(tag->txt);
2100  char *val = p;
2101  switch_url_decode(val);
2102  switch_channel_set_variable(channel, tag->name, val);
2103  if (!strcasecmp(tag->name, "channel_name")) {
2104  switch_channel_set_name(channel, val);
2105  }
2106  free(p);
2107  }
2108  }
2109  }
2110 
2111  if ((callflow = switch_xml_child(xml, "callflow"))) {
2112  if ((tag2 = switch_xml_child(callflow, "caller_profile"))) {
2113  switch_caller_profile_t *caller_profile;
2114  char *tmp;
2115 
2116  caller_profile = switch_caller_profile_new(switch_core_session_get_pool(session),
2117  xml_find_var(tag2, "username"),
2118  xml_find_var(tag2, "dialplan"),
2119  xml_find_var(tag2, "caller_id_name"),
2120  xml_find_var(tag2, "caller_id_number"),
2121  xml_find_var(tag2, "network_addr"),
2122  xml_find_var(tag2, "ani"),
2123  xml_find_var(tag2, "aniii"),
2124  xml_find_var(tag2, "rdnis"),
2125  xml_find_var(tag2, "source"),
2126  xml_find_var(tag2, "context"), xml_find_var(tag2, "destination_number"));
2127 
2128  if ((tmp = xml_find_var(tag2, "callee_id_name"))) {
2129  caller_profile->callee_id_name = switch_core_session_strdup(session, tmp);
2130  }
2131 
2132  if ((tmp = xml_find_var(tag2, "callee_id_number"))) {
2133  caller_profile->callee_id_number = switch_core_session_strdup(session, tmp);
2134  }
2135 
2136  if ((tag3 = switch_xml_child(callflow, "times"))) {
2137  caller_profile->times = (switch_channel_timetable_t *) switch_core_session_alloc(session, sizeof(*caller_profile->times));
2138 
2139  caller_profile->times->resurrected = switch_time_now();
2140 
2141  for (tag3 = tag3->child; tag3; tag3 = tag3->sibling) {
2142  int64_t v;
2143 
2144  if (tag3->name && tag3->txt) {
2145  v = atoll(tag3->txt);
2146  if (!strcmp(tag3->name, "created_time")) {
2147  caller_profile->times->created = v;
2148  } else if (!strcmp(tag3->name, "profile_created_time")) {
2149  caller_profile->times->profile_created = v;
2150  } else if (!strcmp(tag3->name, "progress_time")) {
2151  caller_profile->times->progress = v;
2152  } else if (!strcmp(tag3->name, "progress_media_time")) {
2153  caller_profile->times->progress_media = v;
2154  } else if (!strcmp(tag3->name, "answered_time")) {
2155  caller_profile->times->answered = v;
2156  } else if (!strcmp(tag3->name, "hangup_time")) {
2157  caller_profile->times->hungup = v;
2158  } else if (!strcmp(tag3->name, "transfer_time")) {
2159  caller_profile->times->transferred = v;
2160  }
2161  }
2162 
2163  }
2164  }
2165 
2166  switch_channel_set_caller_profile(channel, caller_profile);
2167  if ((tag = switch_xml_child(tag2, "originator")) && (tag = tag->child)) {
2168  caller_profile = switch_caller_profile_new(switch_core_session_get_pool(session),
2169  xml_find_var(tag, "username"),
2170  xml_find_var(tag, "dialplan"),
2171  xml_find_var(tag, "caller_id_name"),
2172  xml_find_var(tag, "caller_id_number"),
2173  xml_find_var(tag, "network_addr"),
2174  xml_find_var(tag, "ani"),
2175  xml_find_var(tag, "aniii"),
2176  xml_find_var(tag, "rdnis"),
2177  xml_find_var(tag, "source"),
2178  xml_find_var(tag, "context"), xml_find_var(tag, "destination_number"));
2179 
2180  switch_channel_set_originator_caller_profile(channel, caller_profile);
2181  }
2182 
2183  if ((tag = switch_xml_child(tag2, "originatee")) && (tag = tag->child)) {
2184  caller_profile = switch_caller_profile_new(switch_core_session_get_pool(session),
2185  xml_find_var(tag, "username"),
2186  xml_find_var(tag, "dialplan"),
2187  xml_find_var(tag, "caller_id_name"),
2188  xml_find_var(tag, "caller_id_number"),
2189  xml_find_var(tag, "network_addr"),
2190  xml_find_var(tag, "ani"),
2191  xml_find_var(tag, "aniii"),
2192  xml_find_var(tag, "rdnis"),
2193  xml_find_var(tag, "source"),
2194  xml_find_var(tag, "context"), xml_find_var(tag, "destination_number"));
2195 
2196  switch_channel_set_originatee_caller_profile(channel, caller_profile);
2197  }
2198 
2199  }
2200 
2201 
2203  }
2204 
2205 
2206  if (!channel || !switch_channel_get_caller_profile(channel)) {
2207  if (session) {
2208  switch_core_session_destroy(&session);
2209  }
2210  }
2211 
2212 
2213  return session;
2214 }
2215 
2216 
2217 
2219  *endpoint_interface,
2220  switch_call_direction_t direction,
2221  switch_originate_flag_t originate_flags,
2222  switch_memory_pool_t **pool, const char *use_uuid)
2223 {
2224  switch_memory_pool_t *usepool;
2225  switch_core_session_t *session;
2226  switch_uuid_t uuid;
2227  uint32_t count = 0;
2228  int32_t sps = 0;
2229 
2230 
2231  if (use_uuid && switch_core_hash_find(session_manager.session_table, use_uuid)) {
2232  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Duplicate UUID!\n");
2233  return NULL;
2234  }
2235 
2237  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "The system cannot create any inbound sessions at this time.\n");
2238  return NULL;
2239  }
2240 
2242  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "The system cannot create any outbound sessions at this time.\n");
2243  return NULL;
2244  }
2245 
2246  if (!switch_core_ready() || endpoint_interface == NULL) {
2247  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "The system cannot create any sessions at this time.\n");
2248  return NULL;
2249  }
2250 
2252  return NULL;
2253  }
2254 
2255  PROTECT_INTERFACE(endpoint_interface);
2256 
2257  if (!(originate_flags & SOF_NO_LIMITS)) {
2260  sps = --runtime.sps;
2262 
2263  if (sps <= 0) {
2265  UNPROTECT_INTERFACE(endpoint_interface);
2266  return NULL;
2267  }
2268 
2269  if ((count + 1) > session_manager.session_limit) {
2271  UNPROTECT_INTERFACE(endpoint_interface);
2272  return NULL;
2273  }
2274  }
2275 
2276 
2277  if (pool && *pool) {
2278  usepool = *pool;
2279  *pool = NULL;
2280  } else {
2281  switch_core_new_memory_pool(&usepool);
2282  }
2283 
2284  session = switch_core_alloc(usepool, sizeof(*session));
2285  session->pool = usepool;
2286 
2287  switch_core_memory_pool_set_data(session->pool, "__session", session);
2288 
2289  if (switch_channel_alloc(&session->channel, direction, session->pool) != SWITCH_STATUS_SUCCESS) {
2290  abort();
2291  }
2292 
2293  switch_channel_init(session->channel, session, CS_NEW, 0);
2294 
2295  if (direction == SWITCH_CALL_DIRECTION_OUTBOUND) {
2297  }
2298 
2299  /* The session *IS* the pool you may not alter it because you have no idea how
2300  its all private it will be passed to the thread run function */
2301 
2302  if (use_uuid) {
2303  switch_set_string(session->uuid_str, use_uuid);
2304  } else {
2305  switch_uuid_get(&uuid);
2306  switch_uuid_format(session->uuid_str, &uuid);
2307  }
2308 
2309  switch_channel_set_variable(session->channel, "uuid", session->uuid_str);
2310  switch_channel_set_variable(session->channel, "call_uuid", session->uuid_str);
2311 
2312  session->endpoint_interface = endpoint_interface;
2313  session->raw_write_frame.data = session->raw_write_buf;
2314  session->raw_write_frame.buflen = sizeof(session->raw_write_buf);
2315  session->raw_read_frame.data = session->raw_read_buf;
2316  session->raw_read_frame.buflen = sizeof(session->raw_read_buf);
2317 
2318 
2319  session->enc_write_frame.data = session->enc_write_buf;
2320  session->enc_write_frame.buflen = sizeof(session->enc_write_buf);
2321  session->enc_read_frame.data = session->enc_read_buf;
2322  session->enc_read_frame.buflen = sizeof(session->enc_read_buf);
2323 
2324  switch_mutex_init(&session->mutex, SWITCH_MUTEX_NESTED, session->pool);
2331  switch_thread_rwlock_create(&session->bug_rwlock, session->pool);
2332  switch_thread_cond_create(&session->cond, session->pool);
2333  switch_thread_rwlock_create(&session->rwlock, session->pool);
2334  switch_thread_rwlock_create(&session->io_rwlock, session->pool);
2340 
2343  session->id = session_manager.session_id++;
2345 
2348  }
2351  }
2352 
2354 
2355  switch_channel_set_variable_printf(session->channel, "session_id", "%u", session->id);
2356 
2357  return session;
2358 }
2359 
2361 {
2363 }
2364 
2366 {
2367  return session->id;
2368 }
2369 
2371 {
2375  return session_manager.session_id;
2376 }
2377 
2379 {
2380  return session_manager.session_id;
2381 }
2382 
2383 
2386 {
2387  switch_endpoint_interface_t *endpoint_interface;
2388  switch_core_session_t *session;
2389 
2390  if ((endpoint_interface = switch_loadable_module_get_endpoint_interface(endpoint_name)) == 0) {
2391  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not locate channel type %s\n", endpoint_name);
2392  return NULL;
2393  }
2394 
2395  session = switch_core_session_request(endpoint_interface, direction, SOF_NONE, pool);
2396 
2397  UNPROTECT_INTERFACE(endpoint_interface);
2398 
2399  return session;
2400 }
2401 
2402 #ifndef SWITCH_PREFIX_DIR
2403 #define SWITCH_PREFIX_DIR "."
2404 #endif
2405 
2407 {
2408  switch_assert(a != NULL);
2409  switch_assert(b != NULL);
2410 
2411  return (uint8_t) (a->endpoint_interface == b->endpoint_interface);
2412 }
2413 
2415 {
2416  switch_assert(session != NULL);
2417  switch_assert(endpoint_interface != NULL);
2418 
2419  return (uint8_t) (session->endpoint_interface == endpoint_interface);
2420 }
2421 
2423 {
2424  if (!session) return NULL;
2425  return session->uuid_str;
2426 }
2427 
2428 
2429 SWITCH_DECLARE(uint32_t) switch_core_session_limit(uint32_t new_limit)
2430 {
2431  if (new_limit) {
2432  session_manager.session_limit = new_limit;
2433  }
2434 
2436 }
2437 
2438 SWITCH_DECLARE(double) switch_core_min_idle_cpu(double new_limit)
2439 {
2440  if (new_limit >= 0) {
2441  runtime.min_idle_time = new_limit;
2442  }
2443 
2444  return runtime.min_idle_time;
2445 }
2446 
2447 
2449 {
2450  return runtime.profile_time;
2451 }
2452 
2454 {
2455  if (new_limit) {
2456  runtime.sps_total = new_limit;
2457  }
2458 
2459  return runtime.sps_total;
2460 }
2461 
2463 {
2464  memset(&session_manager, 0, sizeof(session_manager));
2472 }
2473 
2475 {
2482 }
2483 
2485 {
2486  return session->app_log;
2487 }
2488 
2490 {
2491  switch_application_interface_t *application_interface;
2493 
2494  switch_assert(flags);
2495 
2496  *flags = 0;
2497 
2498  if ((application_interface = switch_loadable_module_get_application_interface(app)) == 0) {
2499  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Application %s\n", app);
2500  goto end;
2501  } else if (application_interface->flags) {
2502  *flags = application_interface->flags;
2503  status = SWITCH_STATUS_SUCCESS;
2504  }
2505 
2506  UNPROTECT_INTERFACE(application_interface);
2507 
2508  end:
2509 
2510  return status;
2511 
2512 }
2513 
2515 {
2516  switch_event_t *execute_event;
2517  char *ap, *arp;
2518 
2519  if (!arg && strstr(app, "::")) {
2520  ap = switch_core_session_strdup(session, app);
2521  app = ap;
2522 
2523  if ((arp = strstr(ap, "::"))) {
2524  *arp = '\0';
2525  arg = arp + 2;
2526  }
2527  }
2528 
2530  switch_event_add_header_string(execute_event, SWITCH_STACK_BOTTOM, "call-command", "execute");
2531  switch_event_add_header_string(execute_event, SWITCH_STACK_BOTTOM, "execute-app-name", app);
2532 
2533  if (arg) {
2534  switch_event_add_header_string(execute_event, SWITCH_STACK_BOTTOM, "execute-app-arg", arg);
2535  }
2536 
2537  if (!switch_channel_test_flag(session->channel, CF_PROXY_MODE)) {
2539  }
2540 
2541  switch_event_add_header_string(execute_event, SWITCH_STACK_BOTTOM, "event-lock", "true");
2542  switch_core_session_queue_private_event(session, &execute_event, SWITCH_FALSE);
2543 
2544  return SWITCH_STATUS_SUCCESS;
2545  }
2546 
2547  return SWITCH_STATUS_FALSE;
2548 }
2549 
2551 {
2552  switch_channel_clear_flag(session->channel, CF_VIDEO_ECHO);
2553  switch_channel_clear_flag(session->channel, CF_VIDEO_PASSIVE);
2554  //switch_channel_clear_flag(session->channel, CF_VIDEO_DECODED_READ);
2557  switch_channel_clear_flag(session->channel, CF_VIDEO_BLANK);
2559 }
2560 
2562  const char *arg, int32_t *flags)
2563 {
2564  switch_application_interface_t *application_interface;
2566 
2569 
2570  if (switch_channel_down_nosig(session->channel)) {
2571  char *p;
2572  if (!arg && (p = strstr(app, "::"))) {
2573  *p++ = '0';
2574  *p++ = '0';
2575  arg = p;
2576 
2577  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "%s ASYNC CALL CONVERTED TO INLINE %s(%s)\n",
2578  switch_channel_get_name(session->channel), app, switch_str_nil(arg));
2579  }
2580 
2581  if ((application_interface = switch_loadable_module_get_application_interface(app)) == 0) {
2582  return SWITCH_STATUS_FALSE;
2583  }
2584 
2585  if (switch_test_flag(application_interface, SAF_ZOMBIE_EXEC)) {
2586  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s ZOMBIE EXEC %s(%s)\n",
2587  switch_channel_get_name(session->channel), app, switch_str_nil(arg));
2588  goto exec;
2589  }
2590 
2592  "%s Channel is hungup and application '%s' does not have the zombie_exec flag.\n",
2593  switch_channel_get_name(session->channel), app);
2594 
2596  }
2597 
2598  if (!arg && strstr(app, "::")) {
2599  return switch_core_session_execute_application_async(session, app, arg);
2600  }
2601 
2602  if ((application_interface = switch_loadable_module_get_application_interface(app)) == 0) {
2603  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Invalid Application %s\n", app);
2606  }
2607 
2608  if (!application_interface->application_function) {
2609  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "No Function for %s\n", app);
2612  }
2613 
2614  if (flags && application_interface->flags) {
2615  *flags = application_interface->flags;
2616  }
2617 
2618  if (!switch_test_flag(application_interface, SAF_SUPPORT_NOMEDIA) && (switch_channel_test_flag(session->channel, CF_VIDEO))) {
2620  }
2621 
2622  if (switch_channel_test_flag(session->channel, CF_PROXY_MODE) && !switch_test_flag(application_interface, SAF_SUPPORT_NOMEDIA)) {
2623  switch_ivr_media(session->uuid_str, SMF_NONE);
2624  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Application %s Requires media on channel %s!\n",
2625  app, switch_channel_get_name(session->channel));
2626  } else if (!switch_test_flag(application_interface, SAF_SUPPORT_NOMEDIA) && !switch_channel_media_ready(session->channel)) {
2627  if (switch_channel_direction(session->channel) == SWITCH_CALL_DIRECTION_INBOUND) {
2628  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Application %s Requires media! pre_answering channel %s\n",
2629  app, switch_channel_get_name(session->channel));
2630  if (switch_channel_pre_answer(session->channel) != SWITCH_STATUS_SUCCESS) {
2631  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Well, that didn't work very well did it? ...\n");
2633  }
2634  } else {
2635  uint32_t ready = 0, sanity = 2000;
2636 
2637  do {
2638  sanity--;
2639  ready = switch_channel_media_up(session->channel);
2640  switch_cond_next();
2641  } while(!ready && sanity);
2642 
2643  if (!ready) {
2645  "Cannot execute app '%s' media required on an outbound channel that does not have media established\n", app);
2647  }
2648  }
2649  }
2650 
2651  exec:
2652 
2653  switch_core_session_exec(session, application_interface, arg);
2654 
2655  done:
2656 
2657  UNPROTECT_INTERFACE(application_interface);
2658 
2659  return status;
2660 }
2661 
2663  const switch_application_interface_t *application_interface, const char *arg)
2664 {
2665  switch_app_log_t *log, *lp;
2666  switch_event_t *event;
2667  const char *var;
2669  char *expanded = NULL;
2670  const char *app, *app_uuid_var;
2671  switch_core_session_message_t msg = { 0 };
2672  char delim = ',';
2673  int scope = 0;
2674  char uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1];
2675  char *app_uuid = uuid_str;
2676 
2677  if ((app_uuid_var = switch_channel_get_variable(channel, "app_uuid"))) {
2678  app_uuid = (char *)app_uuid_var;
2679  switch_channel_set_variable(channel, "app_uuid", NULL);
2680  } else {
2681  switch_uuid_str(uuid_str, sizeof(uuid_str));
2682  }
2683 
2684  switch_assert(application_interface);
2685 
2686  app = application_interface->interface_name;
2687 
2688  if (arg) {
2689  expanded = switch_channel_expand_variables(session->channel, arg);
2690  }
2691 
2692  if (expanded && *expanded == '%' && (*(expanded+1) == '[' || *(expanded+2) == '[')) {
2693  char *p, *dup;
2694  switch_event_t *ovars = NULL;
2695 
2696  p = expanded + 1;
2697 
2698  if (*p != '[') {
2699  delim = *p;
2700  p++;
2701  }
2702 
2703  dup = strdup(p);
2704 
2705  if (expanded != arg) {
2706  switch_safe_free(expanded);
2707  }
2708 
2709  switch_event_create_brackets(dup, '[', ']', delim, &ovars, &expanded, SWITCH_TRUE);
2710  free(dup);
2711 
2712  switch_channel_set_scope_variables(session->channel, &ovars);
2713  scope = 1;
2714  }
2715 
2716 
2718  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "EXECUTE %s %s(%s)\n",
2719  switch_channel_get_name(session->channel), app, switch_str_nil(expanded));
2720  } else {
2721  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG, "EXECUTE %s %s(%s)\n",
2722  switch_channel_get_name(session->channel), app, switch_str_nil(expanded));
2723  }
2724 
2725  if ((var = switch_channel_get_variable(session->channel, "verbose_presence")) && switch_true(var)) {
2726  char *myarg = NULL;
2727  if (expanded) {
2728  myarg = switch_mprintf("%s(%s)", app, expanded);
2729  } else if (!zstr(arg)) {
2730  myarg = switch_mprintf("%s(%s)", app, arg);
2731  } else {
2732  myarg = switch_mprintf("%s", app);
2733  }
2734  if (myarg) {
2735  switch_channel_presence(session->channel, "unknown", myarg, NULL);
2736  switch_safe_free(myarg);
2737  }
2738  }
2739 
2740  if (!(var = switch_channel_get_variable(session->channel, SWITCH_DISABLE_APP_LOG_VARIABLE)) || (!(switch_true(var)))) {
2741  log = switch_core_session_alloc(session, sizeof(*log));
2742 
2743  log->app = switch_core_session_strdup(session, application_interface->interface_name);
2744  if (expanded) {
2745  log->arg = switch_core_session_strdup(session, expanded);
2746  }
2747 
2748  log->stamp = switch_time_now();
2749 
2750  for (lp = session->app_log; lp && lp->next; lp = lp->next);
2751 
2752  if (lp) {
2753  lp->next = log;
2754  } else {
2755  session->app_log = log;
2756  }
2757  }
2758 
2759  switch_channel_set_variable(channel, SWITCH_CURRENT_APPLICATION_VARIABLE, application_interface->interface_name);
2762 
2764  switch_channel_event_set_data(session->channel, event);
2765  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Application", application_interface->interface_name);
2766  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Application-Data", expanded);
2767  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Application-UUID", app_uuid);
2768  switch_event_fire(&event);
2769  }
2770 
2771  switch_channel_clear_flag(session->channel, CF_BREAK);
2772 
2773  switch_assert(application_interface->application_function);
2774 
2775  switch_channel_set_variable(session->channel, SWITCH_CURRENT_APPLICATION_VARIABLE, application_interface->interface_name);
2776 
2777  msg.from = __FILE__;
2779  msg.string_array_arg[0] = application_interface->interface_name;
2780  msg.string_array_arg[1] = expanded;
2781  switch_core_session_receive_message(session, &msg);
2782 
2783  application_interface->application_function(session, expanded);
2784 
2786  const char *resp = switch_channel_get_variable(session->channel, SWITCH_CURRENT_APPLICATION_RESPONSE_VARIABLE);
2787  switch_channel_event_set_data(session->channel, event);
2788  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Application", application_interface->interface_name);
2789  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Application-Data", expanded);
2790  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Application-Response", resp ? resp : "_none_");
2791  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Application-UUID", app_uuid);
2792  switch_event_fire(&event);
2793  }
2794 
2796  switch_core_session_receive_message(session, &msg);
2797 
2798  if (expanded != arg) {
2799  switch_safe_free(expanded);
2800  }
2801 
2802  if (scope) {
2803  switch_channel_set_scope_variables(session->channel, NULL);
2804  }
2805 
2806  return SWITCH_STATUS_SUCCESS;
2807 }
2808 
2810  const char *context)
2811 {
2812  char *dp[25];
2813  char *dpstr;
2814  int argc, x, count = 0;
2815  switch_caller_profile_t *profile, *new_profile, *pp = NULL;
2817  switch_dialplan_interface_t *dialplan_interface = NULL;
2818  switch_caller_extension_t *extension = NULL;
2820 
2821  if (!(profile = switch_channel_get_caller_profile(channel))) {
2822  return SWITCH_STATUS_FALSE;
2823  }
2824 
2825  if (session->stack_count > SWITCH_MAX_STACKS) {
2826  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Error %s too many stacked extensions\n",
2827  switch_channel_get_name(session->channel));
2828  return SWITCH_STATUS_FALSE;
2829  }
2830 
2831  session->stack_count++;
2832 
2833  new_profile = switch_caller_profile_clone(session, profile);
2834  new_profile->destination_number = switch_core_strdup(new_profile->pool, exten);
2835  new_profile->times = (switch_channel_timetable_t *) switch_core_session_alloc(session, sizeof(*new_profile->times));
2836  *new_profile->times = *profile->times;
2837 
2838 
2839  if (!zstr(dialplan)) {
2840  new_profile->dialplan = switch_core_strdup(new_profile->pool, dialplan);
2841  }
2842 
2843  if (!zstr(context)) {
2844  new_profile->context = switch_core_strdup(new_profile->pool, context);
2845  }
2846 
2847  dpstr = switch_core_session_strdup(session, new_profile->dialplan);
2848 
2849  switch_channel_set_hunt_caller_profile(channel, new_profile);
2850  argc = switch_separate_string(dpstr, ',', dp, (sizeof(dp) / sizeof(dp[0])));
2851  for (x = 0; x < argc; x++) {
2852  char *dpname = dp[x];
2853  char *dparg = NULL;
2854 
2855  if (dpname) {
2856  if ((dparg = strchr(dpname, ':'))) {
2857  *dparg++ = '\0';
2858  }
2859  } else {
2860  continue;
2861  }
2862 
2863  if (!(dialplan_interface = switch_loadable_module_get_dialplan_interface(dpname))) {
2864  continue;
2865  }
2866 
2867  count++;
2868 
2869  extension = dialplan_interface->hunt_function(session, dparg, new_profile);
2870  UNPROTECT_INTERFACE(dialplan_interface);
2871 
2872  if (extension) {
2873  break;
2874  }
2875  }
2876 
2877  if (!extension) {
2878  status = SWITCH_STATUS_FALSE;
2879  goto done;
2880  }
2881 
2882  new_profile->caller_extension = extension;
2883 
2884  if (profile->caller_extension) {
2885  for (pp = profile->caller_extension->children; pp && pp->next; pp = pp->next);
2886 
2887  if (pp) {
2888  pp->next = new_profile;
2889  } else {
2890  profile->caller_extension->children = new_profile;
2891  }
2892  }
2893 
2894  while (switch_channel_ready(channel) && extension->current_application) {
2895  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Execute %s(%s)\n",
2897 
2901  goto done;
2902  }
2903 
2904  extension->current_application = extension->current_application->next;
2905  }
2906 
2907  done:
2909 
2910  session->stack_count--;
2911  return status;
2912 }
2913 
2915 {
2916  switch_assert(session != NULL);
2917  session->loglevel = loglevel;
2918  return SWITCH_STATUS_SUCCESS;
2919 }
2920 
2922 {
2923  switch_assert(session != NULL);
2924  return session->loglevel;
2925 }
2926 
2928 {
2929  stream->write_function(stream, "Thread pool: running:%d busy:%d popping:%d\n",
2931 }
2932 
2934 {
2935  if (session->sdata) {
2936  if (session->sdata && switch_core_codec_ready(&session->sdata->codec)) {
2937  switch_core_codec_destroy(&session->sdata->codec);
2938  }
2939  memset(session->sdata, 0, sizeof(*session->sdata));
2940  } else {
2941  session->sdata = switch_core_session_alloc(session, sizeof(*session->sdata));
2942  }
2943 
2944  switch_core_session_set_codec_slin(session, session->sdata);
2945 }
2946 
2947 /* For Emacs:
2948  * Local Variables:
2949  * mode:c
2950  * indent-tabs-mode:t
2951  * tab-width:4
2952  * c-basic-offset:4
2953  * End:
2954  * For VIM:
2955  * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
2956  */
struct apr_queue_t switch_queue_t
Definition: switch_apr.h:590
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:90
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:61
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:412
#define switch_channel_hangup(channel, hangup_cause)
Hangup a channel flagging it's state machine to end.
#define switch_core_media_gen_key_frame(_session)
void switch_time_sync(void)
Definition: switch_time.c:589
unsigned int switch_queue_size(switch_queue_t *queue)
Definition: switch_apr.c:1114
void switch_core_session_set_dmachine(switch_core_session_t *session, switch_ivr_dmachine_t *dmachine, switch_digit_action_target_t target)
#define SWITCH_MUTEX_DEFAULT
Definition: switch_apr.h:317
#define switch_core_new_memory_pool(p)
Create a new sub memory pool from the core's master pool.
Definition: switch_core.h:631
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:78
switch_status_t switch_thread_cond_create(switch_thread_cond_t **cond, switch_memory_pool_t *pool)
Definition: switch_apr.c:350
void * switch_core_session_get_private_class(switch_core_session_t *session, switch_pvt_class_t index)
#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:631
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:204
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:181
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:295
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:211
static const char * message_names[]
Abstraction of an module endpoint interface This is the glue between the abstract idea of a "channel"...
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:772
const char * switch_channel_get_partner_uuid(switch_channel_t *channel)
int switch_core_test_flag(int flag)
Definition: switch_core.c:1800
#define switch_core_hash_init(_hash)
Definition: switch_core.h:1390
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:550
void switch_channel_flush_dtmf(_In_ switch_channel_t *channel)
switch_queue_t * thread_queue
#define MESSAGE_STRING_ARG_MAX
Definition: switch_core.h:175
switch_status_t switch_queue_pop_timeout(switch_queue_t *queue, void **data, switch_interval_time_t timeout)
Definition: switch_apr.c:1124
switch_call_direction_t
Definition: switch_types.h:293
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:94
switch_pvt_class_t
Definition: switch_types.h:248
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:405
switch_mutex_t * switch_core_session_get_mutex(switch_core_session_t *session)
Signal a session'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:729
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.
Node in which to store custom receive message callback hooks.
void switch_core_session_init(switch_memory_pool_t *pool)
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:660
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:640
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:262
#define switch_channel_ready(_channel)
switch_io_routines_t * io_routines
switch_core_session_t * switch_core_session_request_xml(switch_endpoint_interface_t *endpoint_interface, switch_memory_pool_t **pool, switch_xml_t xml)
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:1140
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:273
void switch_channel_set_caller_profile(switch_channel_t *channel, switch_caller_profile_t *caller_profile)
Set the given channel's caller profile.
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)
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:360
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:969
A representation of an XML tree.
Definition: switch_xml.h:76
switch_memory_pool_t * pool
Definition: switch_core.h:69
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:209
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:325
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_ivr_media(const char *uuid, switch_media_flag_t flags)
Signal a session to request direct media access to it's remote end.
Definition: switch_ivr.c:1674
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:279
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:64
static int switch_true(const char *expr)
Evaluate the truthfullness of a string expression.
Definition: switch_utils.h:450
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_BEGIN_EXTERN_C int switch_status_is_timeup(int status)
Definition: switch_apr.c:72
A message object designed to allow unlike technologies to exchange data.
Definition: switch_core.h:177
void switch_channel_set_origination_caller_profile(switch_channel_t *channel, switch_caller_profile_t *caller_profile)
Set the given channel'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:225
#define SWITCH_ORIGINATE_SIGNAL_BOND_VARIABLE
Definition: switch_types.h:203
#define zstr(x)
Definition: switch_utils.h:281
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'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)
char * txt
Definition: switch_xml.h:82
switch_status_t switch_mutex_unlock(switch_mutex_t *lock)
Definition: switch_apr.c:290
#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:1103
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:205
#define switch_clear_flag(obj, flag)
Clear a flag on an arbitrary object while locked.
Definition: switch_utils.h:655
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)
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:655
const switch_codec_implementation_t * implementation
double switch_core_idle_cpu(void)
uint32_t buflen
Definition: switch_frame.h:59
int32_t sessions_peak_fivemin
#define SWITCH_PROCESS_CDR_VARIABLE
Definition: switch_types.h:177
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:908
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_dialplan_hunt_function_t hunt_function
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_mutex_t * video_codec_write_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'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:285
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_alloc(_pool, _mem)
Allocate memory directly from a memory pool.
Definition: switch_core.h:682
uint32_t switch_scheduler_del_task_id(uint32_t task_id)
Delete a scheduled task.
#define switch_channel_get_variable(_c, _v)
#define SWITCH_THREAD_STACKSIZE
Definition: switch_types.h:551
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.
uint32_t switch_core_session_messages_waiting(switch_core_session_t *session)
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:789
switch_status_t switch_thread_rwlock_tryrdlock(switch_thread_rwlock_t *rwlock)
Definition: switch_apr.c:232
switch_thread_start_t func
Definition: switch_core.h:66
struct switch_caller_profile * children
uint32_t switch_core_session_flush_private_events(switch_core_session_t *session)
Flush the private event queue of a session.
static void *SWITCH_THREAD_FUNC switch_core_session_thread_pool_worker(switch_thread_t *thread, void *obj)
switch_status_t switch_channel_pass_sdp(switch_channel_t *from_channel, switch_channel_t *to_channel, const char *sdp)
void switch_console_push_match(switch_console_callback_match_t **matches, const char *new_val)
switch_status_t switch_mutex_init(switch_mutex_t **lock, unsigned int flags, switch_memory_pool_t *pool)
Definition: switch_apr.c:270
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:206
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)
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:132
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:125
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:809
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:797
void switch_channel_set_originator_caller_profile(switch_channel_t *channel, switch_caller_profile_t *caller_profile)
Set the given channel'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:1602
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:638
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:131
double switch_core_min_idle_cpu(double new_limit)
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
void * switch_core_hash_delete(_In_ switch_hash_t *hash, _In_z_ const char *key)
Delete data from a hash based on desired key.
#define switch_core_session_receive_message(_session, _message)
Definition: switch_core.h:1217
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
apr_pool_t * pool
Definition: switch_apr.c:626
#define switch_str_nil(s)
Make a null string a blank string instead.
Definition: switch_utils.h:903
#define SWITCH_CORE_SESSION_MAX_PRIVATES
Definition: switch_types.h:232
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:371
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:88
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's state machine.
void switch_uuid_format(char *buffer, const switch_uuid_t *uuid)
Definition: switch_apr.c:1055
#define switch_channel_expand_variables(_channel, _in)
#define SWITCH_R_SDP_VARIABLE
Definition: switch_types.h:196
switch_mutex_t * video_codec_read_mutex
switch_queue_t * private_event_queue_pri
switch_status_t switch_core_session_request_video_refresh(switch_core_session_t *session)
struct switch_io_event_hook_state_change * next
static const char * ep
Definition: switch_json.c:36
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
struct apr_thread_mutex_t switch_mutex_t
Definition: switch_apr.h:314
switch_memory_pool_t * pool
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:256
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's registered name.
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'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.
uint8_t enc_read_buf[SWITCH_RECOMMENDED_BUFFER_SIZE]
#define SWITCH_SIGNAL_BOND_VARIABLE
Definition: switch_types.h:202
#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's originatee caller profile.
void *SWITCH_THREAD_FUNC * switch_thread_start_t(switch_thread_t *, void *)
Definition: switch_apr.h:950
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:1410
struct apr_thread_t switch_thread_t
Definition: switch_apr.h:941
#define switch_core_session_locate(uuid_str)
Locate a session based on it's uuid.
Definition: switch_core.h:916
Main Library Header.
#define switch_core_media_bug_remove_all(_s)
Definition: switch_core.h:404
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:383
switch_bool_t switch_core_ready_outbound(void)
Determines if the core is ready to place outbound calls.
Definition: switch_core.c:2872
#define SWITCH_DECLARE(type)
switch_frame_t enc_write_frame
void switch_uuid_get(switch_uuid_t *uuid)
Definition: switch_apr.c:1067
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_call_direction_t switch_channel_direction(switch_channel_t *channel)
#define switch_set_string(_dst, _src)
Definition: switch_utils.h:665
switch_status_t switch_queue_trypush(switch_queue_t *queue, void *data)
Definition: switch_apr.c:1155
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)
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:321
const char * caller_id_number
Definition: switch_caller.h:81
switch_status_t switch_queue_term(switch_queue_t *queue)
Definition: switch_apr.c:1150
#define switch_core_session_alloc(_session, _memory)
Allocate memory from a session's pool.
Definition: switch_core.h:694
switch_status_t switch_queue_push(switch_queue_t *queue, void *data)
Definition: switch_apr.c:1129
struct apr_pool_t switch_memory_pool_t
switch_status_t switch_thread_rwlock_create(switch_thread_rwlock_t **rwlock, switch_memory_pool_t *pool)
Definition: switch_apr.c:212
#define switch_test_flag(obj, flag)
Test for the existance of a flag on an arbitary object.
Definition: switch_utils.h:624
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:140
switch_status_t switch_threadattr_create(switch_threadattr_t **new_attr, switch_memory_pool_t *pool)
Definition: switch_apr.c:642
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:675
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
#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:1109
#define switch_core_session_strdup(_session, _todup)
Copy a string using memory allocation from a session's pool.
Definition: switch_core.h:717
switch_thread_id_t switch_thread_self(void)
Definition: switch_apr.c:79
switch_status_t switch_ivr_deactivate_unicast(switch_core_session_t *session)
Definition: switch_ivr.c:365
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_thread_id_t thread_id
void switch_ivr_dmachine_destroy(switch_ivr_dmachine_t **dmachine)
#define switch_assert(expr)
#define SWITCH_MAX_FORWARDS_VARIABLE
Definition: switch_types.h:223
#define switch_channel_set_variable(_channel, _var, _val)
switch_mutex_t * mutex
switch_time_t switch_time_now(void)
Definition: switch_apr.c:302
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'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's caller profile.
#define switch_core_session_kill_channel(session, sig)
Send a signal to a channel.
Definition: switch_core.h:1352
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:2867
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:1501
switch_bool_t switch_core_ready(void)
Determines if the core is ready to take calls.
Definition: switch_core.c:2862
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.
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.
#define SWITCH_SIZE_T_FMT
switch_time_t progress_media
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_outgoing_channel_hook_t outgoing_channel
struct switch_app_log * next
Definition: switch_core.h:62
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
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:665