diff --git a/src/mod/endpoints/mod_exosip/Makefile b/src/mod/endpoints/mod_exosip/Makefile index 9823dd718a..4f1edb15eb 100644 --- a/src/mod/endpoints/mod_exosip/Makefile +++ b/src/mod/endpoints/mod_exosip/Makefile @@ -1,13 +1,13 @@ -#CFLAGS += -I/usr/src/common/src +CFLAGS += -I. LDFLAGS += -leXosip2 -ljrtp - +OBJS=osip_rfc3264.o ifeq ($(OSARCH),Darwin) LINKER=g++ else LINKER=$(CC) endif -all: depends $(MODNAME).$(DYNAMIC_LIB_EXTEN) +all: depends $(OBJS) $(MODNAME).$(DYNAMIC_LIB_EXTEN) depends: MAKE=$(MAKE) $(BASE)/build/buildlib.sh $(BASE) install jrtplib --prefix=$(PREFIX) --disable-gst @@ -15,9 +15,12 @@ depends: MAKE=$(MAKE) $(BASE)/build/buildlib.sh $(BASE) install libeXosip2-2.2.2.tar.gz --disable-josua --prefix=$(PREFIX) +%.o: %.c + $(CC) -fPIC $(CFLAGS) -c -o $@ $< + $(MODNAME).$(DYNAMIC_LIB_EXTEN): $(MODNAME).c $(CC) $(CFLAGS) -fPIC -c $(MODNAME).c -o $(MODNAME).o - $(LINKER) $(SOLINK) -o $(MODNAME).$(DYNAMIC_LIB_EXTEN) $(MODNAME).o $(LDFLAGS) + $(LINKER) $(SOLINK) -o $(MODNAME).$(DYNAMIC_LIB_EXTEN) $(OBJS) $(MODNAME).o $(LDFLAGS) clean: rm -fr *.$(DYNAMIC_LIB_EXTEN) *.o *~ diff --git a/src/mod/endpoints/mod_exosip/mod_exosip.c b/src/mod/endpoints/mod_exosip/mod_exosip.c index 4784dbe619..cd8f1856cc 100644 --- a/src/mod/endpoints/mod_exosip/mod_exosip.c +++ b/src/mod/endpoints/mod_exosip/mod_exosip.c @@ -35,8 +35,9 @@ #include #include #include -#include +#include #include +#define ENABLE_TRACE static const char modname[] = "mod_exosip"; #define STRLEN 15 @@ -951,6 +952,9 @@ SWITCH_MOD_DECLARE(switch_status) switch_module_load(const switch_loadable_modul { /* NOTE: **interface is **_interface because the common lib redefines interface to struct in some situations */ + + osip_trace_initialize(10, stdout); + if (switch_core_new_memory_pool(&module_pool) != SWITCH_STATUS_SUCCESS) { switch_console_printf(SWITCH_CHANNEL_CONSOLE, "OH OH no pool\n"); return SWITCH_STATUS_TERM; diff --git a/src/mod/endpoints/mod_exosip/osip_rfc3264.c b/src/mod/endpoints/mod_exosip/osip_rfc3264.c new file mode 100644 index 0000000000..62c0c711d6 --- /dev/null +++ b/src/mod/endpoints/mod_exosip/osip_rfc3264.c @@ -0,0 +1,1092 @@ +/* + The oSIP library implements the Session Initiation Protocol (SIP -rfc3261-) + Copyright (C) 2001,2002,2003,2004,2005 Aymeric MOIZARD jack@atosc.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include + +#include +#include +#include /* internal include */ + +/** + * Initialize negotiation facility.. + * @param config The element to work on. + */ +int +osip_rfc3264_init (struct osip_rfc3264 **config) +{ + osip_rfc3264_t *cnf; + + *config = NULL; + cnf = (osip_rfc3264_t *) osip_malloc (sizeof (osip_rfc3264_t)); + if (cnf == NULL) + return -1; + memset (cnf, 0, sizeof (osip_rfc3264_t)); + *config = cnf; + return 0; +} + + +/** + * Free negotiation facility. + * @param config The element to work on. + */ +void +osip_rfc3264_free (struct osip_rfc3264 *config) +{ + osip_rfc3264_t *cnf = (osip_rfc3264_t *) config; + int i; + + if (config == NULL) + return; + + for (i = 0; i < MAX_AUDIO_CODECS; i++) + { + if (cnf->audio_medias[i] != NULL) + { + sdp_media_free (cnf->audio_medias[i]); + cnf->audio_medias[i] = NULL; + } + } + for (i = 0; i < MAX_VIDEO_CODECS; i++) + { + if (cnf->video_medias[i] != NULL) + { + sdp_media_free (cnf->video_medias[i]); + cnf->video_medias[i] = NULL; + } + } + for (i = 0; i < MAX_T38_CODECS; i++) + { + if (cnf->t38_medias[i] != NULL) + { + sdp_media_free (cnf->t38_medias[i]); + cnf->t38_medias[i] = NULL; + } + } + for (i = 0; i < MAX_APP_CODECS; i++) + { + if (cnf->app_medias[i] != NULL) + { + sdp_media_free (cnf->app_medias[i]); + cnf->app_medias[i] = NULL; + } + } + osip_free (cnf); +} + + +/** + * Test if a media exist in the configuration. + * @param config The element to work on. + * @param pos The index of the media element. + */ +int +osip_rfc3264_endof_media (struct osip_rfc3264 *config, int pos) +{ + if (config == NULL) + return -1; + + return 0; +} + + +/** + * Get a media from the configuration. + * @param config The element to work on. + * @param pos The index of the media element to get. + */ +sdp_media_t * +osip_rfc3264_get (struct osip_rfc3264 * config, int pos) +{ + if (config == NULL) + return NULL; + + return NULL; +} + + +/** + * Remove a media from the configuration. + * @param config The element to work on. + * @param pos The index of the media element to remove. + */ +int +osip_rfc3264_remove (struct osip_rfc3264 *config, int pos) +{ + if (config == NULL) + return -1; + + return 0; +} + + +/** + * Remove all medias from the configuration. + * @param config The element to work on. + */ +int +osip_rfc3264_reset_media (struct osip_rfc3264 *config) +{ + if (config == NULL) + return -1; + + return 0; +} + + +/** + * Add a media (for audio) in the configuration. + * @param config The element to work on. + * @param med The media element to add. + * @param pos The index of the media element to add. + */ +int +osip_rfc3264_add_audio_media (struct osip_rfc3264 *config, sdp_media_t * med, + int pos) +{ + osip_rfc3264_t *cnf = (osip_rfc3264_t *) config; + + if (config == NULL) + return -1; + if (pos >= MAX_AUDIO_CODECS) + return -1; + + if (pos == -1) + { + for (pos = 0; pos < MAX_AUDIO_CODECS && cnf->audio_medias[pos] != NULL; + pos++) + { + } + } + if (pos >= MAX_AUDIO_CODECS) + return -1; /* no space left */ + + cnf->audio_medias[pos] = med; + return 0; +} + + +/** + * Remove a media in the configuration. + * @param config The element to work on. + * @param pos The index of the media element to remove. + */ +int +osip_rfc3264_del_audio_media (struct osip_rfc3264 *config, int pos) +{ + osip_rfc3264_t *cnf = (osip_rfc3264_t *) config; + + if (config == NULL) + return -1; + if (pos >= MAX_AUDIO_CODECS) + return -1; + sdp_media_free (cnf->audio_medias[pos]); + cnf->audio_medias[pos] = NULL; + return 0; +} + +/** + * Add a media (for video) in the configuration. + * @param config The element to work on. + * @param med The media element to add. + * @param pos The index of the media element to add. + */ +int +osip_rfc3264_add_video_media (struct osip_rfc3264 *config, sdp_media_t * med, + int pos) +{ + osip_rfc3264_t *cnf = (osip_rfc3264_t *) config; + + if (config == NULL) + return -1; + if (pos >= MAX_VIDEO_CODECS) + return -1; + + if (pos == -1) + { + for (pos = 0; pos < MAX_VIDEO_CODECS && cnf->video_medias[pos] != NULL; + pos++) + { + } + } + if (pos >= MAX_VIDEO_CODECS) + return -1; /* no space left */ + + cnf->video_medias[pos] = med; + return 0; +} + + +/** + * Remove a media in the configuration. + * @param config The element to work on. + * @param pos The index of the media element to remove. + */ +int +osip_rfc3264_del_video_media (struct osip_rfc3264 *config, int pos) +{ + osip_rfc3264_t *cnf = (osip_rfc3264_t *) config; + + if (config == NULL) + return -1; + if (pos >= MAX_VIDEO_CODECS) + return -1; + sdp_media_free (cnf->video_medias[pos]); + cnf->video_medias[pos] = NULL; + return 0; +} + +/** + * Add a media (for t38) in the configuration. + * @param config The element to work on. + * @param med The media element to add. + * @param pos The index of the media element to add. + */ +int +osip_rfc3264_add_t38_media (struct osip_rfc3264 *config, sdp_media_t * med, + int pos) +{ + osip_rfc3264_t *cnf = (osip_rfc3264_t *) config; + + if (config == NULL) + return -1; + if (pos >= MAX_T38_CODECS) + return -1; + + if (pos == -1) + { + for (pos = 0; pos < MAX_T38_CODECS && cnf->t38_medias[pos] != NULL; pos++) + { + } + } + if (pos >= MAX_T38_CODECS) + return -1; /* no space left */ + + cnf->t38_medias[pos] = med; + return 0; +} + + +/** + * Remove a media in the configuration. + * @param config The element to work on. + * @param pos The index of the media element to remove. + */ +int +osip_rfc3264_del_t38_media (struct osip_rfc3264 *config, int pos) +{ + osip_rfc3264_t *cnf = (osip_rfc3264_t *) config; + + if (config == NULL) + return -1; + if (pos >= MAX_T38_CODECS) + return -1; + sdp_media_free (cnf->t38_medias[pos]); + cnf->t38_medias[pos] = NULL; + return 0; +} + +/** + * Search for support of a special codec. + * @param config The element to work on. + * @param payload The payload to find. + * @param rtpmap The rtpmap for the payload. + */ +sdp_media_t * +osip_rfc3264_find_audio (struct osip_rfc3264 * config, char *payload, char *rtpmap) +{ + osip_rfc3264_t *cnf = (osip_rfc3264_t *) config; + int i; + + if (config == NULL) + return NULL; + + if (rtpmap == NULL) + { + for (i = 0; i < MAX_AUDIO_CODECS; i++) + { + if (cnf->audio_medias[i] != NULL) + { + sdp_media_t *med = cnf->audio_medias[i]; + char *str = (char *) osip_list_get (med->m_payloads, 0); + + /* static payload?: only compare payload number */ + if (strlen (str) == strlen (payload) + && 0 == osip_strcasecmp (str, payload)) + return med; + } + } + return NULL; + } + + for (i = 0; i < MAX_AUDIO_CODECS; i++) + { + if (cnf->audio_medias[i] != NULL) + { + sdp_media_t *med = cnf->audio_medias[i]; + + int pos = 0; + + while (!osip_list_eol (med->a_attributes, pos)) + { + sdp_attribute_t *attr = + (sdp_attribute_t *) osip_list_get (med->a_attributes, pos); + + if (0 == osip_strcasecmp ("rtpmap", attr->a_att_field) + && attr->a_att_value != NULL) + { + char *tmp = strchr (attr->a_att_value, ' '); + char *tmp2 = strchr (rtpmap, ' '); + + if (tmp != NULL && tmp2 != NULL) + { + if (0 == osip_strcasecmp (tmp, tmp2)) + return med; + } + } + pos++; + } + } + } + + return NULL; +} + +/** + * Search for support of a special codec. + * @param config The element to work on. + * @param payload The payload to find. + * @param rtpmap The rtpmap for the payload. + */ +sdp_media_t * +osip_rfc3264_find_video (struct osip_rfc3264 * config, char *payload, char *rtpmap) +{ + osip_rfc3264_t *cnf = (osip_rfc3264_t *) config; + int i; + + if (config == NULL) + return NULL; + + if (rtpmap == NULL) + { + for (i = 0; i < MAX_VIDEO_CODECS; i++) + { + if (cnf->video_medias[i] != NULL) + { + sdp_media_t *med = cnf->video_medias[i]; + char *str = (char *) osip_list_get (med->m_payloads, 0); + + /* static payload?: only compare payload number */ + if (strlen (str) == strlen (payload) + && 0 == osip_strcasecmp (str, payload)) + return med; + } + } + return NULL; + } + + for (i = 0; i < MAX_VIDEO_CODECS; i++) + { + if (cnf->video_medias[i] != NULL) + { + sdp_media_t *med = cnf->video_medias[i]; + + int pos = 0; + + while (!osip_list_eol (med->a_attributes, pos)) + { + sdp_attribute_t *attr = + (sdp_attribute_t *) osip_list_get (med->a_attributes, pos); + + if (0 == osip_strcasecmp ("rtpmap", attr->a_att_field) + && attr->a_att_value != NULL) + { + char *tmp = strchr (attr->a_att_value, ' '); + char *tmp2 = strchr (rtpmap, ' '); + + if (tmp != NULL && tmp2 != NULL) + { + if (0 == osip_strcasecmp (tmp, tmp2)) + return med; + } + } + pos++; + } + } + } + + return NULL; +} + +/** + * Search for support of a special codec. + * @param config The element to work on. + * @param payload The payload to find. + */ +sdp_media_t * +osip_rfc3264_find_t38 (struct osip_rfc3264 * config, char *payload) +{ + //osip_rfc3264_t *cnf = (osip_rfc3264_t *) config; + + if (config == NULL) + return NULL; + return NULL; +} + +/** + * Search for support of a special codec. + * @param config The element to work on. + * @param payload The payload to find. + */ +sdp_media_t * +osip_rfc3264_find_app (struct osip_rfc3264 * config, char *payload) +{ + // osip_rfc3264_t *cnf = (osip_rfc3264_t *) config; + + if (config == NULL) + return NULL; + return NULL; +} + +/** + * Compare remote sdp packet against local supported media. + * Only one media line is checked. + * + * @param config The element to work on. + * @param remote_sdp The remote SDP packet. + * @param audio_tab The local list of media supported by both side. + * @param video_tab The local list of media supported by both side. + * @param t38_tab The local list of media supported by both side. + * @param app_tab The local list of media supported by both side. + * @param pos_media The position of the media line to match. + */ +int +osip_rfc3264_match (struct osip_rfc3264 *config, + sdp_message_t * remote_sdp, + sdp_media_t * audio_tab[], + sdp_media_t * video_tab[], + sdp_media_t * t38_tab[], + sdp_media_t * app_tab[], int pos_media) +{ + sdp_media_t *remote_med; + int pos; + + audio_tab[0] = NULL; + video_tab[0] = NULL; + t38_tab[0] = NULL; + app_tab[0] = NULL; + + if (config == NULL) + return -1; + + pos = 0; + while (!sdp_message_endof_media (remote_sdp, pos)) + { + if (pos_media == 0) + { + remote_med = osip_list_get (remote_sdp->m_medias, pos); + if (remote_med->m_media != NULL + && 0 == osip_strcasecmp (remote_med->m_media, "audio")) + { + osip_rfc3264_match_audio (config, remote_sdp, remote_med, audio_tab); + } else if (remote_med->m_media != NULL + && 0 == osip_strcasecmp (remote_med->m_media, "video")) + { + osip_rfc3264_match_video (config, remote_sdp, remote_med, video_tab); + } else if (remote_med->m_media != NULL + && 0 == osip_strcasecmp (remote_med->m_media, "image")) + { + osip_rfc3264_match_t38 (config, remote_sdp, remote_med, t38_tab); + } else if (remote_med->m_media != NULL + && 0 == osip_strcasecmp (remote_med->m_media, "application")) + { + osip_rfc3264_match_app (config, remote_sdp, remote_med, app_tab); + } + return 0; + } + + remote_med = NULL; + pos++; + pos_media--; + } + + return -1; +} + +/** + * Compare remote sdp packet against local supported media for audio. + * @param config The element to work on. + * @param remote_sdp The remote SDP packet. + * @param remote_med The remote Media SDP line. + * @param audio_tab The local list of media supported by both side. + */ +int +osip_rfc3264_match_audio (struct osip_rfc3264 *config, + sdp_message_t * remote_sdp, + sdp_media_t * remote_med, sdp_media_t * audio_tab[]) +{ + osip_rfc3264_t *cnf = (osip_rfc3264_t *) config; + int num = 0; + int pos; + + audio_tab[0] = NULL; + + if (cnf == NULL) + return -1; + + /* search for the audio media line */ + pos = 0; + while (!osip_list_eol (remote_med->m_payloads, pos)) + { + char *payload = (char *) osip_list_get (remote_med->m_payloads, pos); + sdp_media_t *local_med; + char *rtpmap = NULL; + int posattr = 0; + + /* search for the rtpmap associated to the payload */ + while (!osip_list_eol (remote_med->a_attributes, posattr)) + { + sdp_attribute_t *attr = + (sdp_attribute_t *) osip_list_get (remote_med->a_attributes, + posattr); + + if (0 == osip_strncasecmp (attr->a_att_field, "rtpmap", 6)) + { + if (attr->a_att_value != NULL && + 0 == osip_strncasecmp (attr->a_att_value, payload, + strlen (payload))) + { + /* TODO check if it was not like 101: == 10 */ + rtpmap = attr->a_att_value; + break; + } + } + posattr++; + } + + local_med = osip_rfc3264_find_audio (config, payload, rtpmap); + if (local_med != NULL) + { + /* found a supported codec? */ + audio_tab[num] = local_med; + num++; + } + + /* search for support of this codec in local media list */ + pos++; + } + + audio_tab[num] = NULL; + return 0; +} + +/** + * Compare remote sdp packet against local supported media for video. + * @param config The element to work on. + * @param remote_sdp The remote SDP packet. + * @param remote_med The remote Media SDP line. + * @param video_tab The local list of media supported by both side. + */ +int +osip_rfc3264_match_video (struct osip_rfc3264 *config, + sdp_message_t * remote_sdp, + sdp_media_t * remote_med, sdp_media_t * video_tab[]) +{ + osip_rfc3264_t *cnf = (osip_rfc3264_t *) config; + int num = 0; + int pos; + + video_tab[0] = NULL; + + if (cnf == NULL) + return -1; + + /* search for the video media line */ + + pos = 0; + while (!osip_list_eol (remote_med->m_payloads, pos)) + { + char *payload = (char *) osip_list_get (remote_med->m_payloads, pos); + sdp_media_t *local_med; + char *rtpmap = NULL; + int posattr = 0; + + /* search for the rtpmap associated to the payload */ + while (!osip_list_eol (remote_med->a_attributes, posattr)) + { + sdp_attribute_t *attr = + (sdp_attribute_t *) osip_list_get (remote_med->a_attributes, + posattr); + + if (0 == osip_strncasecmp (attr->a_att_field, "rtpmap", 6)) + { + if (attr->a_att_value != NULL && + 0 == osip_strncasecmp (attr->a_att_value, payload, + strlen (payload))) + { + /* TODO check if it was not like 101: == 10 */ + rtpmap = attr->a_att_value; + break; + } + } + posattr++; + } + + local_med = osip_rfc3264_find_video (config, payload, rtpmap); + if (local_med != NULL) + { + /* found a supported codec? */ + video_tab[num] = local_med; + num++; + } + + /* search for support of this codec in local media list */ + pos++; + } + + video_tab[num] = NULL; + return 0; +} + +/** + * Compare remote sdp packet against local supported media for t38. + * @param config The element to work on. + * @param remote_sdp The remote SDP packet. + * @param remote_med The remote Media SDP line. + * @param t38_tab The local list of media supported by both side. + */ +int +osip_rfc3264_match_t38 (struct osip_rfc3264 *config, + sdp_message_t * remote_sdp, + sdp_media_t * remote_med, sdp_media_t * t38_tab[]) +{ + osip_rfc3264_t *cnf = (osip_rfc3264_t *) config; + + t38_tab[0] = NULL; + + if (cnf == NULL) + return -1; + + return 0; +} + +/** + * Compare remote sdp packet against local supported media for application. + * @param config The element to work on. + * @param remote_sdp The remote SDP packet. + * @param remote_med The remote Media SDP line. + * @param app_tab The local list of media supported by both side. + */ +int +osip_rfc3264_match_app (struct osip_rfc3264 *config, + sdp_message_t * remote_sdp, + sdp_media_t * remote_med, sdp_media_t * app_tab[]) +{ + osip_rfc3264_t *cnf = (osip_rfc3264_t *) config; + + app_tab[0] = NULL; + + if (cnf == NULL) + return -1; + + return 0; +} + + +/** + * Prepare an uncomplete answer. + * @param config The element to work on. + * @param remote_sdp The remote SDP packet. + * @param local_sdp The local SDP packet to prepare. + * @param length The local SDP packet's length. + */ +int +osip_rfc3264_prepare_answer (struct osip_rfc3264 *config, + sdp_message_t * remote_sdp, + char *local_sdp, int length) +{ + int pos, pos2; + + if (config == NULL) + return -1; + if (remote_sdp == NULL) + return -1; + + if (osip_list_size (remote_sdp->t_descrs) > 0) + +#if !defined __PALMOS__ && (defined WIN32 || defined _WIN32_WCE) + _snprintf (local_sdp, 4096, "v=0\r\n\ +o=userX 20000001 20000001 IN IP4 TOREPLACE\r\n\ +s=-\r\n\ +c=IN IP4 TOREPLACE\r\n"); +#else + snprintf (local_sdp, 4096, "v=0\r\n\ +o=userX 20000001 20000001 IN IP4 TOREPLACE\r\n\ +s=-\r\n\ +c=IN IP4 TOREPLACE\r\n"); +#endif + /* Fill t= (and r=) fields */ + pos = 0; + while (!osip_list_eol (remote_sdp->t_descrs, pos)) + { + char tmp[100]; + sdp_time_descr_t *td; + + td = (sdp_time_descr_t *) osip_list_get (remote_sdp->t_descrs, pos); + if (td->t_start_time != NULL && td->t_stop_time != NULL) +#if !defined __PALMOS__ && (defined WIN32 || defined _WIN32_WCE) + _snprintf (tmp, 100, "t=%s %s\r\n", td->t_start_time, td->t_stop_time); +#else + snprintf (tmp, 100, "t=%s %s\r\n", td->t_start_time, td->t_stop_time); +#endif + else +#if !defined __PALMOS__ && (defined WIN32 || defined _WIN32_WCE) + _snprintf (tmp, 100, "t=0 0\r\n"); +#else + snprintf (tmp, 100, "t=0 0\r\n"); +#endif + if ((int) (strlen (local_sdp) + strlen (tmp) + 1) < length) + + { + strcat (local_sdp, tmp); + + pos2 = 0; + while (!osip_list_eol (td->r_repeats, pos2)) + { + char *str = (char *) osip_list_get (td->r_repeats, pos2); + + if ((int) (strlen (local_sdp) + strlen (str) + 5 + 1) < length) + { + strcat (local_sdp, "r="); + strcat (local_sdp, str); + strcat (local_sdp, "\r\n"); + } else + return -1; + pos2++; + } + } else + return -1; + pos++; + } + + + pos = 0; + while (!osip_list_eol (remote_sdp->m_medias, pos)) + { + int posattr = 0; + char tmp[200]; + char tmp2[200]; + char inactive = 'X'; + sdp_media_t *med; + +#if !defined __PALMOS__ && (defined WIN32 || defined _WIN32_WCE) + _snprintf (tmp2, 199, "\r\n"); +#else + snprintf (tmp2, 199, "\r\n"); +#endif + med = (sdp_media_t *) osip_list_get (remote_sdp->m_medias, pos); + + /* search for the rtpmap associated to the payload */ + while (!osip_list_eol (med->a_attributes, posattr)) + { + sdp_attribute_t *attr = + (sdp_attribute_t *) osip_list_get (med->a_attributes, posattr); + if (strlen (attr->a_att_field) == 8 && attr->a_att_value == NULL) + { + if (0 == osip_strncasecmp (attr->a_att_field, "sendonly", 8)) + { +#if !defined __PALMOS__ && (defined WIN32 || defined _WIN32_WCE) + _snprintf (tmp2, 199, "\r\na=recvonly\r\n"); +#else + snprintf (tmp2, 199, "\r\na=recvonly\r\n"); +#endif + break; + } else if (0 == osip_strncasecmp (attr->a_att_field, "recvonly", 8)) + { +#if !defined __PALMOS__ && (defined WIN32 || defined _WIN32_WCE) + _snprintf (tmp2, 199, "\r\na=sendonly\r\n"); +#else + snprintf (tmp2, 199, "\r\na=sendonly\r\n"); +#endif + break; + } else if (0 == osip_strncasecmp (attr->a_att_field, "sendrecv", 8)) + { + break; + } else if (0 == osip_strncasecmp (attr->a_att_field, "inactive", 8)) + { +#if !defined __PALMOS__ && (defined WIN32 || defined _WIN32_WCE) + _snprintf (tmp2, 199, "\r\na=inactive\r\n"); +#else + snprintf (tmp2, 199, "\r\na=inactive\r\n"); +#endif + inactive = '0'; + break; + } + } + posattr++; + } + + if (med->m_media != NULL && med->m_proto != NULL + && med->m_number_of_port == NULL) + { +#if !defined __PALMOS__ && (defined WIN32 || defined _WIN32_WCE) + _snprintf (tmp, 199, "m=%s %c %s ", med->m_media, inactive, + med->m_proto); +#else + snprintf (tmp, 199, "m=%s %c %s ", med->m_media, inactive, med->m_proto); +#endif + } else if (med->m_media != NULL && med->m_proto != NULL + && med->m_number_of_port != NULL) + { +#if !defined __PALMOS__ && (defined WIN32 || defined _WIN32_WCE) + _snprintf (tmp, 199, "m=%s %c %s/%s ", med->m_media, inactive, + med->m_proto, med->m_number_of_port); +#else + snprintf (tmp, 199, "m=%s %c %s/%s ", med->m_media, inactive, + med->m_proto, med->m_number_of_port); +#endif + } else + return -1; + + if ((int) (strlen (local_sdp) + strlen (tmp) + 1) < length) + strcat (local_sdp, tmp); + else + return -1; + + if ((int) (strlen (local_sdp) + strlen (tmp2) + 1) < length) + strcat (local_sdp, tmp2); + else + return -1; + + pos++; + } + + return 0; +} + +/** + * Agree to support a specific codec. + * This method should be called for each codec returned by + * osip_rfc3264_match(...) that the calle agree to support. + * + * @param config The element to work on. + * @param remote_sdp The remote SDP packet. + * @param local_sdp The local SDP packet to complete. + * @param med One of the media returned by osip_rfc3264_match. + * @param mline The position of the media line to complete. + */ +int +osip_rfc3264_complete_answer (struct osip_rfc3264 *config, + sdp_message_t * remote_sdp, + sdp_message_t * local_sdp, + sdp_media_t * med, int mline) +{ + osip_rfc3264_t *cnf = (osip_rfc3264_t *) config; + sdp_media_t *remote_med = NULL; + sdp_media_t *local_med = NULL; + int pos; + + if (cnf == NULL) + return -1; + if (remote_sdp == NULL) + return -1; + if (med == NULL) + return -1; + if (mline < 0) + return -1; + if (local_sdp == NULL) + return -1; + pos = 0; + while (!osip_list_eol (remote_sdp->m_medias, pos)) + { + remote_med = (sdp_media_t *) osip_list_get (remote_sdp->m_medias, pos); + local_med = (sdp_media_t *) osip_list_get (local_sdp->m_medias, pos); + if (pos == mline) + break; + remote_med = NULL; + local_med = NULL; + pos++; + } + if (remote_med == NULL) + return -1; + + pos = 0; + while (!osip_list_eol (med->a_attributes, pos)) + { + sdp_attribute_t *attr = + (sdp_attribute_t *) osip_list_get (med->a_attributes, pos); + + if (0 == osip_strcasecmp ("rtpmap", attr->a_att_field) + && attr->a_att_value != NULL) + { + sdp_attribute_t *mattr; + char *tmp; + + /* fill the m= line */ + tmp = (char *) osip_list_get (med->m_payloads, 0); + if (tmp != NULL) + osip_list_add (local_med->m_payloads, osip_strdup (tmp), -1); + else + return -1; + + sdp_attribute_init (&mattr); + mattr->a_att_field = osip_strdup (attr->a_att_field); + mattr->a_att_value = osip_strdup (attr->a_att_value); + + /* fill the a= line */ + osip_list_add (local_med->a_attributes, mattr, -1); + return 0; + } + } + + return -1; /* no rtpmap found? It is mandatory in audio and video media */ +} + +/** + * Agree to support a specific codec. + * This method should be called for each codec returned by + * osip_rfc3264_match(...) + * + * @param config The element to work on. + * @param med One of the media returned by osip_rfc3264_match + * @param remote_sdp The remote SDP packet. + * @param local_sdp The local SDP packet to prepare. + */ +int +osip_rfc3264_accept_codec (struct osip_rfc3264 *config, + sdp_media_t * med, + sdp_message_t * remote_sdp, sdp_message_t * local_sdp) +{ + if (config == NULL) + return -1; + + return 0; +} + + +/* #ifdef RFC3264_DEBUG */ + +/** + * List supported codecs. (for debugging purpose only) + * + * @param config The element to work on. + */ +int +__osip_rfc3264_print_codecs (struct osip_rfc3264 *config) +{ + osip_rfc3264_t *cnf = (osip_rfc3264_t *) config; + int i, pos; + + if (config == NULL) + return -1; + + fprintf (stdout, "Audio codecs Supported:\n"); + for (i = 0; i < MAX_AUDIO_CODECS; i++) + { + if (cnf->audio_medias[i] != NULL) + { + sdp_media_t *med = cnf->audio_medias[i]; + char *str = (char *) osip_list_get (med->m_payloads, 0); + + fprintf (stdout, "\tm=%s %s %s %s\n", + med->m_media, med->m_port, med->m_proto, str); + pos = 0; + while (!osip_list_eol (med->a_attributes, pos)) + { + sdp_attribute_t *attr = + (sdp_attribute_t *) osip_list_get (med->a_attributes, pos); + fprintf (stdout, "\ta=%s:%s\n", + attr->a_att_field, attr->a_att_value); + pos++; + } + fprintf (stdout, "\n"); + } + } + + fprintf (stdout, "Video codecs Supported:\n"); + for (i = 0; i < MAX_VIDEO_CODECS; i++) + { + if (cnf->video_medias[i] != NULL) + { + sdp_media_t *med = cnf->video_medias[i]; + char *str = (char *) osip_list_get (med->m_payloads, 0); + + fprintf (stdout, "\tm=%s %s %s %s\n", + med->m_media, med->m_port, med->m_proto, str); + pos = 0; + while (!osip_list_eol (med->a_attributes, pos)) + { + sdp_attribute_t *attr = + (sdp_attribute_t *) osip_list_get (med->a_attributes, pos); + fprintf (stdout, "\ta=%s:%s\n", + attr->a_att_field, attr->a_att_value); + pos++; + } + fprintf (stdout, "\n"); + } + } + + fprintf (stdout, "t38 configs Supported:\n"); + for (i = 0; i < MAX_T38_CODECS; i++) + { + if (cnf->t38_medias[i] != NULL) + { + sdp_media_t *med = cnf->t38_medias[i]; + + fprintf (stdout, "m=%s %s %s X\n", + med->m_media, med->m_port, med->m_proto); + pos = 0; + while (!osip_list_eol (med->a_attributes, pos)) + { + sdp_attribute_t *attr = + (sdp_attribute_t *) osip_list_get (med->a_attributes, pos); + fprintf (stdout, "\ta=%s:%s\n", + attr->a_att_field, attr->a_att_value); + pos++; + } + fprintf (stdout, "\n"); + } + } + + fprintf (stdout, "Application config Supported:\n"); + for (i = 0; i < MAX_APP_CODECS; i++) + { + if (cnf->app_medias[i] != NULL) + { + sdp_media_t *med = cnf->app_medias[i]; + + fprintf (stdout, "m=%s %s %s X\n", + med->m_media, med->m_port, med->m_proto); + pos = 0; + while (!osip_list_eol (med->a_attributes, pos)) + { + sdp_attribute_t *attr = + (sdp_attribute_t *) osip_list_get (med->a_attributes, pos); + fprintf (stdout, "\ta=%s:%s\n", + attr->a_att_field, attr->a_att_value); + pos++; + } + fprintf (stdout, "\n"); + } + } + + return 0; +} + +/* #endif */ diff --git a/src/mod/endpoints/mod_exosip/osip_rfc3264.h b/src/mod/endpoints/mod_exosip/osip_rfc3264.h new file mode 100644 index 0000000000..957af3a2c7 --- /dev/null +++ b/src/mod/endpoints/mod_exosip/osip_rfc3264.h @@ -0,0 +1,309 @@ +/* + The oSIP library implements the Session Initiation Protocol (SIP -rfc3261-) + Copyright (C) 2001,2002,2003,2004 Aymeric MOIZARD jack@atosc.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef __SDP_RFC3264_H__ +#define __SDP_RFC3264_H__ + +#include +#include + +/** + * @file osip_rfc3264.h + * @brief oSIP sdp negotiation facility. + */ + +/** + * @defgroup oSIP_rfc3264 oSIP sdp negotiation facility. + * @ingroup osip2_sdp + * @{ + */ + +#ifdef __cplusplus +extern "C" +{ +#endif + +/** + * Structure to hold support for codecs. + * @struct osip_rfc3264 + */ + struct osip_rfc3264; + +/** + * Maximum number of supported audio payload. + * @def MAX_AUDIO_CODECS + */ +#define MAX_AUDIO_CODECS 100 +/** + * Maximum number of supported video payload. + * @def MAX_VIDEO_CODECS + */ +#define MAX_VIDEO_CODECS 100 +/** + * Maximum number of supported t38 config. + * @def MAX_T38_CODECS + */ +#define MAX_T38_CODECS 2 +/** + * Maximum number of supported application config. + * @def MAX_APP_CODECS + */ +#define MAX_APP_CODECS 100 + +/** + * Initialize negotiation facility.. + * @param config The element to work on. + */ + int osip_rfc3264_init (struct osip_rfc3264 **config); + +/** + * Free negotiation facility. + * @param config The element to work on. + */ + void osip_rfc3264_free (struct osip_rfc3264 *config); + +/** + * Test if a media exist in the configuration. + * @param config The element to work on. + * @param pos The index of the media element. + */ + int osip_rfc3264_endof_media (struct osip_rfc3264 *config, int pos); + +/** + * Get a media from the configuration. + * @param config The element to work on. + * @param pos The index of the media element to get. + */ + sdp_media_t *osip_rfc3264_get (struct osip_rfc3264 *config, int pos); + +/** + * Remove a media from the configuration. + * @param config The element to work on. + * @param pos The index of the media element to remove. + */ + int osip_rfc3264_remove (struct osip_rfc3264 *config, int pos); + +/** + * Remove all medias from the configuration. + * @param config The element to work on. + */ + int osip_rfc3264_reset_media (struct osip_rfc3264 *config); + +/** + * Add a media in the configuration. + * @param config The element to work on. + * @param med The media element to add. + * @param pos The index of the media element to add. + */ + int osip_rfc3264_add_audio_media (struct osip_rfc3264 *config, + sdp_media_t * med, int pos); + +/** + * Remove a media in the configuration. + * @param config The element to work on. + * @param pos The index of the media element to remove. + */ + int osip_rfc3264_del_audio_media (struct osip_rfc3264 *config, int pos); + +/** + * Add a media (for T.38) in the configuration. + * @param config The element to work on. + * @param med The media element to add. + * @param pos The index of the media element to add. + */ + int osip_rfc3264_add_t38_media (struct osip_rfc3264 *config, + sdp_media_t * med, int pos); + +/** + * Remove a media (for T.38) in the configuration. + * @param config The element to work on. + * @param pos The index of the media element to remove. + */ + int osip_rfc3264_del_t38_media (struct osip_rfc3264 *config, int pos); + +/** + * Add a media (for video) in the configuration. + * @param config The element to work on. + * @param med The media element to add. + * @param pos The index of the media element to add. + */ + int osip_rfc3264_add_video_media (struct osip_rfc3264 *config, + sdp_media_t * med, int pos); + +/** + * Remove a media in the configuration. + * @param config The element to work on. + * @param pos The index of the media element to remove. + */ + int osip_rfc3264_del_video_media (struct osip_rfc3264 *config, int pos); + + +/** + * Search for support of a special codec. + * @param config The element to work on. + */ + sdp_media_t *osip_rfc3264_find_audio (struct osip_rfc3264 *config, + char *payload, char *rtpmap); + +/** + * Search for support of a special codec. + * @param config The element to work on. + * @param payload The payload to find. + * @param rtpmap The rtpmap for the payload. + */ + sdp_media_t *osip_rfc3264_find_video (struct osip_rfc3264 *config, + char *payload, char *rtpmap); + +/** + * Search for support of a special codec. + * @param config The element to work on. + * @param payload The payload to find. + */ + sdp_media_t *osip_rfc3264_find_t38 (struct osip_rfc3264 *config, char *payload); + +/** + * Search for support of a special codec. + * @param config The element to work on. + * @param payload The payload to find. + */ + sdp_media_t *osip_rfc3264_find_app (struct osip_rfc3264 *config, char *payload); + +/** + * Compare remote sdp packet against local supported media. + * Only one media line is checked. + * + * @param config The element to work on. + * @param remote_sdp The remote SDP packet. + * @param audio_tab The local list of media supported by both side. + * @param video_tab The local list of media supported by both side. + * @param t38_tab The local list of media supported by both side. + * @param app_tab The local list of media supported by both side. + * @param pos_media The position of the media line to match. + */ + int osip_rfc3264_match (struct osip_rfc3264 *config, + sdp_message_t * remote_sdp, + sdp_media_t * audio_tab[], + sdp_media_t * video_tab[], + sdp_media_t * t38_tab[], + sdp_media_t * app_tab[], int pos_media); + +/** + * Compare remote sdp packet against local supported media for audio. + * @param config The element to work on. + * @param remote_sdp The remote SDP packet. + * @param remote_med The remote Media SDP line. + * @param audio_tab The local list of media supported by both side. + */ + int osip_rfc3264_match_audio (struct osip_rfc3264 *config, + sdp_message_t * remote_sdp, + sdp_media_t * remote_med, + sdp_media_t * audio_tab[]); + +/** + * Compare remote sdp packet against local supported media for video. + * @param config The element to work on. + * @param remote_sdp The remote SDP packet. + * @param remote_med The remote Media SDP line. + * @param video_tab The local list of media supported by both side. + */ + int osip_rfc3264_match_video (struct osip_rfc3264 *config, + sdp_message_t * remote_sdp, + sdp_media_t * remote_med, + sdp_media_t * video_tab[]); + +/** + * Compare remote sdp packet against local supported media for t38. + * @param config The element to work on. + * @param remote_sdp The remote SDP packet. + * @param remote_med The remote Media SDP line. + * @param t38_tab The local list of media supported by both side. + */ + int osip_rfc3264_match_t38 (struct osip_rfc3264 *config, + sdp_message_t * remote_sdp, + sdp_media_t * remote_med, sdp_media_t * t38_tab[]); + +/** + * Compare remote sdp packet against local supported media for application. + * @param config The element to work on. + * @param remote_sdp The remote SDP packet. + * @param remote_med The remote Media SDP line. + * @param app_tab The local list of media supported by both side. + */ + int osip_rfc3264_match_app (struct osip_rfc3264 *config, + sdp_message_t * remote_sdp, + sdp_media_t * remote_med, sdp_media_t * app_tab[]); + + +/** + * Prepare an uncomplete answer. + * @param config The element to work on. + * @param remote_sdp The remote SDP packet. + * @param local_sdp The local SDP packet to prepare. + * @param length The local SDP packet's length. + */ + int osip_rfc3264_prepare_answer (struct osip_rfc3264 *config, + sdp_message_t * remote_sdp, + char *local_sdp, int length); + +/** + * Agree to support a specific codec. + * This method should be called for each codec returned by + * osip_rfc3264_match(...) that the calle agree to support. + * + * @param config The element to work on. + * @param remote_sdp The remote SDP packet. + * @param local_sdp The local SDP packet to complete. + * @param med One of the media returned by osip_rfc3264_match. + * @param mline The position of the media line to complete. + */ + int + osip_rfc3264_complete_answer (struct osip_rfc3264 *config, + sdp_message_t * remote_sdp, + sdp_message_t * local_sdp, + sdp_media_t * med, int mline); + +/** + * Agree to support a specific codec. + * This method should be called for each codec returned by + * osip_rfc3264_match(...) + * + * @param config The element to work on. + * @param med One of the media returned by osip_rfc3264_match + * @param remote_sdp The remote SDP packet. + * @param local_sdp The local SDP packet to prepare. + */ + int osip_rfc3264_accept_codec (struct osip_rfc3264 *config, + sdp_media_t * med, + sdp_message_t * remote_sdp, + sdp_message_t * local_sdp); + + +/** + * List supported codecs. (for debugging purpose only) + * + * @param config The element to work on. + */ + int __osip_rfc3264_print_codecs (struct osip_rfc3264 *config); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/mod/endpoints/mod_exosip/osip_rfc3264i.h b/src/mod/endpoints/mod_exosip/osip_rfc3264i.h new file mode 100644 index 0000000000..6107cac7ce --- /dev/null +++ b/src/mod/endpoints/mod_exosip/osip_rfc3264i.h @@ -0,0 +1,41 @@ +/* + The oSIP library implements the Session Initiation Protocol (SIP -rfc3261-) + Copyright (C) 2001,2002,2003,2004,2005 Aymeric MOIZARD jack@atosc.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef __SDP_RFC3264I_H__ +#define __SDP_RFC3264I_H__ + +#include +#include +#include + +#ifndef DOXYGEN + +typedef struct osip_rfc3264 osip_rfc3264_t; + +struct osip_rfc3264 +{ + sdp_media_t *audio_medias[MAX_AUDIO_CODECS]; + sdp_media_t *video_medias[MAX_VIDEO_CODECS]; + sdp_media_t *t38_medias[MAX_T38_CODECS]; + sdp_media_t *app_medias[MAX_APP_CODECS]; +}; + +#endif + +#endif diff --git a/src/mod/endpoints/mod_wanpipe/Makefile b/src/mod/endpoints/mod_wanpipe/Makefile index 0b9b876b52..af35732770 100644 --- a/src/mod/endpoints/mod_wanpipe/Makefile +++ b/src/mod/endpoints/mod_wanpipe/Makefile @@ -1,5 +1,5 @@ CFLAGS +=-I/usr/local/include -I/usr/src/libpri -I/usr/src/linux/include -I. -I/usr/include -CFLAGS +=-D__LINUX__ -D_REENTRANT -D_GNU_SOURCE -O6 -march=i686 -DAFT_A104 +CFLAGS +=-D__LINUX__ -D_REENTRANT -D_GNU_SOURCE -DAFT_A104 LDFLAGS += -lsangoma @@ -12,6 +12,7 @@ endif all: depends $(MODNAME).$(DYNAMIC_LIB_EXTEN) depends: + MAKE=$(MAKE) $(BASE)/build/buildlib.sh $(BASE) install libsangoma --prefix=$(PREFIX) $(MODNAME).$(DYNAMIC_LIB_EXTEN): $(MODNAME).c $(CC) $(CFLAGS) -fPIC -c $(MODNAME).c -o $(MODNAME).o diff --git a/src/switch_channel.c b/src/switch_channel.c index b379365857..ea738f4938 100644 --- a/src/switch_channel.c +++ b/src/switch_channel.c @@ -395,7 +395,9 @@ SWITCH_DECLARE(switch_channel_state) switch_channel_set_state(switch_channel *ch switch_console_printf(SWITCH_CHANNEL_CONSOLE, "%s State Change %s -> %s\n", channel->name, state_names[last_state], state_names[state]); channel->state = state; - switch_core_session_signal_state_change(channel->session); + if (state < CS_DONE) { + switch_core_session_signal_state_change(channel->session); + } } else { switch_console_printf(SWITCH_CHANNEL_CONSOLE, "%s Invalid State Change %s -> %s\n", channel->name, state_names[last_state], state_names[state]); @@ -560,6 +562,7 @@ SWITCH_DECLARE(switch_status) switch_channel_hangup(switch_channel *channel) if (channel->state < CS_HANGUP) { channel->times.hungup = switch_time_now(); channel->state = CS_HANGUP; + switch_core_session_kill_channel(channel->session, SWITCH_SIG_KILL); switch_core_session_signal_state_change(channel->session); } return channel->state; diff --git a/src/switch_core.c b/src/switch_core.c index 74f1a5cb00..efe3ae1a7b 100644 --- a/src/switch_core.c +++ b/src/switch_core.c @@ -1723,13 +1723,13 @@ SWITCH_DECLARE(void) switch_core_session_run(switch_core_session *session) switch (state) { case CS_NEW: /* Just created, Waiting for first instructions */ - switch_console_printf(SWITCH_CHANNEL_CONSOLE, "State NEW\n"); + switch_console_printf(SWITCH_CHANNEL_CONSOLE, "(%s) State NEW\n", switch_channel_get_name(session->channel)); break; case CS_DONE: continue; break; case CS_HANGUP: /* Deactivate and end the thread */ - switch_console_printf(SWITCH_CHANNEL_CONSOLE, "State HANGUP\n"); + switch_console_printf(SWITCH_CHANNEL_CONSOLE, "(%s) State HANGUP\n", switch_channel_get_name(session->channel)); if (!driver_state_handler->on_hangup || (driver_state_handler->on_hangup && driver_state_handler->on_hangup(session) == SWITCH_STATUS_SUCCESS && @@ -1768,7 +1768,7 @@ SWITCH_DECLARE(void) switch_core_session_run(switch_core_session *session) midstate = switch_channel_get_state(session->channel); break; case CS_INIT: /* Basic setup tasks */ - switch_console_printf(SWITCH_CHANNEL_CONSOLE, "State INIT\n"); + switch_console_printf(SWITCH_CHANNEL_CONSOLE, "(%s) State INIT\n", switch_channel_get_name(session->channel)); if (!driver_state_handler->on_init || (driver_state_handler->on_init && driver_state_handler->on_init(session) == SWITCH_STATUS_SUCCESS && @@ -1804,7 +1804,7 @@ SWITCH_DECLARE(void) switch_core_session_run(switch_core_session *session) } break; case CS_RING: /* Look for a dialplan and find something to do */ - switch_console_printf(SWITCH_CHANNEL_CONSOLE, "State RING\n"); + switch_console_printf(SWITCH_CHANNEL_CONSOLE, "(%s) State RING\n", switch_channel_get_name(session->channel)); if (!driver_state_handler->on_ring || (driver_state_handler->on_ring && driver_state_handler->on_ring(session) == SWITCH_STATUS_SUCCESS && @@ -1840,7 +1840,7 @@ SWITCH_DECLARE(void) switch_core_session_run(switch_core_session *session) } break; case CS_EXECUTE: /* Execute an Operation */ - switch_console_printf(SWITCH_CHANNEL_CONSOLE, "State EXECUTE\n"); + switch_console_printf(SWITCH_CHANNEL_CONSOLE, "(%s) State EXECUTE\n", switch_channel_get_name(session->channel)); if (!driver_state_handler->on_execute || (driver_state_handler->on_execute && driver_state_handler->on_execute(session) == SWITCH_STATUS_SUCCESS && @@ -1876,7 +1876,7 @@ SWITCH_DECLARE(void) switch_core_session_run(switch_core_session *session) } break; case CS_LOOPBACK: /* loop all data back to source */ - switch_console_printf(SWITCH_CHANNEL_CONSOLE, "State LOOPBACK\n"); + switch_console_printf(SWITCH_CHANNEL_CONSOLE, "(%s) State LOOPBACK\n", switch_channel_get_name(session->channel)); if (!driver_state_handler->on_loopback || (driver_state_handler->on_loopback && driver_state_handler->on_loopback(session) == SWITCH_STATUS_SUCCESS && @@ -1912,7 +1912,7 @@ SWITCH_DECLARE(void) switch_core_session_run(switch_core_session *session) } break; case CS_TRANSMIT: /* send/recieve data to/from another channel */ - switch_console_printf(SWITCH_CHANNEL_CONSOLE, "State TRANSMIT\n"); + switch_console_printf(SWITCH_CHANNEL_CONSOLE, "(%s) State TRANSMIT\n", switch_channel_get_name(session->channel)); if (!driver_state_handler->on_transmit || (driver_state_handler->on_transmit && driver_state_handler->on_transmit(session) == SWITCH_STATUS_SUCCESS && @@ -1957,12 +1957,11 @@ SWITCH_DECLARE(void) switch_core_session_run(switch_core_session *session) laststate = midstate; } - if (state < CS_DONE && midstate == switch_channel_get_state(session->channel)) { switch_thread_cond_wait(session->cond, session->mutex); } - } + session->thread_running = 0; } @@ -2071,9 +2070,8 @@ static void *SWITCH_THREAD_FUNC switch_core_session_thread(switch_thread *thread switch_core_hash_insert(runtime.session_table, session->uuid_str, session); switch_core_session_run(session); switch_core_hash_delete(runtime.session_table, session->uuid_str); + switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Session %ld (%s) Ended\n", id, switch_channel_get_name(session->channel)); switch_core_session_destroy(&session); - switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Session %ld Ended\n", id); - return NULL; }