Пример #1
0
void app_update(struct stasis_app *app, stasis_app_cb handler, void *data)
{
	SCOPED_AO2LOCK(lock, app);

	if (app->handler) {
		RAII_VAR(struct ast_json *, msg, NULL, ast_json_unref);

		ast_verb(1, "Replacing Stasis app '%s'\n", app->name);

		msg = ast_json_pack("{s: s, s: s}",
			"type", "ApplicationReplaced",
			"application", app->name);
		if (msg) {
			app_send(app, msg);
		}
	} else {
		ast_verb(1, "Activating Stasis app '%s'\n", app->name);
	}

	app->handler = handler;
	ao2_cleanup(app->data);
	if (data) {
		ao2_ref(data, +1);
	}
	app->data = data;
}
Пример #2
0
/*!
 * \internal
 * \pre mixmonitor_ds must be locked before calling this function
 */
static void mixmonitor_ds_close_fs(struct mixmonitor_ds *mixmonitor_ds)
{
	unsigned char quitting = 0;

	if (mixmonitor_ds->fs) {
		quitting = 1;
		ast_closestream(mixmonitor_ds->fs);
		mixmonitor_ds->fs = NULL;
		ast_verb(2, "MixMonitor close filestream (mixed)\n");
	}

	if (mixmonitor_ds->fs_read) {
		quitting = 1;
		ast_closestream(mixmonitor_ds->fs_read);
		mixmonitor_ds->fs_read = NULL;
		ast_verb(2, "MixMonitor close filestream (read)\n");
	}

	if (mixmonitor_ds->fs_write) {
		quitting = 1;
		ast_closestream(mixmonitor_ds->fs_write);
		mixmonitor_ds->fs_write = NULL;
		ast_verb(2, "MixMonitor close filestream (write)\n");
	}

	if (quitting) {
		mixmonitor_ds->fs_quit = 1;
	}
}
Пример #3
0
static int cpeid_exec(struct ast_channel *chan, const char *idata)
{
	int res=0;
	unsigned char cpeid[4];
	int gotgeometry = 0;
	int gotcpeid = 0;
	int width, height, buttons;
	char *data[4];
	unsigned int x;

	for (x = 0; x < 4; x++)
		data[x] = alloca(80);

	strcpy(data[0], "** CPE Info **");
	strcpy(data[1], "Identifying CPE...");
	strcpy(data[2], "Please wait...");
	res = ast_adsi_load_session(chan, NULL, 0, 1);
	if (res > 0) {
		cpeid_setstatus(chan, data, 0);
		res = ast_adsi_get_cpeid(chan, cpeid, 0);
		if (res > 0) {
			gotcpeid = 1;
			ast_verb(3, "Got CPEID of '%02x:%02x:%02x:%02x' on '%s'\n", cpeid[0], cpeid[1], cpeid[2], cpeid[3], chan->name);
		}
		if (res > -1) {
			strcpy(data[1], "Measuring CPE...");
			strcpy(data[2], "Please wait...");
			cpeid_setstatus(chan, data, 0);
			res = ast_adsi_get_cpeinfo(chan, &width, &height, &buttons, 0);
			if (res > -1) {
				ast_verb(3, "CPE has %d lines, %d columns, and %d buttons on '%s'\n", height, width, buttons, chan->name);
				gotgeometry = 1;
			}
		}
		if (res > -1) {
			if (gotcpeid)
				snprintf(data[1], 80, "CPEID: %02x:%02x:%02x:%02x", cpeid[0], cpeid[1], cpeid[2], cpeid[3]);
			else
				strcpy(data[1], "CPEID Unknown");
			if (gotgeometry) 
				snprintf(data[2], 80, "Geom: %dx%d, %d buttons", width, height, buttons);
			else
				strcpy(data[2], "Geometry unknown");
			strcpy(data[3], "Press # to exit");
			cpeid_setstatus(chan, data, 1);
			for(;;) {
				res = ast_waitfordigit(chan, 1000);
				if (res < 0)
					break;
				if (res == '#') {
					res = 0;
					break;
				}
			}
			ast_adsi_unload_session(chan);
		}
	}

	return res;
}
Пример #4
0
void *agent_thread(void *arg)
{
	ast_verb(2, "Starting %sAgent\n", res_snmp_agentx_subagent ? "Sub" : "");

	snmp_enable_stderrlog();

	if (res_snmp_agentx_subagent)
		netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID,
							   NETSNMP_DS_AGENT_ROLE,
							   1);

	init_agent("asterisk");

	init_asterisk_mib();

	init_snmp("asterisk");

	if (!res_snmp_agentx_subagent)
		init_master_agent();

	while (res_snmp_dont_stop)
		agent_check_and_process(1);

	snmp_shutdown("asterisk");

	ast_verb(2, "Terminating %sAgent\n", res_snmp_agentx_subagent ? "Sub" : "");

	return NULL;
}
Пример #5
0
/*
* Attempt to access a database variable and increment it,
* provided that the user defined db-family in alarmreceiver.conf
* The alarmreceiver app will write statistics to a few variables
* in this family if it is defined. If the new key doesn't exist in the
* family, then create it and set its value to 1.
*/
static void database_increment( char *key )
{
	int res = 0;
	unsigned v;
	char value[16];
	
	
	if (ast_strlen_zero(db_family))
		return; /* If not defined, don't do anything */
	
	res = ast_db_get(db_family, key, value, sizeof(value) - 1);
	
	if (res) {
		ast_verb(4, "AlarmReceiver: Creating database entry %s and setting to 1\n", key);
		/* Guess we have to create it */
		res = ast_db_put(db_family, key, "1");
		return;
	}
	
	sscanf(value, "%30u", &v);
	v++;

	ast_verb(4, "AlarmReceiver: New value for %s: %u\n", key, v);

	snprintf(value, sizeof(value), "%u", v);

	res = ast_db_put(db_family, key, value);

	if (res)
		ast_verb(4, "AlarmReceiver: database_increment write error\n");

	return;
}
Пример #6
0
static int del_exec(struct ast_channel *chan, const char *data)
{
	char *argv, *family, *key;
	static int deprecation_warning = 0;

	if (!deprecation_warning) {
		deprecation_warning = 1;
		ast_log(LOG_WARNING, "The DBdel application has been deprecated in favor of the DB_DELETE dialplan function!\n");
	}

	argv = ast_strdupa(data);

	if (strchr(argv, '/')) {
		family = strsep(&argv, "/");
		key = strsep(&argv, "\0");
		if (!family || !key) {
			ast_debug(1, "Ignoring; Syntax error in argument\n");
			return 0;
		}
		ast_verb(3, "DBdel: family=%s, key=%s\n", family, key);
		if (ast_db_del(family, key))
			ast_verb(3, "DBdel: Error deleting key from database.\n");
	} else {
		ast_debug(1, "Ignoring, no parameters\n");
	}

	return 0;
}
Пример #7
0
static int deltree_exec(struct ast_channel *chan, const char *data)
{
	char *argv, *family, *keytree;

	argv = ast_strdupa(data);

	if (strchr(argv, '/')) {
		family = strsep(&argv, "/");
		keytree = strsep(&argv, "\0");
		if (!family || !keytree) {
			ast_debug(1, "Ignoring; Syntax error in argument\n");
			return 0;
		}
		if (ast_strlen_zero(keytree))
			keytree = 0;
	} else {
		family = argv;
		keytree = 0;
	}

	if (keytree) {
		ast_verb(3, "DBdeltree: family=%s, keytree=%s\n", family, keytree);
	} else {
		ast_verb(3, "DBdeltree: family=%s\n", family);
	}

	if (ast_db_deltree(family, keytree) < 0) {
		ast_verb(3, "DBdeltree: Error deleting key from database.\n");
	}

	return 0;
}
static void stop_automonitor(struct ast_bridge_channel *bridge_channel, struct ast_channel *peer_chan, struct ast_features_general_config *features_cfg, const char *stop_message)
{
	ast_verb(3, "AutoMonitor used to stop recording call.\n");

	ast_channel_lock(peer_chan);
	if (ast_channel_monitor(peer_chan)) {
		if (ast_channel_monitor(peer_chan)->stop(peer_chan, 1)) {
			ast_verb(3, "Cannot stop AutoMonitor for %s\n", ast_channel_name(bridge_channel->chan));
			if (features_cfg && !(ast_strlen_zero(features_cfg->recordingfailsound))) {
				ast_bridge_channel_queue_playfile(bridge_channel, NULL, features_cfg->recordingfailsound, NULL);
			}
			ast_channel_unlock(peer_chan);
			return;
		}
	} else {
		/* Something else removed the Monitor before we got to it. */
		ast_channel_unlock(peer_chan);
		return;
	}

	ast_channel_unlock(peer_chan);

	if (features_cfg && !(ast_strlen_zero(features_cfg->courtesytone))) {
		ast_bridge_channel_queue_playfile(bridge_channel, NULL, features_cfg->courtesytone, NULL);
		ast_bridge_channel_write_playfile(bridge_channel, NULL, features_cfg->courtesytone, NULL);
	}

	if (!ast_strlen_zero(stop_message)) {
		ast_bridge_channel_queue_playfile(bridge_channel, NULL, stop_message, NULL);
		ast_bridge_channel_write_playfile(bridge_channel, NULL, stop_message, NULL);
	}
}
Пример #9
0
static int dahdiras_exec(struct ast_channel *chan, const char *data)
{
    int res=-1;
    char *args;
    struct dahdi_params dahdip;

    if (!data)
        data = "";

    args = ast_strdupa(data);

    /* Answer the channel if it's not up */
    if (ast_channel_state(chan) != AST_STATE_UP)
        ast_answer(chan);
    if (strcasecmp(ast_channel_tech(chan)->type, "DAHDI")) {
        /* If it's not a DAHDI channel, we're done.  Wait a couple of
           seconds and then hangup... */
        ast_verb(2, "Channel %s is not a DAHDI channel\n", ast_channel_name(chan));
        sleep(2);
    } else {
        memset(&dahdip, 0, sizeof(dahdip));
        if (ioctl(ast_channel_fd(chan, 0), DAHDI_GET_PARAMS, &dahdip)) {
            ast_log(LOG_WARNING, "Unable to get DAHDI parameters\n");
        } else if (dahdip.sigtype != DAHDI_SIG_CLEAR) {
            ast_verb(2, "Channel %s is not a clear channel\n", ast_channel_name(chan));
        } else {
            /* Everything should be okay.  Run PPP. */
            ast_verb(3, "Starting RAS on %s\n", ast_channel_name(chan));
            /* Execute RAS */
            run_ras(chan, args);
        }
    }
    return res;
}
Пример #10
0
static void run_ras(struct ast_channel *chan, char *args)
{
    pid_t pid;
    int status;
    int res;
    int signalled = 0;
    struct dahdi_bufferinfo savebi;
    int x;

    res = ioctl(ast_channel_fd(chan, 0), DAHDI_GET_BUFINFO, &savebi);
    if(res) {
        ast_log(LOG_WARNING, "Unable to check buffer policy on channel %s\n", ast_channel_name(chan));
        return;
    }

    pid = spawn_ras(chan, args);
    if (pid < 0) {
        ast_log(LOG_WARNING, "Failed to spawn RAS\n");
    } else {
        for (;;) {
            res = waitpid(pid, &status, WNOHANG);
            if (!res) {
                /* Check for hangup */
                if (ast_check_hangup(chan) && !signalled) {
                    ast_debug(1, "Channel '%s' hungup.  Signalling RAS at %d to die...\n", ast_channel_name(chan), pid);
                    kill(pid, SIGTERM);
                    signalled=1;
                }
                /* Try again */
                sleep(1);
                continue;
            }
            if (res < 0) {
                ast_log(LOG_WARNING, "waitpid returned %d: %s\n", res, strerror(errno));
            }
            if (WIFEXITED(status)) {
                ast_verb(3, "RAS on %s terminated with status %d\n", ast_channel_name(chan), WEXITSTATUS(status));
            } else if (WIFSIGNALED(status)) {
                ast_verb(3, "RAS on %s terminated with signal %d\n",
                         ast_channel_name(chan), WTERMSIG(status));
            } else {
                ast_verb(3, "RAS on %s terminated weirdly.\n", ast_channel_name(chan));
            }
            /* Throw back into audio mode */
            x = 1;
            ioctl(ast_channel_fd(chan, 0), DAHDI_AUDIOMODE, &x);

            /* Restore saved values */
            res = ioctl(ast_channel_fd(chan, 0), DAHDI_SET_BUFINFO, &savebi);
            if (res < 0) {
                ast_log(LOG_WARNING, "Unable to set buffer policy on channel %s\n", ast_channel_name(chan));
            }
            break;
        }
    }
    ast_safe_fork_cleanup();
}
Пример #11
0
static int __ssl_setup(struct ast_tls_config *cfg, int client)
{
#ifndef DO_SSL
	cfg->enabled = 0;
	return 0;
#else
	if (!cfg->enabled)
		return 0;

	SSL_load_error_strings();
	SSLeay_add_ssl_algorithms();

	if (!(cfg->ssl_ctx = SSL_CTX_new( client ? SSLv23_client_method() : SSLv23_server_method() ))) {
		ast_debug(1, "Sorry, SSL_CTX_new call returned null...\n");
		cfg->enabled = 0;
		return 0;
	}
	if (!ast_strlen_zero(cfg->certfile)) {
		if (SSL_CTX_use_certificate_file(cfg->ssl_ctx, cfg->certfile, SSL_FILETYPE_PEM) == 0 ||
		    SSL_CTX_use_PrivateKey_file(cfg->ssl_ctx, cfg->certfile, SSL_FILETYPE_PEM) == 0 ||
		    SSL_CTX_check_private_key(cfg->ssl_ctx) == 0 ) {
			if (!client) {
				/* Clients don't need a certificate, but if its setup we can use it */
				ast_verb(0, "SSL cert error <%s>", cfg->certfile);
				sleep(2);
				cfg->enabled = 0;
				return 0;
			}
		}
	}
	if (!ast_strlen_zero(cfg->cipher)) {
		if (SSL_CTX_set_cipher_list(cfg->ssl_ctx, cfg->cipher) == 0 ) {
			if (!client) {
				ast_verb(0, "SSL cipher error <%s>", cfg->cipher);
				sleep(2);
				cfg->enabled = 0;
				return 0;
			}
		}
	}
	if (!ast_strlen_zero(cfg->cafile) || !ast_strlen_zero(cfg->capath)) {
		if (SSL_CTX_load_verify_locations(cfg->ssl_ctx, S_OR(cfg->cafile, NULL), S_OR(cfg->capath,NULL)) == 0)
			ast_verb(0, "SSL CA file(%s)/path(%s) error\n", cfg->cafile, cfg->capath);
	}

	ast_verb(0, "SSL certificate ok\n");
	return 1;
#endif
}
Пример #12
0
static int unload_module(void)
{
    ast_cdr_unregister(name);

    if (dsn) {
        ast_verb(11, "cdr_odbc: free dsn\n");
        ast_free(dsn);
    }
    if (table) {
        ast_verb(11, "cdr_odbc: free table\n");
        ast_free(table);
    }

    return 0;
}
Пример #13
0
/*
* Receive a string of DTMF digits where the length of the digit string is known in advance. Do not give preferential
* treatment to any digit value, and allow separate time out values to be specified for the first digit and all subsequent
* digits.
*
* Returns 0 if all digits successfully received.
* Returns 1 if a digit time out occurred
* Returns -1 if the caller hung up or there was a channel error.
*
*/
static int receive_dtmf_digits(struct ast_channel *chan, char *digit_string, int length, int fdto, int sdto)
{
	int res = 0;
	int i = 0;
	int r;
	struct ast_frame *f;
	struct timeval lastdigittime;

	lastdigittime = ast_tvnow();
	for (;;) {
		/* if outa time, leave */
		if (ast_tvdiff_ms(ast_tvnow(), lastdigittime) > ((i > 0) ? sdto : fdto)) {
			ast_verb(4, "AlarmReceiver: DTMF Digit Timeout on %s\n", ast_channel_name(chan));
			ast_debug(1,"AlarmReceiver: DTMF timeout on chan %s\n",ast_channel_name(chan));
			res = 1;
			break;
		}

		if ((r = ast_waitfor(chan, -1)) < 0) {
			ast_debug(1, "Waitfor returned %d\n", r);
			continue;
		}

		f = ast_read(chan);

		if (f == NULL) {
			res = -1;
			break;
		}

		/* If they hung up, leave */
		if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass.integer == AST_CONTROL_HANGUP)) {
			if (f->data.uint32) {
				ast_channel_hangupcause_set(chan, f->data.uint32);
			}
			ast_frfree(f);
			res = -1;
			break;
		}

		/* if not DTMF, just do it again */
		if (f->frametype != AST_FRAME_DTMF) {
			ast_frfree(f);
			continue;
		}

		digit_string[i++] = f->subclass.integer;  /* save digit */

		ast_frfree(f);

		/* If we have all the digits we expect, leave */
		if(i >= length)
			break;

		lastdigittime = ast_tvnow();
	}

	digit_string[i] = '\0'; /* Nul terminate the end of the digit string */
	return res;
}
Пример #14
0
/*!
 * \brief Send a message to the given application.
 * \param app App to send the message to.
 * \param message Message to send.
 */
void app_send(struct stasis_app *app, struct ast_json *message)
{
	stasis_app_cb handler;
	char eid[20];
	RAII_VAR(void *, data, NULL, ao2_cleanup);

	if (ast_json_object_set(message, "asterisk_id", ast_json_string_create(
			ast_eid_to_str(eid, sizeof(eid), &ast_eid_default)))) {
		ast_log(AST_LOG_WARNING, "Failed to append EID to outgoing event %s\n",
			ast_json_string_get(ast_json_object_get(message, "type")));
	}

	/* Copy off mutable state with lock held */
	{
		SCOPED_AO2LOCK(lock, app);
		handler = app->handler;
		if (app->data) {
			ao2_ref(app->data, +1);
			data = app->data;
		}
		/* Name is immutable; no need to copy */
	}

	if (!handler) {
		ast_verb(3,
			"Inactive Stasis app '%s' missed message\n", app->name);
		return;
	}

	handler(data, app->name, message);
}
Пример #15
0
int __ast_format_interface_register(const char *codec, const struct ast_format_interface *interface, struct ast_module *mod)
{
	SCOPED_AO2WRLOCK(lock, interfaces);
	struct format_interface *format_interface;

	if (!interface->format_clone || !interface->format_destroy) {
		ast_log(LOG_ERROR, "Format interface for codec '%s' does not implement required callbacks\n", codec);
		return -1;
	}

	format_interface = ao2_find(interfaces, codec, OBJ_SEARCH_KEY | OBJ_NOLOCK);
	if (format_interface) {
		ast_log(LOG_ERROR, "A format interface is already present for codec '%s'\n", codec);
		ao2_ref(format_interface, -1);
		return -1;
	}

	format_interface = ao2_alloc_options(sizeof(*format_interface) + strlen(codec) + 1,
		NULL, AO2_ALLOC_OPT_LOCK_NOLOCK);
	if (!format_interface) {
		return -1;
	}
	format_interface->interface = interface;
	strcpy(format_interface->codec, codec); /* Safe */

	/* Once registered a format interface cannot be unregistered. */
	ast_module_shutdown_ref(mod);
	ao2_link_flags(interfaces, format_interface, OBJ_NOLOCK);
	ao2_ref(format_interface, -1);

	ast_verb(2, "Registered format interface for codec '%s'\n", codec);

	return 0;
}
Пример #16
0
void ast_jb_destroy(struct ast_channel *chan)
{
	struct ast_jb *jb = ast_channel_jb(chan);
	const struct ast_jb_impl *jbimpl = jb->impl;
	void *jbobj = jb->jbobj;
	struct ast_frame *f;

	if (jb->logfile) {
		fclose(jb->logfile);
		jb->logfile = NULL;
	}

	if (ast_test_flag(jb, JB_CREATED)) {
		/* Remove and free all frames still queued in jb */
		while (jbimpl->remove(jbobj, &f) == AST_JB_IMPL_OK) {
			ast_frfree(f);
		}

		jbimpl->destroy(jbobj);
		jb->jbobj = NULL;

		ast_clear_flag(jb, JB_CREATED);

		ast_verb(3, "%s jitterbuffer destroyed on channel %s\n", jbimpl->name, ast_channel_name(chan));
	}
}
Пример #17
0
static int bridgewait_timeout_callback(struct ast_bridge_channel *bridge_channel, void *hook_pvt)
{
    ast_verb(3, "Channel %s timed out.\n", ast_channel_name(bridge_channel->chan));
    ast_bridge_channel_leave_bridge(bridge_channel, BRIDGE_CHANNEL_STATE_END,
                                    AST_CAUSE_NORMAL_CLEARING);
    return -1;
}
Пример #18
0
static int adsi_exec(struct ast_channel *chan, const char *data)
{
	int res = 0;
	
	if (ast_strlen_zero(data))
		data = "asterisk.adsi";

	if (!ast_adsi_available(chan)) {
		ast_verb(3, "ADSI Unavailable on CPE.  Not bothering to try.\n");
	} else {
		ast_verb(3, "ADSI Available on CPE.  Attempting Upload.\n");
		res = adsi_prog(chan, data);
	}

	return res;
}
Пример #19
0
static int flash_exec(struct ast_channel *chan, void *data)
{
	int res = -1;
	int x;
	struct dahdi_params dahdip;

	if (strcasecmp(chan->tech->type, "DAHDI")) {
		ast_log(LOG_WARNING, "%s is not a DAHDI channel\n", chan->name);
		return -1;
	}
	
	memset(&dahdip, 0, sizeof(dahdip));
	res = ioctl(chan->fds[0], DAHDI_GET_PARAMS, &dahdip);
	if (!res) {
		if (dahdip.sigtype & __DAHDI_SIG_FXS) {
			x = DAHDI_FLASH;
			res = ioctl(chan->fds[0], DAHDI_HOOK, &x);
			if (!res || (errno == EINPROGRESS)) {
				if (res) {
					/* Wait for the event to finish */
					dahdi_wait_event(chan->fds[0]);
				}
				res = ast_safe_sleep(chan, 1000);
				ast_verb(3, "Flashed channel %s\n", chan->name);
			} else
				ast_log(LOG_WARNING, "Unable to flash channel %s: %s\n", chan->name, strerror(errno));
		} else
			ast_log(LOG_WARNING, "%s is not an FXO Channel\n", chan->name);
	} else
		ast_log(LOG_WARNING, "Unable to get parameters of %s: %s\n", chan->name, strerror(errno));

	return res;
}
Пример #20
0
int AST_OPTIONAL_API_NAME(ast_websocket_add_protocol)(const char *name, ast_websocket_callback callback)
{
	struct websocket_protocol *protocol;

	ao2_lock(protocols);

	/* Ensure a second protocol handler is not registered for the same protocol */
	if ((protocol = ao2_find(protocols, name, OBJ_KEY | OBJ_NOLOCK))) {
		ao2_ref(protocol, -1);
		ao2_unlock(protocols);
		return -1;
	}

	if (!(protocol = ao2_alloc(sizeof(*protocol), protocol_destroy_fn))) {
		ao2_unlock(protocols);
		return -1;
	}

	if (!(protocol->name = ast_strdup(name))) {
		ao2_ref(protocol, -1);
		ao2_unlock(protocols);
		return -1;
	}

	protocol->callback = callback;

	ao2_link_flags(protocols, protocol, OBJ_NOLOCK);
	ao2_unlock(protocols);
	ao2_ref(protocol, -1);

	ast_verb(2, "WebSocket registered sub-protocol '%s'\n", name);

	return 0;
}
Пример #21
0
static int register_contact_transport_remove_cb(void *data)
{
	struct contact_transport_monitor *monitor = data;
	struct ast_sip_contact *contact;
	struct ast_sip_aor *aor;

	aor = ast_sip_location_retrieve_aor(monitor->aor_name);
	if (!aor) {
		ao2_ref(monitor, -1);
		return 0;
	}

	ao2_lock(aor);
	contact = ast_sip_location_retrieve_contact(monitor->contact_name);
	if (contact) {
		ast_sip_location_delete_contact(contact);
		ast_verb(3, "Removed contact '%s' from AOR '%s' due to transport shutdown\n",
			contact->uri, monitor->aor_name);
		ast_test_suite_event_notify("AOR_CONTACT_REMOVED",
			"Contact: %s\r\n"
			"AOR: %s\r\n"
			"UserAgent: %s",
			contact->uri,
			monitor->aor_name,
			contact->user_agent);
		ao2_ref(contact, -1);
	}
	ao2_unlock(aor);
	ao2_ref(aor, -1);

	ao2_ref(monitor, -1);
	return 0;
}
Пример #22
0
/*!
 * \brief Send a message to the given application.
 * \param app App to send the message to.
 * \param message Message to send.
 */
void app_send(struct stasis_app *app, struct ast_json *message)
{
	stasis_app_cb handler;
	char eid[20];
	void *data;

	if (ast_json_object_set(message, "asterisk_id", ast_json_string_create(
			ast_eid_to_str(eid, sizeof(eid), &ast_eid_default)))) {
		ast_log(AST_LOG_WARNING, "Failed to append EID to outgoing event %s\n",
			ast_json_string_get(ast_json_object_get(message, "type")));
	}

	/* Copy off mutable state with lock held */
	ao2_lock(app);
	handler = app->handler;
	data = ao2_bump(app->data);
	ao2_unlock(app);
	/* Name is immutable; no need to copy */

	if (handler) {
		handler(data, app->name, message);
	} else {
		ast_verb(3,
			"Inactive Stasis app '%s' missed message\n", app->name);
	}
	ao2_cleanup(data);
}
Пример #23
0
static void app_dtor(void *obj)
{
	struct stasis_app *app = obj;
	size_t size = strlen("stasis-") + strlen(app->name) + 1;
	char context_name[size];

	ast_verb(1, "Destroying Stasis app %s\n", app->name);

	ast_assert(app->router == NULL);
	ast_assert(app->bridge_router == NULL);
	ast_assert(app->endpoint_router == NULL);

	/* If we created a context for this application, remove it */
	strcpy(context_name, "stasis-");
	strcat(context_name, app->name);
	ast_context_destroy_by_name(context_name, "res_stasis");

	ao2_cleanup(app->topic);
	app->topic = NULL;
	ao2_cleanup(app->forwards);
	app->forwards = NULL;
	ao2_cleanup(app->data);
	app->data = NULL;

	ast_json_unref(app->events_allowed);
	app->events_allowed = NULL;
	ast_json_unref(app->events_disallowed);
	app->events_disallowed = NULL;

}
Пример #24
0
int ast_format_cache_set(struct ast_format *format)
{
	SCOPED_AO2WRLOCK(lock, formats);
	struct ast_format *old_format;

	ast_assert(format != NULL);

	if (ast_strlen_zero(ast_format_get_name(format))) {
		return -1;
	}

	old_format = ao2_find(formats, ast_format_get_name(format), OBJ_SEARCH_KEY | OBJ_NOLOCK);
	if (old_format) {
		ao2_unlink_flags(formats, old_format, OBJ_NOLOCK);
	}
	ao2_link_flags(formats, format, OBJ_NOLOCK);

	set_cached_format(ast_format_get_name(format), format);

	ast_verb(2, "%s cached format with name '%s'\n",
		old_format ? "Updated" : "Created",
		ast_format_get_name(format));

	ao2_cleanup(old_format);

	return 0;
}
Пример #25
0
/*!
 * \brief Verify Ademco checksum
 * \since 11.0
 *
 * \param event Received DTMF String
 * \param expected Number of Digits expected
 *
 * \retval 0 success
 * \retval -1 failure
 */
static int ademco_verify_checksum(char *event, int expected)
{
	int checksum = 0;
	int i, j;

	for (j = 0; j < expected; j++) {
		for (i = 0; i < ARRAY_LEN(digits_mapping); i++) {
			if (digits_mapping[i].digit == event[j]) {
				break;
			}
		}

		if (i >= ARRAY_LEN(digits_mapping)) {
			ast_verb(2, "AlarmReceiver: Bad DTMF character %c, trying again\n", event[j]);
			return -1;
		}

		checksum += digits_mapping[i].weight;
	}

	/* Checksum is mod(15) of the total */
	if (!(checksum % 15)) {
		return 0;
	}

	return -1;
}
Пример #26
0
static int unload_module(void)
{
    ast_verb(1, "Unloading [Sub]Agent Module\n");

    res_snmp_dont_stop = 0;
    return ((thread != AST_PTHREADT_NULL) ? pthread_join(thread, NULL) : 0);
}
Пример #27
0
static void aoc_display_decoded_debug(const struct ast_aoc_decoded *decoded, int decoding, struct ast_channel *chan)
{
	struct ast_str *msg;

	if (!decoded || !(msg = ast_str_create(1024))) {
		return;
	}

	if (decoding) {
		ast_str_append(&msg, 0, "---- DECODED AOC MSG ----\r\n");
	} else {
		ast_str_append(&msg, 0, "---- ENCODED AOC MSG ----\r\n");
	}
	if (chan) {
		ast_str_append(&msg, 0, "CHANNEL: %s\r\n", ast_channel_name(chan));
	}

	if (ast_aoc_decoded2str(decoded, &msg)) {
		ast_free(msg);
		return;
	}

	ast_verb(1, "%s\r\n", ast_str_buffer(msg));
	ast_free(msg);
}
Пример #28
0
int ast_set_qos(int sockfd, int tos, int cos, const char *desc)
{
	int res = 0;
	int set_tos;
	int set_tclass;
	struct ast_sockaddr addr;

	/* If the sock address is IPv6, the TCLASS field must be set. */
	set_tclass = !ast_getsockname(sockfd, &addr) && ast_sockaddr_is_ipv6(&addr) ? 1 : 0;

	/* If the the sock address is IPv4 or (IPv6 set to any address [::]) set TOS bits */
	set_tos = (!set_tclass || (set_tclass && ast_sockaddr_is_any(&addr))) ? 1 : 0;

	if (set_tos) {
		if ((res = setsockopt(sockfd, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)))) {
			ast_log(LOG_WARNING, "Unable to set %s DSCP TOS value to %d (may be you have no "
				"root privileges): %s\n", desc, tos, strerror(errno));
		} else if (tos) {
			ast_verb(2, "Using %s TOS bits %d\n", desc, tos);
		}
	}

#if defined(IPV6_TCLASS) && defined(IPPROTO_IPV6)
	if (set_tclass) {
		if (!ast_getsockname(sockfd, &addr) && ast_sockaddr_is_ipv6(&addr)) {
			if ((res = setsockopt(sockfd, IPPROTO_IPV6, IPV6_TCLASS, &tos, sizeof(tos)))) {
				ast_log(LOG_WARNING, "Unable to set %s DSCP TCLASS field to %d (may be you have no "
					"root privileges): %s\n", desc, tos, strerror(errno));
			} else if (tos) {
				ast_verb(2, "Using %s TOS bits %d in TCLASS field.\n", desc, tos);
			}
		}
	}
#endif

#ifdef linux
	if (setsockopt(sockfd, SOL_SOCKET, SO_PRIORITY, &cos, sizeof(cos))) {
		ast_log(LOG_WARNING, "Unable to set %s CoS to %d: %s\n", desc, cos,
			strerror(errno));
	} else if (cos) {
		ast_verb(2, "Using %s CoS mark %d\n", desc, cos);
	}
#endif

	return res;
}
Пример #29
0
void app_deactivate(struct stasis_app *app)
{
	SCOPED_AO2LOCK(lock, app);
	ast_verb(1, "Deactivating Stasis app '%s'\n", app->name);
	app->handler = NULL;
	ao2_cleanup(app->data);
	app->data = NULL;
}
Пример #30
0
/*
 * Input: CC code
 *
 * Output: number of digits in the number before the i-enum branch
 *
 * Algorithm:  Build <ienum_branchlabel>.c.c.<suffix> and look for a TXT lookup.
 *		Return atoi(TXT-record).
 *		Return -1 on not found.
 *
 */
static int blr_txt(const char *cc, const char *suffix)
{
	struct txt_context context;
	char domain[128] = "";
	char *p1, *p2;
	int ret;

	ast_mutex_lock(&enumlock);

	ast_verb(4, "blr_txt()  cc='%s', suffix='%s', c_bl='%s'\n", cc, suffix, ienum_branchlabel);

	if (sizeof(domain) < (strlen(cc) * 2 + strlen(ienum_branchlabel) + strlen(suffix) + 2)) {
		ast_mutex_unlock(&enumlock);
		ast_log(LOG_WARNING, "ERROR: string sizing in blr_txt.\n");
		return -1;
	}

	p1 = domain + snprintf(domain, sizeof(domain), "%s.", ienum_branchlabel);
	ast_mutex_unlock(&enumlock);

	for (p2 = (char *) cc + strlen(cc) - 1; p2 >= cc; p2--) {
		if (isdigit(*p2)) {
			*p1++ = *p2;
			*p1++ = '.';
		}
	}
	strcat(p1, suffix);

	ast_verb(4, "blr_txt() FQDN for TXT record: %s, cc was %s\n", domain, cc);

	ret = ast_search_dns(&context, domain, C_IN, T_TXT, txt_callback);

	if (ret > 0) {
		ret = atoi(context.txt);

		if ((ret >= 0) && (ret < 20)) {
			ast_verb(3, "blr_txt() BLR TXT record for %s is %d (apex: %s)\n", cc, ret, suffix);
			return ret;
		}
	}

	ast_verb(3, "blr_txt() BLR TXT record for %s not found (apex: %s)\n", cc, suffix);

	return -1;
}