From a7cb1e7eeaf5d463e424094cd7d1f8abf3b50a03 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 12 Jan 2006 17:51:08 +0000 Subject: [PATCH] update git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@321 d0543943-73ff-0310-b7d9-9358b9ac24b2 --- libs/iax/src/iax-client.h | 1 + libs/iax/src/iax.c | 11 ++++ libs/iax/src/iax2-parser.c | 2 + libs/iax/src/iax2.h | 1 + src/mod/endpoints/mod_iaxchan/mod_iaxchan.c | 63 ++++++++++++++++++--- 5 files changed, 69 insertions(+), 9 deletions(-) diff --git a/libs/iax/src/iax-client.h b/libs/iax/src/iax-client.h index a50e70c80f..c3199f6679 100644 --- a/libs/iax/src/iax-client.h +++ b/libs/iax/src/iax-client.h @@ -227,6 +227,7 @@ extern void iax_pref_codec_del(struct iax_session *session, unsigned int format) extern int iax_pref_codec_get(struct iax_session *session, unsigned int *array, int len); extern char *iax_get_peer_ip(struct iax_session *session); extern char *iax_event_get_apparent_ip(struct iax_event *event); +extern void iax_set_samplerate(struct iax_session *session, unsigned short samplemask); #if defined(__cplusplus) } diff --git a/libs/iax/src/iax.c b/libs/iax/src/iax.c index ae101b824c..e4490b737e 100644 --- a/libs/iax/src/iax.c +++ b/libs/iax/src/iax.c @@ -253,6 +253,7 @@ struct iax_session { #endif struct iax_netstat remote_netstats; + unsigned short samplemask; /* For linking if there are multiple connections */ struct iax_session *next; }; @@ -1880,6 +1881,12 @@ int iax_pref_codec_get(struct iax_session *session, unsigned int *array, int len return x; } +void iax_set_samplerate(struct iax_session *session, unsigned short samplemask) +{ + session->samplemask = samplemask; +} + + int iax_call(struct iax_session *session, char *cidnum, char *cidname, char *ich, char *lang, int wait, int formats, int capabilities) { char tmp[256]=""; @@ -1898,7 +1905,11 @@ int iax_call(struct iax_session *session, char *cidnum, char *cidname, char *ich } memset(&ied, 0, sizeof(ied)); strncpy(tmp, ich, sizeof(tmp) - 1); + iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION); + if (session->samplemask) { + iax_ie_append_short(&ied, IAX_IE_SAMPLINGRATE, session->samplemask); + } if (cidnum) iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, (unsigned char *) cidnum); if (cidname) diff --git a/libs/iax/src/iax2-parser.c b/libs/iax/src/iax2-parser.c index eaaad16eac..378907dda4 100644 --- a/libs/iax/src/iax2-parser.c +++ b/libs/iax/src/iax2-parser.c @@ -143,6 +143,8 @@ static void dump_samprate(char *output, int maxlen, void *value, int len) strcat(tmp, ",11.025khz"); if (sr & IAX_RATE_16KHZ) strcat(tmp, ",16khz"); + if (sr & IAX_RATE_32KHZ) + strcat(tmp, ",32khz"); if (sr & IAX_RATE_22KHZ) strcat(tmp, ",22.05khz"); if (sr & IAX_RATE_44KHZ) diff --git a/libs/iax/src/iax2.h b/libs/iax/src/iax2.h index c06da16436..cd212f60db 100644 --- a/libs/iax/src/iax2.h +++ b/libs/iax/src/iax2.h @@ -143,6 +143,7 @@ #define IAX_RATE_22KHZ (1 << 3) /* 22.05khz sampling */ #define IAX_RATE_44KHZ (1 << 4) /* 44.1khz sampling */ #define IAX_RATE_48KHZ (1 << 5) /* 48khz sampling */ +#define IAX_RATE_32KHZ (1 << 6) /* 32khz sampling */ #define IAX_DPSTATUS_EXISTS (1 << 0) #define IAX_DPSTATUS_CANEXIST (1 << 1) diff --git a/src/mod/endpoints/mod_iaxchan/mod_iaxchan.c b/src/mod/endpoints/mod_iaxchan/mod_iaxchan.c index 6a4deb9fe4..b082a93ec2 100644 --- a/src/mod/endpoints/mod_iaxchan/mod_iaxchan.c +++ b/src/mod/endpoints/mod_iaxchan/mod_iaxchan.c @@ -69,6 +69,9 @@ static struct { char *codec_string; char *codec_order[SWITCH_MAX_CODECS]; int codec_order_last; + char *codec_rates_string; + char *codec_rates[SWITCH_MAX_CODECS]; + int codec_rates_last; unsigned int flags; } globals; @@ -89,6 +92,7 @@ struct private_object { SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_dialplan, globals.dialplan) SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_codec_string, globals.codec_string) +SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_codec_rates_string, globals.codec_rates_string) static char *IAXNAMES[] = {"IAX_EVENT_CONNECT","IAX_EVENT_ACCEPT","IAX_EVENT_HANGUP","IAX_EVENT_REJECT","IAX_EVENT_VOICE", @@ -161,7 +165,7 @@ typedef enum { IAX_QUERY = 2 } iax_io_t; -static switch_status iax_set_codec(struct private_object *tech_pvt, struct iax_session *iax_session, unsigned int *format, unsigned int *cababilities, iax_io_t io) +static switch_status iax_set_codec(struct private_object *tech_pvt, struct iax_session *iax_session, unsigned int *format, unsigned int *cababilities, unsigned short *samprate, iax_io_t io) { char *dname = NULL; //int rate = 8000; @@ -205,6 +209,40 @@ static switch_status iax_set_codec(struct private_object *tech_pvt, struct iax_s chosen = leading; *format = chosen; *cababilities = local_cap; + if (globals.codec_rates_last) { + int x; + unsigned short samples = 0; + + for (x = 0; x < globals.codec_rates_last; x++) { + int rate = atoi(globals.codec_rates[x]); + switch (rate) { + case 8: + samples |= IAX_RATE_8KHZ; + break; + case 16: + samples |= IAX_RATE_16KHZ; + break; + case 22: + samples |= IAX_RATE_22KHZ; + break; + case 32: + samples |= IAX_RATE_32KHZ; + break; + case 44: + samples |= IAX_RATE_44KHZ; + break; + case 48: + samples |= IAX_RATE_48KHZ; + break; + default: + switch_console_printf(SWITCH_CHANNEL_CONSOLE, "I don't know rate %d\n", rate); + break; + } + } + if (samples) { + *samprate = samples; + } + } return SWITCH_STATUS_SUCCESS; } else if (switch_test_flag(&globals, GFLAG_MY_CODEC_PREFS) && (leading & mixed_cap)) { chosen = leading; @@ -489,6 +527,7 @@ static switch_status channel_outgoing_channel(switch_core_session *session, swit switch_channel *channel; switch_caller_profile *caller_profile; unsigned int req = 0, cap = 0; + unsigned short samprate = 0; switch_core_session_add_stream(*new_session, NULL); if ((tech_pvt = (struct private_object *) switch_core_session_alloc(*new_session, sizeof(struct private_object)))) { @@ -521,12 +560,14 @@ static switch_status channel_outgoing_channel(switch_core_session *session, swit } - if (iax_set_codec(tech_pvt, tech_pvt->iax_session, &req, &cap, IAX_QUERY) != SWITCH_STATUS_SUCCESS) { + if (iax_set_codec(tech_pvt, tech_pvt->iax_session, &req, &cap, &samprate, IAX_QUERY) != SWITCH_STATUS_SUCCESS) { switch_core_session_destroy(new_session); return SWITCH_STATUS_GENERR; } - + if (samprate) { + iax_set_samplerate(tech_pvt->iax_session, samprate); + } iax_call(tech_pvt->iax_session, caller_profile->caller_id_number, @@ -747,6 +788,9 @@ static switch_status load_config(void) } else if (!strcmp(var, "codec_prefs")) { set_global_codec_string(val); globals.codec_order_last = switch_separate_string(globals.codec_string, ',', globals.codec_order, SWITCH_MAX_CODECS); + } else if (!strcmp(var, "codec_rates")) { + set_global_codec_rates_string(val); + globals.codec_rates_last = switch_separate_string(globals.codec_rates_string, ',', globals.codec_rates, SWITCH_MAX_CODECS); } } } @@ -819,7 +863,7 @@ SWITCH_MOD_DECLARE(switch_status) switch_module_runtime(void) unsigned int cap = iax_session_get_capability(iaxevent->session); unsigned int format = iaxevent->ies.format; - if (iax_set_codec(tech_pvt, iaxevent->session, &format, &cap, IAX_SET) != SWITCH_STATUS_SUCCESS) { + if (iax_set_codec(tech_pvt, iaxevent->session, &format, &cap, &iaxevent->ies.samprate, IAX_SET) != SWITCH_STATUS_SUCCESS) { switch_console_printf(SWITCH_CHANNEL_CONSOLE, "WTF? %d %d\n",iaxevent->ies.format, iaxevent->ies.capability); } } @@ -890,11 +934,12 @@ SWITCH_MOD_DECLARE(switch_status) switch_module_runtime(void) } if (iax_set_codec(tech_pvt, iaxevent->session, - &iaxevent->ies.format, - &iaxevent->ies.capability, - IAX_SET) != SWITCH_STATUS_SUCCESS) { - iax_reject(iaxevent->session, "Codec Error!"); - switch_core_session_destroy(&session); + &iaxevent->ies.format, + &iaxevent->ies.capability, + &iaxevent->ies.samprate, + IAX_SET) != SWITCH_STATUS_SUCCESS) { + iax_reject(iaxevent->session, "Codec Error!"); + switch_core_session_destroy(&session); } else { tech_pvt->iax_session = iaxevent->session; tech_pvt->session = session;