diff options
Diffstat (limited to 'channels')
41 files changed, 1896 insertions, 674 deletions
diff --git a/channels/Makefile b/channels/Makefile index 242d3f46a..9f6f9d6aa 100644 --- a/channels/Makefile +++ b/channels/Makefile @@ -36,4 +36,3 @@ misdn_config.o: _ASTCFLAGS+=-Imisdn misdn/isdn_lib.o: _ASTCFLAGS+=-Wno-strict-aliasing $(call MOD_ADD_C,chan_oss,console_video.c vgrabbers.c console_board.c) - diff --git a/channels/chan_alsa.c b/channels/chan_alsa.c index c53c1a344..a5dead1a2 100644 --- a/channels/chan_alsa.c +++ b/channels/chan_alsa.c @@ -16,8 +16,8 @@ * at the top of the source tree. */ -/*! \file - * \brief ALSA sound card channel driver +/*! \file + * \brief ALSA sound card channel driver * * \author Matthew Fredrickson <creslin@digium.com> * @@ -39,6 +39,10 @@ #include "asterisk.h" +#include <errno.h> +#ifndef ESTRPIPE +#define ESTRPIPE EPIPE +#endif #include <fcntl.h> #include <sys/ioctl.h> #include <sys/time.h> @@ -127,7 +131,7 @@ static struct chan_alsa_pvt { } alsa; /* Number of buffers... Each is FRAMESIZE/8 ms long. For example - with 160 sample frames, and a buffer size of 3, we have a 60ms buffer, + with 160 sample frames, and a buffer size of 3, we have a 60ms buffer, usually plenty. */ #define MAX_BUFFER_SIZE 100 @@ -295,7 +299,7 @@ static int soundcard_init(void) static int alsa_digit(struct ast_channel *c, char digit, unsigned int duration) { ast_mutex_lock(&alsalock); - ast_verbose(" << Console Received digit %c of duration %u ms >> \n", + ast_verbose(" << Console Received digit %c of duration %u ms >> \n", digit, duration); ast_mutex_unlock(&alsalock); @@ -686,7 +690,7 @@ static char *console_answer(struct ast_cli_entry *e, int cmd, struct ast_cli_arg return NULL; case CLI_GENERATE: - return NULL; + return NULL; } if (a->argc != 2) @@ -732,7 +736,7 @@ static char *console_sendtext(struct ast_cli_entry *e, int cmd, struct ast_cli_a " Sends a text message for display on the remote terminal.\n"; return NULL; case CLI_GENERATE: - return NULL; + return NULL; } if (a->argc < 3) @@ -780,9 +784,9 @@ static char *console_hangup(struct ast_cli_entry *e, int cmd, struct ast_cli_arg " Hangs up any call currently placed on the console.\n"; return NULL; case CLI_GENERATE: - return NULL; + return NULL; } - + if (a->argc != 2) return CLI_SHOWUSAGE; @@ -950,8 +954,8 @@ static int unload_module(void) * Module loading including tests for configuration or dependencies. * This function can return AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_DECLINE, * or AST_MODULE_LOAD_SUCCESS. If a dependency or environment variable fails - * tests return AST_MODULE_LOAD_FAILURE. If the module can not load the - * configuration file or other non-critical problem return + * tests return AST_MODULE_LOAD_FAILURE. If the module can not load the + * configuration file or other non-critical problem return * AST_MODULE_LOAD_DECLINE. On success return AST_MODULE_LOAD_SUCCESS. */ static int load_module(void) diff --git a/channels/chan_console.c b/channels/chan_console.c index a24a6c8af..7692b26cc 100644 --- a/channels/chan_console.c +++ b/channels/chan_console.c @@ -16,9 +16,9 @@ * at the top of the source tree. */ -/*! - * \file - * \brief Cross-platform console channel driver +/*! + * \file + * \brief Cross-platform console channel driver * * \author Russell Bryant <russell@digium.com> * @@ -26,7 +26,7 @@ * chan_oss, Mark Spencer <markster@digium.com> * chan_oss, Luigi Rizzo * chan_alsa, Matthew Fredrickson <creslin@digium.com> - * + * * \ingroup channel_drivers * * Portaudio http://www.portaudio.com/ @@ -77,15 +77,15 @@ #include "asterisk/stasis_channels.h" #include "asterisk/format_cache.h" -/*! - * \brief The sample rate to request from PortAudio +/*! + * \brief The sample rate to request from PortAudio * * \todo Make this optional. If this is only going to talk to 8 kHz endpoints, * then it makes sense to use 8 kHz natively. */ #define SAMPLE_RATE 16000 -/*! +/*! * \brief The number of samples to configure the portaudio stream for * * 320 samples (20 ms) is the most common frame size in Asterisk. So, the code @@ -103,7 +103,7 @@ /*! \brief Mono Output */ #define OUTPUT_CHANNELS 1 -/*! +/*! * \brief Maximum text message length * \note This should be changed if there is a common definition somewhere * that defines the maximum length of a text message. @@ -177,8 +177,8 @@ static struct ao2_container *pvts; static struct console_pvt *active_pvt; AST_RWLOCK_DEFINE_STATIC(active_lock); -/*! - * \brief Global jitterbuffer configuration +/*! + * \brief Global jitterbuffer configuration * * \note Disabled by default. * \note Values shown here match the defaults shown in console.conf.sample @@ -203,7 +203,7 @@ static int console_answer(struct ast_channel *c); static struct ast_frame *console_read(struct ast_channel *chan); static int console_call(struct ast_channel *c, const char *dest, int timeout); static int console_write(struct ast_channel *chan, struct ast_frame *f); -static int console_indicate(struct ast_channel *chan, int cond, +static int console_indicate(struct ast_channel *chan, int cond, const void *data, size_t datalen); static int console_fixup(struct ast_channel *oldchan, struct ast_channel *newchan); /*! @} */ @@ -253,7 +253,7 @@ static struct console_pvt *find_pvt(const char *name) } /*! - * \brief Stream monitor thread + * \brief Stream monitor thread * * \arg data A pointer to the console_pvt structure that contains the portaudio * stream that needs to be monitored. @@ -278,7 +278,9 @@ static void *stream_monitor(void *data) for (;;) { pthread_testcancel(); + console_pvt_lock(pvt); res = Pa_ReadStream(pvt->stream, buf, sizeof(buf) / sizeof(int16_t)); + console_pvt_unlock(pvt); pthread_testcancel(); if (!pvt->owner) { @@ -296,19 +298,19 @@ static int open_stream(struct console_pvt *pvt) { int res = paInternalError; - if (!strcasecmp(pvt->input_device, "default") && + if (!strcasecmp(pvt->input_device, "default") && !strcasecmp(pvt->output_device, "default")) { - res = Pa_OpenDefaultStream(&pvt->stream, INPUT_CHANNELS, OUTPUT_CHANNELS, + res = Pa_OpenDefaultStream(&pvt->stream, INPUT_CHANNELS, OUTPUT_CHANNELS, paInt16, SAMPLE_RATE, NUM_SAMPLES, NULL, NULL); } else { - PaStreamParameters input_params = { + PaStreamParameters input_params = { .channelCount = 1, .sampleFormat = paInt16, .suggestedLatency = (1.0 / 50.0), /* 20 ms */ .device = paNoDevice, }; - PaStreamParameters output_params = { - .channelCount = 1, + PaStreamParameters output_params = { + .channelCount = 1, .sampleFormat = paInt16, .suggestedLatency = (1.0 / 50.0), /* 20 ms */ .device = paNoDevice, @@ -321,10 +323,10 @@ static int open_stream(struct console_pvt *pvt) def_input = Pa_GetDefaultInputDevice(); def_output = Pa_GetDefaultOutputDevice(); - for (idx = 0; - idx < num_devices && (input_params.device == paNoDevice - || output_params.device == paNoDevice); - idx++) + for (idx = 0; + idx < num_devices && (input_params.device == paNoDevice + || output_params.device == paNoDevice); + idx++) { const PaDeviceInfo *dev = Pa_GetDeviceInfo(idx); @@ -428,7 +430,7 @@ static struct ast_channel *console_new(struct console_pvt *pvt, const char *ext, return NULL; } - if (!(chan = ast_channel_alloc(1, state, pvt->cid_num, pvt->cid_name, NULL, + if (!(chan = ast_channel_alloc(1, state, pvt->cid_num, pvt->cid_name, NULL, ext, ctx, assignedids, requestor, 0, "Console/%s", pvt->name))) { ao2_ref(caps, -1); return NULL; @@ -511,7 +513,7 @@ static int console_digit_begin(struct ast_channel *c, char digit) static int console_digit_end(struct ast_channel *c, char digit, unsigned int duration) { - ast_verb(1, V_BEGIN "Console Received End of Digit %c (duration %u)" V_END, + ast_verb(1, V_BEGIN "Console Received End of Digit %c (duration %u)" V_END, digit, duration); return -1; /* non-zero to request inband audio */ @@ -556,7 +558,7 @@ static int console_answer(struct ast_channel *c) * Calling this function is harmless. However, if it does get called, it * is an indication that something weird happened that really shouldn't * have and is worth looking into. - * + * * Why should this function not get called? Well, let me explain. There are * a couple of ways to pass on audio that has come from this channel. The way * that this channel driver uses is that once the audio is available, it is @@ -611,7 +613,9 @@ static int console_write(struct ast_channel *chan, struct ast_frame *f) { struct console_pvt *pvt = ast_channel_tech_pvt(chan); + console_pvt_lock(pvt); Pa_WriteStream(pvt->stream, f->data.ptr, f->samples); + console_pvt_unlock(pvt); return 0; } @@ -644,7 +648,7 @@ static int console_indicate(struct ast_channel *chan, int cond, const void *data ast_moh_stop(chan); break; default: - ast_log(LOG_WARNING, "Don't know how to display condition %d on %s\n", + ast_log(LOG_WARNING, "Don't know how to display condition %d on %s\n", cond, ast_channel_name(chan)); /* The core will play inband indications for us if appropriate */ res = -1; @@ -701,13 +705,13 @@ static struct console_pvt *get_active_pvt(void) struct console_pvt *pvt; ast_rwlock_rdlock(&active_lock); - pvt = ref_pvt(active_pvt); + pvt = ref_pvt(active_pvt); ast_rwlock_unlock(&active_lock); return pvt; } -static char *cli_console_autoanswer(struct ast_cli_entry *e, int cmd, +static char *cli_console_autoanswer(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { struct console_pvt *pvt; @@ -798,7 +802,7 @@ static char *cli_console_flash(struct ast_cli_entry *e, int cmd, struct ast_cli_ static char *cli_console_dial(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { char *s = NULL; - const char *mye = NULL, *myc = NULL; + const char *mye = NULL, *myc = NULL; struct console_pvt *pvt; if (cmd == CLI_INIT) { @@ -845,7 +849,7 @@ static char *cli_console_dial(struct ast_cli_entry *e, int cmd, struct ast_cli_a if (a->argc == e->args + 1) { char *ext = NULL, *con = NULL; s = ast_ext_ctx(pvt, a->argv[e->args], &ext, &con); - ast_debug(1, "provided '%s', exten '%s' context '%s'\n", + ast_debug(1, "provided '%s', exten '%s' context '%s'\n", a->argv[e->args], mye, myc); mye = ext; myc = con; @@ -945,7 +949,7 @@ static char *cli_console_mute(struct ast_cli_entry *e, int cmd, struct ast_cli_a else res = CLI_SHOWUSAGE; - ast_verb(1, V_BEGIN "The Console is now %s" V_END, + ast_verb(1, V_BEGIN "The Console is now %s" V_END, pvt->muted ? "Muted" : "Unmuted"); unref_pvt(pvt); @@ -1233,7 +1237,7 @@ static char *cli_console_active(struct ast_cli_entry *e, int cmd, struct ast_cli return CLI_SUCCESS; } - if (!(pvt = find_pvt(a->argv[e->args - 1]))) { + if (!(pvt = find_pvt(a->argv[e->args]))) { ast_cli(a->fd, "Could not find a device called '%s'.\n", a->argv[e->args]); return CLI_FAILURE; } @@ -1277,7 +1281,7 @@ static void set_pvt_defaults(struct console_pvt *pvt) ast_string_field_set(pvt, cid_num, ""); ast_string_field_set(pvt, cid_name, ""); ast_string_field_set(pvt, parkinglot, ""); - + pvt->overridecontext = 0; pvt->autoanswer = 0; } else { @@ -1303,7 +1307,7 @@ static void store_callerid(struct console_pvt *pvt, const char *value) char cid_name[256]; char cid_num[256]; - ast_callerid_split(value, cid_name, sizeof(cid_name), + ast_callerid_split(value, cid_name, sizeof(cid_name), cid_num, sizeof(cid_num)); ast_string_field_set(pvt, cid_name, cid_name); @@ -1386,7 +1390,7 @@ static void build_device(struct ast_config *cfg, const char *name) ao2_link(pvts, pvt); else console_pvt_unlock(pvt); - + unref_pvt(pvt); } @@ -1442,7 +1446,7 @@ static int load_config(int reload) ast_log(LOG_NOTICE, "Config file %s has an invalid format\n", config_file); return -1; } - + ao2_callback(pvts, OBJ_NODATA, pvt_mark_destroy_cb, NULL); ast_mutex_lock(&globals_lock); @@ -1515,8 +1519,8 @@ static int unload_module(void) * Module loading including tests for configuration or dependencies. * This function can return AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_DECLINE, * or AST_MODULE_LOAD_SUCCESS. If a dependency or environment variable fails - * tests return AST_MODULE_LOAD_FAILURE. If the module can not load the - * configuration file or other non-critical problem return + * tests return AST_MODULE_LOAD_FAILURE. If the module can not load the + * configuration file or other non-critical problem return * AST_MODULE_LOAD_DECLINE. On success return AST_MODULE_LOAD_SUCCESS. */ static int load_module(void) diff --git a/channels/chan_dahdi.c b/channels/chan_dahdi.c index b20a0f33a..37e277432 100644 --- a/channels/chan_dahdi.c +++ b/channels/chan_dahdi.c @@ -8000,7 +8000,7 @@ static struct ast_frame *dahdi_handle_event(struct ast_channel *ast) p->subs[otherindex].needunhold = 1; p->owner = p->subs[SUB_REAL].owner; } else { - ast_verb(3, "Dumping incomplete call on on %s\n", ast_channel_name(p->subs[SUB_THREEWAY].owner)); + ast_verb(3, "Dumping incomplete call on %s\n", ast_channel_name(p->subs[SUB_THREEWAY].owner)); swap_subs(p, SUB_THREEWAY, SUB_REAL); ast_channel_softhangup_internal_flag_add(p->subs[SUB_THREEWAY].owner, AST_SOFTHANGUP_DEV); p->owner = p->subs[SUB_REAL].owner; @@ -15058,14 +15058,14 @@ retry: ast_mutex_lock(&p->lock); if (p->owner && !p->restartpending) { if (ast_channel_trylock(p->owner)) { - if (option_debug > 2) + if (DEBUG_ATLEAST(3)) ast_verbose("Avoiding deadlock\n"); /* Avoid deadlock since you're not supposed to lock iflock or pvt before a channel */ ast_mutex_unlock(&p->lock); ast_mutex_unlock(&iflock); goto retry; } - if (option_debug > 2) + if (DEBUG_ATLEAST(3)) ast_verbose("Softhanging up on %s\n", ast_channel_name(p->owner)); ast_softhangup_nolock(p->owner, AST_SOFTHANGUP_EXPLICIT); p->restartpending = 1; @@ -19542,5 +19542,6 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, tdesc, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_CHANNEL_DRIVER, - .nonoptreq = "res_smdi", + .requires = "ccss", + .optional_modules = "res_smdi", ); diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c index 69261f35a..dec9dfda1 100644 --- a/channels/chan_iax2.c +++ b/channels/chan_iax2.c @@ -99,7 +99,6 @@ #include "asterisk/localtime.h" #include "asterisk/dnsmgr.h" #include "asterisk/devicestate.h" -#include "asterisk/netsock.h" #include "asterisk/stringfields.h" #include "asterisk/linkedlists.h" #include "asterisk/astobj2.h" @@ -122,6 +121,7 @@ #include "iax2/include/provision.h" #include "iax2/include/codec_pref.h" #include "iax2/include/format_compatibility.h" +#include "iax2/include/netsock.h" #include "jitterbuf.h" @@ -7141,7 +7141,7 @@ static char *complete_iax2_unregister(const char *line, const char *word, int po if (pos == 2) { struct ao2_iterator i = ao2_iterator_init(peers, 0); while ((p = ao2_iterator_next(&i))) { - if (!strncasecmp(p->name, word, wordlen) && + if (!strncasecmp(p->name, word, wordlen) && ++which > state && p->expire > -1) { res = ast_strdup(p->name); peer_unref(p); @@ -14902,5 +14902,6 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Inter Asterisk eXchan .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_CHANNEL_DRIVER, - .nonoptreq = "res_crypto", + .requires = "dnsmgr", + .optional_modules = "res_crypto", ); diff --git a/channels/chan_mgcp.c b/channels/chan_mgcp.c index 6cac4bc8a..2ac7690a6 100644 --- a/channels/chan_mgcp.c +++ b/channels/chan_mgcp.c @@ -389,7 +389,7 @@ struct mgcp_endpoint { /* struct ast_channel *owner; */ /* struct ast_rtp *rtp; */ /* struct sockaddr_in tmpdest; */ - /* message go the the endpoint and not the channel so they stay here */ + /* message go the endpoint and not the channel so they stay here */ struct ast_variable *chanvars; /*!< Variables to set for channel created by user */ struct mgcp_endpoint *next; struct mgcp_gateway *parent; @@ -5025,5 +5025,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Media Gateway Control .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_CHANNEL_DRIVER, - .nonoptreq = "res_pktccops", + .optional_modules = "res_pktccops", ); diff --git a/channels/chan_motif.c b/channels/chan_motif.c index 210cf36c6..05184ca04 100644 --- a/channels/chan_motif.c +++ b/channels/chan_motif.c @@ -541,8 +541,8 @@ static int jingle_endpoint_cmp(void *obj, void *arg, int flags) static struct aco_type endpoint_option = { .type = ACO_ITEM, .name = "endpoint", - .category_match = ACO_BLACKLIST, - .category = "^general$", + .category_match = ACO_BLACKLIST_EXACT, + .category = "general", .item_alloc = jingle_endpoint_alloc, .item_find = jingle_endpoint_find, .item_offset = offsetof(struct jingle_config, endpoints), @@ -2715,8 +2715,8 @@ static int custom_transport_handler(const struct aco_option *opt, struct ast_var * Module loading including tests for configuration or dependencies. * This function can return AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_DECLINE, * or AST_MODULE_LOAD_SUCCESS. If a dependency or environment variable fails - * tests return AST_MODULE_LOAD_FAILURE. If the module can not load the - * configuration file or other non-critical problem return + * tests return AST_MODULE_LOAD_FAILURE. If the module can not load the + * configuration file or other non-critical problem return * AST_MODULE_LOAD_DECLINE. On success return AST_MODULE_LOAD_SUCCESS. */ static int load_module(void) @@ -2821,4 +2821,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Motif Jingle Channel .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_CHANNEL_DRIVER, + .requires = "res_xmpp", ); diff --git a/channels/chan_nbs.c b/channels/chan_nbs.c index a12470cee..4a080a75b 100644 --- a/channels/chan_nbs.c +++ b/channels/chan_nbs.c @@ -19,7 +19,7 @@ /*! \file * * \brief Network broadcast sound support channel driver - * + * * \author Mark Spencer <markster@digium.com> * * \ingroup channel_drivers @@ -27,7 +27,7 @@ /*** MODULEINFO <depend>nbs</depend> - <support_level>extended</support_level> + <support_level>extended</support_level> ***/ #include "asterisk.h" @@ -53,7 +53,7 @@ static char context[AST_MAX_EXTENSION] = "default"; static const char type[] = "NBS"; /* NBS creates private structures on demand */ - + struct nbs_pvt { NBS *nbs; struct ast_channel *owner; /* Channel we belong to, possibly NULL */ @@ -138,7 +138,7 @@ static struct nbs_pvt *nbs_alloc(const char *data) flags |= NBS_FLAG_OVERRIDE; } else flags = NBS_FLAG_OVERSPEAK; - + ast_copy_string(p->stream, stream, sizeof(p->stream)); p->nbs = nbs_newstream("asterisk", stream, flags); if (!p->nbs) { @@ -185,7 +185,7 @@ static int nbs_xwrite(struct ast_channel *ast, struct ast_frame *frame) /* Don't try tos end audio on-hook */ return 0; } - if (nbs_write(p->nbs, frame->data.ptr, frame->datalen / 2) < 0) + if (nbs_write(p->nbs, frame->data.ptr, frame->datalen / 2) < 0) return -1; return 0; } @@ -271,4 +271,3 @@ static int load_module(void) } AST_MODULE_INFO_STANDARD_EXTENDED(ASTERISK_GPL_KEY, "Network Broadcast Sound Support"); - diff --git a/channels/chan_oss.c b/channels/chan_oss.c index ec112de38..69863d271 100644 --- a/channels/chan_oss.c +++ b/channels/chan_oss.c @@ -47,7 +47,7 @@ #include <ctype.h> /* isalnum() used here */ #include <math.h> -#include <sys/ioctl.h> +#include <sys/ioctl.h> #ifdef __linux #include <linux/soundcard.h> @@ -580,7 +580,7 @@ static int oss_digit_begin(struct ast_channel *c, char digit) static int oss_digit_end(struct ast_channel *c, char digit, unsigned int duration) { /* no better use for received digits than print them */ - ast_verbose(" << Console Received digit %c of duration %u ms >> \n", + ast_verbose(" << Console Received digit %c of duration %u ms >> \n", digit, duration); return 0; } @@ -890,7 +890,7 @@ static char *console_cmd(struct ast_cli_entry *e, int cmd, struct ast_cli_args * switch (cmd) { case CLI_INIT: e->command = CONSOLE_VIDEO_CMDS; - e->usage = + e->usage = "Usage: " CONSOLE_VIDEO_CMDS "...\n" " Generic handler for console commands.\n"; return NULL; @@ -1142,7 +1142,7 @@ static char *console_mute(struct ast_cli_entry *e, int cmd, struct ast_cli_args struct chan_oss_pvt *o = find_desc(oss_active); const char *s; int toggle = 0; - + if (cmd == CLI_INIT) { e->command = "console {mute|unmute} [toggle]"; e->usage = @@ -1292,7 +1292,7 @@ static struct ast_cli_entry cli_oss[] = { AST_CLI_DEFINE(console_flash, "Flash a call on the console"), AST_CLI_DEFINE(console_dial, "Dial an extension on the console"), AST_CLI_DEFINE(console_mute, "Disable/Enable mic input"), - AST_CLI_DEFINE(console_transfer, "Transfer a call to a different extension"), + AST_CLI_DEFINE(console_transfer, "Transfer a call to a different extension"), AST_CLI_DEFINE(console_cmd, "Generic console command"), AST_CLI_DEFINE(console_sendtext, "Send text to the remote device"), AST_CLI_DEFINE(console_autoanswer, "Sets/displays autoanswer"), @@ -1466,8 +1466,8 @@ static int unload_module(void) * Module loading including tests for configuration or dependencies. * This function can return AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_DECLINE, * or AST_MODULE_LOAD_SUCCESS. If a dependency or environment variable fails - * tests return AST_MODULE_LOAD_FAILURE. If the module can not load the - * configuration file or other non-critical problem return + * tests return AST_MODULE_LOAD_FAILURE. If the module can not load the + * configuration file or other non-critical problem return * AST_MODULE_LOAD_DECLINE. On success return AST_MODULE_LOAD_SUCCESS. */ static int load_module(void) @@ -1520,4 +1520,3 @@ static int load_module(void) } AST_MODULE_INFO_STANDARD_EXTENDED(ASTERISK_GPL_KEY, "OSS Console Channel Driver"); - diff --git a/channels/chan_phone.c b/channels/chan_phone.c index 76891ac98..c33f27a87 100644 --- a/channels/chan_phone.c +++ b/channels/chan_phone.c @@ -21,7 +21,7 @@ * \brief Generic Linux Telephony Interface driver * * \author Mark Spencer <markster@digium.com> - * + * * \ingroup channel_drivers */ @@ -114,7 +114,7 @@ AST_MUTEX_DEFINE_STATIC(monlock); /* Boolean value whether the monitoring thread shall continue. */ static unsigned int monitor; - + /* This is the thread for the monitor which checks for input on the channels which are not currently in use. */ static pthread_t monitor_thread = AST_PTHREADT_NULL; @@ -123,7 +123,7 @@ static int restart_monitor(void); /* The private structures of the Phone Jack channels are linked for selecting outgoing channels */ - + #define MODE_DIALTONE 1 #define MODE_IMMEDIATE 2 #define MODE_FXO 3 @@ -336,7 +336,7 @@ static int phone_call(struct ast_channel *ast, const char *dest, int timeout) start = IXJ_PHONE_RING_START(cid); if (start == -1) return -1; - + if (p->mode == MODE_FXS) { const char *digit = strchr(dest, '/'); if (digit) @@ -346,7 +346,7 @@ static int phone_call(struct ast_channel *ast, const char *dest, int timeout) phone_digit_end(ast, *digit++, 0); } } - + ast_setstate(ast, AST_STATE_RINGING); ast_queue_control(ast, AST_CONTROL_RINGING); return 0; @@ -449,7 +449,7 @@ static int phone_setup(struct ast_channel *ast) if (!p->lastinput || (ast_format_cmp(p->lastinput, ast_channel_rawreadformat(ast)) == AST_FORMAT_CMP_NOT_EQUAL)) { ao2_replace(p->lastinput, ast_channel_rawreadformat(ast)); if (ioctl(p->fd, PHONE_REC_CODEC, ast_channel_rawreadformat(ast))) { - ast_log(LOG_WARNING, "Failed to set codec to %s\n", + ast_log(LOG_WARNING, "Failed to set codec to %s\n", ast_format_get_name(ast_channel_rawreadformat(ast))); return -1; } @@ -515,11 +515,11 @@ static struct ast_frame *phone_exception(struct ast_channel *ast) p->fr.offset = 0; p->fr.mallocd=0; p->fr.delivery = ast_tv(0,0); - + phonee.bytes = ioctl(p->fd, PHONE_EXCEPTION); if (phonee.bits.dtmf_ready) { ast_debug(1, "phone_exception(): DTMF\n"); - + /* We've got a digit -- Just handle this nicely and easily */ digit = ioctl(p->fd, PHONE_GET_DTMF_ASCII); p->fr.subclass.integer = digit; @@ -541,7 +541,7 @@ static struct ast_frame *phone_exception(struct ast_channel *ast) phone_setup(ast); ast_setstate(ast, AST_STATE_UP); return &p->fr; - } else + } else ast_log(LOG_WARNING, "Got off hook in weird state %u\n", ast_channel_state(ast)); } } @@ -564,7 +564,7 @@ static struct ast_frame *phone_read(struct ast_channel *ast) { int res; struct phone_pvt *p = ast_channel_tech_pvt(ast); - + /* Some nice norms */ p->fr.datalen = 0; @@ -645,7 +645,7 @@ static int phone_write_buf(struct phone_pvt *p, const char *buf, int len, int fr } p->obuflen -= frlen; /* Move memory if necessary */ - if (p->obuflen) + if (p->obuflen) memmove(p->obuf, p->obuf + frlen, p->obuflen); } return len; @@ -654,7 +654,7 @@ static int phone_write_buf(struct phone_pvt *p, const char *buf, int len, int fr static int phone_send_text(struct ast_channel *ast, const char *text) { int length = strlen(text); - return phone_write_buf(ast_channel_tech_pvt(ast), text, length, length, 0) == + return phone_write_buf(ast_channel_tech_pvt(ast), text, length, length, 0) == length ? 0 : -1; } @@ -685,7 +685,7 @@ static int phone_write(struct ast_channel *ast, struct ast_frame *frame) /* Don't try tos end audio on-hook */ return 0; } -#endif +#endif if (ast_format_cmp(frame->subclass.format, ast_format_g729) == AST_FORMAT_CMP_EQUAL) { if (!p->lastformat || (ast_format_cmp(p->lastformat, ast_format_g729) != AST_FORMAT_CMP_EQUAL)) { ioctl(p->fd, PHONE_PLAY_STOP); @@ -812,7 +812,7 @@ static int phone_write(struct ast_channel *ast, struct ast_frame *frame) expected = frame->datalen - sofar; if (maxfr < expected) expected = maxfr; - /* XXX Internet Phone Jack does not handle the 4-byte VAD frame properly! XXX + /* XXX Internet Phone Jack does not handle the 4-byte VAD frame properly! XXX we have to pad it to 24 bytes still. */ if (frame->datalen == 4) { if (p->silencesupression) { @@ -832,7 +832,7 @@ static int phone_write(struct ast_channel *ast, struct ast_frame *frame) } if (res != expected) { if ((errno != EAGAIN) && (errno != EINTR)) { - if (res < 0) + if (res < 0) ast_log(LOG_WARNING, "Write returned error (%s)\n", strerror(errno)); /* * Card is in non-blocking mode now and it works well now, but there are @@ -1024,8 +1024,8 @@ static void phone_check_exception(struct phone_pvt *i) } if (phonee.bits.caller_id) ast_verbose("We have caller ID\n"); - - + + } static void *do_monitor(void *data) @@ -1191,8 +1191,7 @@ static struct phone_pvt *mkif(const char *iface, int mode, int txgain, int rxgai { /* Make a phone_pvt structure for this interface */ struct phone_pvt *tmp; - int flags; - + tmp = ast_calloc(1, sizeof(*tmp)); if (tmp) { tmp->fd = open(iface, O_RDWR); @@ -1206,7 +1205,7 @@ static struct phone_pvt *mkif(const char *iface, int mode, int txgain, int rxgai ast_debug(1, "Unable to set port to PSTN\n"); } } else { - if (ioctl(tmp->fd, IXJCTL_PORT, PORT_POTS)) + if (ioctl(tmp->fd, IXJCTL_PORT, PORT_POTS)) if (mode != MODE_FXS) ast_debug(1, "Unable to set port to POTS\n"); } @@ -1218,14 +1217,13 @@ static struct phone_pvt *mkif(const char *iface, int mode, int txgain, int rxgai ast_debug(1, "ioctl(PHONE_PSTN_SET_STATE) failed on %s (%s)\n",iface, strerror(errno)); if (echocancel != AEC_OFF) ioctl(tmp->fd, IXJCTL_AEC_START, echocancel); - if (silencesupression) + if (silencesupression) tmp->silencesupression = 1; #ifdef PHONE_VAD ioctl(tmp->fd, PHONE_VAD, tmp->silencesupression); #endif tmp->mode = mode; - flags = fcntl(tmp->fd, F_GETFL); - fcntl(tmp->fd, F_SETFL, flags | O_NONBLOCK); + ast_fd_set_flags(tmp->fd, O_NONBLOCK); tmp->owner = NULL; ao2_cleanup(tmp->lastformat); tmp->lastformat = NULL; @@ -1302,7 +1300,7 @@ static int parse_gain_value(const char *gain_type, const char *value) return DEFAULT_GAIN; } - /* multiplicate gain by 1.0 gain value */ + /* multiplicate gain by 1.0 gain value */ gain = gain * (float)DEFAULT_GAIN; /* percentage? */ @@ -1426,7 +1424,7 @@ static int load_module(void) if (tmp) { tmp->next = iflist; iflist = tmp; - + } else { ast_log(LOG_ERROR, "Unable to register channel '%s'\n", v->value); ast_config_destroy(cfg); @@ -1441,7 +1439,7 @@ static int load_module(void) } else if (!strcasecmp(v->name, "callerid")) { ast_callerid_split(v->value, cid_name, sizeof(cid_name), cid_num, sizeof(cid_num)); } else if (!strcasecmp(v->name, "mode")) { - if (!strncasecmp(v->value, "di", 2)) + if (!strncasecmp(v->value, "di", 2)) mode = MODE_DIALTONE; else if (!strncasecmp(v->value, "sig", 3)) mode = MODE_SIGMA; @@ -1485,13 +1483,13 @@ static int load_module(void) echocancel = AEC_MED; } else if (!strcasecmp(v->value, "high")) { echocancel = AEC_HIGH; - } else + } else ast_log(LOG_WARNING, "Unknown echo cancellation '%s'\n", v->value); } else if (!strcasecmp(v->name, "txgain")) { txgain = parse_gain_value(v->name, v->value); } else if (!strcasecmp(v->name, "rxgain")) { rxgain = parse_gain_value(v->name, v->value); - } + } v = v->next; } ast_mutex_unlock(&iflock); @@ -1517,4 +1515,3 @@ static int load_module(void) } AST_MODULE_INFO_STANDARD_EXTENDED(ASTERISK_GPL_KEY, "Linux Telephony API Support"); - diff --git a/channels/chan_phone.h b/channels/chan_phone.h index e71ba0c7d..d15570850 100644 --- a/channels/chan_phone.h +++ b/channels/chan_phone.h @@ -15,243 +15,243 @@ */ static unsigned char DialTone[] = { -0xff, 0xab, 0x9d, 0x96, 0x91, 0x90, 0x91, 0x96, 0x9c, 0xaa, -0xd9, 0x2f, 0x1f, 0x19, 0x15, 0x14, 0x15, 0x19, 0x1f, 0x2c, -0x4e, 0xb9, 0xa7, 0x9f, 0x9c, 0x9b, 0x9c, 0x9f, 0xa7, 0xb3, -0xcf, 0x47, 0x34, 0x2d, 0x2a, 0x2a, 0x2c, 0x31, 0x3a, 0x47, -0x5f, 0xe4, 0xd8, 0xd9, 0xe9, 0x64, 0x4f, 0x49, 0x46, 0x49, -0x58, 0xde, 0xc2, 0xb5, 0xad, 0xa8, 0xa6, 0xa6, 0xa9, 0xaf, -0xbf, 0x56, 0x32, 0x26, 0x1e, 0x1b, 0x19, 0x1a, 0x1d, 0x24, -0x33, 0xdd, 0xad, 0x9f, 0x98, 0x94, 0x92, 0x93, 0x97, 0x9e, -0xac, 0xf8, 0x2c, 0x1d, 0x16, 0x11, 0xf, 0x10, 0x15, 0x1b, -0x29, 0x55, 0xae, 0x9e, 0x97, 0x92, 0x90, 0x91, 0x95, 0x9c, -0xa8, 0xca, 0x35, 0x22, 0x1a, 0x16, 0x15, 0x16, 0x19, 0x1f, -0x2b, 0x47, 0xbe, 0xab, 0xa2, 0x9e, 0x9d, 0x9e, 0xa2, 0xa9, -0xb4, 0xcc, 0x4f, 0x3a, 0x32, 0x2f, 0x2f, 0x32, 0x39, 0x41, -0x4f, 0x67, 0xf5, 0xf5, 0x67, 0x51, 0x46, 0x3e, 0x3b, 0x3b, -0x3f, 0x4d, 0xe2, 0xbe, 0xb0, 0xa9, 0xa4, 0xa1, 0xa1, 0xa5, -0xab, 0xba, 0x64, 0x33, 0x25, 0x1d, 0x19, 0x17, 0x18, 0x1b, -0x20, 0x2e, 0x72, 0xae, 0x9f, 0x98, 0x94, 0x91, 0x92, 0x96, -0x9c, 0xa9, 0xd4, 0x2f, 0x1e, 0x17, 0x11, 0xf, 0x10, 0x14, -0x1a, 0x26, 0x48, 0xb2, 0x9f, 0x98, 0x93, 0x91, 0x92, 0x95, -0x9b, 0xa7, 0xc1, 0x3a, 0x25, 0x1c, 0x18, 0x16, 0x17, 0x1a, -0x1f, 0x2b, 0x42, 0xc6, 0xae, 0xa6, 0xa0, 0x9f, 0xa0, 0xa5, -0xab, 0xb6, 0xcb, 0x5a, 0x40, 0x39, 0x36, 0x37, 0x3b, 0x43, -0x4e, 0x60, 0x7b, 0x7c, 0x60, 0x4e, 0x41, 0x3a, 0x34, 0x32, -0x33, 0x39, 0x45, 0xed, 0xbd, 0xae, 0xa6, 0xa0, 0x9e, 0x9e, -0xa0, 0xa8, 0xb4, 0xef, 0x34, 0x24, 0x1c, 0x18, 0x16, 0x16, -0x19, 0x1e, 0x2b, 0x54, 0xb1, 0x9f, 0x98, 0x93, 0x91, 0x91, -0x95, 0x9b, 0xa6, 0xc6, 0x33, 0x1f, 0x17, 0x12, 0xf, 0x10, -0x13, 0x1a, 0x24, 0x3e, 0xb8, 0xa2, 0x99, 0x94, 0x92, 0x92, -0x96, 0x9b, 0xa6, 0xbc, 0x40, 0x29, 0x1e, 0x1a, 0x18, 0x19, -0x1b, 0x20, 0x2b, 0x3f, 0xcf, 0xb3, 0xa9, 0xa5, 0xa3, 0xa4, -0xa8, 0xae, 0xb9, 0xcc, 0x67, 0x49, 0x40, 0x3f, 0x42, 0x4a, -0x59, 0x79, 0xe5, 0xe4, 0x7a, 0x54, 0x43, 0x39, 0x31, 0x2d, -0x2c, 0x2d, 0x32, 0x3e, 0x71, 0xbd, 0xad, 0xa4, 0x9e, 0x9c, -0x9c, 0x9e, 0xa4, 0xaf, 0xd7, 0x36, 0x24, 0x1c, 0x17, 0x15, -0x15, 0x17, 0x1d, 0x28, 0x47, 0xb5, 0xa1, 0x98, 0x93, 0x90, -0x90, 0x93, 0x99, 0xa4, 0xbd, 0x38, 0x21, 0x18, 0x13, 0x10, -0x10, 0x13, 0x19, 0x22, 0x39, 0xbe, 0xa5, 0x9b, 0x96, 0x93, -0x93, 0x96, 0x9b, 0xa5, 0xb9, 0x4a, 0x2c, 0x20, 0x1c, 0x1a, -0x1a, 0x1d, 0x22, 0x2c, 0x3d, 0xdc, 0xb8, 0xad, 0xa9, 0xa8, -0xa9, 0xac, 0xb2, 0xbd, 0xce, 0x78, 0x54, 0x4d, 0x4f, 0x5a, -0xff, 0xda, 0xcf, 0xcd, 0xd4, 0xf8, 0x4e, 0x3d, 0x32, 0x2c, -0x29, 0x28, 0x29, 0x2d, 0x38, 0x5c, 0xbd, 0xac, 0xa2, 0x9d, -0x9a, 0x9a, 0x9c, 0xa0, 0xac, 0xca, 0x39, 0x25, 0x1b, 0x16, -0x13, 0x13, 0x16, 0x1b, 0x25, 0x3e, 0xb9, 0xa2, 0x99, 0x93, -0x90, 0x90, 0x93, 0x98, 0xa1, 0xb8, 0x3d, 0x24, 0x19, 0x13, -0x10, 0x10, 0x13, 0x18, 0x21, 0x35, 0xc7, 0xa8, 0x9d, 0x97, -0x95, 0x95, 0x97, 0x9c, 0xa4, 0xb6, 0x57, 0x2f, 0x24, 0x1e, -0x1c, 0x1c, 0x1e, 0x24, 0x2d, 0x3d, 0xf1, 0xbe, 0xb2, 0xad, -0xac, 0xad, 0xb1, 0xb9, 0xc3, 0xd4, 0xfa, 0x64, 0x65, 0xf9, -0xd9, 0xca, 0xc2, 0xbf, 0xc0, 0xc9, 0xe7, 0x4c, 0x39, 0x2e, -0x28, 0x24, 0x23, 0x25, 0x29, 0x33, 0x4f, 0xbf, 0xab, 0xa0, -0x9b, 0x99, 0x98, 0x9a, 0x9e, 0xa9, 0xc0, 0x3c, 0x26, 0x1b, -0x16, 0x12, 0x12, 0x14, 0x19, 0x22, 0x38, 0xbe, 0xa4, 0x9a, -0x93, 0x90, 0x8f, 0x92, 0x97, 0x9f, 0xb3, 0x46, 0x26, 0x1b, -0x15, 0x11, 0x11, 0x13, 0x18, 0x1f, 0x31, 0xd4, 0xab, 0x9e, -0x99, 0x96, 0x96, 0x98, 0x9c, 0xa4, 0xb4, 0x6f, 0x34, 0x28, -0x20, 0x1e, 0x1e, 0x20, 0x26, 0x2e, 0x3d, 0x6d, 0xc5, 0xb9, -0xb3, 0xb2, 0xb4, 0xba, 0xc1, 0xcd, 0xe0, 0xfc, 0xfb, 0xe0, -0xce, 0xc3, 0xbb, 0xb7, 0xb6, 0xb9, 0xc0, 0xda, 0x4b, 0x36, -0x2b, 0x25, 0x20, 0x1f, 0x20, 0x26, 0x2e, 0x46, 0xc2, 0xab, -0x9f, 0x9a, 0x97, 0x96, 0x98, 0x9c, 0xa5, 0xba, 0x41, 0x27, -0x1b, 0x15, 0x12, 0x11, 0x13, 0x18, 0x1f, 0x32, 0xc8, 0xa6, -0x9a, 0x94, 0x90, 0x8f, 0x91, 0x97, 0x9e, 0xaf, 0x54, 0x29, -0x1c, 0x16, 0x12, 0x11, 0x14, 0x18, 0x1f, 0x2e, 0xf2, 0xae, -0xa0, 0x9b, 0x98, 0x97, 0x99, 0x9d, 0xa5, 0xb3, 0xe4, 0x3a, -0x2b, 0x25, 0x21, 0x21, 0x24, 0x29, 0x30, 0x3e, 0x62, 0xcd, -0xbf, 0xbb, 0xbb, 0xbe, 0xc6, 0xd1, 0xe7, 0x76, 0x75, 0xe7, -0xcf, 0xc1, 0xb9, 0xb2, 0xaf, 0xaf, 0xb2, 0xba, 0xcf, 0x4c, -0x34, 0x29, 0x22, 0x1e, 0x1d, 0x1e, 0x22, 0x2b, 0x3e, 0xc7, -0xab, 0x9f, 0x99, 0x96, 0x95, 0x96, 0x9a, 0xa2, 0xb5, 0x4a, -0x28, 0x1c, 0x15, 0x11, 0x10, 0x12, 0x17, 0x1e, 0x2e, 0xd5, -0xa9, 0x9b, 0x95, 0x90, 0x8f, 0x91, 0x96, 0x9d, 0xac, 0x78, -0x2c, 0x1e, 0x17, 0x13, 0x12, 0x14, 0x18, 0x1f, 0x2d, 0x5d, -0xb3, 0xa4, 0x9d, 0x9a, 0x99, 0x9b, 0x9e, 0xa6, 0xb2, 0xd6, -0x3f, 0x2f, 0x29, 0x26, 0x26, 0x28, 0x2d, 0x35, 0x42, 0x5e, -0xd8, 0xca, 0xc6, 0xc9, 0xcf, 0xe4, 0x69, 0x59, 0x58, 0x64, -0xdf, 0xc7, 0xba, 0xb1, 0xac, 0xaa, 0xaa, 0xad, 0xb4, 0xc7, -0x4f, 0x33, 0x27, 0x1f, 0x1c, 0x1b, 0x1c, 0x1f, 0x27, 0x39, -0xce, 0xac, 0x9f, 0x99, 0x95, 0x94, 0x95, 0x99, 0x9f, 0xaf, -0x59, 0x2a, 0x1c, 0x16, 0x11, 0x10, 0x11, 0x16, 0x1d, 0x2b, -0xff, 0xab, 0x9d, 0x96, 0x91, 0x90, 0x91, 0x96, 0x9c, 0xaa, -0xd9, 0x2f, 0x1f, 0x19, 0x15, 0x14, 0x15, 0x19, 0x1f, 0x2c, -0x4e, 0xb9, 0xa7, 0x9f, 0x9c, 0x9b, 0x9c, 0x9f, 0xa7, 0xb3, -0xcf, 0x47, 0x34, 0x2d, 0x2a, 0x2a, 0x2c, 0x31, 0x3a, 0x47, -0x5f, 0xe4, 0xd8, 0xd9, 0xe9, 0x64, 0x4f, 0x49, 0x46, 0x49, -0x58, 0xde, 0xc2, 0xb5, 0xad, 0xa8, 0xa6, 0xa6, 0xa9, 0xaf, -0xbf, 0x56, 0x32, 0x26, 0x1e, 0x1b, 0x19, 0x1a, 0x1d, 0x24, -0x33, 0xdd, 0xad, 0x9f, 0x98, 0x94, 0x92, 0x93, 0x97, 0x9e, -0xac, 0xf8, 0x2c, 0x1d, 0x16, 0x11, 0xf, 0x10, 0x15, 0x1b, -0x29, 0x55, 0xae, 0x9e, 0x97, 0x92, 0x90, 0x91, 0x95, 0x9c, -0xa8, 0xca, 0x35, 0x22, 0x1a, 0x16, 0x15, 0x16, 0x19, 0x1f, -0x2b, 0x47, 0xbe, 0xab, 0xa2, 0x9e, 0x9d, 0x9e, 0xa2, 0xa9, -0xb4, 0xcc, 0x4f, 0x3a, 0x32, 0x2f, 0x2f, 0x32, 0x39, 0x41, -0x4f, 0x67, 0xf5, 0xf5, 0x67, 0x51, 0x46, 0x3e, 0x3b, 0x3b, -0x3f, 0x4d, 0xe2, 0xbe, 0xb0, 0xa9, 0xa4, 0xa1, 0xa1, 0xa5, -0xab, 0xba, 0x64, 0x33, 0x25, 0x1d, 0x19, 0x17, 0x18, 0x1b, -0x20, 0x2e, 0x72, 0xae, 0x9f, 0x98, 0x94, 0x91, 0x92, 0x96, -0x9c, 0xa9, 0xd4, 0x2f, 0x1e, 0x17, 0x11, 0xf, 0x10, 0x14, -0x1a, 0x26, 0x48, 0xb2, 0x9f, 0x98, 0x93, 0x91, 0x92, 0x95, -0x9b, 0xa7, 0xc1, 0x3a, 0x25, 0x1c, 0x18, 0x16, 0x17, 0x1a, -0x1f, 0x2b, 0x42, 0xc6, 0xae, 0xa6, 0xa0, 0x9f, 0xa0, 0xa5, -0xab, 0xb6, 0xcb, 0x5a, 0x40, 0x39, 0x36, 0x37, 0x3b, 0x43, -0x4e, 0x60, 0x7b, 0x7c, 0x60, 0x4e, 0x41, 0x3a, 0x34, 0x32, -0x33, 0x39, 0x45, 0xed, 0xbd, 0xae, 0xa6, 0xa0, 0x9e, 0x9e, -0xa0, 0xa8, 0xb4, 0xef, 0x34, 0x24, 0x1c, 0x18, 0x16, 0x16, -0x19, 0x1e, 0x2b, 0x54, 0xb1, 0x9f, 0x98, 0x93, 0x91, 0x91, -0x95, 0x9b, 0xa6, 0xc6, 0x33, 0x1f, 0x17, 0x12, 0xf, 0x10, -0x13, 0x1a, 0x24, 0x3e, 0xb8, 0xa2, 0x99, 0x94, 0x92, 0x92, -0x96, 0x9b, 0xa6, 0xbc, 0x40, 0x29, 0x1e, 0x1a, 0x18, 0x19, -0x1b, 0x20, 0x2b, 0x3f, 0xcf, 0xb3, 0xa9, 0xa5, 0xa3, 0xa4, -0xa8, 0xae, 0xb9, 0xcc, 0x67, 0x49, 0x40, 0x3f, 0x42, 0x4a, -0x59, 0x79, 0xe5, 0xe4, 0x7a, 0x54, 0x43, 0x39, 0x31, 0x2d, -0x2c, 0x2d, 0x32, 0x3e, 0x71, 0xbd, 0xad, 0xa4, 0x9e, 0x9c, -0x9c, 0x9e, 0xa4, 0xaf, 0xd7, 0x36, 0x24, 0x1c, 0x17, 0x15, -0x15, 0x17, 0x1d, 0x28, 0x47, 0xb5, 0xa1, 0x98, 0x93, 0x90, -0x90, 0x93, 0x99, 0xa4, 0xbd, 0x38, 0x21, 0x18, 0x13, 0x10, -0x10, 0x13, 0x19, 0x22, 0x39, 0xbe, 0xa5, 0x9b, 0x96, 0x93, -0x93, 0x96, 0x9b, 0xa5, 0xb9, 0x4a, 0x2c, 0x20, 0x1c, 0x1a, -0x1a, 0x1d, 0x22, 0x2c, 0x3d, 0xdc, 0xb8, 0xad, 0xa9, 0xa8, -0xa9, 0xac, 0xb2, 0xbd, 0xce, 0x78, 0x54, 0x4d, 0x4f, 0x5a, -0xff, 0xda, 0xcf, 0xcd, 0xd4, 0xf8, 0x4e, 0x3d, 0x32, 0x2c, -0x29, 0x28, 0x29, 0x2d, 0x38, 0x5c, 0xbd, 0xac, 0xa2, 0x9d, -0x9a, 0x9a, 0x9c, 0xa0, 0xac, 0xca, 0x39, 0x25, 0x1b, 0x16, -0x13, 0x13, 0x16, 0x1b, 0x25, 0x3e, 0xb9, 0xa2, 0x99, 0x93, -0x90, 0x90, 0x93, 0x98, 0xa1, 0xb8, 0x3d, 0x24, 0x19, 0x13, -0x10, 0x10, 0x13, 0x18, 0x21, 0x35, 0xc7, 0xa8, 0x9d, 0x97, -0x95, 0x95, 0x97, 0x9c, 0xa4, 0xb6, 0x57, 0x2f, 0x24, 0x1e, -0x1c, 0x1c, 0x1e, 0x24, 0x2d, 0x3d, 0xf1, 0xbe, 0xb2, 0xad, -0xac, 0xad, 0xb1, 0xb9, 0xc3, 0xd4, 0xfa, 0x64, 0x65, 0xf9, -0xd9, 0xca, 0xc2, 0xbf, 0xc0, 0xc9, 0xe7, 0x4c, 0x39, 0x2e, -0x28, 0x24, 0x23, 0x25, 0x29, 0x33, 0x4f, 0xbf, 0xab, 0xa0, -0x9b, 0x99, 0x98, 0x9a, 0x9e, 0xa9, 0xc0, 0x3c, 0x26, 0x1b, -0x16, 0x12, 0x12, 0x14, 0x19, 0x22, 0x38, 0xbe, 0xa4, 0x9a, -0x93, 0x90, 0x8f, 0x92, 0x97, 0x9f, 0xb3, 0x46, 0x26, 0x1b, -0x15, 0x11, 0x11, 0x13, 0x18, 0x1f, 0x31, 0xd4, 0xab, 0x9e, -0x99, 0x96, 0x96, 0x98, 0x9c, 0xa4, 0xb4, 0x6f, 0x34, 0x28, -0x20, 0x1e, 0x1e, 0x20, 0x26, 0x2e, 0x3d, 0x6d, 0xc5, 0xb9, -0xb3, 0xb2, 0xb4, 0xba, 0xc1, 0xcd, 0xe0, 0xfc, 0xfb, 0xe0, -0xce, 0xc3, 0xbb, 0xb7, 0xb6, 0xb9, 0xc0, 0xda, 0x4b, 0x36, -0x2b, 0x25, 0x20, 0x1f, 0x20, 0x26, 0x2e, 0x46, 0xc2, 0xab, -0x9f, 0x9a, 0x97, 0x96, 0x98, 0x9c, 0xa5, 0xba, 0x41, 0x27, -0x1b, 0x15, 0x12, 0x11, 0x13, 0x18, 0x1f, 0x32, 0xc8, 0xa6, -0x9a, 0x94, 0x90, 0x8f, 0x91, 0x97, 0x9e, 0xaf, 0x54, 0x29, -0x1c, 0x16, 0x12, 0x11, 0x14, 0x18, 0x1f, 0x2e, 0xf2, 0xae, -0xa0, 0x9b, 0x98, 0x97, 0x99, 0x9d, 0xa5, 0xb3, 0xe4, 0x3a, -0x2b, 0x25, 0x21, 0x21, 0x24, 0x29, 0x30, 0x3e, 0x62, 0xcd, -0xbf, 0xbb, 0xbb, 0xbe, 0xc6, 0xd1, 0xe7, 0x76, 0x75, 0xe7, -0xcf, 0xc1, 0xb9, 0xb2, 0xaf, 0xaf, 0xb2, 0xba, 0xcf, 0x4c, -0x34, 0x29, 0x22, 0x1e, 0x1d, 0x1e, 0x22, 0x2b, 0x3e, 0xc7, -0xab, 0x9f, 0x99, 0x96, 0x95, 0x96, 0x9a, 0xa2, 0xb5, 0x4a, -0x28, 0x1c, 0x15, 0x11, 0x10, 0x12, 0x17, 0x1e, 0x2e, 0xd5, -0xa9, 0x9b, 0x95, 0x90, 0x8f, 0x91, 0x96, 0x9d, 0xac, 0x78, -0x2c, 0x1e, 0x17, 0x13, 0x12, 0x14, 0x18, 0x1f, 0x2d, 0x5d, -0xb3, 0xa4, 0x9d, 0x9a, 0x99, 0x9b, 0x9e, 0xa6, 0xb2, 0xd6, -0x3f, 0x2f, 0x29, 0x26, 0x26, 0x28, 0x2d, 0x35, 0x42, 0x5e, -0xd8, 0xca, 0xc6, 0xc9, 0xcf, 0xe4, 0x69, 0x59, 0x58, 0x64, -0xdf, 0xc7, 0xba, 0xb1, 0xac, 0xaa, 0xaa, 0xad, 0xb4, 0xc7, -0x4f, 0x33, 0x27, 0x1f, 0x1c, 0x1b, 0x1c, 0x1f, 0x27, 0x39, -0xce, 0xac, 0x9f, 0x99, 0x95, 0x94, 0x95, 0x99, 0x9f, 0xaf, -0x59, 0x2a, 0x1c, 0x16, 0x11, 0x10, 0x11, 0x16, 0x1d, 0x2b, -0xff, 0xab, 0x9d, 0x96, 0x91, 0x90, 0x91, 0x96, 0x9c, 0xaa, -0xd9, 0x2f, 0x1f, 0x19, 0x15, 0x14, 0x15, 0x19, 0x1f, 0x2c, -0x4e, 0xb9, 0xa7, 0x9f, 0x9c, 0x9b, 0x9c, 0x9f, 0xa7, 0xb3, -0xcf, 0x47, 0x34, 0x2d, 0x2a, 0x2a, 0x2c, 0x31, 0x3a, 0x47, -0x5f, 0xe4, 0xd8, 0xd9, 0xe9, 0x64, 0x4f, 0x49, 0x46, 0x49, -0x58, 0xde, 0xc2, 0xb5, 0xad, 0xa8, 0xa6, 0xa6, 0xa9, 0xaf, -0xbf, 0x56, 0x32, 0x26, 0x1e, 0x1b, 0x19, 0x1a, 0x1d, 0x24, -0x33, 0xdd, 0xad, 0x9f, 0x98, 0x94, 0x92, 0x93, 0x97, 0x9e, -0xac, 0xf8, 0x2c, 0x1d, 0x16, 0x11, 0xf, 0x10, 0x15, 0x1b, -0x29, 0x55, 0xae, 0x9e, 0x97, 0x92, 0x90, 0x91, 0x95, 0x9c, -0xa8, 0xca, 0x35, 0x22, 0x1a, 0x16, 0x15, 0x16, 0x19, 0x1f, -0x2b, 0x47, 0xbe, 0xab, 0xa2, 0x9e, 0x9d, 0x9e, 0xa2, 0xa9, -0xb4, 0xcc, 0x4f, 0x3a, 0x32, 0x2f, 0x2f, 0x32, 0x39, 0x41, -0x4f, 0x67, 0xf5, 0xf5, 0x67, 0x51, 0x46, 0x3e, 0x3b, 0x3b, -0x3f, 0x4d, 0xe2, 0xbe, 0xb0, 0xa9, 0xa4, 0xa1, 0xa1, 0xa5, -0xab, 0xba, 0x64, 0x33, 0x25, 0x1d, 0x19, 0x17, 0x18, 0x1b, -0x20, 0x2e, 0x72, 0xae, 0x9f, 0x98, 0x94, 0x91, 0x92, 0x96, -0x9c, 0xa9, 0xd4, 0x2f, 0x1e, 0x17, 0x11, 0xf, 0x10, 0x14, -0x1a, 0x26, 0x48, 0xb2, 0x9f, 0x98, 0x93, 0x91, 0x92, 0x95, -0x9b, 0xa7, 0xc1, 0x3a, 0x25, 0x1c, 0x18, 0x16, 0x17, 0x1a, -0x1f, 0x2b, 0x42, 0xc6, 0xae, 0xa6, 0xa0, 0x9f, 0xa0, 0xa5, -0xab, 0xb6, 0xcb, 0x5a, 0x40, 0x39, 0x36, 0x37, 0x3b, 0x43, -0x4e, 0x60, 0x7b, 0x7c, 0x60, 0x4e, 0x41, 0x3a, 0x34, 0x32, -0x33, 0x39, 0x45, 0xed, 0xbd, 0xae, 0xa6, 0xa0, 0x9e, 0x9e, -0xa0, 0xa8, 0xb4, 0xef, 0x34, 0x24, 0x1c, 0x18, 0x16, 0x16, -0x19, 0x1e, 0x2b, 0x54, 0xb1, 0x9f, 0x98, 0x93, 0x91, 0x91, -0x95, 0x9b, 0xa6, 0xc6, 0x33, 0x1f, 0x17, 0x12, 0xf, 0x10, -0x13, 0x1a, 0x24, 0x3e, 0xb8, 0xa2, 0x99, 0x94, 0x92, 0x92, -0x96, 0x9b, 0xa6, 0xbc, 0x40, 0x29, 0x1e, 0x1a, 0x18, 0x19, -0x1b, 0x20, 0x2b, 0x3f, 0xcf, 0xb3, 0xa9, 0xa5, 0xa3, 0xa4, -0xa8, 0xae, 0xb9, 0xcc, 0x67, 0x49, 0x40, 0x3f, 0x42, 0x4a, -0x59, 0x79, 0xe5, 0xe4, 0x7a, 0x54, 0x43, 0x39, 0x31, 0x2d, -0x2c, 0x2d, 0x32, 0x3e, 0x71, 0xbd, 0xad, 0xa4, 0x9e, 0x9c, -0x9c, 0x9e, 0xa4, 0xaf, 0xd7, 0x36, 0x24, 0x1c, 0x17, 0x15, -0x15, 0x17, 0x1d, 0x28, 0x47, 0xb5, 0xa1, 0x98, 0x93, 0x90, -0x90, 0x93, 0x99, 0xa4, 0xbd, 0x38, 0x21, 0x18, 0x13, 0x10, -0x10, 0x13, 0x19, 0x22, 0x39, 0xbe, 0xa5, 0x9b, 0x96, 0x93, -0x93, 0x96, 0x9b, 0xa5, 0xb9, 0x4a, 0x2c, 0x20, 0x1c, 0x1a, -0x1a, 0x1d, 0x22, 0x2c, 0x3d, 0xdc, 0xb8, 0xad, 0xa9, 0xa8, -0xa9, 0xac, 0xb2, 0xbd, 0xce, 0x78, 0x54, 0x4d, 0x4f, 0x5a, -0xff, 0xda, 0xcf, 0xcd, 0xd4, 0xf8, 0x4e, 0x3d, 0x32, 0x2c, -0x29, 0x28, 0x29, 0x2d, 0x38, 0x5c, 0xbd, 0xac, 0xa2, 0x9d, -0x9a, 0x9a, 0x9c, 0xa0, 0xac, 0xca, 0x39, 0x25, 0x1b, 0x16, -0x13, 0x13, 0x16, 0x1b, 0x25, 0x3e, 0xb9, 0xa2, 0x99, 0x93, -0x90, 0x90, 0x93, 0x98, 0xa1, 0xb8, 0x3d, 0x24, 0x19, 0x13, -0x10, 0x10, 0x13, 0x18, 0x21, 0x35, 0xc7, 0xa8, 0x9d, 0x97, -0x95, 0x95, 0x97, 0x9c, 0xa4, 0xb6, 0x57, 0x2f, 0x24, 0x1e, -0x1c, 0x1c, 0x1e, 0x24, 0x2d, 0x3d, 0xf1, 0xbe, 0xb2, 0xad, -0xac, 0xad, 0xb1, 0xb9, 0xc3, 0xd4, 0xfa, 0x64, 0x65, 0xf9, -0xd9, 0xca, 0xc2, 0xbf, 0xc0, 0xc9, 0xe7, 0x4c, 0x39, 0x2e, -0x28, 0x24, 0x23, 0x25, 0x29, 0x33, 0x4f, 0xbf, 0xab, 0xa0, -0x9b, 0x99, 0x98, 0x9a, 0x9e, 0xa9, 0xc0, 0x3c, 0x26, 0x1b, -0x16, 0x12, 0x12, 0x14, 0x19, 0x22, 0x38, 0xbe, 0xa4, 0x9a, -0x93, 0x90, 0x8f, 0x92, 0x97, 0x9f, 0xb3, 0x46, 0x26, 0x1b, -0x15, 0x11, 0x11, 0x13, 0x18, 0x1f, 0x31, 0xd4, 0xab, 0x9e, -0x99, 0x96, 0x96, 0x98, 0x9c, 0xa4, 0xb4, 0x6f, 0x34, 0x28, -0x20, 0x1e, 0x1e, 0x20, 0x26, 0x2e, 0x3d, 0x6d, 0xc5, 0xb9, -0xb3, 0xb2, 0xb4, 0xba, 0xc1, 0xcd, 0xe0, 0xfc, 0xfb, 0xe0, -0xce, 0xc3, 0xbb, 0xb7, 0xb6, 0xb9, 0xc0, 0xda, 0x4b, 0x36, -0x2b, 0x25, 0x20, 0x1f, 0x20, 0x26, 0x2e, 0x46, 0xc2, 0xab, -0x9f, 0x9a, 0x97, 0x96, 0x98, 0x9c, 0xa5, 0xba, 0x41, 0x27, -0x1b, 0x15, 0x12, 0x11, 0x13, 0x18, 0x1f, 0x32, 0xc8, 0xa6, -0x9a, 0x94, 0x90, 0x8f, 0x91, 0x97, 0x9e, 0xaf, 0x54, 0x29, -0x1c, 0x16, 0x12, 0x11, 0x14, 0x18, 0x1f, 0x2e, 0xf2, 0xae, -0xa0, 0x9b, 0x98, 0x97, 0x99, 0x9d, 0xa5, 0xb3, 0xe4, 0x3a, -0x2b, 0x25, 0x21, 0x21, 0x24, 0x29, 0x30, 0x3e, 0x62, 0xcd, -0xbf, 0xbb, 0xbb, 0xbe, 0xc6, 0xd1, 0xe7, 0x76, 0x75, 0xe7, -0xcf, 0xc1, 0xb9, 0xb2, 0xaf, 0xaf, 0xb2, 0xba, 0xcf, 0x4c, -0x34, 0x29, 0x22, 0x1e, 0x1d, 0x1e, 0x22, 0x2b, 0x3e, 0xc7, -0xab, 0x9f, 0x99, 0x96, 0x95, 0x96, 0x9a, 0xa2, 0xb5, 0x4a, -0x28, 0x1c, 0x15, 0x11, 0x10, 0x12, 0x17, 0x1e, 0x2e, 0xd5, -0xa9, 0x9b, 0x95, 0x90, 0x8f, 0x91, 0x96, 0x9d, 0xac, 0x78, -0x2c, 0x1e, 0x17, 0x13, 0x12, 0x14, 0x18, 0x1f, 0x2d, 0x5d, -0xb3, 0xa4, 0x9d, 0x9a, 0x99, 0x9b, 0x9e, 0xa6, 0xb2, 0xd6, -0x3f, 0x2f, 0x29, 0x26, 0x26, 0x28, 0x2d, 0x35, 0x42, 0x5e, -0xd8, 0xca, 0xc6, 0xc9, 0xcf, 0xe4, 0x69, 0x59, 0x58, 0x64, -0xdf, 0xc7, 0xba, 0xb1, 0xac, 0xaa, 0xaa, 0xad, 0xb4, 0xc7, -0x4f, 0x33, 0x27, 0x1f, 0x1c, 0x1b, 0x1c, 0x1f, 0x27, 0x39, -0xce, 0xac, 0x9f, 0x99, 0x95, 0x94, 0x95, 0x99, 0x9f, 0xaf, +0xff, 0xab, 0x9d, 0x96, 0x91, 0x90, 0x91, 0x96, 0x9c, 0xaa, +0xd9, 0x2f, 0x1f, 0x19, 0x15, 0x14, 0x15, 0x19, 0x1f, 0x2c, +0x4e, 0xb9, 0xa7, 0x9f, 0x9c, 0x9b, 0x9c, 0x9f, 0xa7, 0xb3, +0xcf, 0x47, 0x34, 0x2d, 0x2a, 0x2a, 0x2c, 0x31, 0x3a, 0x47, +0x5f, 0xe4, 0xd8, 0xd9, 0xe9, 0x64, 0x4f, 0x49, 0x46, 0x49, +0x58, 0xde, 0xc2, 0xb5, 0xad, 0xa8, 0xa6, 0xa6, 0xa9, 0xaf, +0xbf, 0x56, 0x32, 0x26, 0x1e, 0x1b, 0x19, 0x1a, 0x1d, 0x24, +0x33, 0xdd, 0xad, 0x9f, 0x98, 0x94, 0x92, 0x93, 0x97, 0x9e, +0xac, 0xf8, 0x2c, 0x1d, 0x16, 0x11, 0xf, 0x10, 0x15, 0x1b, +0x29, 0x55, 0xae, 0x9e, 0x97, 0x92, 0x90, 0x91, 0x95, 0x9c, +0xa8, 0xca, 0x35, 0x22, 0x1a, 0x16, 0x15, 0x16, 0x19, 0x1f, +0x2b, 0x47, 0xbe, 0xab, 0xa2, 0x9e, 0x9d, 0x9e, 0xa2, 0xa9, +0xb4, 0xcc, 0x4f, 0x3a, 0x32, 0x2f, 0x2f, 0x32, 0x39, 0x41, +0x4f, 0x67, 0xf5, 0xf5, 0x67, 0x51, 0x46, 0x3e, 0x3b, 0x3b, +0x3f, 0x4d, 0xe2, 0xbe, 0xb0, 0xa9, 0xa4, 0xa1, 0xa1, 0xa5, +0xab, 0xba, 0x64, 0x33, 0x25, 0x1d, 0x19, 0x17, 0x18, 0x1b, +0x20, 0x2e, 0x72, 0xae, 0x9f, 0x98, 0x94, 0x91, 0x92, 0x96, +0x9c, 0xa9, 0xd4, 0x2f, 0x1e, 0x17, 0x11, 0xf, 0x10, 0x14, +0x1a, 0x26, 0x48, 0xb2, 0x9f, 0x98, 0x93, 0x91, 0x92, 0x95, +0x9b, 0xa7, 0xc1, 0x3a, 0x25, 0x1c, 0x18, 0x16, 0x17, 0x1a, +0x1f, 0x2b, 0x42, 0xc6, 0xae, 0xa6, 0xa0, 0x9f, 0xa0, 0xa5, +0xab, 0xb6, 0xcb, 0x5a, 0x40, 0x39, 0x36, 0x37, 0x3b, 0x43, +0x4e, 0x60, 0x7b, 0x7c, 0x60, 0x4e, 0x41, 0x3a, 0x34, 0x32, +0x33, 0x39, 0x45, 0xed, 0xbd, 0xae, 0xa6, 0xa0, 0x9e, 0x9e, +0xa0, 0xa8, 0xb4, 0xef, 0x34, 0x24, 0x1c, 0x18, 0x16, 0x16, +0x19, 0x1e, 0x2b, 0x54, 0xb1, 0x9f, 0x98, 0x93, 0x91, 0x91, +0x95, 0x9b, 0xa6, 0xc6, 0x33, 0x1f, 0x17, 0x12, 0xf, 0x10, +0x13, 0x1a, 0x24, 0x3e, 0xb8, 0xa2, 0x99, 0x94, 0x92, 0x92, +0x96, 0x9b, 0xa6, 0xbc, 0x40, 0x29, 0x1e, 0x1a, 0x18, 0x19, +0x1b, 0x20, 0x2b, 0x3f, 0xcf, 0xb3, 0xa9, 0xa5, 0xa3, 0xa4, +0xa8, 0xae, 0xb9, 0xcc, 0x67, 0x49, 0x40, 0x3f, 0x42, 0x4a, +0x59, 0x79, 0xe5, 0xe4, 0x7a, 0x54, 0x43, 0x39, 0x31, 0x2d, +0x2c, 0x2d, 0x32, 0x3e, 0x71, 0xbd, 0xad, 0xa4, 0x9e, 0x9c, +0x9c, 0x9e, 0xa4, 0xaf, 0xd7, 0x36, 0x24, 0x1c, 0x17, 0x15, +0x15, 0x17, 0x1d, 0x28, 0x47, 0xb5, 0xa1, 0x98, 0x93, 0x90, +0x90, 0x93, 0x99, 0xa4, 0xbd, 0x38, 0x21, 0x18, 0x13, 0x10, +0x10, 0x13, 0x19, 0x22, 0x39, 0xbe, 0xa5, 0x9b, 0x96, 0x93, +0x93, 0x96, 0x9b, 0xa5, 0xb9, 0x4a, 0x2c, 0x20, 0x1c, 0x1a, +0x1a, 0x1d, 0x22, 0x2c, 0x3d, 0xdc, 0xb8, 0xad, 0xa9, 0xa8, +0xa9, 0xac, 0xb2, 0xbd, 0xce, 0x78, 0x54, 0x4d, 0x4f, 0x5a, +0xff, 0xda, 0xcf, 0xcd, 0xd4, 0xf8, 0x4e, 0x3d, 0x32, 0x2c, +0x29, 0x28, 0x29, 0x2d, 0x38, 0x5c, 0xbd, 0xac, 0xa2, 0x9d, +0x9a, 0x9a, 0x9c, 0xa0, 0xac, 0xca, 0x39, 0x25, 0x1b, 0x16, +0x13, 0x13, 0x16, 0x1b, 0x25, 0x3e, 0xb9, 0xa2, 0x99, 0x93, +0x90, 0x90, 0x93, 0x98, 0xa1, 0xb8, 0x3d, 0x24, 0x19, 0x13, +0x10, 0x10, 0x13, 0x18, 0x21, 0x35, 0xc7, 0xa8, 0x9d, 0x97, +0x95, 0x95, 0x97, 0x9c, 0xa4, 0xb6, 0x57, 0x2f, 0x24, 0x1e, +0x1c, 0x1c, 0x1e, 0x24, 0x2d, 0x3d, 0xf1, 0xbe, 0xb2, 0xad, +0xac, 0xad, 0xb1, 0xb9, 0xc3, 0xd4, 0xfa, 0x64, 0x65, 0xf9, +0xd9, 0xca, 0xc2, 0xbf, 0xc0, 0xc9, 0xe7, 0x4c, 0x39, 0x2e, +0x28, 0x24, 0x23, 0x25, 0x29, 0x33, 0x4f, 0xbf, 0xab, 0xa0, +0x9b, 0x99, 0x98, 0x9a, 0x9e, 0xa9, 0xc0, 0x3c, 0x26, 0x1b, +0x16, 0x12, 0x12, 0x14, 0x19, 0x22, 0x38, 0xbe, 0xa4, 0x9a, +0x93, 0x90, 0x8f, 0x92, 0x97, 0x9f, 0xb3, 0x46, 0x26, 0x1b, +0x15, 0x11, 0x11, 0x13, 0x18, 0x1f, 0x31, 0xd4, 0xab, 0x9e, +0x99, 0x96, 0x96, 0x98, 0x9c, 0xa4, 0xb4, 0x6f, 0x34, 0x28, +0x20, 0x1e, 0x1e, 0x20, 0x26, 0x2e, 0x3d, 0x6d, 0xc5, 0xb9, +0xb3, 0xb2, 0xb4, 0xba, 0xc1, 0xcd, 0xe0, 0xfc, 0xfb, 0xe0, +0xce, 0xc3, 0xbb, 0xb7, 0xb6, 0xb9, 0xc0, 0xda, 0x4b, 0x36, +0x2b, 0x25, 0x20, 0x1f, 0x20, 0x26, 0x2e, 0x46, 0xc2, 0xab, +0x9f, 0x9a, 0x97, 0x96, 0x98, 0x9c, 0xa5, 0xba, 0x41, 0x27, +0x1b, 0x15, 0x12, 0x11, 0x13, 0x18, 0x1f, 0x32, 0xc8, 0xa6, +0x9a, 0x94, 0x90, 0x8f, 0x91, 0x97, 0x9e, 0xaf, 0x54, 0x29, +0x1c, 0x16, 0x12, 0x11, 0x14, 0x18, 0x1f, 0x2e, 0xf2, 0xae, +0xa0, 0x9b, 0x98, 0x97, 0x99, 0x9d, 0xa5, 0xb3, 0xe4, 0x3a, +0x2b, 0x25, 0x21, 0x21, 0x24, 0x29, 0x30, 0x3e, 0x62, 0xcd, +0xbf, 0xbb, 0xbb, 0xbe, 0xc6, 0xd1, 0xe7, 0x76, 0x75, 0xe7, +0xcf, 0xc1, 0xb9, 0xb2, 0xaf, 0xaf, 0xb2, 0xba, 0xcf, 0x4c, +0x34, 0x29, 0x22, 0x1e, 0x1d, 0x1e, 0x22, 0x2b, 0x3e, 0xc7, +0xab, 0x9f, 0x99, 0x96, 0x95, 0x96, 0x9a, 0xa2, 0xb5, 0x4a, +0x28, 0x1c, 0x15, 0x11, 0x10, 0x12, 0x17, 0x1e, 0x2e, 0xd5, +0xa9, 0x9b, 0x95, 0x90, 0x8f, 0x91, 0x96, 0x9d, 0xac, 0x78, +0x2c, 0x1e, 0x17, 0x13, 0x12, 0x14, 0x18, 0x1f, 0x2d, 0x5d, +0xb3, 0xa4, 0x9d, 0x9a, 0x99, 0x9b, 0x9e, 0xa6, 0xb2, 0xd6, +0x3f, 0x2f, 0x29, 0x26, 0x26, 0x28, 0x2d, 0x35, 0x42, 0x5e, +0xd8, 0xca, 0xc6, 0xc9, 0xcf, 0xe4, 0x69, 0x59, 0x58, 0x64, +0xdf, 0xc7, 0xba, 0xb1, 0xac, 0xaa, 0xaa, 0xad, 0xb4, 0xc7, +0x4f, 0x33, 0x27, 0x1f, 0x1c, 0x1b, 0x1c, 0x1f, 0x27, 0x39, +0xce, 0xac, 0x9f, 0x99, 0x95, 0x94, 0x95, 0x99, 0x9f, 0xaf, +0x59, 0x2a, 0x1c, 0x16, 0x11, 0x10, 0x11, 0x16, 0x1d, 0x2b, +0xff, 0xab, 0x9d, 0x96, 0x91, 0x90, 0x91, 0x96, 0x9c, 0xaa, +0xd9, 0x2f, 0x1f, 0x19, 0x15, 0x14, 0x15, 0x19, 0x1f, 0x2c, +0x4e, 0xb9, 0xa7, 0x9f, 0x9c, 0x9b, 0x9c, 0x9f, 0xa7, 0xb3, +0xcf, 0x47, 0x34, 0x2d, 0x2a, 0x2a, 0x2c, 0x31, 0x3a, 0x47, +0x5f, 0xe4, 0xd8, 0xd9, 0xe9, 0x64, 0x4f, 0x49, 0x46, 0x49, +0x58, 0xde, 0xc2, 0xb5, 0xad, 0xa8, 0xa6, 0xa6, 0xa9, 0xaf, +0xbf, 0x56, 0x32, 0x26, 0x1e, 0x1b, 0x19, 0x1a, 0x1d, 0x24, +0x33, 0xdd, 0xad, 0x9f, 0x98, 0x94, 0x92, 0x93, 0x97, 0x9e, +0xac, 0xf8, 0x2c, 0x1d, 0x16, 0x11, 0xf, 0x10, 0x15, 0x1b, +0x29, 0x55, 0xae, 0x9e, 0x97, 0x92, 0x90, 0x91, 0x95, 0x9c, +0xa8, 0xca, 0x35, 0x22, 0x1a, 0x16, 0x15, 0x16, 0x19, 0x1f, +0x2b, 0x47, 0xbe, 0xab, 0xa2, 0x9e, 0x9d, 0x9e, 0xa2, 0xa9, +0xb4, 0xcc, 0x4f, 0x3a, 0x32, 0x2f, 0x2f, 0x32, 0x39, 0x41, +0x4f, 0x67, 0xf5, 0xf5, 0x67, 0x51, 0x46, 0x3e, 0x3b, 0x3b, +0x3f, 0x4d, 0xe2, 0xbe, 0xb0, 0xa9, 0xa4, 0xa1, 0xa1, 0xa5, +0xab, 0xba, 0x64, 0x33, 0x25, 0x1d, 0x19, 0x17, 0x18, 0x1b, +0x20, 0x2e, 0x72, 0xae, 0x9f, 0x98, 0x94, 0x91, 0x92, 0x96, +0x9c, 0xa9, 0xd4, 0x2f, 0x1e, 0x17, 0x11, 0xf, 0x10, 0x14, +0x1a, 0x26, 0x48, 0xb2, 0x9f, 0x98, 0x93, 0x91, 0x92, 0x95, +0x9b, 0xa7, 0xc1, 0x3a, 0x25, 0x1c, 0x18, 0x16, 0x17, 0x1a, +0x1f, 0x2b, 0x42, 0xc6, 0xae, 0xa6, 0xa0, 0x9f, 0xa0, 0xa5, +0xab, 0xb6, 0xcb, 0x5a, 0x40, 0x39, 0x36, 0x37, 0x3b, 0x43, +0x4e, 0x60, 0x7b, 0x7c, 0x60, 0x4e, 0x41, 0x3a, 0x34, 0x32, +0x33, 0x39, 0x45, 0xed, 0xbd, 0xae, 0xa6, 0xa0, 0x9e, 0x9e, +0xa0, 0xa8, 0xb4, 0xef, 0x34, 0x24, 0x1c, 0x18, 0x16, 0x16, +0x19, 0x1e, 0x2b, 0x54, 0xb1, 0x9f, 0x98, 0x93, 0x91, 0x91, +0x95, 0x9b, 0xa6, 0xc6, 0x33, 0x1f, 0x17, 0x12, 0xf, 0x10, +0x13, 0x1a, 0x24, 0x3e, 0xb8, 0xa2, 0x99, 0x94, 0x92, 0x92, +0x96, 0x9b, 0xa6, 0xbc, 0x40, 0x29, 0x1e, 0x1a, 0x18, 0x19, +0x1b, 0x20, 0x2b, 0x3f, 0xcf, 0xb3, 0xa9, 0xa5, 0xa3, 0xa4, +0xa8, 0xae, 0xb9, 0xcc, 0x67, 0x49, 0x40, 0x3f, 0x42, 0x4a, +0x59, 0x79, 0xe5, 0xe4, 0x7a, 0x54, 0x43, 0x39, 0x31, 0x2d, +0x2c, 0x2d, 0x32, 0x3e, 0x71, 0xbd, 0xad, 0xa4, 0x9e, 0x9c, +0x9c, 0x9e, 0xa4, 0xaf, 0xd7, 0x36, 0x24, 0x1c, 0x17, 0x15, +0x15, 0x17, 0x1d, 0x28, 0x47, 0xb5, 0xa1, 0x98, 0x93, 0x90, +0x90, 0x93, 0x99, 0xa4, 0xbd, 0x38, 0x21, 0x18, 0x13, 0x10, +0x10, 0x13, 0x19, 0x22, 0x39, 0xbe, 0xa5, 0x9b, 0x96, 0x93, +0x93, 0x96, 0x9b, 0xa5, 0xb9, 0x4a, 0x2c, 0x20, 0x1c, 0x1a, +0x1a, 0x1d, 0x22, 0x2c, 0x3d, 0xdc, 0xb8, 0xad, 0xa9, 0xa8, +0xa9, 0xac, 0xb2, 0xbd, 0xce, 0x78, 0x54, 0x4d, 0x4f, 0x5a, +0xff, 0xda, 0xcf, 0xcd, 0xd4, 0xf8, 0x4e, 0x3d, 0x32, 0x2c, +0x29, 0x28, 0x29, 0x2d, 0x38, 0x5c, 0xbd, 0xac, 0xa2, 0x9d, +0x9a, 0x9a, 0x9c, 0xa0, 0xac, 0xca, 0x39, 0x25, 0x1b, 0x16, +0x13, 0x13, 0x16, 0x1b, 0x25, 0x3e, 0xb9, 0xa2, 0x99, 0x93, +0x90, 0x90, 0x93, 0x98, 0xa1, 0xb8, 0x3d, 0x24, 0x19, 0x13, +0x10, 0x10, 0x13, 0x18, 0x21, 0x35, 0xc7, 0xa8, 0x9d, 0x97, +0x95, 0x95, 0x97, 0x9c, 0xa4, 0xb6, 0x57, 0x2f, 0x24, 0x1e, +0x1c, 0x1c, 0x1e, 0x24, 0x2d, 0x3d, 0xf1, 0xbe, 0xb2, 0xad, +0xac, 0xad, 0xb1, 0xb9, 0xc3, 0xd4, 0xfa, 0x64, 0x65, 0xf9, +0xd9, 0xca, 0xc2, 0xbf, 0xc0, 0xc9, 0xe7, 0x4c, 0x39, 0x2e, +0x28, 0x24, 0x23, 0x25, 0x29, 0x33, 0x4f, 0xbf, 0xab, 0xa0, +0x9b, 0x99, 0x98, 0x9a, 0x9e, 0xa9, 0xc0, 0x3c, 0x26, 0x1b, +0x16, 0x12, 0x12, 0x14, 0x19, 0x22, 0x38, 0xbe, 0xa4, 0x9a, +0x93, 0x90, 0x8f, 0x92, 0x97, 0x9f, 0xb3, 0x46, 0x26, 0x1b, +0x15, 0x11, 0x11, 0x13, 0x18, 0x1f, 0x31, 0xd4, 0xab, 0x9e, +0x99, 0x96, 0x96, 0x98, 0x9c, 0xa4, 0xb4, 0x6f, 0x34, 0x28, +0x20, 0x1e, 0x1e, 0x20, 0x26, 0x2e, 0x3d, 0x6d, 0xc5, 0xb9, +0xb3, 0xb2, 0xb4, 0xba, 0xc1, 0xcd, 0xe0, 0xfc, 0xfb, 0xe0, +0xce, 0xc3, 0xbb, 0xb7, 0xb6, 0xb9, 0xc0, 0xda, 0x4b, 0x36, +0x2b, 0x25, 0x20, 0x1f, 0x20, 0x26, 0x2e, 0x46, 0xc2, 0xab, +0x9f, 0x9a, 0x97, 0x96, 0x98, 0x9c, 0xa5, 0xba, 0x41, 0x27, +0x1b, 0x15, 0x12, 0x11, 0x13, 0x18, 0x1f, 0x32, 0xc8, 0xa6, +0x9a, 0x94, 0x90, 0x8f, 0x91, 0x97, 0x9e, 0xaf, 0x54, 0x29, +0x1c, 0x16, 0x12, 0x11, 0x14, 0x18, 0x1f, 0x2e, 0xf2, 0xae, +0xa0, 0x9b, 0x98, 0x97, 0x99, 0x9d, 0xa5, 0xb3, 0xe4, 0x3a, +0x2b, 0x25, 0x21, 0x21, 0x24, 0x29, 0x30, 0x3e, 0x62, 0xcd, +0xbf, 0xbb, 0xbb, 0xbe, 0xc6, 0xd1, 0xe7, 0x76, 0x75, 0xe7, +0xcf, 0xc1, 0xb9, 0xb2, 0xaf, 0xaf, 0xb2, 0xba, 0xcf, 0x4c, +0x34, 0x29, 0x22, 0x1e, 0x1d, 0x1e, 0x22, 0x2b, 0x3e, 0xc7, +0xab, 0x9f, 0x99, 0x96, 0x95, 0x96, 0x9a, 0xa2, 0xb5, 0x4a, +0x28, 0x1c, 0x15, 0x11, 0x10, 0x12, 0x17, 0x1e, 0x2e, 0xd5, +0xa9, 0x9b, 0x95, 0x90, 0x8f, 0x91, 0x96, 0x9d, 0xac, 0x78, +0x2c, 0x1e, 0x17, 0x13, 0x12, 0x14, 0x18, 0x1f, 0x2d, 0x5d, +0xb3, 0xa4, 0x9d, 0x9a, 0x99, 0x9b, 0x9e, 0xa6, 0xb2, 0xd6, +0x3f, 0x2f, 0x29, 0x26, 0x26, 0x28, 0x2d, 0x35, 0x42, 0x5e, +0xd8, 0xca, 0xc6, 0xc9, 0xcf, 0xe4, 0x69, 0x59, 0x58, 0x64, +0xdf, 0xc7, 0xba, 0xb1, 0xac, 0xaa, 0xaa, 0xad, 0xb4, 0xc7, +0x4f, 0x33, 0x27, 0x1f, 0x1c, 0x1b, 0x1c, 0x1f, 0x27, 0x39, +0xce, 0xac, 0x9f, 0x99, 0x95, 0x94, 0x95, 0x99, 0x9f, 0xaf, +0x59, 0x2a, 0x1c, 0x16, 0x11, 0x10, 0x11, 0x16, 0x1d, 0x2b, +0xff, 0xab, 0x9d, 0x96, 0x91, 0x90, 0x91, 0x96, 0x9c, 0xaa, +0xd9, 0x2f, 0x1f, 0x19, 0x15, 0x14, 0x15, 0x19, 0x1f, 0x2c, +0x4e, 0xb9, 0xa7, 0x9f, 0x9c, 0x9b, 0x9c, 0x9f, 0xa7, 0xb3, +0xcf, 0x47, 0x34, 0x2d, 0x2a, 0x2a, 0x2c, 0x31, 0x3a, 0x47, +0x5f, 0xe4, 0xd8, 0xd9, 0xe9, 0x64, 0x4f, 0x49, 0x46, 0x49, +0x58, 0xde, 0xc2, 0xb5, 0xad, 0xa8, 0xa6, 0xa6, 0xa9, 0xaf, +0xbf, 0x56, 0x32, 0x26, 0x1e, 0x1b, 0x19, 0x1a, 0x1d, 0x24, +0x33, 0xdd, 0xad, 0x9f, 0x98, 0x94, 0x92, 0x93, 0x97, 0x9e, +0xac, 0xf8, 0x2c, 0x1d, 0x16, 0x11, 0xf, 0x10, 0x15, 0x1b, +0x29, 0x55, 0xae, 0x9e, 0x97, 0x92, 0x90, 0x91, 0x95, 0x9c, +0xa8, 0xca, 0x35, 0x22, 0x1a, 0x16, 0x15, 0x16, 0x19, 0x1f, +0x2b, 0x47, 0xbe, 0xab, 0xa2, 0x9e, 0x9d, 0x9e, 0xa2, 0xa9, +0xb4, 0xcc, 0x4f, 0x3a, 0x32, 0x2f, 0x2f, 0x32, 0x39, 0x41, +0x4f, 0x67, 0xf5, 0xf5, 0x67, 0x51, 0x46, 0x3e, 0x3b, 0x3b, +0x3f, 0x4d, 0xe2, 0xbe, 0xb0, 0xa9, 0xa4, 0xa1, 0xa1, 0xa5, +0xab, 0xba, 0x64, 0x33, 0x25, 0x1d, 0x19, 0x17, 0x18, 0x1b, +0x20, 0x2e, 0x72, 0xae, 0x9f, 0x98, 0x94, 0x91, 0x92, 0x96, +0x9c, 0xa9, 0xd4, 0x2f, 0x1e, 0x17, 0x11, 0xf, 0x10, 0x14, +0x1a, 0x26, 0x48, 0xb2, 0x9f, 0x98, 0x93, 0x91, 0x92, 0x95, +0x9b, 0xa7, 0xc1, 0x3a, 0x25, 0x1c, 0x18, 0x16, 0x17, 0x1a, +0x1f, 0x2b, 0x42, 0xc6, 0xae, 0xa6, 0xa0, 0x9f, 0xa0, 0xa5, +0xab, 0xb6, 0xcb, 0x5a, 0x40, 0x39, 0x36, 0x37, 0x3b, 0x43, +0x4e, 0x60, 0x7b, 0x7c, 0x60, 0x4e, 0x41, 0x3a, 0x34, 0x32, +0x33, 0x39, 0x45, 0xed, 0xbd, 0xae, 0xa6, 0xa0, 0x9e, 0x9e, +0xa0, 0xa8, 0xb4, 0xef, 0x34, 0x24, 0x1c, 0x18, 0x16, 0x16, +0x19, 0x1e, 0x2b, 0x54, 0xb1, 0x9f, 0x98, 0x93, 0x91, 0x91, +0x95, 0x9b, 0xa6, 0xc6, 0x33, 0x1f, 0x17, 0x12, 0xf, 0x10, +0x13, 0x1a, 0x24, 0x3e, 0xb8, 0xa2, 0x99, 0x94, 0x92, 0x92, +0x96, 0x9b, 0xa6, 0xbc, 0x40, 0x29, 0x1e, 0x1a, 0x18, 0x19, +0x1b, 0x20, 0x2b, 0x3f, 0xcf, 0xb3, 0xa9, 0xa5, 0xa3, 0xa4, +0xa8, 0xae, 0xb9, 0xcc, 0x67, 0x49, 0x40, 0x3f, 0x42, 0x4a, +0x59, 0x79, 0xe5, 0xe4, 0x7a, 0x54, 0x43, 0x39, 0x31, 0x2d, +0x2c, 0x2d, 0x32, 0x3e, 0x71, 0xbd, 0xad, 0xa4, 0x9e, 0x9c, +0x9c, 0x9e, 0xa4, 0xaf, 0xd7, 0x36, 0x24, 0x1c, 0x17, 0x15, +0x15, 0x17, 0x1d, 0x28, 0x47, 0xb5, 0xa1, 0x98, 0x93, 0x90, +0x90, 0x93, 0x99, 0xa4, 0xbd, 0x38, 0x21, 0x18, 0x13, 0x10, +0x10, 0x13, 0x19, 0x22, 0x39, 0xbe, 0xa5, 0x9b, 0x96, 0x93, +0x93, 0x96, 0x9b, 0xa5, 0xb9, 0x4a, 0x2c, 0x20, 0x1c, 0x1a, +0x1a, 0x1d, 0x22, 0x2c, 0x3d, 0xdc, 0xb8, 0xad, 0xa9, 0xa8, +0xa9, 0xac, 0xb2, 0xbd, 0xce, 0x78, 0x54, 0x4d, 0x4f, 0x5a, +0xff, 0xda, 0xcf, 0xcd, 0xd4, 0xf8, 0x4e, 0x3d, 0x32, 0x2c, +0x29, 0x28, 0x29, 0x2d, 0x38, 0x5c, 0xbd, 0xac, 0xa2, 0x9d, +0x9a, 0x9a, 0x9c, 0xa0, 0xac, 0xca, 0x39, 0x25, 0x1b, 0x16, +0x13, 0x13, 0x16, 0x1b, 0x25, 0x3e, 0xb9, 0xa2, 0x99, 0x93, +0x90, 0x90, 0x93, 0x98, 0xa1, 0xb8, 0x3d, 0x24, 0x19, 0x13, +0x10, 0x10, 0x13, 0x18, 0x21, 0x35, 0xc7, 0xa8, 0x9d, 0x97, +0x95, 0x95, 0x97, 0x9c, 0xa4, 0xb6, 0x57, 0x2f, 0x24, 0x1e, +0x1c, 0x1c, 0x1e, 0x24, 0x2d, 0x3d, 0xf1, 0xbe, 0xb2, 0xad, +0xac, 0xad, 0xb1, 0xb9, 0xc3, 0xd4, 0xfa, 0x64, 0x65, 0xf9, +0xd9, 0xca, 0xc2, 0xbf, 0xc0, 0xc9, 0xe7, 0x4c, 0x39, 0x2e, +0x28, 0x24, 0x23, 0x25, 0x29, 0x33, 0x4f, 0xbf, 0xab, 0xa0, +0x9b, 0x99, 0x98, 0x9a, 0x9e, 0xa9, 0xc0, 0x3c, 0x26, 0x1b, +0x16, 0x12, 0x12, 0x14, 0x19, 0x22, 0x38, 0xbe, 0xa4, 0x9a, +0x93, 0x90, 0x8f, 0x92, 0x97, 0x9f, 0xb3, 0x46, 0x26, 0x1b, +0x15, 0x11, 0x11, 0x13, 0x18, 0x1f, 0x31, 0xd4, 0xab, 0x9e, +0x99, 0x96, 0x96, 0x98, 0x9c, 0xa4, 0xb4, 0x6f, 0x34, 0x28, +0x20, 0x1e, 0x1e, 0x20, 0x26, 0x2e, 0x3d, 0x6d, 0xc5, 0xb9, +0xb3, 0xb2, 0xb4, 0xba, 0xc1, 0xcd, 0xe0, 0xfc, 0xfb, 0xe0, +0xce, 0xc3, 0xbb, 0xb7, 0xb6, 0xb9, 0xc0, 0xda, 0x4b, 0x36, +0x2b, 0x25, 0x20, 0x1f, 0x20, 0x26, 0x2e, 0x46, 0xc2, 0xab, +0x9f, 0x9a, 0x97, 0x96, 0x98, 0x9c, 0xa5, 0xba, 0x41, 0x27, +0x1b, 0x15, 0x12, 0x11, 0x13, 0x18, 0x1f, 0x32, 0xc8, 0xa6, +0x9a, 0x94, 0x90, 0x8f, 0x91, 0x97, 0x9e, 0xaf, 0x54, 0x29, +0x1c, 0x16, 0x12, 0x11, 0x14, 0x18, 0x1f, 0x2e, 0xf2, 0xae, +0xa0, 0x9b, 0x98, 0x97, 0x99, 0x9d, 0xa5, 0xb3, 0xe4, 0x3a, +0x2b, 0x25, 0x21, 0x21, 0x24, 0x29, 0x30, 0x3e, 0x62, 0xcd, +0xbf, 0xbb, 0xbb, 0xbe, 0xc6, 0xd1, 0xe7, 0x76, 0x75, 0xe7, +0xcf, 0xc1, 0xb9, 0xb2, 0xaf, 0xaf, 0xb2, 0xba, 0xcf, 0x4c, +0x34, 0x29, 0x22, 0x1e, 0x1d, 0x1e, 0x22, 0x2b, 0x3e, 0xc7, +0xab, 0x9f, 0x99, 0x96, 0x95, 0x96, 0x9a, 0xa2, 0xb5, 0x4a, +0x28, 0x1c, 0x15, 0x11, 0x10, 0x12, 0x17, 0x1e, 0x2e, 0xd5, +0xa9, 0x9b, 0x95, 0x90, 0x8f, 0x91, 0x96, 0x9d, 0xac, 0x78, +0x2c, 0x1e, 0x17, 0x13, 0x12, 0x14, 0x18, 0x1f, 0x2d, 0x5d, +0xb3, 0xa4, 0x9d, 0x9a, 0x99, 0x9b, 0x9e, 0xa6, 0xb2, 0xd6, +0x3f, 0x2f, 0x29, 0x26, 0x26, 0x28, 0x2d, 0x35, 0x42, 0x5e, +0xd8, 0xca, 0xc6, 0xc9, 0xcf, 0xe4, 0x69, 0x59, 0x58, 0x64, +0xdf, 0xc7, 0xba, 0xb1, 0xac, 0xaa, 0xaa, 0xad, 0xb4, 0xc7, +0x4f, 0x33, 0x27, 0x1f, 0x1c, 0x1b, 0x1c, 0x1f, 0x27, 0x39, +0xce, 0xac, 0x9f, 0x99, 0x95, 0x94, 0x95, 0x99, 0x9f, 0xaf, 0x59, 0x2a, 0x1c, 0x16, 0x11, 0x10, 0x11, 0x16, 0x1d, 0x2b }; diff --git a/channels/chan_pjsip.c b/channels/chan_pjsip.c index e4e8fa586..2c111feeb 100644 --- a/channels/chan_pjsip.c +++ b/channels/chan_pjsip.c @@ -605,6 +605,11 @@ static struct ast_channel *chan_pjsip_new(struct ast_sip_session *session, int s ast_party_id_copy(&ast_channel_caller(chan)->id, &session->id); ast_party_id_copy(&ast_channel_caller(chan)->ani, &session->id); + if (!ast_strlen_zero(exten)) { + /* Set provided DNID on the new channel. */ + ast_channel_dialed(chan)->number.str = ast_strdup(exten); + } + ast_channel_priority_set(chan, 1); ast_channel_callgroup_set(chan, session->endpoint->pickup.callgroup); @@ -786,7 +791,7 @@ static struct ast_frame *chan_pjsip_cng_tone_detected(struct ast_sip_session *se } /*! - * \brief Function called by core to read any waiting frames + * \brief Function called by core to read any waiting frames * * \note The channel is already locked. */ @@ -2376,7 +2381,7 @@ static int request(void *obj) struct request_data *req_data = obj; struct ast_sip_session *session = NULL; char *tmp = ast_strdupa(req_data->dest), *endpoint_name = NULL, *request_user = NULL; - RAII_VAR(struct ast_sip_endpoint *, endpoint, NULL, ao2_cleanup); + struct ast_sip_endpoint *endpoint; AST_DECLARE_APP_ARGS(args, AST_APP_ARG(endpoint); @@ -2401,10 +2406,18 @@ static int request(void *obj) } if (ast_strlen_zero(endpoint_name)) { - ast_log(LOG_ERROR, "Unable to create PJSIP channel with empty endpoint name\n"); + if (request_user) { + ast_log(LOG_ERROR, "Unable to create PJSIP channel with empty endpoint name: %s@<endpoint-name>\n", + request_user); + } else { + ast_log(LOG_ERROR, "Unable to create PJSIP channel with empty endpoint name\n"); + } req_data->cause = AST_CAUSE_CHANNEL_UNACCEPTABLE; return -1; - } else if (!(endpoint = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "endpoint", endpoint_name))) { + } + endpoint = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "endpoint", + endpoint_name); + if (!endpoint) { ast_log(LOG_ERROR, "Unable to create PJSIP channel - endpoint '%s' was not found\n", endpoint_name); req_data->cause = AST_CAUSE_NO_ROUTE_DESTINATION; return -1; @@ -2416,23 +2429,38 @@ static int request(void *obj) ast_log(LOG_ERROR, "Unable to create PJSIP channel with empty endpoint name\n"); req_data->cause = AST_CAUSE_CHANNEL_UNACCEPTABLE; return -1; - } else if (!(endpoint = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "endpoint", endpoint_name))) { + } + endpoint = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "endpoint", + endpoint_name); + if (!endpoint) { /* It seems it's not a multi-domain endpoint or single endpoint exact match, * it's possible that it's a SIP trunk with a specified user (user@trunkname), * so extract the user before @ sign. */ - if ((endpoint_name = strchr(args.endpoint, '@'))) { - request_user = args.endpoint; - *endpoint_name++ = '\0'; + endpoint_name = strchr(args.endpoint, '@'); + if (!endpoint_name) { + /* + * Couldn't find an '@' so it had to be an endpoint + * name that doesn't exist. + */ + ast_log(LOG_ERROR, "Unable to create PJSIP channel - endpoint '%s' was not found\n", + args.endpoint); + req_data->cause = AST_CAUSE_NO_ROUTE_DESTINATION; + return -1; } + request_user = args.endpoint; + *endpoint_name++ = '\0'; if (ast_strlen_zero(endpoint_name)) { - ast_log(LOG_ERROR, "Unable to create PJSIP channel with empty endpoint name\n"); + ast_log(LOG_ERROR, "Unable to create PJSIP channel with empty endpoint name: %s@<endpoint-name>\n", + request_user); req_data->cause = AST_CAUSE_CHANNEL_UNACCEPTABLE; return -1; } - if (!(endpoint = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "endpoint", endpoint_name))) { + endpoint = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "endpoint", + endpoint_name); + if (!endpoint) { ast_log(LOG_ERROR, "Unable to create PJSIP channel - endpoint '%s' was not found\n", endpoint_name); req_data->cause = AST_CAUSE_NO_ROUTE_DESTINATION; return -1; @@ -2440,7 +2468,10 @@ static int request(void *obj) } } - if (!(session = ast_sip_session_create_outgoing(endpoint, NULL, args.aor, request_user, req_data->topology))) { + session = ast_sip_session_create_outgoing(endpoint, NULL, args.aor, request_user, + req_data->topology); + ao2_ref(endpoint, -1); + if (!session) { ast_log(LOG_ERROR, "Failed to create outgoing session to endpoint '%s'\n", endpoint_name); req_data->cause = AST_CAUSE_NO_ROUTE_DESTINATION; return -1; @@ -2950,8 +2981,6 @@ static int load_module(void) { struct ao2_container *endpoints; - CHECK_PJSIP_SESSION_MODULE_LOADED(); - if (!(chan_pjsip_tech.capabilities = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT))) { return AST_MODULE_LOAD_DECLINE; } @@ -2985,10 +3014,7 @@ static int load_module(void) goto end; } - if (ast_sip_session_register_supplement(&chan_pjsip_supplement)) { - ast_log(LOG_ERROR, "Unable to register PJSIP supplement\n"); - goto end; - } + ast_sip_session_register_supplement(&chan_pjsip_supplement); if (!(pjsip_uids_onhold = ao2_container_alloc_hash(AO2_ALLOC_OPT_LOCK_RWLOCK, AO2_CONTAINER_ALLOC_OPT_DUPS_REJECT, 37, uid_hold_hash_fn, @@ -2997,26 +3023,9 @@ static int load_module(void) goto end; } - if (ast_sip_session_register_supplement(&call_pickup_supplement)) { - ast_log(LOG_ERROR, "Unable to register PJSIP call pickup supplement\n"); - ast_sip_session_unregister_supplement(&chan_pjsip_supplement); - goto end; - } - - if (ast_sip_session_register_supplement(&pbx_start_supplement)) { - ast_log(LOG_ERROR, "Unable to register PJSIP pbx start supplement\n"); - ast_sip_session_unregister_supplement(&chan_pjsip_supplement); - ast_sip_session_unregister_supplement(&call_pickup_supplement); - goto end; - } - - if (ast_sip_session_register_supplement(&chan_pjsip_ack_supplement)) { - ast_log(LOG_ERROR, "Unable to register PJSIP ACK supplement\n"); - ast_sip_session_unregister_supplement(&pbx_start_supplement); - ast_sip_session_unregister_supplement(&chan_pjsip_supplement); - ast_sip_session_unregister_supplement(&call_pickup_supplement); - goto end; - } + ast_sip_session_register_supplement(&call_pickup_supplement); + ast_sip_session_register_supplement(&pbx_start_supplement); + ast_sip_session_register_supplement(&chan_pjsip_ack_supplement); if (pjsip_channel_cli_register()) { ast_log(LOG_ERROR, "Unable to register PJSIP Channel CLI\n"); @@ -3079,4 +3088,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "PJSIP Channel Driver" .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_CHANNEL_DRIVER, + .requires = "res_pjsip,res_pjsip_session", ); diff --git a/channels/chan_rtp.c b/channels/chan_rtp.c index 0a59e330e..7d9e26db8 100644 --- a/channels/chan_rtp.c +++ b/channels/chan_rtp.c @@ -432,4 +432,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "RTP Media Channel", .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_CHANNEL_DRIVER, + .requires = "res_rtp_multicast", ); diff --git a/channels/chan_sip.c b/channels/chan_sip.c index 72436dfa1..138021e82 100644 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -593,6 +593,9 @@ <para>At least one variable pair must be specified. <replaceable>name</replaceable>=<replaceable>value</replaceable></para> </parameter> + <parameter name="Call-ID" required="false"> + <para>When specified, SIP notity will be sent as a part of an existing dialog.</para> + </parameter> </syntax> <description> <para>Sends a SIP Notify event.</para> @@ -9283,7 +9286,7 @@ static enum match_req_res match_req_to_dialog(struct sip_pvt *sip_pvt_ptr, struc } /*! \brief This function creates a dialog to handle a forked request. This dialog - * exists only to properly terminiate the the forked request immediately. + * exists only to properly terminiate the forked request immediately. */ static void forked_invite_init(struct sip_request *req, const char *new_theirtag, struct sip_pvt *original, struct ast_sockaddr *addr) { @@ -10961,22 +10964,25 @@ static int process_sdp(struct sip_pvt *p, struct sip_request *req, int t38action if (portno != -1 || vportno != -1 || tportno != -1) { /* We are now ready to change the sip session and RTP structures with the offered codecs, since they are acceptable */ + unsigned int framing; ast_format_cap_remove_by_type(p->jointcaps, AST_MEDIA_TYPE_UNKNOWN); ast_format_cap_append_from_cap(p->jointcaps, newjointcapability, AST_MEDIA_TYPE_UNKNOWN); /* Our joint codec profile for this call */ ast_format_cap_remove_by_type(p->peercaps, AST_MEDIA_TYPE_UNKNOWN); ast_format_cap_append_from_cap(p->peercaps, newpeercapability, AST_MEDIA_TYPE_UNKNOWN); /* The other side's capability in latest offer */ p->jointnoncodeccapability = newnoncodeccapability; /* DTMF capabilities */ + tmp_fmt = ast_format_cap_get_format(p->jointcaps, 0); + framing = ast_format_cap_get_format_framing(p->jointcaps, tmp_fmt); /* respond with single most preferred joint codec, limiting the other side's choice */ if (ast_test_flag(&p->flags[1], SIP_PAGE2_PREFERRED_CODEC)) { - unsigned int framing; - - tmp_fmt = ast_format_cap_get_format(p->jointcaps, 0); - framing = ast_format_cap_get_format_framing(p->jointcaps, tmp_fmt); ast_format_cap_remove_by_type(p->jointcaps, AST_MEDIA_TYPE_UNKNOWN); ast_format_cap_append(p->jointcaps, tmp_fmt, framing); - ao2_ref(tmp_fmt, -1); } + if (!ast_rtp_codecs_get_framing(&newaudiortp)) { + /* Peer did not force us to use a specific framing, so use our own */ + ast_rtp_codecs_set_framing(&newaudiortp, framing); + } + ao2_ref(tmp_fmt, -1); } /* Setup audio address and port */ @@ -11340,7 +11346,7 @@ static int process_sdp_a_ice(const char *a, struct sip_pvt *p, struct ast_rtp_in { struct ast_rtp_engine_ice *ice; int found = FALSE; - char ufrag[256], pwd[256], foundation[32], transport[4], address[46], cand_type[6], relay_address[46] = ""; + char ufrag[256], pwd[256], foundation[33], transport[4], address[46], cand_type[6], relay_address[46] = ""; struct ast_rtp_engine_ice_candidate candidate = { 0, }; unsigned int port, relay_port = 0; @@ -11354,7 +11360,7 @@ static int process_sdp_a_ice(const char *a, struct sip_pvt *p, struct ast_rtp_in } else if (sscanf(a, "ice-pwd: %255s", pwd) == 1) { ice->set_authentication(instance, NULL, pwd); found = TRUE; - } else if (sscanf(a, "candidate: %31s %30u %3s %30u %23s %30u typ %5s %*s %23s %*s %30u", foundation, &candidate.id, transport, (unsigned *)&candidate.priority, + } else if (sscanf(a, "candidate: %32s %30u %3s %30u %23s %30u typ %5s %*s %23s %*s %30u", foundation, &candidate.id, transport, (unsigned *)&candidate.priority, address, &port, cand_type, relay_address, &relay_port) >= 7) { if (rtcp_mux_offered && ast_test_flag(&p->flags[2], SIP_PAGE3_RTCP_MUX) && candidate.id > 1) { @@ -11485,6 +11491,7 @@ static int process_sdp_a_audio(const char *a, struct sip_pvt *p, struct ast_rtp_ if (framing && p->autoframing) { ast_debug(1, "Setting framing to %ld\n", framing); ast_format_cap_set_framing(p->caps, framing); + ast_rtp_codecs_set_framing(newaudiortp, framing); } found = TRUE; } else if (sscanf(a, "rtpmap: %30u %127[^/]/%30u", &codec, mimeSubtype, &sample_rate) == 3) { @@ -15591,11 +15598,13 @@ static int manager_sipnotify(struct mansession *s, const struct message *m) { const char *channame = astman_get_header(m, "Channel"); struct ast_variable *vars = astman_get_variables_order(m, ORDER_NATURAL); + const char *callid = astman_get_header(m, "Call-ID"); struct sip_pvt *p; struct ast_variable *header, *var; if (ast_strlen_zero(channame)) { astman_send_error(s, m, "SIPNotify requires a channel name"); + ast_variables_destroy(vars); return 0; } @@ -15603,23 +15612,46 @@ static int manager_sipnotify(struct mansession *s, const struct message *m) channame += 4; } - if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY, NULL, 0))) { - astman_send_error(s, m, "Unable to build sip pvt data for notify (memory/socket error)"); - return 0; - } + /* check if Call-ID header is set */ + if (!ast_strlen_zero(callid)) { + struct sip_pvt tmp_dialog = { + .callid = callid, + }; - if (create_addr(p, channame, NULL, 0)) { - /* Maybe they're not registered, etc. */ - dialog_unlink_all(p); - dialog_unref(p, "unref dialog inside for loop" ); - /* sip_destroy(p); */ - astman_send_error(s, m, "Could not create address"); - return 0; - } + p = ao2_find(dialogs, &tmp_dialog, OBJ_SEARCH_OBJECT); + if (!p) { + astman_send_error(s, m, "Call-ID not found"); + ast_variables_destroy(vars); + return 0; + } - /* Notify is outgoing call */ - ast_set_flag(&p->flags[0], SIP_OUTGOING); - sip_notify_alloc(p); + if (!(p->notify)) { + sip_notify_alloc(p); + } else { + ast_variables_destroy(p->notify->headers); + } + } else { + if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY, NULL, 0))) { + astman_send_error(s, m, "Unable to build sip pvt data for notify (memory/socket error)"); + ast_variables_destroy(vars); + return 0; + } + + if (create_addr(p, channame, NULL, 0)) { + /* Maybe they're not registered, etc. */ + dialog_unlink_all(p); + dialog_unref(p, "unref dialog inside for loop" ); + /* sip_destroy(p); */ + astman_send_error(s, m, "Could not create address"); + ast_variables_destroy(vars); + return 0; + } + + /* Notify is outgoing call */ + ast_set_flag(&p->flags[0], SIP_OUTGOING); + sip_notify_alloc(p); + + } p->notify->headers = header = ast_variable_new("Subscription-State", "terminated", ""); @@ -15636,14 +15668,19 @@ static int manager_sipnotify(struct mansession *s, const struct message *m) } } - /* Now that we have the peer's address, set our ip and change callid */ - ast_sip_ouraddrfor(&p->sa, &p->ourip, p); - build_via(p); + if (ast_strlen_zero(callid)) { + /* Now that we have the peer's address, set our ip and change callid */ + ast_sip_ouraddrfor(&p->sa, &p->ourip, p); + build_via(p); - change_callid_pvt(p, NULL); + change_callid_pvt(p, NULL); - sip_scheddestroy(p, SIP_TRANS_TIMEOUT); - transmit_invite(p, SIP_NOTIFY, 0, 2, NULL); + sip_scheddestroy(p, SIP_TRANS_TIMEOUT); + transmit_invite(p, SIP_NOTIFY, 0, 2, NULL); + } else { + sip_scheddestroy(p, SIP_TRANS_TIMEOUT); + transmit_invite(p, SIP_NOTIFY, 0, 1, NULL); + } dialog_unref(p, "bump down the count of p since we're done with it."); astman_send_ack(s, m, "Notify Sent"); @@ -15775,7 +15812,7 @@ static int sip_reregister(const void *data) if (r->call && r->call->do_history) { append_history(r->call, "RegistryRenew", "Account: %s@%s", r->username, r->hostname); } - /* Since registry's are only added/removed by the the monitor thread, this + /* Since registry's are only added/removed by the monitor thread, this may be overkill to reference/dereference at all here */ if (sipdebug) { ast_log(LOG_NOTICE, " -- Re-registration for %s@%s\n", r->username, r->hostname); @@ -22442,7 +22479,7 @@ static void sip_dump_history(struct sip_pvt *dialog) return; } - if (!option_debug && !sipdebug) { + if (!sipdebug && !DEBUG_ATLEAST(1)) { if (!errmsg) { ast_log(LOG_NOTICE, "You must have debugging enabled (SIP or Asterisk) in order to dump SIP history.\n"); errmsg = 1; @@ -22450,20 +22487,20 @@ static void sip_dump_history(struct sip_pvt *dialog) return; } - ast_debug(1, "\n---------- SIP HISTORY for '%s' \n", dialog->callid); + ast_log(LOG_DEBUG, "\n---------- SIP HISTORY for '%s' \n", dialog->callid); if (dialog->subscribed) { - ast_debug(1, " * Subscription\n"); + ast_log(LOG_DEBUG, " * Subscription\n"); } else { - ast_debug(1, " * SIP Call\n"); + ast_log(LOG_DEBUG, " * SIP Call\n"); } if (dialog->history) { AST_LIST_TRAVERSE(dialog->history, hist, list) - ast_debug(1, " %-3.3d. %s\n", ++x, hist->event); + ast_log(LOG_DEBUG, " %-3.3d. %s\n", ++x, hist->event); } if (!x) { - ast_debug(1, "Call '%s' has no history\n", dialog->callid); + ast_log(LOG_DEBUG, "Call '%s' has no history\n", dialog->callid); } - ast_debug(1, "\n---------- END SIP HISTORY for '%s' \n", dialog->callid); + ast_log(LOG_DEBUG, "\n---------- END SIP HISTORY for '%s' \n", dialog->callid); } @@ -23397,6 +23434,8 @@ static void change_redirecting_information(struct sip_pvt *p, struct sip_request redirecting->from.number.valid = 1; ast_free(redirecting->from.number.str); redirecting->from.number.str = redirecting_from_number; + } else { + ast_free(redirecting_from_number); } if (!ast_strlen_zero(redirecting_from_name)) { ast_debug(3, "Got redirecting from name %s\n", redirecting_from_name); @@ -23404,6 +23443,8 @@ static void change_redirecting_information(struct sip_pvt *p, struct sip_request redirecting->from.name.valid = 1; ast_free(redirecting->from.name.str); redirecting->from.name.str = redirecting_from_name; + } else { + ast_free(redirecting_from_name); } if (!ast_strlen_zero(p->cid_tag)) { ast_free(redirecting->from.tag); @@ -23417,13 +23458,17 @@ static void change_redirecting_information(struct sip_pvt *p, struct sip_request redirecting->to.number.valid = 1; ast_free(redirecting->to.number.str); redirecting->to.number.str = redirecting_to_number; + } else { + ast_free(redirecting_to_number); } if (!ast_strlen_zero(redirecting_to_name)) { - ast_debug(3, "Got redirecting to name %s\n", redirecting_from_number); + ast_debug(3, "Got redirecting to name %s\n", redirecting_to_name); update_redirecting->to.name = 1; redirecting->to.name.valid = 1; ast_free(redirecting->to.name.str); redirecting->to.name.str = redirecting_to_name; + } else { + ast_free(redirecting_to_name); } redirecting->reason.code = reason; ast_free(redirecting->reason.str); @@ -23943,6 +23988,9 @@ static void handle_response_invite(struct sip_pvt *p, int resp, const char *rest ast_queue_control(p->owner, AST_CONTROL_RINGING); if (ast_channel_state(p->owner) != AST_STATE_UP) { ast_setstate(p->owner, AST_STATE_RINGING); + if (p->relatedpeer) { + ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_NOT_CACHABLE, "SIP/%s", p->relatedpeer->name); + } } } if (find_sdp(req)) { @@ -24453,6 +24501,7 @@ static void handle_response_subscribe(struct sip_pvt *p, int resp, const char *r ast_cc_monitor_failed(monitor_instance->core_id, monitor_instance->device_name, "Received error response to our SUBSCRIBE"); + ao2_ref(monitor_instance, -1); } return; } @@ -26305,7 +26354,7 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, str if (p->owner) { ast_debug(3, "INVITE w Replaces on existing call? Refusing action. [%s]\n", p->callid); - transmit_response_reliable(p, "400 Bad request", req); /* The best way to not not accept the transfer */ + transmit_response_reliable(p, "400 Bad request", req); /* The best way to not accept the transfer */ check_via(p, req); copy_request(&p->initreq, req); /* Do not destroy existing call */ @@ -26393,7 +26442,7 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, str if (replaces_pvt == p) { ast_log(LOG_NOTICE, "INVITE with replaces into it's own call id (%s == %s)!\n", replace_id, p->callid); - transmit_response_reliable(p, "400 Bad request", req); /* The best way to not not accept the transfer */ + transmit_response_reliable(p, "400 Bad request", req); /* The best way to not accept the transfer */ error = 1; } @@ -26621,6 +26670,7 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, str ast_log(LOG_NOTICE, "Call from '%s' (%s) to extension" " '%s' rejected because extension not found in context '%s'.\n", S_OR(p->username, p->peername), ast_sockaddr_stringify(&p->recv), decoded_exten, p->context); + sip_report_failed_acl(p, "no_extension_match"); } break; case SIP_GET_DEST_REFUSED: @@ -27382,7 +27432,7 @@ static int handle_request_cancel(struct sip_pvt *p, struct sip_request *req) } else { sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); } - if (ast_str_strlen(p->initreq.data) > 0) { + if (p->initreq.data && ast_str_strlen(p->initreq.data) > 0) { struct sip_pkt *pkt, *prev_pkt; /* If the CANCEL we are receiving is a retransmission, and we already have scheduled * a reliable 487, then we don't want to schedule another one on top of the previous @@ -29407,7 +29457,7 @@ static int sip_prepare_socket(struct sip_pvt *p) return s->fd; } if ((s->type & (AST_TRANSPORT_TCP | AST_TRANSPORT_TLS)) && - s->tcptls_session) { + s->tcptls_session && s->tcptls_session->stream) { return ast_iostream_get_fd(s->tcptls_session->stream); } if ((s->type & (AST_TRANSPORT_WS | AST_TRANSPORT_WSS))) { @@ -30286,6 +30336,7 @@ static int sip_send_keepalive(const void *data) struct sip_peer *peer = (struct sip_peer*) data; int res = 0; const char keepalive[] = "\r\n"; + size_t count = sizeof(keepalive) - 1; peer->keepalivesend = -1; @@ -30296,12 +30347,12 @@ static int sip_send_keepalive(const void *data) /* Send the packet out using the proper method for this peer */ if ((peer->socket.fd != -1) && (peer->socket.type == AST_TRANSPORT_UDP)) { - res = ast_sendto(peer->socket.fd, keepalive, sizeof(keepalive), 0, &peer->addr); + res = ast_sendto(peer->socket.fd, keepalive, count, 0, &peer->addr); } else if ((peer->socket.type & (AST_TRANSPORT_TCP | AST_TRANSPORT_TLS)) && peer->socket.tcptls_session) { - res = sip_tcptls_write(peer->socket.tcptls_session, keepalive, sizeof(keepalive)); + res = sip_tcptls_write(peer->socket.tcptls_session, keepalive, count); } else if (peer->socket.type == AST_TRANSPORT_UDP) { - res = ast_sendto(sipsock, keepalive, sizeof(keepalive), 0, &peer->addr); + res = ast_sendto(sipsock, keepalive, count, 0, &peer->addr); } if (res == -1) { @@ -30315,7 +30366,7 @@ static int sip_send_keepalive(const void *data) } } - if (res != sizeof(keepalive)) { + if (res != count) { ast_log(LOG_WARNING, "sip_send_keepalive to %s returned %d: %s\n", ast_sockaddr_stringify(&peer->addr), res, strerror(errno)); } @@ -30715,6 +30766,14 @@ static struct ast_channel *sip_request_call(const char *type, struct ast_format_ } } + /* If stripping the DNID left us with nothing, bail out */ + if (ast_strlen_zero(tmp)) { + dialog_unlink_all(p); + dialog_unref(p, "unref dialog p from bad destination"); + *cause = AST_CAUSE_DESTINATION_OUT_OF_ORDER; + return NULL; + } + /* Divvy up the items separated by slashes */ AST_NONSTANDARD_APP_ARGS(args, tmp, '/'); @@ -34334,7 +34393,7 @@ static int peer_cmp_cb(void *obj, void *arg, int flags) } /*! - * Hash function based on the the peer's ip address. For IPv6, we use the end + * Hash function based on the peer's ip address. For IPv6, we use the end * of the address. * \todo Find a better hashing function */ @@ -35684,5 +35743,6 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Session Initiation Pr .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_CHANNEL_DRIVER, - .nonoptreq = "res_crypto,res_http_websocket", + .requires = "ccss,dnsmgr,udptl", + .optional_modules = "res_crypto,res_http_websocket", ); diff --git a/channels/chan_skinny.c b/channels/chan_skinny.c index 6f4231acd..0093a1fcb 100644 --- a/channels/chan_skinny.c +++ b/channels/chan_skinny.c @@ -4753,15 +4753,19 @@ static void start_rtp(struct skinny_subchannel *sub) { struct skinny_line *l = sub->line; struct skinny_device *d = l->device; +#if 0 int hasvideo = 0; +#endif struct ast_sockaddr bindaddr_tmp; skinny_locksub(sub); SKINNY_DEBUG(DEBUG_AUDIO, 3, "Sub %u - Starting RTP\n", sub->callid); ast_sockaddr_from_sin(&bindaddr_tmp, &bindaddr); sub->rtp = ast_rtp_instance_new("asterisk", sched, &bindaddr_tmp, NULL); +#if 0 if (hasvideo) sub->vrtp = ast_rtp_instance_new("asterisk", sched, &bindaddr_tmp, NULL); +#endif if (sub->rtp) { ast_rtp_instance_set_prop(sub->rtp, AST_RTP_PROPERTY_RTCP, 1); @@ -4775,11 +4779,13 @@ static void start_rtp(struct skinny_subchannel *sub) ast_channel_set_fd(sub->owner, 0, ast_rtp_instance_fd(sub->rtp, 0)); ast_channel_set_fd(sub->owner, 1, ast_rtp_instance_fd(sub->rtp, 1)); } +#if 0 if (hasvideo && sub->vrtp && sub->owner) { ast_rtp_instance_set_channel_id(sub->vrtp, ast_channel_uniqueid(sub->owner)); ast_channel_set_fd(sub->owner, 2, ast_rtp_instance_fd(sub->vrtp, 0)); ast_channel_set_fd(sub->owner, 3, ast_rtp_instance_fd(sub->vrtp, 1)); } +#endif if (sub->rtp) { ast_rtp_instance_set_qos(sub->rtp, qos.tos_audio, qos.cos_audio, "Skinny RTP"); ast_rtp_instance_set_prop(sub->rtp, AST_RTP_PROPERTY_NAT, l->nat); diff --git a/channels/chan_unistim.c b/channels/chan_unistim.c index f124c0f2b..28d84eeea 100644 --- a/channels/chan_unistim.c +++ b/channels/chan_unistim.c @@ -41,7 +41,7 @@ #include <sys/stat.h> #include <signal.h> -#if defined(__CYGWIN__) +#if defined(__CYGWIN__) || defined(__NetBSD__) /* * cygwin headers are partly inconsistent. struct iovec is defined in sys/uio.h * which is not included by default by sys/socket.h - in_pktinfo is defined in @@ -53,7 +53,7 @@ #ifdef HAVE_PKTINFO #undef HAVE_PKTINFO #endif -#endif /* __CYGWIN__ */ +#endif /* __CYGWIN__ || __NetBSD__ */ #include "asterisk/paths.h" /* ast_config_AST_LOG_DIR used in (too ?) many places */ #include "asterisk/network.h" @@ -114,7 +114,6 @@ #define SUB_REAL 0 #define SUB_RING 1 #define SUB_THREEWAY 2 -#define SUB_ONHOLD 3 struct ast_format_cap *global_cap; @@ -351,13 +350,14 @@ struct wsabuf { struct unistim_subchannel { ast_mutex_t lock; - unsigned int subtype; /*! SUB_REAL, SUB_RING, SUB_THREEWAY or SUB_ONHOLD */ + unsigned int subtype; /*! SUB_REAL, SUB_RING or SUB_THREEWAY */ struct ast_channel *owner; /*! Asterisk channel used by the subchannel */ struct unistim_line *parent; /*! Unistim line */ struct ast_rtp_instance *rtp; /*! RTP handle */ int softkey; /*! Softkey assigned */ pthread_t ss_thread; /*! unistim_ss thread handle */ int alreadygone; + int holding; /*! this subchannel holds someone */ signed char ringvolume; signed char ringstyle; int moh; /*!< Music on hold in progress */ @@ -2015,8 +2015,6 @@ static const char *subtype_tostr(const int type) switch (type) { case SUB_REAL: return "REAL"; - case SUB_ONHOLD: - return "ONHOLD"; case SUB_RING: return "RINGING"; case SUB_THREEWAY: @@ -2496,6 +2494,24 @@ static struct unistim_subchannel* get_sub(struct unistim_device *device, int typ return sub; } +static struct unistim_subchannel* get_sub_holding(struct unistim_device *device, int type, int holding) +{ + struct unistim_subchannel *sub = NULL; + + AST_LIST_LOCK(&device->subs); + AST_LIST_TRAVERSE(&device->subs, sub, list) { + if (!sub) { + continue; + } + if (sub->subtype == type && sub->holding == holding) { + break; + } + } + AST_LIST_UNLOCK(&device->subs); + + return sub; +} + static void sub_start_silence(struct unistimsession *pte, struct unistim_subchannel *sub) { /* Silence our channel */ @@ -2533,13 +2549,12 @@ static void sub_hold(struct unistimsession *pte, struct unistim_subchannel *sub) return; } sub->moh = 1; - sub->subtype = SUB_ONHOLD; + sub->holding = 1; send_favorite_short(sub->softkey, FAV_ICON_ONHOLD_BLACK + FAV_BLINK_SLOW, pte); send_select_output(pte, pte->device->output, pte->device->volume, MUTE_ON); send_stop_timer(pte); if (sub->owner) { ast_queue_hold(sub->owner, NULL); - send_end_call(pte); } return; } @@ -2554,7 +2569,7 @@ static void sub_unhold(struct unistimsession *pte, struct unistim_subchannel *su } sub->moh = 0; - sub->subtype = SUB_REAL; + sub->holding = 0; send_favorite_short(sub->softkey, FAV_ICON_OFFHOOK_BLACK, pte); send_select_output(pte, pte->device->output, pte->device->volume, MUTE_OFF); send_start_timer(pte); @@ -3355,12 +3370,12 @@ static int unistim_do_senddigit(struct unistimsession *pte, char digit) static void handle_key_fav(struct unistimsession *pte, char keycode) { int keynum = keycode - KEY_FAV0; - struct unistim_subchannel *sub; - - sub = get_sub(pte->device, SUB_REAL); + struct unistim_subchannel *sub, *sub_key = NULL; + sub = get_sub_holding(pte->device, SUB_REAL, 0); /* Make an action on selected favorite key */ if (!pte->device->ssub[keynum]) { /* Key have no assigned call */ + sub = get_sub_holding(pte->device, SUB_REAL, 0); send_favorite_selected(FAV_LINE_ICON, pte); if (is_key_line(pte->device, keynum)) { if (unistimdebug) { @@ -3385,21 +3400,24 @@ static void handle_key_fav(struct unistimsession *pte, char keycode) key_favorite(pte, keycode); } } else { - sub = pte->device->ssub[keynum]; + sub_key = pte->device->ssub[keynum]; /* Favicon have assigned sub, activate it and put current on hold */ - if (sub->subtype == SUB_REAL) { - sub_hold(pte, sub); + if (sub_key->subtype == SUB_REAL && !sub_key->holding) { + sub_hold(pte, sub_key); show_main_page(pte); - } else if (sub->subtype == SUB_RING) { - sub->softkey = keynum; - handle_call_incoming(pte); - } else if (sub->subtype == SUB_ONHOLD) { + } else if (sub_key->subtype == SUB_REAL && sub_key->holding) { + /* We are going to unhold line (we should put active line on hold, of any) */ if (pte->state == STATE_DIALPAGE){ send_tone(pte, 0, 0); } - send_callerid_screen(pte, sub); - sub_unhold(pte, sub); + sub_hold(pte, sub); + send_callerid_screen(pte, sub_key); + sub_unhold(pte, sub_key); pte->state = STATE_CALL; + } else if (sub_key->subtype == SUB_RING) { + sub_hold(pte, sub); + sub_key->softkey = keynum; + handle_call_incoming(pte); } } } @@ -3469,8 +3487,13 @@ static void key_call(struct unistimsession *pte, char keycode) case KEY_ONHOLD: if (!sub) { if(pte->device->ssub[pte->device->selected]) { - sub_hold(pte, pte->device->ssub[pte->device->selected]); + sub = pte->device->ssub[pte->device->selected]; + } else { + break; } + } + if (sub->holding) { + sub_unhold(pte, sub); } else { sub_hold(pte, sub); } @@ -4484,7 +4507,7 @@ static void process_request(int size, unsigned char *buf, struct unistimsession } if (!memcmp(buf + SIZE_HEADER, packet_recv_expansion_pressed_key, sizeof(packet_recv_expansion_pressed_key))) { char keycode = buf[13]; - + if (unistimdebug) { ast_verb(0, "Expansion key pressed: keycode = 0x%02hhx - current state: %s\n", (unsigned char)keycode, ptestate_tostr(pte->state)); @@ -4964,7 +4987,7 @@ static int unistim_hangup(struct ast_channel *ast) continue; } if (d->ssub[i] != sub) { - if (d->ssub[i] != NULL) { /* Found other subchannel active other then hangup'ed one */ + if (d->ssub[i] != NULL) { /* Found other subchannel active other than hangup'ed one */ end_call = 0; } continue; @@ -5428,7 +5451,8 @@ static struct unistim_subchannel *find_subchannel_by_name(const char *dest) } if (sub->owner) { /* Allocate additional channel if asterisk channel already here */ - sub = unistim_alloc_sub(d, SUB_ONHOLD); + sub = unistim_alloc_sub(d, SUB_REAL); + sub->holding = 1; } sub->ringvolume = -1; sub->ringstyle = -1; @@ -6515,7 +6539,7 @@ static struct unistim_device *build_device(const char *cat, const struct ast_var } ast_mutex_init(&d->lock); ast_copy_string(d->name, cat, sizeof(d->name)); - + ast_copy_string(d->context, DEFAULTCONTEXT, sizeof(d->context)); d->contrast = -1; d->output = OUTPUT_HANDSET; @@ -7032,7 +7056,7 @@ static int unistim_set_rtp_peer(struct ast_channel *chan, struct ast_rtp_instanc if (!rtp) { return 0; } - + sub = (struct unistim_subchannel *) ast_channel_tech_pvt(chan); if (!sub) { ast_log(LOG_ERROR, "No Private Structure, this is bad\n"); @@ -7045,9 +7069,9 @@ static int unistim_set_rtp_peer(struct ast_channel *chan, struct ast_rtp_instanc ast_rtp_instance_get_local_address(rtp, &tmp); ast_sockaddr_to_sin(&tmp, &us); } - + /* TODO: Set rtp on phone in case of direct rtp (not implemented) */ - + return 0; } diff --git a/channels/chan_vpb.cc b/channels/chan_vpb.cc index 6e77dc272..1736cc6b2 100644 --- a/channels/chan_vpb.cc +++ b/channels/chan_vpb.cc @@ -6,7 +6,7 @@ * Copyright (C) 2004 - 2005, Ben Kramer * Ben Kramer <ben@voicetronix.com.au> * - * Daniel Bichara <daniel@bichara.com.br> - Brazilian CallerID detection (c)2004 + * Daniel Bichara <daniel@bichara.com.br> - Brazilian CallerID detection (c)2004 * * Welber Silveira - welberms@magiclink.com.br - (c)2004 * Copying CLID string to propper structure after detection @@ -25,7 +25,7 @@ /*! \file * * \brief VoiceTronix Interface driver - * + * * \ingroup channel_drivers */ @@ -87,8 +87,8 @@ extern "C" { #define DEFAULT_GAIN 0 #define DEFAULT_ECHO_CANCEL 1 - -#define VPB_SAMPLES 160 + +#define VPB_SAMPLES 160 #define VPB_MAX_BUF VPB_SAMPLES*4 + AST_FRIENDLY_OFFSET #define VPB_NULL_EVENT 200 @@ -98,7 +98,7 @@ extern "C" { #define MAX_VPB_GAIN 12.0 #define MIN_VPB_GAIN -12.0 -#define DTMF_CALLERID +#define DTMF_CALLERID #define DTMF_CID_START 'D' #define DTMF_CID_STOP 'C' @@ -136,9 +136,9 @@ static int mthreadactive = -1; /* Flag for monitoring monitorthread.*/ static int restart_monitor(void); -/* The private structures of the VPB channels are +/* The private structures of the VPB channels are linked for selecting outgoing channels */ - + #define MODE_DIALTONE 1 #define MODE_IMMEDIATE 2 #define MODE_FXO 3 @@ -198,7 +198,7 @@ static int dtmf_idd = 3000; #define TIMER_PERIOD_BUSY 700 #define TIMER_PERIOD_RING 4000 static int timer_period_ring = TIMER_PERIOD_RING; - + #define VPB_EVENTS_ALL (VPB_MRING|VPB_MDIGIT|VPB_MDTMF|VPB_MTONEDETECT|VPB_MTIMEREXP \ |VPB_MSTATION_OFFHOOK|VPB_MSTATION_ONHOOK \ |VPB_MRING_OFF|VPB_MDROP|VPB_MSTATION_FLASH) @@ -260,7 +260,7 @@ static int max_bridges = MAX_BRIDGES_V4PCI; AST_MUTEX_DEFINE_STATIC(bridge_lock); typedef enum { - vpb_model_unknown = 0, + vpb_model_unknown = 0, vpb_model_v4pci, vpb_model_v12pci } vpb_model_t; @@ -428,7 +428,7 @@ static struct ast_channel_tech vpb_tech_indicate = { }; #if defined(VPB_NATIVE_BRIDGING) -/* Can't get ast_vpb_bridge() working on v4pci without either a horrible +/* Can't get ast_vpb_bridge() working on v4pci without either a horrible * high pitched feedback noise or bad hiss noise depending on gain settings * Get asterisk to do the bridging */ @@ -469,7 +469,7 @@ static enum ast_bridge_result ast_vpb_bridge(struct ast_channel *c0, struct ast_ /* Bridge channels, check if we can. I believe we always can, so find a slot.*/ ast_mutex_lock(&bridge_lock); - for (i = 0; i < max_bridges; i++) + for (i = 0; i < max_bridges; i++) if (!bridges[i].inuse) break; if (i < max_bridges) { @@ -480,8 +480,8 @@ static enum ast_bridge_result ast_vpb_bridge(struct ast_channel *c0, struct ast_ bridges[i].fo = fo; bridges[i].c0 = c0; bridges[i].c1 = c1; - } - ast_mutex_unlock(&bridge_lock); + } + ast_mutex_unlock(&bridge_lock); if (i == max_bridges) { ast_log(LOG_WARNING, "%s: vpb_bridge: Failed to bridge %s and %s!\n", p0->dev, ast_channel_name(c0), ast_channel_name(c1)); @@ -562,18 +562,18 @@ static enum ast_bridge_result ast_vpb_bridge(struct ast_channel *c0, struct ast_ } f = ast_read(who); if (!f || ((f->frametype == AST_FRAME_DTMF) && - (((who == c0) && (flags & AST_BRIDGE_DTMF_CHANNEL_0)) || + (((who == c0) && (flags & AST_BRIDGE_DTMF_CHANNEL_0)) || ((who == c1) && (flags & AST_BRIDGE_DTMF_CHANNEL_1))))) { *fo = f; *rc = who; ast_debug(1, "%s: vpb_bridge: Got a [%s]\n", p0->dev, f ? "digit" : "hangup"); #if 0 if ((c0->tech_pvt == pvt0) && (!ast_check_hangup(c0))) { - if (pr0->set_rtp_peer(c0, NULL, NULL, 0)) + if (pr0->set_rtp_peer(c0, NULL, NULL, 0)) ast_log(LOG_WARNING, "Channel '%s' failed to revert\n", c0->name); } if ((c1->tech_pvt == pvt1) && (!ast_check_hangup(c1))) { - if (pr1->set_rtp_peer(c1, NULL, NULL, 0)) + if (pr1->set_rtp_peer(c1, NULL, NULL, 0)) ast_log(LOG_WARNING, "Channel '%s' failed to revert back\n", c1->name); } /* That's all we needed */ @@ -586,9 +586,9 @@ static enum ast_bridge_result ast_vpb_bridge(struct ast_channel *c0, struct ast_ break; } } else { - if ((f->frametype == AST_FRAME_DTMF) || - (f->frametype == AST_FRAME_VOICE) || - (f->frametype == AST_FRAME_VIDEO)) + if ((f->frametype == AST_FRAME_DTMF) || + (f->frametype == AST_FRAME_VOICE) || + (f->frametype == AST_FRAME_VIDEO)) { /* Forward voice or DTMF frames if they happen upon us */ /* Actually I dont think we want to forward on any frames! @@ -606,14 +606,14 @@ static enum ast_bridge_result ast_vpb_bridge(struct ast_channel *c0, struct ast_ cs[0] = cs[1]; cs[1] = cs[2]; }; - vpb_bridge(p0->handle, p1->handle, VPB_BRIDGE_OFF); + vpb_bridge(p0->handle, p1->handle, VPB_BRIDGE_OFF); } #endif ast_mutex_lock(&bridge_lock); bridges[i].inuse = 0; - ast_mutex_unlock(&bridge_lock); + ast_mutex_unlock(&bridge_lock); p0->bridge = NULL; p1->bridge = NULL; @@ -644,7 +644,7 @@ static void get_callerid(struct vpb_pvt *p) int rc; struct ast_channel *owner = p->owner; /* - char callerid[AST_MAX_EXTENSION] = ""; + char callerid[AST_MAX_EXTENSION] = ""; */ #ifdef ANALYSE_CID void * ws; @@ -699,7 +699,7 @@ static void get_callerid(struct vpb_pvt *p) ast_free(owner->cid.cid_name); owner->cid.cid_name=NULL; */ - + if (cli_struct->ra_cldn[0] == '\0') { /* owner->cid.cid_num = ast_strdup(cli_struct->cldn); @@ -725,7 +725,7 @@ static void get_callerid(struct vpb_pvt *p) } delete cli_struct; - } else + } else ast_log(LOG_ERROR, "CID record - Failed to set record mode for caller id on %s\n", p->dev); } @@ -767,9 +767,9 @@ static void get_callerid_ast(struct vpb_pvt *p) cs = callerid_new(which_cid); if (cs) { #ifdef ANALYSE_CID - vpb_wave_open_write(&ws, file, VPB_MULAW); - vpb_record_set_gain(p->handle, 3.0); - vpb_record_set_hw_gain(p->handle, 12.0); + vpb_wave_open_write(&ws, file, VPB_MULAW); + vpb_record_set_gain(p->handle, 3.0); + vpb_record_set_hw_gain(p->handle, 12.0); #endif vpb_record_buf_start(p->handle, VPB_MULAW); while ((rc == 0) && (sam_count < 8000 * 3)) { @@ -778,7 +778,7 @@ static void get_callerid_ast(struct vpb_pvt *p) ast_log(LOG_ERROR, "%s: Caller ID couldn't read audio buffer!\n", p->dev); rc = callerid_feed(cs, (unsigned char *)buf, sizeof(buf), ast_format_ulaw); #ifdef ANALYSE_CID - vpb_wave_write(ws, (char *)buf, sizeof(buf)); + vpb_wave_write(ws, (char *)buf, sizeof(buf)); #endif sam_count += sizeof(buf); ast_verb(4, "Collecting Caller ID samples [%d][%d]...\n", sam_count, rc); @@ -886,7 +886,7 @@ static inline int monitor_handle_owned(struct vpb_pvt *p, VPB_EVENT *e) vpb_timer_stop(p->ring_timer); f.frametype = AST_FRAME_NULL; } - + } else { f.frametype = AST_FRAME_NULL; /* Ignore. */ } @@ -938,7 +938,7 @@ static inline int monitor_handle_owned(struct vpb_pvt *p, VPB_EVENT *e) /* Nothing heard on line for a very long time * Timeout connection */ ast_verb(3, "grunt timeout\n"); - ast_log(LOG_NOTICE, "%s: Line hangup due of lack of conversation\n", p->dev); + ast_log(LOG_NOTICE, "%s: Line hangup due of lack of conversation\n", p->dev); f.subclass.integer = AST_CONTROL_HANGUP; } else { p->lastgrunt = ast_tvnow(); @@ -961,7 +961,7 @@ static inline int monitor_handle_owned(struct vpb_pvt *p, VPB_EVENT *e) f.subclass.integer = AST_CONTROL_HANGUP; } #else - ast_log(LOG_NOTICE, "%s: Got call progress callback but blind dialing \n", p->dev); + ast_log(LOG_NOTICE, "%s: Got call progress callback but blind dialing \n", p->dev); f.frametype = AST_FRAME_NULL; #endif break; @@ -1023,15 +1023,15 @@ static inline int monitor_handle_owned(struct vpb_pvt *p, VPB_EVENT *e) /* ast_verb(4, "%s: LOCKING in handle_owned [%d]\n", p->dev,res); - res = ast_mutex_lock(&p->lock); + res = ast_mutex_lock(&p->lock); ast_verb(4, "%s: LOCKING count[%d] owner[%d] \n", p->dev, p->lock.__m_count,p->lock.__m_owner); */ if (p->bridge) { /* Check what happened, see if we need to report it. */ switch (f.frametype) { case AST_FRAME_DTMF: - if ( !(p->bridge->c0 == p->owner && + if ( !(p->bridge->c0 == p->owner && (p->bridge->flags & AST_BRIDGE_DTMF_CHANNEL_0) ) && - !(p->bridge->c1 == p->owner && + !(p->bridge->c1 == p->owner && (p->bridge->flags & AST_BRIDGE_DTMF_CHANNEL_1) )) { /* Kill bridge, this is interesting. */ endbridge = 1; @@ -1058,8 +1058,8 @@ static inline int monitor_handle_owned(struct vpb_pvt *p, VPB_EVENT *e) ast_mutex_lock(&p->bridge->lock); p->bridge->endbridge = 1; ast_cond_signal(&p->bridge->cond); - ast_mutex_unlock(&p->bridge->lock); - } + ast_mutex_unlock(&p->bridge->lock); + } } if (endbridge) { @@ -1170,7 +1170,7 @@ static inline int monitor_handle_notowned(struct vpb_pvt *p, VPB_EVENT *e) else if (p->state == VPB_STATE_PLAYBUSY) { playtone(p->handle, &Busytone); p->wantdtmf = 1; - p->ext[0] = 0; + p->ext[0] = 0; } else if (p->state == VPB_STATE_PLAYRING) { playtone(p->handle, &Ringbacktone); p->wantdtmf = 1; @@ -1206,7 +1206,7 @@ static inline int monitor_handle_notowned(struct vpb_pvt *p, VPB_EVENT *e) /* No owner any more, Assume caller has hung up */ vpb_timer_stop(p->ring_timer); } - } + } break; case VPB_DTMF: @@ -1259,7 +1259,7 @@ static inline int monitor_handle_notowned(struct vpb_pvt *p, VPB_EVENT *e) if (ast_pickup_call(c)) { /* Call pickup wasnt possible */ } - } else + } else #endif if (ast_exists_extension(NULL, p->context, p->ext, 1, p->callerid)) { if (ast_canmatch_extension(NULL, p->context, p->ext, 1, p->callerid)) { @@ -1354,15 +1354,15 @@ static void *do_monitor(void *unused) } } - ast_mutex_unlock(&monlock); + ast_mutex_unlock(&monlock); if (!p) { if (e.type != VPB_NULL_EVENT) { - ast_log(LOG_WARNING, "Got event [%s][%d], no matching iface!\n", str, e.type); + ast_log(LOG_WARNING, "Got event [%s][%d], no matching iface!\n", str, e.type); ast_verb(4, "vpb/ERR: No interface for Event [%d=>%s] \n", e.type, str); } continue; - } + } /* flush the event from the channel event Q */ vpb_get_event_ch_async(e.handle, &je); @@ -1432,7 +1432,7 @@ static int restart_monitor(void) vpb_put_event(&e); } else { /* Start a new monitor */ - int pid = ast_pthread_create(&monitor_thread, NULL, do_monitor, NULL); + int pid = ast_pthread_create(&monitor_thread, NULL, do_monitor, NULL); ast_verb(4, "Created new monitor thread %d\n", pid); if (pid < 0) { ast_log(LOG_ERROR, "Unable to start monitor thread.\n"); @@ -1502,13 +1502,13 @@ static struct vpb_pvt *mkif(int board, int channel, int mode, int gains, float t tmp->handle = vpb_open(board, channel); - if (tmp->handle < 0) { - ast_log(LOG_WARNING, "Unable to create channel vpb/%d-%d: %s\n", + if (tmp->handle < 0) { + ast_log(LOG_WARNING, "Unable to create channel vpb/%d-%d: %s\n", board, channel, strerror(errno)); ast_free(tmp); return NULL; } - + snprintf(tmp->dev, sizeof(tmp->dev), "vpb/%d-%d", board, channel); tmp->mode = mode; @@ -1524,7 +1524,7 @@ static struct vpb_pvt *mkif(int board, int channel, int mode, int gains, float t ast_copy_string(tmp->context, context, sizeof(tmp->context)); tmp->callerid_type = 0; - if (callerid) { + if (callerid) { if (strcasecmp(callerid, "on") == 0) { tmp->callerid_type = 1; ast_copy_string(tmp->callerid, "unknown", sizeof(tmp->callerid)); @@ -1561,7 +1561,7 @@ static struct vpb_pvt *mkif(int board, int channel, int mode, int gains, float t } else { tmp->txgain = txgain; } - + ast_log(LOG_NOTICE, "VPB setting Tx Hw gain to [%f]\n", tmp->txgain); vpb_play_set_hw_gain(tmp->handle, tmp->txgain); } @@ -1607,7 +1607,7 @@ static struct vpb_pvt *mkif(int board, int channel, int mode, int gains, float t /* set default read state */ tmp->read_state = 0; - + tmp->golock = 0; tmp->busy_timer_id = vpb_timer_get_unique_timer_id(); @@ -1618,10 +1618,10 @@ static struct vpb_pvt *mkif(int board, int channel, int mode, int gains, float t tmp->ring_timer_id = vpb_timer_get_unique_timer_id(); vpb_timer_open(&tmp->ring_timer, tmp->handle, tmp->ring_timer_id, timer_period_ring); - + tmp->dtmfidd_timer_id = vpb_timer_get_unique_timer_id(); vpb_timer_open(&tmp->dtmfidd_timer, tmp->handle, tmp->dtmfidd_timer_id, dtmf_idd); - + if (mode == MODE_FXO){ if (use_ast_dtmfdet) vpb_set_event_mask(tmp->handle, VPB_EVENTS_NODTMF); @@ -1689,8 +1689,8 @@ static int vpb_indicate(struct ast_channel *ast, int condition, const void *data if (ast_channel_state(ast) == AST_STATE_UP) { playtone(p->handle, &Busytone); p->state = VPB_STATE_PLAYBUSY; - vpb_timer_stop(p->busy_timer); - vpb_timer_start(p->busy_timer); + vpb_timer_stop(p->busy_timer); + vpb_timer_start(p->busy_timer); } break; case AST_CONTROL_RINGING: @@ -1702,7 +1702,7 @@ static int vpb_indicate(struct ast_channel *ast, int condition, const void *data vpb_timer_stop(p->ringback_timer); vpb_timer_start(p->ringback_timer); } - break; + break; case AST_CONTROL_ANSWER: case -1: /* -1 means stop playing? */ vpb_timer_stop(p->ringback_timer); @@ -1860,7 +1860,7 @@ static int vpb_call(struct ast_channel *ast, const char *dest, int timeout) call.answer_timeout); for (j = 0; !call.tone_map[j].terminate; j++) { ast_verb(2, "%s: Dial parms for %s tone %d->%d\n", p->dev, - ast_channel_name(ast), call.tone_map[j].tone_id, call.tone_map[j].call_id); + ast_channel_name(ast), call.tone_map[j].tone_id, call.tone_map[j].call_id); } ast_verb(4, "%s: Disabling Loop Drop detection\n", p->dev); @@ -1930,7 +1930,7 @@ static int vpb_hangup(struct ast_channel *ast) /* Stop record */ p->stopreads = 1; if (p->readthread) { - pthread_join(p->readthread, NULL); + pthread_join(p->readthread, NULL); ast_verb(4, "%s: stopped record thread \n", ast_channel_name(ast)); } @@ -1959,7 +1959,7 @@ static int vpb_hangup(struct ast_channel *ast) vpb_ring_station_async(p->handle, 0); if (p->state != VPB_STATE_ONHOOK) { /* This is causing a "dial end" "play tone" loop - playtone(p->handle, &Busytone); + playtone(p->handle, &Busytone); p->state = VPB_STATE_PLAYBUSY; ast_verb(5, "%s: Station offhook[%d], playing busy tone\n", ast->name,p->state); @@ -2064,8 +2064,8 @@ static int vpb_answer(struct ast_channel *ast) static struct ast_frame *vpb_read(struct ast_channel *ast) { - struct vpb_pvt *p = (struct vpb_pvt *)ast_channel_tech_pvt(ast); - static struct ast_frame f = { AST_FRAME_NULL }; + struct vpb_pvt *p = (struct vpb_pvt *)ast_channel_tech_pvt(ast); + static struct ast_frame f = { AST_FRAME_NULL }; f.src = "vpb"; ast_log(LOG_NOTICE, "%s: vpb_read: should never be called!\n", p->dev); @@ -2115,7 +2115,7 @@ static inline int astformatbits(struct ast_format *format) } } -int a_gain_vector(float g, short *v, int n) +int a_gain_vector(float g, short *v, int n) { int i; float tmp; @@ -2125,15 +2125,15 @@ int a_gain_vector(float g, short *v, int n) tmp = 32767.0; if (tmp < -32768.0) tmp = -32768.0; - v[i] = (short)tmp; - } + v[i] = (short)tmp; + } return i; } /* Writes a frame of voice data to a VPB channel */ static int vpb_write(struct ast_channel *ast, struct ast_frame *frame) { - struct vpb_pvt *p = (struct vpb_pvt *)ast_channel_tech_pvt(ast); + struct vpb_pvt *p = (struct vpb_pvt *)ast_channel_tech_pvt(ast); int res = 0; AudioCompress fmt = VPB_RAW; struct timeval play_buf_time_start; @@ -2164,20 +2164,20 @@ static int vpb_write(struct ast_channel *ast, struct ast_frame *frame) } tdiff = ast_tvdiff_ms(ast_tvnow(), p->lastplay); - ast_debug(1, "%s: vpb_write: time since last play(%d) \n", p->dev, tdiff); + ast_debug(1, "%s: vpb_write: time since last play(%d) \n", p->dev, tdiff); if (tdiff < (VPB_SAMPLES / 8 - 1)) { - ast_debug(1, "%s: vpb_write: Asked to play too often (%d) (%d)\n", p->dev, tdiff, frame->datalen); + ast_debug(1, "%s: vpb_write: Asked to play too often (%d) (%d)\n", p->dev, tdiff, frame->datalen); /* return 0; */ } p->lastplay = ast_tvnow(); /* - ast_debug(1, "%s: vpb_write: Checked frame format..\n", p->dev); + ast_debug(1, "%s: vpb_write: Checked frame format..\n", p->dev); */ ast_mutex_lock(&p->play_lock); /* - ast_debug(1, "%s: vpb_write: Got play lock..\n", p->dev); + ast_debug(1, "%s: vpb_write: Got play lock..\n", p->dev); */ /* Check if we have set up the play_buf */ @@ -2251,7 +2251,7 @@ static void *do_chanreads(void *pvt) ast_verb(3, "%s: chanreads: starting thread\n", p->dev); ast_mutex_lock(&p->record_lock); - p->stopreads = 0; + p->stopreads = 0; p->read_state = 1; while (!p->stopreads && p->owner) { @@ -2291,7 +2291,7 @@ static void *do_chanreads(void *pvt) } p->last_ignore_dtmf = ignore_dtmf; - /* Play DTMF digits here to avoid problem you get if playing a digit during + /* Play DTMF digits here to avoid problem you get if playing a digit during * a record operation */ ast_verb(6, "%s: chanreads: Checking dtmf's \n", p->dev); @@ -2311,7 +2311,7 @@ static void *do_chanreads(void *pvt) p->play_dtmf[0] = '\0'; ast_mutex_unlock(&p->play_dtmf_lock); vpb_sleep(700); /* Long enough to miss echo and DTMF event */ - if( !ignore_dtmf) + if( !ignore_dtmf) vpb_set_event_mask(p->handle, VPB_EVENTS_ALL); continue; } @@ -2423,13 +2423,13 @@ static void *do_chanreads(void *pvt) ast_mutex_unlock(&p->record_lock); ast_verb(2, "%s: Ending record mode (%d/%s)\n", - p->dev, p->stopreads, p->owner ? "yes" : "no"); + p->dev, p->stopreads, p->owner ? "yes" : "no"); return NULL; } static struct ast_channel *vpb_new(struct vpb_pvt *me, enum ast_channel_state state, const char *context, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor) { - struct ast_channel *tmp; + struct ast_channel *tmp; char cid_num[256]; char cid_name[256]; @@ -2449,7 +2449,7 @@ static struct ast_channel *vpb_new(struct vpb_pvt *me, enum ast_channel_state st ast_channel_callgroup_set(tmp, me->callgroup); ast_channel_pickupgroup_set(tmp, me->pickupgroup); - + /* Linear is the preferred format. Although Voicetronix supports other formats * they are all converted to/from linear in the vpb code. Best for us to use * linear since we can then adjust volume in this modules. @@ -2465,7 +2465,7 @@ static struct ast_channel *vpb_new(struct vpb_pvt *me, enum ast_channel_state st ast_set_callerid(tmp, cid_num, cid_name, cid_num); } ast_channel_tech_pvt_set(tmp, me); - + ast_channel_context_set(tmp, context); if (!ast_strlen_zero(me->ext)) ast_channel_exten_set(tmp, me->ext); @@ -2484,7 +2484,7 @@ static struct ast_channel *vpb_new(struct vpb_pvt *me, enum ast_channel_state st me->readthread = 0; me->play_dtmf[0] = '\0'; me->faxhandled = 0; - + me->lastgrunt = ast_tvnow(); /* Assume at least one grunt tone seen now. */ me->lastplay = ast_tvnow(); /* Assume at least one grunt tone seen now. */ @@ -2503,7 +2503,7 @@ static struct ast_channel *vpb_new(struct vpb_pvt *me, enum ast_channel_state st return tmp; } -static struct ast_channel *vpb_request(const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, int *cause) +static struct ast_channel *vpb_request(const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, int *cause) { struct vpb_pvt *p; struct ast_channel *tmp = NULL; @@ -2612,7 +2612,7 @@ static int unload_module(void) /* Destroy all the interfaces and free their memory */ while (iflist) { - p = iflist; + p = iflist; ast_mutex_destroy(&p->lock); pthread_cancel(p->readthread); ast_mutex_destroy(&p->owner_lock); @@ -2654,8 +2654,8 @@ static int unload_module(void) * Module loading including tests for configuration or dependencies. * This function can return AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_DECLINE, * or AST_MODULE_LOAD_SUCCESS. If a dependency or environment variable fails - * tests return AST_MODULE_LOAD_FAILURE. If the module can not load the - * configuration file or other non-critical problem return + * tests return AST_MODULE_LOAD_FAILURE. If the module can not load the + * configuration file or other non-critical problem return * AST_MODULE_LOAD_DECLINE. On success return AST_MODULE_LOAD_SUCCESS. */ static enum ast_module_load_result load_module() @@ -2668,14 +2668,14 @@ static enum ast_module_load_result load_module() ast_group_t callgroup = 0; ast_group_t pickupgroup = 0; int mode = MODE_IMMEDIATE; - float txgain = DEFAULT_GAIN, rxgain = DEFAULT_GAIN; - float txswgain = 0, rxswgain = 0; + float txgain = DEFAULT_GAIN, rxgain = DEFAULT_GAIN; + float txswgain = 0, rxswgain = 0; int got_gain=0; int first_channel = 1; int echo_cancel = DEFAULT_ECHO_CANCEL; enum ast_module_load_result error = AST_MODULE_LOAD_SUCCESS; /* Error flag */ int bal1 = -1; /* Special value - means do not set */ - int bal2 = -1; + int bal2 = -1; int bal3 = -1; char * callerid = NULL; int num_cards = 0; @@ -2707,7 +2707,7 @@ static enum ast_module_load_result load_module() if (!cfg || cfg == CONFIG_STATUS_FILEINVALID) { ast_log(LOG_ERROR, "Unable to load config %s\n", config); return AST_MODULE_LOAD_DECLINE; - } + } ast_mutex_lock(&iflock); v = ast_variable_browse(cfg, "general"); @@ -2743,7 +2743,7 @@ static enum ast_module_load_result load_module() } v = v->next; } - + v = ast_variable_browse(cfg, "interfaces"); while (v) { /* Create the interface list */ @@ -2864,7 +2864,7 @@ static enum ast_module_load_result load_module() if (error != AST_MODULE_LOAD_SUCCESS) unload_module(); - else + else restart_monitor(); /* And start the monitor for the first time */ return error; diff --git a/channels/console_board.c b/channels/console_board.c index e5ff1fcbd..6d24d1617 100644 --- a/channels/console_board.c +++ b/channels/console_board.c @@ -16,7 +16,7 @@ * $Revision$ */ -/* +/* * Message board implementation. * * A message board is a region of the SDL screen where @@ -28,7 +28,7 @@ * of fixed size (rows and cols). A portion of the buffer is * visible on the screen, and the visible window can be moved up and * down by dragging (not yet!) - * + * * TODO: font dynamic allocation * * The region where the text is displayed on the screen is defined @@ -135,7 +135,7 @@ struct board *board_setup(SDL_Surface *screen, SDL_Rect *dest, screen->format->Rmask, screen->format->Gmask, screen->format->Bmask, screen->format->Amask); - if (b->blank == NULL) { + if (b->blank == NULL) { ast_log(LOG_WARNING, "Unable to allocate board virtual screen: %s\n", SDL_GetError()); ast_free(b->text); diff --git a/channels/console_gui.c b/channels/console_gui.c index 916c40801..312da396b 100644 --- a/channels/console_gui.c +++ b/channels/console_gui.c @@ -6,7 +6,7 @@ /* * GUI layout, structure and management - + For the GUI we use SDL to create a large surface (gui->screen) with 4 areas: remote video on the left, local video on the right, keypad with all controls and text windows in the center, and source device thumbnails on the top. @@ -148,7 +148,7 @@ struct gui_info { int outfd; /* fd for output */ SDL_Surface *keypad; /* the skin for the keypad */ SDL_Rect kp_rect; /* portion of the skin to display - default all */ - SDL_Surface *font; /* font to be used */ + SDL_Surface *font; /* font to be used */ SDL_Rect font_rects[96]; /* only printable chars */ /* each of the following board has two rectangles, @@ -189,10 +189,10 @@ static struct gui_info *cleanup_sdl(struct gui_info *gui, int device_num) if (gui == NULL) return NULL; - /* unload font file */ + /* unload font file */ if (gui->font) { SDL_FreeSurface(gui->font); - gui->font = NULL; + gui->font = NULL; } if (gui->outfd > -1) @@ -221,7 +221,7 @@ static struct gui_info *cleanup_sdl(struct gui_info *gui, int device_num) if (gui->thumb_bd_array[i].board) /* may be useless */ delete_board(gui->thumb_bd_array[i].board); } - + ast_free(gui); SDL_Quit(); return NULL; @@ -290,7 +290,7 @@ static void show_frame(struct video_desc *env, int out) return; p_in = NULL; b_out = &env->src_dpy[i]; - } + } bmp = gui->win[out].bmp; SDL_LockYUVOverlay(bmp); /* output picture info - this is sdl, YUV420P */ @@ -372,7 +372,7 @@ enum skin_area { /* accumulate digits, possibly call dial if in connected mode */ static void keypad_digit(struct video_desc *env, int digit) -{ +{ if (env->owner) { /* we have a call, send the digit */ struct ast_frame f = { AST_FRAME_DTMF, 0 }; @@ -457,7 +457,7 @@ static void keypad_pick_up(struct video_desc *env) * * To generate a font we can use the 'fly' command with the * following script (3 lines with 32 chars each) - + size 320,64 name font.png transparent 0,0,0 @@ -473,7 +473,7 @@ static int gui_output(struct video_desc *env, const char *text) { return 1; /* error, not supported */ } -#endif +#endif static int video_geom(struct fbuf_t *b, const char *s); static void sdl_setup(struct video_desc *env); @@ -495,23 +495,23 @@ static int update_device_info(struct video_desc *env, int i) } /*! \brief Changes the video output (local video) source, controlling if - * it is already using that video device, + * it is already using that video device, * and switching the correct fields of env->out. * grabbers are always open and saved in the device table. * The secondary or the primary device can be changed, * according to the "button" parameter: * the primary device is changed if button = SDL_BUTTON_LEFT; * the secondary device is changed if button = not SDL_BUTTON_LEFT; - * + * * the correct message boards of the sources are also updated * with the new status - * + * * \param env = pointer to the video environment descriptor * \param index = index of the device the caller wants to use are primary or secondary device * \param button = button clicked on the mouse * * returns 0 on success, - * returns 1 on error + * returns 1 on error */ static int switch_video_out(struct video_desc *env, int index, Uint8 button) { @@ -532,7 +532,7 @@ static int switch_video_out(struct video_desc *env, int index, Uint8 button) ast_log(LOG_WARNING, "switching to %s...\n", env->out.devices[index].name); /* already open */ if (env->out.devices[index].grabber) { - /* we also have to update the messages in the source + /* we also have to update the messages in the source message boards below the source windows */ /* first we update the board of the previous source */ if (p == &env->out.device_primary) @@ -607,7 +607,7 @@ static int turn_on_off(int index, struct video_desc *env) /* print the new message in the message board */ update_device_info(env, index); return 2; /* closed */ - } + } } /* @@ -620,24 +620,24 @@ static void handle_mousedown(struct video_desc *env, SDL_MouseButtonEvent button { uint8_t index = KEY_OUT_OF_KEYPAD; /* the key or region of the display we clicked on */ struct gui_info *gui = env->gui; - + int i; /* integer variable used as iterator */ int x; /* integer variable usable as a container */ - + /* total width of source device thumbnails */ int src_wins_tot_w = env->out.device_num*(SRC_WIN_W+BORDER)+BORDER; /* x coordinate of the center of the keypad */ int x0 = MAX(env->rem_dpy.w+gui->keypad->w/2+2*BORDER, src_wins_tot_w/2); - + #if 0 ast_log(LOG_WARNING, "event %d %d have %d/%d regions at %p\n", button.x, button.y, gui->kp_used, gui->kp_size, gui->kp); #endif /* for each mousedown we end previous drag */ gui->drag.drag_window = DRAG_NONE; - + /* define keypad boundary */ /* XXX this should be extended for clicks on different audio device markers */ if (button.y >= (env->out.device_num ? SRC_WIN_H+2*BORDER+SRC_MSG_BD_H : 0)) { @@ -662,7 +662,7 @@ static void handle_mousedown(struct video_desc *env, SDL_MouseButtonEvent button else if (button.x >= x0 + gui->keypad->w/2) index = KEY_OUT_OF_KEYPAD; else if (gui->kp) { - /* we have to calculate the first coordinate + /* we have to calculate the first coordinate inside the keypad before calling the kp_match_area*/ int x_keypad = button.x - (x0 - gui->keypad->w/2); /* find the key clicked (if one was clicked) */ @@ -682,7 +682,7 @@ static void handle_mousedown(struct video_desc *env, SDL_MouseButtonEvent button else if (button.x < x) index = KEY_OUT_OF_KEYPAD; else if (button.x < x + src_wins_tot_w - BORDER) { - /* note that the additional device windows + /* note that the additional device windows are numbered from left to right starting from 0, with a maximum of 8, the index associated on a click is: KEY_SRCS_WIN + number_of_the_window */ @@ -779,7 +779,7 @@ static void handle_mousedown(struct video_desc *env, SDL_MouseButtonEvent button if (index == KEY_LOC_DPY && env->out.picture_in_picture && button.x >= x0+gui->keypad->w/2+BORDER+pip_loc_x && button.x < x0+gui->keypad->w/2+BORDER+pip_loc_x+env->loc_dpy.w/3 && - button.y >= BORDER+pip_loc_y && + button.y >= BORDER+pip_loc_y && button.y < BORDER+pip_loc_y+env->loc_dpy.h/3) { /* set the y cordinate to his previous value */ button.y += (env->out.device_num ? SRC_WIN_H+2*BORDER+SRC_MSG_BD_H : 0); @@ -800,14 +800,14 @@ static void handle_mousedown(struct video_desc *env, SDL_MouseButtonEvent button fb->w, fb->h); video_geom(fb, buf); sdl_setup(env); - /* writes messages in the source boards, those can be - modified during the execution, because of the events + /* writes messages in the source boards, those can be + modified during the execution, because of the events this must be done here, otherwise the status of sources will not be shown after sdl_setup */ for (i = 0; i < env->out.device_num; i++) { update_device_info(env, i); } - /* we also have to refresh other boards, + /* we also have to refresh other boards, to avoid messages to disappear after video resize */ print_message(gui->bd_msg, " \b"); print_message(gui->bd_dialed, " \b"); @@ -1043,7 +1043,7 @@ static void eventhandler(struct video_desc *env, const char *caption) static SDL_Surface *load_image(const char *file) { SDL_Surface *temp; - + #ifdef HAVE_SDL_IMAGE temp = IMG_Load(file); #else @@ -1223,7 +1223,7 @@ static void sdl_setup(struct video_desc *env) const SDL_VideoInfo *info; int kp_w = 0, kp_h = 0; /* keypad width and height */ struct gui_info *gui = env->gui; - + /* Some helper variables used for filling the SDL window */ int x0; /* the x coordinate of the center of the keypad */ int x1; /* userful for calculating of the size of the parent window */ @@ -1231,7 +1231,7 @@ static void sdl_setup(struct video_desc *env) int src_wins_tot_w; /* total width of the source windows */ int i; int x; /* useful for the creation of the source windows; */ - + #ifdef HAVE_X11 const char *e = getenv("SDL_WINDOWID"); @@ -1247,7 +1247,7 @@ static void sdl_setup(struct video_desc *env) ast_log(LOG_WARNING, "%s error in window\n", __FUNCTION__); return; } - } + } #endif /* * initialize the SDL environment. We have one large window @@ -1294,23 +1294,23 @@ static void sdl_setup(struct video_desc *env) kp_h = gui->keypad->h; } } - + /* total width of the thumbnails */ src_wins_tot_w = env->out.device_num*(SRC_WIN_W+BORDER)+BORDER; - + /* x coordinate of the center of the keypad */ x0 = MAX(env->rem_dpy.w+kp_w/2+2*BORDER, src_wins_tot_w/2); - + /* from center of the keypad to right border */ x1 = MAX(env->loc_dpy.w+kp_w/2+2*BORDER, src_wins_tot_w/2); - + /* total width of the SDL window to create */ maxw = x0+x1; - + /* total height of the mother window to create */ maxh = MAX( MAX(env->rem_dpy.h, env->loc_dpy.h), kp_h)+2*BORDER; maxh += env->out.device_num ? (2*BORDER+SRC_WIN_H+SRC_MSG_BD_H) : 0; - + gui->screen = SDL_SetVideoMode(maxw, maxh, depth, 0); if (!gui->screen) { ast_log(LOG_ERROR, "SDL: could not set video mode - exiting\n"); @@ -1411,9 +1411,9 @@ static void sdl_setup(struct video_desc *env) #endif /* HAVE_X11 */ y0 = env->out.device_num ? (3*BORDER+SRC_WIN_H+SRC_MSG_BD_H) : BORDER; - + SDL_WM_SetCaption("Asterisk console Video Output", NULL); - + /* intialize the windows for local and remote video */ if (set_win(gui->screen, &gui->win[WIN_REMOTE], dpy_fmt, env->rem_dpy.w, env->rem_dpy.h, x0-kp_w/2-BORDER-env->rem_dpy.w, y0)) @@ -1425,7 +1425,7 @@ static void sdl_setup(struct video_desc *env) env->loc_dpy.w, env->loc_dpy.h, x0+kp_w/2+BORDER, y0)) goto no_sdl; - + /* initialize device_num source windows (thumbnails) and boards (for a maximum of 9 additional windows and boards) */ x = x0 - src_wins_tot_w/2 + BORDER; diff --git a/channels/console_video.c b/channels/console_video.c index de81a8a90..4bf29189a 100644 --- a/channels/console_video.c +++ b/channels/console_video.c @@ -150,7 +150,7 @@ int console_video_formats = 0; #else /* defined(HAVE_FFMPEG) && defined(HAVE_SDL) */ /*! The list of video formats we support. */ -int console_video_formats = +int console_video_formats = AST_FORMAT_H263_PLUS | AST_FORMAT_H263 | AST_FORMAT_MP4_VIDEO | AST_FORMAT_H264 | AST_FORMAT_H261 ; @@ -186,7 +186,7 @@ struct video_codec_desc; /* forward declaration */ * + the encoding and RTP info, including timestamps to generate * frames at the correct rate; * + source-specific info, i.e. fd for /dev/video, dpy-image for x11, etc, - * filled in by grabber_open, part of source_specific information are in + * filled in by grabber_open, part of source_specific information are in * the device table (devices member), others are shared; * NOTE: loc_src.data == NULL means the rest of the struct is invalid, and * the video source is not available. @@ -213,18 +213,18 @@ struct video_out_desc { AVFrame *enc_in_frame; /* enc_in mapped into avcodec format. */ /* The initial part of AVFrame is an AVPicture */ int mtu; - + /* Table of devices specified with "videodevice=" in oss.conf. * Static size as we have a limited number of entries. */ - struct video_device devices[MAX_VIDEO_SOURCES]; + struct video_device devices[MAX_VIDEO_SOURCES]; int device_num; /*number of devices in table*/ int device_primary; /*index of the actual primary device in the table*/ int device_secondary; /*index of the actual secondary device in the table*/ int picture_in_picture; /*Is the PiP mode activated? 0 = NO | 1 = YES*/ - /* these are the coordinates of the picture inside the picture (visible if PiP mode is active) + /* these are the coordinates of the picture inside the picture (visible if PiP mode is active) these coordinates are valid considering the containing buffer with cif geometry*/ int pip_x; int pip_y; @@ -307,7 +307,7 @@ used_mem(const char *msg) return 0; } #endif - + #include "vcodecs.c" #include "console_gui.c" @@ -321,7 +321,7 @@ used_mem(const char *msg) * * \param v = video out environment descriptor * - * returns 0 on success, 1 on error + * returns 0 on success, 1 on error */ static int grabber_open(struct video_out_desc *v) { @@ -347,7 +347,7 @@ static int grabber_open(struct video_out_desc *v) } /* the first working device is selected as the primary one and the secondary one */ for (i = 0; i < v->device_num; i++) { - if (!v->devices[i].grabber) + if (!v->devices[i].grabber) continue; v->device_primary = i; v->device_secondary = i; @@ -373,7 +373,7 @@ static struct fbuf_t *grabber_read(struct video_device *dev, int fps) if (dev->grabber == NULL) /* not initialized */ return NULL; - + /* the last_frame field in this row of the device table (dev) is always initialized, it is set during the parsing of the config file, and never unset, function fill_device_table(). */ @@ -421,7 +421,7 @@ static int video_out_uninit(struct video_desc *env) { struct video_out_desc *v = &env->out; int i; /* integer variable used as iterator */ - + /* XXX this should be a codec callback */ if (v->enc_ctx) { AVCodecContext *enc_ctx = (AVCodecContext *)v->enc_ctx; @@ -589,7 +589,7 @@ static AVPicture *fill_pict(struct fbuf_t *b, AVPicture *p) int len = b->w; /* Y linesize, bytes */ int luv = b->w/2; /* U/V linesize, bytes */ int sample_size = 1; - + memset(p, '\0', sizeof(*p)); switch (b->pix_fmt) { case PIX_FMT_RGB555: @@ -607,7 +607,7 @@ static AVPicture *fill_pict(struct fbuf_t *b, AVPicture *p) break; } len *= sample_size; - + p->data[0] = b->data; p->linesize[0] = len; /* these are only valid for component images */ @@ -615,11 +615,11 @@ static AVPicture *fill_pict(struct fbuf_t *b, AVPicture *p) p->data[2] = luv ? b->data + 5*l4 : b->data+len; p->linesize[1] = luv; p->linesize[2] = luv; - - /* add the offsets to the pointers previously calculated, + + /* add the offsets to the pointers previously calculated, it is necessary for the picture in picture mode */ p->data[0] += len*b->win_y + b->win_x*sample_size; - if (luv) { + if (luv) { p->data[1] += luv*(b->win_y/2) + (b->win_x/2) * sample_size; p->data[2] += luv*(b->win_y/2) + (b->win_x/2) * sample_size; } @@ -832,7 +832,7 @@ static struct ast_frame *get_video_frames(struct video_desc *env, struct ast_fra } } show_frame(env, WIN_LOCAL); /* local rendering */ - for (i = 0; i < env->out.device_num; i++) + for (i = 0; i < env->out.device_num; i++) show_frame(env, i+WIN_SRC1); /* rendering of every source device in thumbnails */ if (tail == NULL) tail = &dummy; @@ -926,7 +926,7 @@ static void *video_thread(void *arg) /* manage keypad events */ /* XXX here we should always check for events, - * otherwise the drag will not work */ + * otherwise the drag will not work */ if (env->gui) eventhandler(env, caption); @@ -1254,7 +1254,7 @@ int console_video_config(struct video_desc **penv, if (env == NULL) { ast_log(LOG_WARNING, "fail to allocate video_desc\n"); return 1; /* error */ - + } /* set default values - 0's are already there */ env->out.device_primary = 0; diff --git a/channels/console_video.h b/channels/console_video.h index f88e5fa1d..1c945e48e 100644 --- a/channels/console_video.h +++ b/channels/console_video.h @@ -64,7 +64,7 @@ struct fbuf_t { /* frame buffers, dynamically allocated */ int ebit; /* bits to ignore at the end */ int x; /* origin, if necessary */ int y; - int w; /* size */ + int w; /* size */ int h; int pix_fmt; /* offsets and size of the copy in Picture-in-Picture mode */ diff --git a/channels/iax2/include/astobj.h b/channels/iax2/include/astobj.h new file mode 100644 index 000000000..e9f00713c --- /dev/null +++ b/channels/iax2/include/astobj.h @@ -0,0 +1,823 @@ +/* + * Asterisk -- An open source telephony toolkit. + * + * Copyright (C) 1999 - 2005, Digium, Inc. + * + * Mark Spencer <markster@digium.com> + * + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2. See the LICENSE file + * at the top of the source tree. + */ + +/*! \file + * \brief Object Model for Asterisk + * + * \deprecated Use astobj2.h instead + */ + +#ifndef _ASTERISK_ASTOBJ_H +#define _ASTERISK_ASTOBJ_H + +#include "asterisk/lock.h" + +/*! \file + * \brief A set of macros implementing objects and containers. + * Macros are used for maximum performance, to support multiple inheritance, + * and to be easily integrated into existing structures without additional + * malloc calls, etc. + * + * These macros expect to operate on two different object types, ASTOBJs and + * ASTOBJ_CONTAINERs. These are not actual types, as any struct can be + * converted into an ASTOBJ compatible object or container using the supplied + * macros. + * + * <b>Sample Usage:</b> + * \code + * struct sample_object { + * ASTOBJ_COMPONENTS(struct sample_object); + * }; + * + * struct sample_container { + * ASTOBJ_CONTAINER_COMPONENTS(struct sample_object); + * } super_container; + * + * void sample_object_destroy(struct sample_object *obj) + * { + * free(obj); + * } + * + * int init_stuff() + * { + * struct sample_object *obj1; + * struct sample_object *found_obj; + * + * obj1 = malloc(sizeof(struct sample_object)); + * + * ASTOBJ_CONTAINER_INIT(&super_container); + * + * ASTOBJ_INIT(obj1); + * ASTOBJ_WRLOCK(obj1); + * ast_copy_string(obj1->name, "obj1", sizeof(obj1->name)); + * ASTOBJ_UNLOCK(obj1); + * + * ASTOBJ_CONTAINER_LINK(&super_container, obj1); + * + * found_obj = ASTOBJ_CONTAINER_FIND(&super_container, "obj1"); + * + * if(found_obj) { + * printf("Found object: %s", found_obj->name); + * ASTOBJ_UNREF(found_obj,sample_object_destroy); + * } + * + * ASTOBJ_CONTAINER_DESTROYALL(&super_container,sample_object_destroy); + * ASTOBJ_CONTAINER_DESTROY(&super_container); + * + * return 0; + * } + * \endcode + */ + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +#define ASTOBJ_DEFAULT_NAMELEN 80 +#define ASTOBJ_DEFAULT_BUCKETS 256 +#define ASTOBJ_DEFAULT_HASH ast_strhash + +#define ASTOBJ_FLAG_MARKED (1 << 0) /* Object has been marked for future operation */ + +/* C++ is simply a syntactic crutch for those who cannot think for themselves + in an object oriented way. */ + +/*! \brief Lock an ASTOBJ for reading. + */ +#define ASTOBJ_RDLOCK(object) ast_mutex_lock(&(object)->_lock) + +/*! \brief Lock an ASTOBJ for writing. + */ +#define ASTOBJ_WRLOCK(object) ast_mutex_lock(&(object)->_lock) + +#define ASTOBJ_TRYWRLOCK(object) ast_mutex_trylock(&(object)->_lock) + +/*! \brief Unlock a locked object. */ +#define ASTOBJ_UNLOCK(object) ast_mutex_unlock(&(object)->_lock) + +#ifdef ASTOBJ_CONTAINER_HASHMODEL +#define __ASTOBJ_HASH(type,hashes) \ + type *next[hashes] +#else +#define __ASTOBJ_HASH(type,hashes) \ + type *next[1] +#endif + +/*! \brief Add ASTOBJ components to a struct (without locking support). + * + * \param type The datatype of the object. + * \param namelen The length to make the name char array. + * \param hashes The number of containers the object can be present in. + * + * This macro adds components to a struct to make it an ASTOBJ. This macro + * differs from ASTOBJ_COMPONENTS_FULL in that it does not create a mutex for + * locking. + * + * <b>Sample Usage:</b> + * \code + * struct sample_struct { + * ASTOBJ_COMPONENTS_NOLOCK_FULL(struct sample_struct,1,1); + * }; + * \endcode + */ +#define ASTOBJ_COMPONENTS_NOLOCK_FULL(type,namelen,hashes) \ + char name[namelen]; \ + unsigned int refcount; \ + unsigned int objflags; \ + __ASTOBJ_HASH(type,hashes) + +/*! \brief Add ASTOBJ components to a struct (without locking support). + * + * \param type The datatype of the object. + * + * This macro works like #ASTOBJ_COMPONENTS_NOLOCK_FULL() except it only accepts a + * type and uses default values for namelen and hashes. + * + * <b>Sample Usage:</b> + * \code + * struct sample_struct_componets { + * ASTOBJ_COMPONENTS_NOLOCK(struct sample_struct); + * }; + * \endcode + */ +#define ASTOBJ_COMPONENTS_NOLOCK(type) \ + ASTOBJ_COMPONENTS_NOLOCK_FULL(type,ASTOBJ_DEFAULT_NAMELEN,1) + +/*! \brief Add ASTOBJ components to a struct (with locking support). + * + * \param type The datatype of the object. + * + * This macro works like #ASTOBJ_COMPONENTS_NOLOCK() except it includes locking + * support. + * + * <b>Sample Usage:</b> + * \code + * struct sample_struct { + * ASTOBJ_COMPONENTS(struct sample_struct); + * }; + * \endcode + */ +#define ASTOBJ_COMPONENTS(type) \ + ASTOBJ_COMPONENTS_NOLOCK(type); \ + ast_mutex_t _lock; + +/*! \brief Add ASTOBJ components to a struct (with locking support). + * + * \param type The datatype of the object. + * \param namelen The length to make the name char array. + * \param hashes The number of containers the object can be present in. + * + * This macro adds components to a struct to make it an ASTOBJ and includes + * support for locking. + * + * <b>Sample Usage:</b> + * \code + * struct sample_struct { + * ASTOBJ_COMPONENTS_FULL(struct sample_struct,1,1); + * }; + * \endcode + */ +#define ASTOBJ_COMPONENTS_FULL(type,namelen,hashes) \ + ASTOBJ_COMPONENTS_NOLOCK_FULL(type,namelen,hashes); \ + ast_mutex_t _lock; + +/*! \brief Increment an object reference count. + * \param object A pointer to the object to operate on. + * \return The object. + */ +#define ASTOBJ_REF(object) \ + ({ \ + ASTOBJ_WRLOCK(object); \ + (object)->refcount++; \ + ASTOBJ_UNLOCK(object); \ + (object); \ + }) + +/*! \brief Decrement the reference count on an object. + * + * \param object A pointer the object to operate on. + * \param destructor The destructor to call if the object is no longer referenced. It will be passed the pointer as an argument. + * + * This macro unreferences an object and calls the specfied destructor if the + * object is no longer referenced. The destructor should free the object if it + * was dynamically allocated. + */ +#define ASTOBJ_UNREF(object,destructor) \ + do { \ + int newcount = 0; \ + ASTOBJ_WRLOCK(object); \ + if (__builtin_expect((object)->refcount > 0, 1)) \ + newcount = --((object)->refcount); \ + else \ + ast_log(AST_LOG_WARNING, "Unreferencing unreferenced (object)!\n"); \ + ASTOBJ_UNLOCK(object); \ + if (newcount == 0) { \ + ast_mutex_destroy(&(object)->_lock); \ + destructor((object)); \ + } \ + (object) = NULL; \ + } while(0) + +/*! \brief Mark an ASTOBJ by adding the #ASTOBJ_FLAG_MARKED flag to its objflags mask. + * \param object A pointer to the object to operate on. + * + * This macro "marks" an object. Marked objects can later be unlinked from a container using + * #ASTOBJ_CONTAINER_PRUNE_MARKED(). + * + */ +#define ASTOBJ_MARK(object) \ + do { \ + ASTOBJ_WRLOCK(object); \ + (object)->objflags |= ASTOBJ_FLAG_MARKED; \ + ASTOBJ_UNLOCK(object); \ + } while(0) + +/*! \brief Unmark an ASTOBJ by subtracting the #ASTOBJ_FLAG_MARKED flag from its objflags mask. + * \param object A pointer to the object to operate on. + */ +#define ASTOBJ_UNMARK(object) \ + do { \ + ASTOBJ_WRLOCK(object); \ + (object)->objflags &= ~ASTOBJ_FLAG_MARKED; \ + ASTOBJ_UNLOCK(object); \ + } while(0) + +/*! \brief Initialize an object. + * \param object A pointer to the object to operate on. + * + * \note This should only be used on objects that support locking (objects + * created with #ASTOBJ_COMPONENTS() or #ASTOBJ_COMPONENTS_FULL()) + */ +#define ASTOBJ_INIT(object) \ + do { \ + ast_mutex_init(&(object)->_lock); \ + object->name[0] = '\0'; \ + object->refcount = 1; \ + } while(0) + +/* Containers for objects -- current implementation is linked lists, but + should be able to be converted to hashes relatively easily */ + +/*! \brief Lock an ASTOBJ_CONTAINER for reading. + */ +#define ASTOBJ_CONTAINER_RDLOCK(container) ast_mutex_lock(&(container)->_lock) + +/*! \brief Lock an ASTOBJ_CONTAINER for writing. + */ +#define ASTOBJ_CONTAINER_WRLOCK(container) ast_mutex_lock(&(container)->_lock) + +/*! \brief Unlock an ASTOBJ_CONTAINER. */ +#define ASTOBJ_CONTAINER_UNLOCK(container) ast_mutex_unlock(&(container)->_lock) + +#ifdef ASTOBJ_CONTAINER_HASHMODEL +#error "Hash model for object containers not yet implemented!" +#else +/* Linked lists */ + +/*! \brief Create a container for ASTOBJs (without locking support). + * + * \param type The type of objects the container will hold. + * \param hashes Currently unused. + * \param buckets Currently unused. + * + * This macro is used to create a container for ASTOBJs without locking + * support. + * + * <b>Sample Usage:</b> + * \code + * struct sample_struct_nolock_container { + * ASTOBJ_CONTAINER_COMPONENTS_NOLOCK_FULL(struct sample_struct,1,1); + * }; + * \endcode + */ +#define ASTOBJ_CONTAINER_COMPONENTS_NOLOCK_FULL(type,hashes,buckets) \ + type *head + +/*! \brief Initialize a container. + * + * \param container A pointer to the container to initialize. + * \param hashes Currently unused. + * \param buckets Currently unused. + * + * This macro initializes a container. It should only be used on containers + * that support locking. + * + * <b>Sample Usage:</b> + * \code + * struct sample_struct_container { + * ASTOBJ_CONTAINER_COMPONENTS_FULL(struct sample_struct,1,1); + * } container; + * + * int func() + * { + * ASTOBJ_CONTAINER_INIT_FULL(&container,1,1); + * } + * \endcode + */ +#define ASTOBJ_CONTAINER_INIT_FULL(container,hashes,buckets) \ + do { \ + ast_mutex_init(&(container)->_lock); \ + } while(0) + +/*! \brief Destroy a container. + * + * \param container A pointer to the container to destroy. + * \param hashes Currently unused. + * \param buckets Currently unused. + * + * This macro frees up resources used by a container. It does not operate on + * the objects in the container. To unlink the objects from the container use + * #ASTOBJ_CONTAINER_DESTROYALL(). + * + * \note This macro should only be used on containers with locking support. + */ +#define ASTOBJ_CONTAINER_DESTROY_FULL(container,hashes,buckets) \ + do { \ + ast_mutex_destroy(&(container)->_lock); \ + } while(0) + +/*! \brief Iterate through the objects in a container. + * + * \param container A pointer to the container to traverse. + * \param continue A condition to allow the traversal to continue. + * \param eval A statement to evaluate in the iteration loop. + * + * This is macro is a little complicated, but it may help to think of it as a + * loop. Basically it iterates through the specfied containter as long as the + * condition is met. Two variables, iterator and next, are provided for use in + * your \p eval statement. See the sample code for an example. + * + * <b>Sample Usage:</b> + * \code + * ASTOBJ_CONTAINER_TRAVERSE(&sample_container,1, { + * ASTOBJ_RDLOCK(iterator); + * printf("Currently iterating over '%s'\n", iterator->name); + * ASTOBJ_UNLOCK(iterator); + * } ); + * \endcode + * + * \code + * ASTOBJ_CONTAINER_TRAVERSE(&sample_container,1, sample_func(iterator)); + * \endcode + */ +#define ASTOBJ_CONTAINER_TRAVERSE(container,continue,eval) \ + do { \ + typeof((container)->head) iterator; \ + typeof((container)->head) next; \ + ASTOBJ_CONTAINER_RDLOCK(container); \ + next = (container)->head; \ + while((continue) && (iterator = next)) { \ + next = iterator->next[0]; \ + eval; \ + } \ + ASTOBJ_CONTAINER_UNLOCK(container); \ + } while(0) + +/*! \brief Find an object in a container. + * + * \param container A pointer to the container to search. + * \param namestr The name to search for. + * + * Use this function to find an object with the specfied name in a container. + * + * \note When the returned object is no longer in use, #ASTOBJ_UNREF() should + * be used to free the additional reference created by this macro. + * + * \return A new reference to the object located or NULL if nothing is found. + */ +#define ASTOBJ_CONTAINER_FIND(container,namestr) \ + ({ \ + typeof((container)->head) found = NULL; \ + ASTOBJ_CONTAINER_TRAVERSE(container, !found, do { \ + if (!(strcasecmp(iterator->name, (namestr)))) \ + found = ASTOBJ_REF(iterator); \ + } while (0)); \ + found; \ + }) + +/*! \brief Find an object in a container. + * + * \param container A pointer to the container to search. + * \param data The data to search for. + * \param field The field/member of the container's objects to search. + * \param hashfunc The hash function to use, currently not implemented. + * \param hashoffset The hash offset to use, currently not implemented. + * \param comparefunc The function used to compare the field and data values. + * + * This macro iterates through a container passing the specified field and data + * elements to the specified comparefunc. The function should return 0 when a match is found. + * + * \note When the returned object is no longer in use, #ASTOBJ_UNREF() should + * be used to free the additional reference created by this macro. + * + * \return A pointer to the object located or NULL if nothing is found. + */ +#define ASTOBJ_CONTAINER_FIND_FULL(container,data,field,hashfunc,hashoffset,comparefunc) \ + ({ \ + typeof((container)->head) found = NULL; \ + ASTOBJ_CONTAINER_TRAVERSE(container, !found, do { \ + ASTOBJ_RDLOCK(iterator); \ + if (!(comparefunc(iterator->field, (data)))) { \ + found = ASTOBJ_REF(iterator); \ + } \ + ASTOBJ_UNLOCK(iterator); \ + } while (0)); \ + found; \ + }) + +/*! \brief Empty a container. + * + * \param container A pointer to the container to operate on. + * \param destructor A destructor function to call on each object. + * + * This macro loops through a container removing all the items from it using + * #ASTOBJ_UNREF(). This does not destroy the container itself, use + * #ASTOBJ_CONTAINER_DESTROY() for that. + * + * \note If any object in the container is only referenced by the container, + * the destructor will be called for that object once it has been removed. + */ +#define ASTOBJ_CONTAINER_DESTROYALL(container,destructor) \ + do { \ + typeof((container)->head) iterator; \ + ASTOBJ_CONTAINER_WRLOCK(container); \ + while((iterator = (container)->head)) { \ + (container)->head = (iterator)->next[0]; \ + ASTOBJ_UNREF(iterator,destructor); \ + } \ + ASTOBJ_CONTAINER_UNLOCK(container); \ + } while(0) + +/*! \brief Remove an object from a container. + * + * \param container A pointer to the container to operate on. + * \param obj A pointer to the object to remove. + * + * This macro iterates through a container and removes the specfied object if + * it exists in the container. + * + * \note This macro does not destroy any objects, it simply unlinks + * them from the list. No destructors are called. + * + * \return The container's reference to the removed object or NULL if no + * matching object was found. + */ +#define ASTOBJ_CONTAINER_UNLINK(container,obj) \ + ({ \ + typeof((container)->head) found = NULL; \ + typeof((container)->head) prev = NULL; \ + ASTOBJ_CONTAINER_TRAVERSE(container, !found, do { \ + if (iterator == obj) { \ + found = iterator; \ + found->next[0] = NULL; \ + ASTOBJ_CONTAINER_WRLOCK(container); \ + if (prev) \ + prev->next[0] = next; \ + else \ + (container)->head = next; \ + ASTOBJ_CONTAINER_UNLOCK(container); \ + } \ + prev = iterator; \ + } while (0)); \ + found; \ + }) + +/*! \brief Find and remove an object from a container. + * + * \param container A pointer to the container to operate on. + * \param namestr The name of the object to remove. + * + * This macro iterates through a container and removes the first object with + * the specfied name from the container. + * + * \note This macro does not destroy any objects, it simply unlinks + * them. No destructors are called. + * + * \return The container's reference to the removed object or NULL if no + * matching object was found. + */ +#define ASTOBJ_CONTAINER_FIND_UNLINK(container,namestr) \ + ({ \ + typeof((container)->head) found = NULL; \ + typeof((container)->head) prev = NULL; \ + ASTOBJ_CONTAINER_TRAVERSE(container, !found, do { \ + if (!(strcasecmp(iterator->name, (namestr)))) { \ + found = iterator; \ + found->next[0] = NULL; \ + ASTOBJ_CONTAINER_WRLOCK(container); \ + if (prev) \ + prev->next[0] = next; \ + else \ + (container)->head = next; \ + ASTOBJ_CONTAINER_UNLOCK(container); \ + } \ + prev = iterator; \ + } while (0)); \ + found; \ + }) + +/*! \brief Find and remove an object in a container. + * + * \param container A pointer to the container to search. + * \param data The data to search for. + * \param field The field/member of the container's objects to search. + * \param hashfunc The hash function to use, currently not implemented. + * \param hashoffset The hash offset to use, currently not implemented. + * \param comparefunc The function used to compare the field and data values. + * + * This macro iterates through a container passing the specified field and data + * elements to the specified comparefunc. The function should return 0 when a match is found. + * If a match is found it is removed from the list. + * + * \note This macro does not destroy any objects, it simply unlinks + * them. No destructors are called. + * + * \return The container's reference to the removed object or NULL if no match + * was found. + */ +#define ASTOBJ_CONTAINER_FIND_UNLINK_FULL(container,data,field,hashfunc,hashoffset,comparefunc) \ + ({ \ + typeof((container)->head) found = NULL; \ + typeof((container)->head) prev = NULL; \ + ASTOBJ_CONTAINER_TRAVERSE(container, !found, do { \ + ASTOBJ_RDLOCK(iterator); \ + if (!(comparefunc(iterator->field, (data)))) { \ + found = iterator; \ + found->next[0] = NULL; \ + ASTOBJ_CONTAINER_WRLOCK(container); \ + if (prev) \ + prev->next[0] = next; \ + else \ + (container)->head = next; \ + ASTOBJ_CONTAINER_UNLOCK(container); \ + } \ + ASTOBJ_UNLOCK(iterator); \ + prev = iterator; \ + } while (0)); \ + found; \ + }) + +/*! \brief Add an object to the end of a container. + * + * \param container A pointer to the container to operate on. + * \param newobj A pointer to the object to be added. + * + * This macro adds an object to the end of a container. + */ +#define ASTOBJ_CONTAINER_LINK_END(container,newobj) \ + do { \ + typeof((container)->head) iterator; \ + typeof((container)->head) next; \ + typeof((container)->head) prev; \ + ASTOBJ_CONTAINER_RDLOCK(container); \ + prev = NULL; \ + next = (container)->head; \ + while((iterator = next)) { \ + next = iterator->next[0]; \ + prev = iterator; \ + } \ + if(prev) { \ + ASTOBJ_CONTAINER_WRLOCK((container)); \ + prev->next[0] = ASTOBJ_REF(newobj); \ + (newobj)->next[0] = NULL; \ + ASTOBJ_CONTAINER_UNLOCK((container)); \ + } else { \ + ASTOBJ_CONTAINER_LINK_START((container),(newobj)); \ + } \ + ASTOBJ_CONTAINER_UNLOCK((container)); \ + } while(0) + +/*! \brief Add an object to the front of a container. + * + * \param container A pointer to the container to operate on. + * \param newobj A pointer to the object to be added. + * + * This macro adds an object to the start of a container. + */ +#define ASTOBJ_CONTAINER_LINK_START(container,newobj) \ + do { \ + ASTOBJ_CONTAINER_WRLOCK(container); \ + (newobj)->next[0] = (container)->head; \ + (container)->head = ASTOBJ_REF(newobj); \ + ASTOBJ_CONTAINER_UNLOCK(container); \ + } while(0) + +/*! \brief Remove an object from the front of a container. + * + * \param container A pointer to the container to operate on. + * + * This macro removes the first object in a container. + * + * \note This macro does not destroy any objects, it simply unlinks + * them from the list. No destructors are called. + * + * \return The container's reference to the removed object or NULL if no + * matching object was found. + */ +#define ASTOBJ_CONTAINER_UNLINK_START(container) \ + ({ \ + typeof((container)->head) found = NULL; \ + ASTOBJ_CONTAINER_WRLOCK(container); \ + if((container)->head) { \ + found = (container)->head; \ + (container)->head = (container)->head->next[0]; \ + found->next[0] = NULL; \ + } \ + ASTOBJ_CONTAINER_UNLOCK(container); \ + found; \ + }) + +/*! \brief Prune marked objects from a container. + * + * \param container A pointer to the container to prune. + * \param destructor A destructor function to call on each marked object. + * + * This macro iterates through the specfied container and prunes any marked + * objects executing the specfied destructor if necessary. + */ +#define ASTOBJ_CONTAINER_PRUNE_MARKED(container,destructor) \ + do { \ + typeof((container)->head) prev = NULL; \ + ASTOBJ_CONTAINER_TRAVERSE(container, 1, do { \ + ASTOBJ_RDLOCK(iterator); \ + if (iterator->objflags & ASTOBJ_FLAG_MARKED) { \ + ASTOBJ_CONTAINER_WRLOCK(container); \ + if (prev) \ + prev->next[0] = next; \ + else \ + (container)->head = next; \ + ASTOBJ_CONTAINER_UNLOCK(container); \ + ASTOBJ_UNLOCK(iterator); \ + ASTOBJ_UNREF(iterator,destructor); \ + continue; \ + } \ + ASTOBJ_UNLOCK(iterator); \ + prev = iterator; \ + } while (0)); \ + } while(0) + +/*! \brief Add an object to a container. + * + * \param container A pointer to the container to operate on. + * \param newobj A pointer to the object to be added. + * \param data Currently unused. + * \param field Currently unused. + * \param hashfunc Currently unused. + * \param hashoffset Currently unused. + * \param comparefunc Currently unused. + * + * Currently this function adds an object to the head of the list. One day it + * will support adding objects atthe position specified using the various + * options this macro offers. + */ +#define ASTOBJ_CONTAINER_LINK_FULL(container,newobj,data,field,hashfunc,hashoffset,comparefunc) \ + do { \ + ASTOBJ_CONTAINER_WRLOCK(container); \ + (newobj)->next[0] = (container)->head; \ + (container)->head = ASTOBJ_REF(newobj); \ + ASTOBJ_CONTAINER_UNLOCK(container); \ + } while(0) + +#endif /* List model */ + +/* Common to hash and linked list models */ + +/*! \brief Create a container for ASTOBJs (without locking support). + * + * \param type The type of objects the container will hold. + * + * This macro is used to create a container for ASTOBJs without locking + * support. + * + * <b>Sample Usage:</b> + * \code + * struct sample_struct_nolock_container { + * ASTOBJ_CONTAINER_COMPONENTS_NOLOCK(struct sample_struct); + * }; + * \endcode + */ +#define ASTOBJ_CONTAINER_COMPONENTS_NOLOCK(type) \ + ASTOBJ_CONTAINER_COMPONENTS_NOLOCK_FULL(type,1,ASTOBJ_DEFAULT_BUCKETS) + + +/*! \brief Create a container for ASTOBJs (with locking support). + * + * \param type The type of objects the container will hold. + * + * This macro is used to create a container for ASTOBJs with locking support. + * + * <b>Sample Usage:</b> + * \code + * struct sample_struct_container { + * ASTOBJ_CONTAINER_COMPONENTS(struct sample_struct); + * }; + * \endcode + */ +#define ASTOBJ_CONTAINER_COMPONENTS(type) \ + ast_mutex_t _lock; \ + ASTOBJ_CONTAINER_COMPONENTS_NOLOCK(type) + +/*! \brief Initialize a container. + * + * \param container A pointer to the container to initialize. + * + * This macro initializes a container. It should only be used on containers + * that support locking. + * + * <b>Sample Usage:</b> + * \code + * struct sample_struct_container { + * ASTOBJ_CONTAINER_COMPONENTS(struct sample_struct); + * } container; + * + * int func() + * { + * ASTOBJ_CONTAINER_INIT(&container); + * } + * \endcode + */ +#define ASTOBJ_CONTAINER_INIT(container) \ + ASTOBJ_CONTAINER_INIT_FULL(container,1,ASTOBJ_DEFAULT_BUCKETS) + +/*! \brief Destroy a container. + * + * \param container A pointer to the container to destory. + * + * This macro frees up resources used by a container. It does not operate on + * the objects in the container. To unlink the objects from the container use + * #ASTOBJ_CONTAINER_DESTROYALL(). + * + * \note This macro should only be used on containers with locking support. + */ +#define ASTOBJ_CONTAINER_DESTROY(container) \ + ASTOBJ_CONTAINER_DESTROY_FULL(container,1,ASTOBJ_DEFAULT_BUCKETS) + +/*! \brief Add an object to a container. + * + * \param container A pointer to the container to operate on. + * \param newobj A pointer to the object to be added. + * + * Currently this macro adds an object to the head of a container. One day it + * should add an object in alphabetical order. + */ +#define ASTOBJ_CONTAINER_LINK(container,newobj) \ + ASTOBJ_CONTAINER_LINK_FULL(container,newobj,(newobj)->name,name,ASTOBJ_DEFAULT_HASH,0,strcasecmp) + +/*! \brief Mark all the objects in a container. + * \param container A pointer to the container to operate on. + */ +#define ASTOBJ_CONTAINER_MARKALL(container) \ + ASTOBJ_CONTAINER_TRAVERSE(container, 1, ASTOBJ_MARK(iterator)) + +/*! \brief Unmark all the objects in a container. + * \param container A pointer to the container to operate on. + */ +#define ASTOBJ_CONTAINER_UNMARKALL(container) \ + ASTOBJ_CONTAINER_TRAVERSE(container, 1, ASTOBJ_UNMARK(iterator)) + +/*! \brief Dump information about an object into a string. + * + * \param s A pointer to the string buffer to use. + * \param slen The length of s. + * \param obj A pointer to the object to dump. + * + * This macro dumps a text representation of the name, objectflags, and + * refcount fields of an object to the specfied string buffer. + */ +#define ASTOBJ_DUMP(s,slen,obj) \ + snprintf((s),(slen),"name: %s\nobjflags: %u\nrefcount: %u\n\n", (obj)->name, (obj)->objflags, (obj)->refcount); + +/*! \brief Dump information about all the objects in a container to a file descriptor. + * + * \param fd The file descriptor to write to. + * \param s A string buffer, same as #ASTOBJ_DUMP(). + * \param slen The length of s, same as #ASTOBJ_DUMP(). + * \param container A pointer to the container to dump. + * + * This macro dumps a text representation of the name, objectflags, and + * refcount fields of all the objects in a container to the specified file + * descriptor. + */ +#define ASTOBJ_CONTAINER_DUMP(fd,s,slen,container) \ + ASTOBJ_CONTAINER_TRAVERSE(container, 1, do { ASTOBJ_DUMP(s,slen,iterator); ast_cli(fd, "%s", s); } while(0)) + +#if defined(__cplusplus) || defined(c_plusplus) +} +#endif + +#endif /* _ASTERISK_ASTOBJ_H */ diff --git a/channels/iax2/include/iax2.h b/channels/iax2/include/iax2.h index ca9ab74dd..3deb5dbcd 100644 --- a/channels/iax2/include/iax2.h +++ b/channels/iax2/include/iax2.h @@ -2,7 +2,7 @@ * Asterisk -- An open source telephony toolkit. * * Implementation of Inter-Asterisk eXchange - * + * * Copyright (C) 2003, Digium * * Mark Spencer <markster@linux-support.net> @@ -19,7 +19,7 @@ * \ref iax2-parser.h * \ref chan_iax2.c */ - + #ifndef _IAX2_H #define _IAX2_H diff --git a/channels/iax2/include/netsock.h b/channels/iax2/include/netsock.h new file mode 100644 index 000000000..bd80072f5 --- /dev/null +++ b/channels/iax2/include/netsock.h @@ -0,0 +1,74 @@ +/* + * Asterisk -- An open source telephony toolkit. + * + * Copyright (C) 1999 - 2005, Digium, Inc. + * + * Mark Spencer <markster@digium.com> + * Kevin P. Fleming <kpfleming@digium.com> + * + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2. See the LICENSE file + * at the top of the source tree. + */ + +/*! \file + * \brief Network socket handling + * + * \deprecated Use netsock2.h instead + */ + +#ifndef _ASTERISK_NETSOCK_H +#define _ASTERISK_NETSOCK_H + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +#include "asterisk/network.h" +#include "asterisk/io.h" +#include "asterisk/netsock2.h" + +struct ast_netsock; + +struct ast_netsock_list; + +struct ast_netsock_list *ast_netsock_list_alloc(void); + +int ast_netsock_init(struct ast_netsock_list *list); + +struct ast_netsock *ast_netsock_bind(struct ast_netsock_list *list, struct io_context *ioc, + const char *bindinfo, int defaultport, int tos, int cos, ast_io_cb callback, void *data); + +struct ast_netsock *ast_netsock_bindaddr(struct ast_netsock_list *list, struct io_context *ioc, + struct ast_sockaddr *bindaddr, int tos, int cos, ast_io_cb callback, void *data); + +int ast_netsock_release(struct ast_netsock_list *list); + +struct ast_netsock *ast_netsock_find(struct ast_netsock_list *list, + struct ast_sockaddr *addr); + +/*! + * \deprecated Use ast_seq_qos in netsock2.h which properly handles IPv4 and IPv6 + * sockets, instead. + */ +int ast_netsock_set_qos(int sockfd, int tos, int cos, const char *desc); + +int ast_netsock_sockfd(const struct ast_netsock *ns); + +const struct ast_sockaddr *ast_netsock_boundaddr(const struct ast_netsock *ns); + +void *ast_netsock_data(const struct ast_netsock *ns); + +void ast_netsock_unref(struct ast_netsock *ns); + +#if defined(__cplusplus) || defined(c_plusplus) +} +#endif + +#endif /* _ASTERISK_NETSOCK_H */ diff --git a/channels/iax2/include/parser.h b/channels/iax2/include/parser.h index 7c9ba2ab5..d8edc4b2a 100644 --- a/channels/iax2/include/parser.h +++ b/channels/iax2/include/parser.h @@ -2,7 +2,7 @@ * Asterisk -- An open source telephony toolkit. * * Implementation of Inter-Asterisk eXchange - * + * * Copyright (C) 2003, Digium * * Mark Spencer <markster@digium.com> @@ -14,7 +14,7 @@ /*!\file * \brief Implementation of the IAX2 protocol */ - + #ifndef _IAX2_PARSER_H #define _IAX2_PARSER_H diff --git a/channels/iax2/netsock.c b/channels/iax2/netsock.c new file mode 100644 index 000000000..17cc62039 --- /dev/null +++ b/channels/iax2/netsock.c @@ -0,0 +1,201 @@ +/* + * Asterisk -- An open source telephony toolkit. + * + * Copyright (C) 1999 - 2005, Digium, Inc. + * + * Kevin P. Fleming <kpfleming@digium.com> + * Mark Spencer <markster@digium.com> + * + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2. See the LICENSE file + * at the top of the source tree. + */ + +/*! \file + * + * \brief Network socket handling + * + * \author Kevin P. Fleming <kpfleming@digium.com> + * \author Mark Spencer <markster@digium.com> + */ + +/*** MODULEINFO + <support_level>core</support_level> + ***/ + +#include "asterisk.h" + +#if !defined (__linux__) && !defined (__GNU__) +#if defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__Darwin__) || defined(__GLIBC__) +#include <net/if_dl.h> +#endif +#endif + +#if defined (SOLARIS) +#include <sys/sockio.h> +#elif defined(HAVE_GETIFADDRS) +#include <ifaddrs.h> +#endif + +#include "include/netsock.h" +#include "asterisk/netsock2.h" +#include "asterisk/utils.h" +#include "include/astobj.h" + +struct ast_netsock { + ASTOBJ_COMPONENTS(struct ast_netsock); + struct ast_sockaddr bindaddr; + int sockfd; + int *ioref; + struct io_context *ioc; + void *data; +}; + +struct ast_netsock_list { + ASTOBJ_CONTAINER_COMPONENTS(struct ast_netsock); + struct io_context *ioc; +}; + +static void ast_netsock_destroy(struct ast_netsock *netsock) +{ + ast_io_remove(netsock->ioc, netsock->ioref); + close(netsock->sockfd); + ast_free(netsock); +} + +struct ast_netsock_list *ast_netsock_list_alloc(void) +{ + return ast_calloc(1, sizeof(struct ast_netsock_list)); +} + +int ast_netsock_init(struct ast_netsock_list *list) +{ + memset(list, 0, sizeof(*list)); + ASTOBJ_CONTAINER_INIT(list); + + return 0; +} + +int ast_netsock_release(struct ast_netsock_list *list) +{ + ASTOBJ_CONTAINER_DESTROYALL(list, ast_netsock_destroy); + ASTOBJ_CONTAINER_DESTROY(list); + ast_free(list); + + return 0; +} + +struct ast_netsock *ast_netsock_find(struct ast_netsock_list *list, struct ast_sockaddr *addr) +{ + struct ast_netsock *sock = NULL; + + ASTOBJ_CONTAINER_TRAVERSE(list, !sock, { + ASTOBJ_RDLOCK(iterator); + if (!ast_sockaddr_cmp(&iterator->bindaddr, addr)) { + sock = iterator; + } + ASTOBJ_UNLOCK(iterator); + }); + + return sock; +} + +struct ast_netsock *ast_netsock_bindaddr(struct ast_netsock_list *list, struct io_context *ioc, struct ast_sockaddr *bindaddr, int tos, int cos, ast_io_cb callback, void *data) +{ + int netsocket = -1; + int *ioref; + + struct ast_netsock *ns; + const int reuseFlag = 1; + + /* Make a UDP socket */ + netsocket = socket(ast_sockaddr_is_ipv6(bindaddr) ? AST_AF_INET6 : AST_AF_INET, SOCK_DGRAM, IPPROTO_IP); + + if (netsocket < 0) { + ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno)); + return NULL; + } + if (setsockopt(netsocket, SOL_SOCKET, SO_REUSEADDR, (char *)&reuseFlag, sizeof reuseFlag) < 0) { + ast_log(LOG_WARNING, "Error setting SO_REUSEADDR on sockfd '%d'\n", netsocket); + } + if (ast_bind(netsocket, bindaddr)) { + ast_log(LOG_ERROR, + "Unable to bind to %s: %s\n", + ast_sockaddr_stringify(bindaddr), + strerror(errno)); + close(netsocket); + return NULL; + } + + ast_set_qos(netsocket, tos, cos, "IAX2"); + + ast_enable_packet_fragmentation(netsocket); + + if (!(ns = ast_calloc(1, sizeof(*ns)))) { + close(netsocket); + return NULL; + } + + /* Establish I/O callback for socket read */ + if (!(ioref = ast_io_add(ioc, netsocket, callback, AST_IO_IN, ns))) { + close(netsocket); + ast_free(ns); + return NULL; + } + ASTOBJ_INIT(ns); + ns->ioref = ioref; + ns->ioc = ioc; + ns->sockfd = netsocket; + ns->data = data; + ast_sockaddr_copy(&ns->bindaddr, bindaddr); + ASTOBJ_CONTAINER_LINK(list, ns); + + return ns; +} + +int ast_netsock_set_qos(int sockfd, int tos, int cos, const char *desc) +{ + return ast_set_qos(sockfd, tos, cos, desc); +} + +struct ast_netsock *ast_netsock_bind(struct ast_netsock_list *list, struct io_context *ioc, const char *bindinfo, int defaultport, int tos, int cos, ast_io_cb callback, void *data) +{ + struct ast_sockaddr addr; + + if (ast_sockaddr_parse(&addr, bindinfo, 0)) { + + if (!ast_sockaddr_port(&addr)) { + ast_sockaddr_set_port(&addr, defaultport); + } + + return ast_netsock_bindaddr(list, ioc, &addr, tos, cos, callback, data); + } + + return NULL; +} + +int ast_netsock_sockfd(const struct ast_netsock *ns) +{ + return ns ? ns-> sockfd : -1; +} + +const struct ast_sockaddr *ast_netsock_boundaddr(const struct ast_netsock *ns) +{ + return &ns->bindaddr; +} + +void *ast_netsock_data(const struct ast_netsock *ns) +{ + return ns->data; +} + +void ast_netsock_unref(struct ast_netsock *ns) +{ + ASTOBJ_UNREF(ns, ast_netsock_destroy); +} diff --git a/channels/iax2/parser.c b/channels/iax2/parser.c index 6eda98260..8880b9280 100644 --- a/channels/iax2/parser.c +++ b/channels/iax2/parser.c @@ -20,7 +20,7 @@ * * \brief Implementation of Inter-Asterisk eXchange Protocol, v 2 * - * \author Mark Spencer <markster@digium.com> + * \author Mark Spencer <markster@digium.com> */ /*** MODULEINFO @@ -136,7 +136,7 @@ static void dump_prefs(char *output, int maxlen, void *value, int len) strncpy(output, value, maxlen); output[maxlen] = '\0'; - + iax2_codec_pref_convert(&pref, output, total_len, 0); memset(output,0,total_len); iax2_codec_pref_string(&pref, output, total_len); @@ -147,7 +147,7 @@ static void dump_int(char *output, int maxlen, void *value, int len) if (len == (int)sizeof(unsigned int)) snprintf(output, maxlen, "%lu", (unsigned long)ntohl(get_unaligned_uint32(value))); else - ast_copy_string(output, "Invalid INT", maxlen); + ast_copy_string(output, "Invalid INT", maxlen); } static void dump_short(char *output, int maxlen, void *value, int len) @@ -177,7 +177,7 @@ static void dump_datetime(char *output, int maxlen, void *value, int len) tm.tm_mday = (val >> 16) & 0x1f; tm.tm_mon = ((val >> 21) & 0x0f) - 1; tm.tm_year = ((val >> 25) & 0x7f) + 100; - ast_strftime(output, maxlen, "%Y-%m-%d %T", &tm); + ast_strftime(output, maxlen, "%Y-%m-%d %T", &tm); } else ast_copy_string(output, "Invalid DATETIME format!", maxlen); } @@ -366,7 +366,7 @@ static void dump_prov_ies(char *output, int maxlen, unsigned char *iedata, int l char tmp[256]; if (len < 2) return; - strcpy(output, "\n"); + strcpy(output, "\n"); maxlen -= strlen(output); output += strlen(output); while(len > 2) { ie = iedata[0]; @@ -748,14 +748,14 @@ int iax_ie_append_versioned_uint64(struct iax_ie_data *ied, unsigned char ie, un return iax_ie_append_raw(ied, ie, &newval, (int) sizeof(newval)); } -int iax_ie_append_int(struct iax_ie_data *ied, unsigned char ie, unsigned int value) +int iax_ie_append_int(struct iax_ie_data *ied, unsigned char ie, unsigned int value) { unsigned int newval; newval = htonl(value); return iax_ie_append_raw(ied, ie, &newval, (int)sizeof(newval)); } -int iax_ie_append_short(struct iax_ie_data *ied, unsigned char ie, unsigned short value) +int iax_ie_append_short(struct iax_ie_data *ied, unsigned char ie, unsigned short value) { unsigned short newval; newval = htons(value); @@ -772,7 +772,7 @@ int iax_ie_append_byte(struct iax_ie_data *ied, unsigned char ie, unsigned char return iax_ie_append_raw(ied, ie, &dat, 1); } -int iax_ie_append(struct iax_ie_data *ied, unsigned char ie) +int iax_ie_append(struct iax_ie_data *ied, unsigned char ie) { return iax_ie_append_raw(ied, ie, NULL, 0); } @@ -978,7 +978,7 @@ int iax_parse_ies(struct iax_ies *ies, unsigned char *data, int datalen) snprintf(tmp, (int)sizeof(tmp), "Expecting msgcount to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len); errorf(tmp); } else - ies->msgcount = ntohs(get_unaligned_uint16(data + 2)); + ies->msgcount = ntohs(get_unaligned_uint16(data + 2)); break; case IAX_IE_AUTOANSWER: ies->autoanswer = 1; @@ -1005,7 +1005,7 @@ int iax_parse_ies(struct iax_ies *ies, unsigned char *data, int datalen) snprintf(tmp, (int)sizeof(tmp), "Expecting firmwarever to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len); errorf(tmp); } else - ies->firmwarever = ntohs(get_unaligned_uint16(data + 2)); + ies->firmwarever = ntohs(get_unaligned_uint16(data + 2)); break; case IAX_IE_DEVICETYPE: ies->devicetype = (char *)data + 2; @@ -1058,7 +1058,7 @@ int iax_parse_ies(struct iax_ies *ies, unsigned char *data, int datalen) snprintf(tmp, (int)sizeof(tmp), "Expecting callingtns to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len); errorf(tmp); } else - ies->calling_tns = ntohs(get_unaligned_uint16(data + 2)); + ies->calling_tns = ntohs(get_unaligned_uint16(data + 2)); break; case IAX_IE_RR_JITTER: if (len != (int)sizeof(unsigned int)) { @@ -1267,12 +1267,12 @@ struct iax_frame *iax_frame_new(int direction, int datalen, unsigned int cacheab fr->direction = direction; fr->retrans = -1; - + if (fr->direction == DIRECTION_INGRESS) ast_atomic_fetchadd_int(&iframes, 1); else ast_atomic_fetchadd_int(&oframes, 1); - + ast_atomic_fetchadd_int(&frames, 1); return fr; diff --git a/channels/iax2/provision.c b/channels/iax2/provision.c index 6bd06faf9..f21c4e6e7 100644 --- a/channels/iax2/provision.c +++ b/channels/iax2/provision.c @@ -17,8 +17,8 @@ */ /*! \file - * - * \brief IAX Provisioning Protocol + * + * \brief IAX Provisioning Protocol * * \author Mark Spencer <markster@digium.com> */ @@ -93,7 +93,7 @@ char *iax_provflags2str(char *buf, int buflen, unsigned int flags) if (!buf || buflen < 1) return NULL; - + buf[0] = '\0'; for (x = 0; x < ARRAY_LEN(iax_flags); x++) { @@ -103,7 +103,7 @@ char *iax_provflags2str(char *buf, int buflen, unsigned int flags) } } - if (!ast_strlen_zero(buf)) + if (!ast_strlen_zero(buf)) buf[strlen(buf) - 1] = '\0'; else strncpy(buf, "none", buflen - 1); @@ -239,7 +239,7 @@ int iax_provision_build(struct iax_ie_data *provdata, unsigned int *signature, c iax_ie_append_int(provdata, PROV_IE_FORMAT, cur->format); if (force || cur->tos) iax_ie_append_byte(provdata, PROV_IE_TOS, cur->tos); - + /* Calculate checksum of message so far */ sig = prov_ver_calc(provdata); if (signature) @@ -299,7 +299,7 @@ static int iax_template_parse(struct iax_template *cur, struct ast_config *cfg, ast_log(LOG_WARNING, "Unable to find base template '%s' for creating '%s'. Trying '%s'\n", t, s, def); else def = t; - } + } if (!src) { src = iax_template_find(def, 0); if (!src) @@ -342,7 +342,7 @@ static int iax_template_parse(struct iax_template *cur, struct ast_config *cfg, cur->server = ntohl(ia.s_addr); else cur->altserver = ntohl(ia.s_addr); - } else + } else ast_log(LOG_WARNING, "Ignoring invalid %s '%s' for '%s' at line %d\n", v->name, v->value, s, v->lineno); } else if (!strcasecmp(v->name, "codec")) { struct ast_format *tmpfmt; @@ -425,10 +425,10 @@ static const char *ifthere(const char *s) static const char *iax_server(unsigned int addr) { struct in_addr ia; - + if (!addr) return "<unspecified>"; - + ia.s_addr = htonl(addr); return ast_inet_ntoa(ia); @@ -461,7 +461,7 @@ static char *iax_show_provisioning(struct ast_cli_entry *e, int cmd, struct ast_ ast_mutex_lock(&provlock); AST_LIST_TRAVERSE(&templates, cur, list) { if ((a->argc == 3) || (!strcasecmp(a->argv[3], cur->name))) { - if (found) + if (found) ast_cli(a->fd, "\n"); ast_copy_string(server, iax_server(cur->server), sizeof(server)); ast_copy_string(alternate, iax_server(cur->altserver), sizeof(alternate)); @@ -535,7 +535,7 @@ int iax_provision_reload(int reload) struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 }; if (!provinit) iax_provision_init(); - + cfg = ast_config_load2("iaxprov.conf", "chan_iax2", config_flags); if (cfg != NULL && cfg != CONFIG_STATUS_FILEUNCHANGED && cfg != CONFIG_STATUS_FILEINVALID) { /* Mark all as dead. No need for locking */ diff --git a/channels/misdn/ie.c b/channels/misdn/ie.c index df5df9afe..67fc9585e 100644 --- a/channels/misdn/ie.c +++ b/channels/misdn/ie.c @@ -1412,4 +1412,3 @@ static void enc_ie_restart_ind(unsigned char **ntmode, msg_t *msg, unsigned char p[2] = rind; } - diff --git a/channels/misdn/isdn_lib.c b/channels/misdn/isdn_lib.c index 8dcf41faa..cb64106b9 100644 --- a/channels/misdn/isdn_lib.c +++ b/channels/misdn/isdn_lib.c @@ -4817,5 +4817,3 @@ void misdn_lib_reinit_nt_stack(int port) misdn_lib_get_l1_up(stack); } } - - diff --git a/channels/pjsip/dialplan_functions.c b/channels/pjsip/dialplan_functions.c index 861edf72d..aa376f892 100644 --- a/channels/pjsip/dialplan_functions.c +++ b/channels/pjsip/dialplan_functions.c @@ -388,7 +388,7 @@ </enumlist> </enum> <enum name="target_uri"> - <para>The request URI of the <literal>INVITE</literal> request associated with the creation of this channel.</para> + <para>The contact URI where requests are sent.</para> </enum> <enum name="local_uri"> <para>The local URI.</para> @@ -402,6 +402,10 @@ <enum name="remote_tag"> <para>Tag in To header</para> </enum> + <enum name="request_uri"> + <para>The request URI of the incoming <literal>INVITE</literal> + associated with the creation of this channel.</para> + </enum> <enum name="t38state"> <para>The current state of any T.38 fax on this channel.</para> <enumlist> @@ -656,6 +660,27 @@ static int channel_read_rtcp(struct ast_channel *chan, const char *type, const c return 0; } +static int print_escaped_uri(struct ast_channel *chan, const char *type, + pjsip_uri_context_e context, const void *uri, char *buf, size_t size) +{ + int res; + char *buf_copy; + + res = pjsip_uri_print(context, uri, buf, size); + if (res < 0) { + ast_log(LOG_ERROR, "Channel %s: Unescaped %s too long for %d byte buffer\n", + ast_channel_name(chan), type, (int) size); + + /* Empty buffer that likely is not terminated. */ + buf[0] = '\0'; + return -1; + } + + buf_copy = ast_strdupa(buf); + ast_escape_quoted(buf_copy, buf, size); + return 0; +} + /*! * \internal \brief Handle reading signalling information */ @@ -664,6 +689,7 @@ static int channel_read_pjsip(struct ast_channel *chan, const char *type, const struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(chan); char *buf_copy; pjsip_dialog *dlg; + int res = 0; if (!channel) { ast_log(AST_LOG_WARNING, "Channel %s has no pvt!\n", ast_channel_name(chan)); @@ -689,25 +715,27 @@ static int channel_read_pjsip(struct ast_channel *chan, const char *type, const return -1; #endif } else if (!strcmp(type, "target_uri")) { - pjsip_uri_print(PJSIP_URI_IN_REQ_URI, dlg->target, buf, buflen); - buf_copy = ast_strdupa(buf); - ast_escape_quoted(buf_copy, buf, buflen); + res = print_escaped_uri(chan, type, PJSIP_URI_IN_REQ_URI, dlg->target, buf, + buflen); } else if (!strcmp(type, "local_uri")) { - pjsip_uri_print(PJSIP_URI_IN_FROMTO_HDR, dlg->local.info->uri, buf, buflen); - buf_copy = ast_strdupa(buf); - ast_escape_quoted(buf_copy, buf, buflen); + res = print_escaped_uri(chan, type, PJSIP_URI_IN_FROMTO_HDR, dlg->local.info->uri, + buf, buflen); } else if (!strcmp(type, "local_tag")) { ast_copy_pj_str(buf, &dlg->local.info->tag, buflen); buf_copy = ast_strdupa(buf); ast_escape_quoted(buf_copy, buf, buflen); } else if (!strcmp(type, "remote_uri")) { - pjsip_uri_print(PJSIP_URI_IN_FROMTO_HDR, dlg->remote.info->uri, buf, buflen); - buf_copy = ast_strdupa(buf); - ast_escape_quoted(buf_copy, buf, buflen); + res = print_escaped_uri(chan, type, PJSIP_URI_IN_FROMTO_HDR, + dlg->remote.info->uri, buf, buflen); } else if (!strcmp(type, "remote_tag")) { ast_copy_pj_str(buf, &dlg->remote.info->tag, buflen); buf_copy = ast_strdupa(buf); ast_escape_quoted(buf_copy, buf, buflen); + } else if (!strcmp(type, "request_uri")) { + if (channel->session->request_uri) { + res = print_escaped_uri(chan, type, PJSIP_URI_IN_REQ_URI, + channel->session->request_uri, buf, buflen); + } } else if (!strcmp(type, "t38state")) { ast_copy_string(buf, t38state_to_string[channel->session->t38state], buflen); } else if (!strcmp(type, "local_addr")) { @@ -743,7 +771,7 @@ static int channel_read_pjsip(struct ast_channel *chan, const char *type, const return -1; } - return 0; + return res; } /*! \brief Struct used to push function arguments to task processor */ diff --git a/channels/sig_analog.h b/channels/sig_analog.h index 6415b6eb8..42e00c029 100644 --- a/channels/sig_analog.h +++ b/channels/sig_analog.h @@ -93,7 +93,7 @@ enum analog_event { ANALOG_EVENT_EC_NLP_ENABLED, ANALOG_EVENT_ERROR, /* not a DAHDI event */ ANALOG_EVENT_DTMFCID, /* not a DAHDI event */ - ANALOG_EVENT_PULSEDIGIT = (1 << 16), + ANALOG_EVENT_PULSEDIGIT = (1 << 16), ANALOG_EVENT_DTMFDOWN = (1 << 17), ANALOG_EVENT_DTMFUP = (1 << 18), }; @@ -231,7 +231,7 @@ struct analog_callback { int (* const check_confirmanswer)(void *pvt); void (* const set_callwaiting)(void *pvt, int callwaiting_enable); void (* const cancel_cidspill)(void *pvt); - int (* const confmute)(void *pvt, int mute); + int (* const confmute)(void *pvt, int mute); void (* const set_pulsedial)(void *pvt, int flag); void (* const set_new_owner)(void *pvt, struct ast_channel *new_owner); diff --git a/channels/sip/config_parser.c b/channels/sip/config_parser.c index 4674901be..211f60016 100644 --- a/channels/sip/config_parser.c +++ b/channels/sip/config_parser.c @@ -924,4 +924,3 @@ void sip_config_parser_unregister_tests(void) AST_TEST_UNREGISTER(sip_parse_host_line_test); AST_TEST_UNREGISTER(sip_parse_nat_test); } - diff --git a/channels/sip/dialplan_functions.c b/channels/sip/dialplan_functions.c index 36d4ea9e4..09804ce8a 100644 --- a/channels/sip/dialplan_functions.c +++ b/channels/sip/dialplan_functions.c @@ -134,7 +134,7 @@ int sip_acf_channel_read(struct ast_channel *chan, const char *funcname, char *p AST_APP_ARG(type); AST_APP_ARG(field); ); - + /* Check for zero arguments */ if (ast_strlen_zero(parse)) { ast_log(LOG_ERROR, "Cannot call %s without arguments\n", funcname); @@ -509,4 +509,3 @@ void sip_dialplan_function_unregister_tests(void) { AST_TEST_UNREGISTER(test_sip_rtpqos_1); } - diff --git a/channels/sip/include/config_parser.h b/channels/sip/include/config_parser.h index fd055b145..811f8951c 100644 --- a/channels/sip/include/config_parser.h +++ b/channels/sip/include/config_parser.h @@ -35,7 +35,7 @@ int sip_parse_register_line(struct sip_registry *reg, int default_expiry, const /*! * \brief parses a config line for a host with a transport * - * An example input would be: + * An example input would be: * <code>tls://www.google.com:8056</code> * * \retval 0 on success diff --git a/channels/sip/include/globals.h b/channels/sip/include/globals.h index d7c9f13d0..3c3ba47bd 100644 --- a/channels/sip/include/globals.h +++ b/channels/sip/include/globals.h @@ -39,4 +39,3 @@ extern struct ast_channel_tech sip_tech; extern struct ast_channel_tech sip_tech_info; #endif /* !defined(SIP_GLOBALS_H) */ - diff --git a/channels/sip/include/reqresp_parser.h b/channels/sip/include/reqresp_parser.h index 2543329dd..338824a53 100644 --- a/channels/sip/include/reqresp_parser.h +++ b/channels/sip/include/reqresp_parser.h @@ -59,8 +59,8 @@ AST_LIST_HEAD_NOLOCK(contactliststruct, contact); * parts, user:secret. * - If the URI contains a port number, hostport will return with both * parts, host:port. - * - This function overwrites the the URI string. - * + * - This function overwrites the URI string. + * * \retval 0 on success * \retval -1 on error. * diff --git a/channels/sip/include/security_events.h b/channels/sip/include/security_events.h index 1d0f58b41..9f4bb2ec9 100644 --- a/channels/sip/include/security_events.h +++ b/channels/sip/include/security_events.h @@ -32,7 +32,7 @@ void sip_report_invalid_peer(const struct sip_pvt *p); void sip_report_failed_acl(const struct sip_pvt *p, const char *aclname); void sip_report_inval_password(const struct sip_pvt *p, const char *responsechallenge, const char *responsehash); -void sip_report_auth_success(const struct sip_pvt *p, uint32_t *using_password); +void sip_report_auth_success(const struct sip_pvt *p, uint32_t using_password); void sip_report_session_limit(const struct sip_pvt *p); void sip_report_failed_challenge_response(const struct sip_pvt *p, const char *response, const char *expected_response); void sip_report_chal_sent(const struct sip_pvt *p); diff --git a/channels/sip/security_events.c b/channels/sip/security_events.c index b51c4736c..86ba413d3 100644 --- a/channels/sip/security_events.c +++ b/channels/sip/security_events.c @@ -120,7 +120,7 @@ void sip_report_inval_password(const struct sip_pvt *p, const char *response_cha ast_security_event_report(AST_SEC_EVT(&inval_password)); } -void sip_report_auth_success(const struct sip_pvt *p, uint32_t *using_password) +void sip_report_auth_success(const struct sip_pvt *p, uint32_t using_password) { char session_id[32]; @@ -269,7 +269,8 @@ void sip_report_inval_transport(const struct sip_pvt *p, const char *transport) } int sip_report_security_event(const char *peer, struct ast_sockaddr *addr, const struct sip_pvt *p, - const struct sip_request *req, const int res) { + const struct sip_request *req, const int res) +{ struct sip_peer *peer_report; enum check_auth_result res_report = res; @@ -295,9 +296,9 @@ int sip_report_security_event(const char *peer, struct ast_sockaddr *addr, const case AUTH_SUCCESSFUL: if (peer_report) { if (ast_strlen_zero(peer_report->secret) && ast_strlen_zero(peer_report->md5secret)) { - sip_report_auth_success(p, (uint32_t *) 0); + sip_report_auth_success(p, 0); } else { - sip_report_auth_success(p, (uint32_t *) 1); + sip_report_auth_success(p, 1); } } break; @@ -355,4 +356,3 @@ int sip_report_security_event(const char *peer, struct ast_sockaddr *addr, const return result; } - diff --git a/channels/vcodecs.c b/channels/vcodecs.c index 76aeb671f..e55c5fef9 100644 --- a/channels/vcodecs.c +++ b/channels/vcodecs.c @@ -154,7 +154,7 @@ static void check_h261(struct fbuf_t *b) { struct bitbuf a = bitbuf_init(b->data, b->used * 8, 0); uint32_t x, y; - + x = getbits(&a, 20); /* PSC, 0000 0000 0000 0001 0000 */ if (x != 0x10) { ast_log(LOG_WARNING, "bad PSC 0x%x\n", x); @@ -386,7 +386,7 @@ static struct ast_frame *h263p_encap(struct fbuf_t *b, int mtu, ast_log(LOG_WARNING, "--- frame error l %d\n", l); break; } - + if (d[0] == 0 && d[1] == 0) { /* we start with a psc */ h = 0; } else { /* no psc, create a header */ @@ -568,8 +568,8 @@ static int h263_enc_init(AVCodecContext *enc_ctx) * TR:8 .... .... temporal reference * PTYPE:13 or more ptype... * If we don't fragment a GOB SBIT and EBIT = 0. - * reference, 8 bit) - * + * reference, 8 bit) + * * The assumption below is that we start with a PSC. */ static struct ast_frame *h263_encap(struct fbuf_t *b, int mtu, @@ -695,7 +695,7 @@ static struct video_codec_desc h263_codec = { .dec_init = NULL, .dec_decap = h263_decap, .dec_run = ffmpeg_decode - + }; /*---- h261 support -----*/ @@ -947,7 +947,7 @@ static int h264_dec_init(AVCodecContext *dec_ctx) * - 0..n 0-byte(s), unused, optional. one zero-byte is always present * in the first NAL before the start code prefix. * - start code prefix (3 bytes): 0x000001 - * (the first bytestream has a + * (the first bytestream has a * like these 0x00000001!) * - NAL header byte ( F[1] | NRI[2] | Type[5] ) where type != 0 * - byte-stream @@ -1127,7 +1127,7 @@ static const struct _cm video_formats[] = { { AST_FORMAT_MP4_VIDEO, CODEC_ID_MPEG4, CM_RDWR }, { 0, 0, 0 }, }; - + /*! \brief map an asterisk format into an ffmpeg one */ static enum CodecID map_video_format(uint32_t ast_format, int rw) diff --git a/channels/vgrabbers.c b/channels/vgrabbers.c index 25817407e..bcccece4d 100644 --- a/channels/vgrabbers.c +++ b/channels/vgrabbers.c @@ -1,7 +1,7 @@ /* * Asterisk -- An open source telephony toolkit. * - * Copyright 2007, Luigi Rizzo + * Copyright 2007, Luigi Rizzo * * See http://www.asterisk.org for more information about * the Asterisk project. Please do not directly contact @@ -208,7 +208,7 @@ static void *grab_v4l1_open(const char *dev, struct fbuf_t *geom, int fps) struct fbuf_t *b; /* name should be something under /dev/ */ - if (strncmp(dev, "/dev/", 5)) + if (strncmp(dev, "/dev/", 5)) return NULL; fd = open(dev, O_RDONLY | O_NONBLOCK); if (fd < 0) { @@ -226,12 +226,8 @@ static void *grab_v4l1_open(const char *dev, struct fbuf_t *geom, int fps) v->b = *geom; b = &v->b; /* shorthand */ - i = fcntl(fd, F_GETFL); - if (-1 == fcntl(fd, F_SETFL, i | O_NONBLOCK)) { - /* non fatal, just emit a warning */ - ast_log(LOG_WARNING, "error F_SETFL for %s [%s]\n", - dev, strerror(errno)); - } + ast_fd_set_flags(fd, O_NONBLOCK); + /* set format for the camera. * In principle we could retry with a different format if the * one we are asking for is not supported. |