/*! * \brief Callback handler for Stasis application messages. */ static void app_handler(void *data, const char *app_name, struct ast_json *message) { struct event_session *session = data; int res; const char *msg_type = S_OR( ast_json_string_get(ast_json_object_get(message, "type")), ""); const char *msg_application = S_OR( ast_json_string_get(ast_json_object_get(message, "application")), ""); /* Determine if we've been replaced */ if (strcmp(msg_type, "ApplicationReplaced") == 0 && strcmp(msg_application, app_name) == 0) { ao2_find(session->websocket_apps, msg_application, OBJ_UNLINK | OBJ_NODATA); } res = ast_json_object_set(message, "application", ast_json_string_create(app_name)); if(res != 0) { return; } ao2_lock(session); if (session->ws_session) { ast_ari_websocket_session_write(session->ws_session, message); } ao2_unlock(session); }
static int iftime(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) { struct ast_timing timing; char *expr; char *iftrue; char *iffalse; data = ast_strip_quoted(data, "\"", "\""); expr = strsep(&data, "?"); iftrue = strsep(&data, ":"); iffalse = data; if (ast_strlen_zero(expr) || !(iftrue || iffalse)) { ast_log(LOG_WARNING, "Syntax IFTIME(<timespec>?[<true>][:<false>])\n"); return -1; } if (!ast_build_timing(&timing, expr)) { ast_log(LOG_WARNING, "Invalid Time Spec.\n"); return -1; } if (iftrue) iftrue = ast_strip_quoted(iftrue, "\"", "\""); if (iffalse) iffalse = ast_strip_quoted(iffalse, "\"", "\""); ast_copy_string(buf, ast_check_timing(&timing) ? S_OR(iftrue, "") : S_OR(iffalse, ""), len); return 0; }
static int callerid_read(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) { char *opt = data; if (!chan) return -1; if (strchr(opt, '|')) { char name[80], num[80]; data = strsep(&opt, "|"); ast_callerid_split(opt, name, sizeof(name), num, sizeof(num)); if (!strncasecmp("all", data, 3)) { snprintf(buf, len, "\"%s\" <%s>", name, num); } else if (!strncasecmp("name", data, 4)) { ast_copy_string(buf, name, len); } else if (!strncasecmp("num", data, 3) || !strncasecmp("number", data, 6)) { ast_copy_string(buf, num, len); } else { ast_log(LOG_ERROR, "Unknown callerid data type '%s'.\n", data); } } else { if (!strncasecmp("all", data, 3)) { snprintf(buf, len, "\"%s\" <%s>", S_OR(chan->cid.cid_name, ""), S_OR(chan->cid.cid_num, "")); } else if (!strncasecmp("name", data, 4)) { if (chan->cid.cid_name) { ast_copy_string(buf, chan->cid.cid_name, len); } } else if (!strncasecmp("num", data, 3) || !strncasecmp("number", data, 6)) { if (chan->cid.cid_num) { ast_copy_string(buf, chan->cid.cid_num, len); } } else if (!strncasecmp("ani", data, 3)) { if (chan->cid.cid_ani) { ast_copy_string(buf, chan->cid.cid_ani, len); } } else if (!strncasecmp("dnid", data, 4)) { if (chan->cid.cid_dnid) { ast_copy_string(buf, chan->cid.cid_dnid, len); } } else if (!strncasecmp("rdnis", data, 5)) { if (chan->cid.cid_rdnis) { ast_copy_string(buf, chan->cid.cid_rdnis, len); } } else { ast_log(LOG_ERROR, "Unknown callerid data type '%s'.\n", data); } } return 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 }
void ast_system_publish_registry(const char *channeltype, const char *username, const char *domain, const char *status, const char *cause) { RAII_VAR(struct ast_json *, registry, NULL, ast_json_unref); RAII_VAR(struct ast_json_payload *, payload, NULL, ao2_cleanup); RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup); if (!ast_system_registry_type()) { return; } registry = ast_json_pack("{s: s, s: s, s: s, s: s, s: s, s: s}", "type", "registry", "channeltype", channeltype, "username", username, "domain", domain, "status", status, "cause", S_OR(cause, "")); if (!(payload = ast_json_payload_create(registry))) { return; } if (!(message = stasis_message_create(ast_system_registry_type(), payload))) { return; } stasis_publish(ast_system_topic(), message); }
/*! \brief Custom handler for TLS cipher setting */ static int transport_tls_cipher_handler(const struct aco_option *opt, struct ast_variable *var, void *obj) { struct ast_sip_transport *transport = obj; char *parse; char *name; int res = 0; RAII_VAR(struct ast_sip_transport_state *, state, find_or_create_temporary_state(transport), ao2_cleanup); if (!state) { return -1; } parse = ast_strdupa(S_OR(var->value, "")); while ((name = ast_strip(strsep(&parse, ",")))) { if (ast_strlen_zero(name)) { continue; } if (ARRAY_LEN(state->ciphers) <= state->tls.ciphers_num) { ast_log(LOG_ERROR, "Too many ciphers specified\n"); res = -1; break; } res |= transport_cipher_add(state, name); } return res ? -1 : 0; }
void ast_ari_asterisk_get_global_var(struct ast_variable *headers, struct ast_ari_asterisk_get_global_var_args *args, struct ast_ari_response *response) { RAII_VAR(struct ast_json *, json, NULL, ast_json_unref); RAII_VAR(struct ast_str *, tmp, NULL, ast_free); const char *value; ast_assert(response != NULL); if (ast_strlen_zero(args->variable)) { ast_ari_response_error( response, 400, "Bad Request", "Variable name is required"); return; } tmp = ast_str_create(32); if (!tmp) { ast_ari_response_alloc_failed(response); return; } value = ast_str_retrieve_variable(&tmp, 0, NULL, NULL, args->variable); if (!(json = ast_json_pack("{s: s}", "value", S_OR(value, "")))) { ast_ari_response_alloc_failed(response); return; } ast_ari_response_ok(response, ast_json_ref(json)); }
static void channel_enter_cb(void *data, struct stasis_subscription *sub, struct stasis_message *message) { static const char *swap_name = "SwapUniqueid: "; struct ast_bridge_blob *blob = stasis_message_data(message); RAII_VAR(struct ast_str *, bridge_text, NULL, ast_free); RAII_VAR(struct ast_str *, channel_text, NULL, ast_free); const char *swap_id; bridge_text = ast_manager_build_bridge_state_string(blob->bridge); channel_text = ast_manager_build_channel_state_string(blob->channel); if (!bridge_text || !channel_text) { return; } swap_id = ast_json_string_get(ast_json_object_get(blob->blob, "swap")); manager_event(EVENT_FLAG_CALL, "BridgeEnter", "%s" "%s" "%s%s%s", ast_str_buffer(bridge_text), ast_str_buffer(channel_text), swap_id ? swap_name : "", S_OR(swap_id, ""), swap_id ? "\r\n" : ""); }
static struct ast_event *alloc_event(const struct ast_security_event_common *sec) { struct ast_str *str = ast_str_alloca(TIMESTAMP_STR_LEN); struct timeval tv = ast_tvnow(); const char *severity_str; if (check_event_type(sec->event_type)) { return NULL; } encode_timestamp(&str, &tv); severity_str = S_OR( ast_security_event_severity_get_name(sec_events[sec->event_type].severity), "Unknown" ); return ast_event_new(AST_EVENT_SECURITY, AST_EVENT_IE_SECURITY_EVENT, AST_EVENT_IE_PLTYPE_UINT, sec->event_type, AST_EVENT_IE_EVENT_VERSION, AST_EVENT_IE_PLTYPE_UINT, sec->version, AST_EVENT_IE_EVENT_TV, AST_EVENT_IE_PLTYPE_STR, ast_str_buffer(str), AST_EVENT_IE_SERVICE, AST_EVENT_IE_PLTYPE_STR, sec->service, AST_EVENT_IE_SEVERITY, AST_EVENT_IE_PLTYPE_STR, severity_str, AST_EVENT_IE_END); }
static int sip_aor_to_ami(const struct ast_sip_aor *aor, struct ast_str **buf) { RAII_VAR(struct ast_variable *, objset, ast_sorcery_objectset_create2( ast_sip_get_sorcery(), aor, AST_HANDLER_ONLY_STRING), ast_variables_destroy); struct ast_variable *i; if (!objset) { return -1; } ast_str_append(buf, 0, "ObjectType: %s\r\n", ast_sorcery_object_get_type(aor)); ast_str_append(buf, 0, "ObjectName: %s\r\n", ast_sorcery_object_get_id(aor)); for (i = objset; i; i = i->next) { char *camel = ast_to_camel_case(i->name); if (strcmp(camel, "Contact") == 0) { ast_free(camel); camel = NULL; } ast_str_append(buf, 0, "%s: %s\r\n", S_OR(camel, "Contacts"), i->value); ast_free(camel); } return 0; }
/* Copyright (C) 2010 */ #ifdef HAVE_CONFIG_H #include <config.h> #endif /* HAVE_CONFIG_H */ #include "dc_config.h" #include <asterisk/callerid.h> /* ast_parse_caller_presentation() */ static struct ast_jb_conf jbconf_default = { .flags = 0, .max_size = -1, .resync_threshold = -1, .impl = "", .target_extra = -1, }; static const char * const dtmf_values[] = { "off", "inband", "relax" }; EXPORT_DEF int dc_dtmf_str2setting(const char * value) { return str2enum(value, dtmf_values, ITEMS_OF(dtmf_values)); } EXPORT_DEF const char * dc_dtmf_setting2str(dc_dtmf_setting_t dtmf) { return enum2str(dtmf, dtmf_values, ITEMS_OF(dtmf_values)); } #/* assume config is zerofill */ static int dc_uconfig_fill(struct ast_config * cfg, const char * cat, struct dc_uconfig * config) { const char * audio_tty; const char * data_tty; const char * imei; const char * imsi; audio_tty = ast_variable_retrieve (cfg, cat, "audio"); data_tty = ast_variable_retrieve (cfg, cat, "data"); imei = ast_variable_retrieve (cfg, cat, "imei"); imsi = ast_variable_retrieve (cfg, cat, "imsi"); if(imei && strlen(imei) != IMEI_SIZE) { ast_log (LOG_WARNING, "[%s] Ignore invalid IMEI value '%s'\n", cat, imei); imei = NULL; } if(imsi && strlen(imsi) != IMSI_SIZE) { ast_log (LOG_WARNING, "[%s] Ignore invalid IMSI value '%s'\n", cat, imsi); imsi = NULL; } if(!audio_tty && !imei && !imsi) { ast_log (LOG_ERROR, "Skipping device %s. Missing required audio_tty setting\n", cat); return 1; } if(!data_tty && !imei && !imsi) { ast_log (LOG_ERROR, "Skipping device %s. Missing required data_tty setting\n", cat); return 1; } if((!data_tty && audio_tty) || (data_tty && !audio_tty)) { ast_log (LOG_ERROR, "Skipping device %s. data_tty and audio_tty should use together\n", cat); return 1; } ast_copy_string (config->id, cat, sizeof (config->id)); ast_copy_string (config->data_tty, S_OR(data_tty, ""), sizeof (config->data_tty)); ast_copy_string (config->audio_tty, S_OR(audio_tty, ""), sizeof (config->audio_tty)); ast_copy_string (config->imei, S_OR(imei, ""), sizeof (config->imei)); ast_copy_string (config->imsi, S_OR(imsi, ""), sizeof (config->imsi)); return 0; }
struct ast_format *__ast_format_cache_get_debug(const char *name, const char *tag, const char *file, int line, const char *func) { if (ast_strlen_zero(name)) { return NULL; } return __ao2_find_debug(formats, name, OBJ_SEARCH_KEY, S_OR(tag, "ast_format_cache_get"), file, line, func); }
static void process_section(bfd *bfdobj, asection *section, void *obj) { struct bfd_data *data = obj; const char *file, *func; unsigned int line; bfd_vma offset; bfd_vma vma; bfd_size_type size; bfd_boolean line_found = 0; char *fn; int inlined = 0; offset = data->pc - (data->dynamic ? (bfd_vma)(uintptr_t) data->dli.dli_fbase : 0); if (!(bfd_get_section_flags(bfdobj, section) & SEC_ALLOC)) { return; } vma = bfd_get_section_vma(bfdobj, section); size = bfd_get_section_size(section); if (offset < vma || offset >= vma + size) { /* Not in this section */ return; } line_found = bfd_find_nearest_line(bfdobj, section, data->syms, offset - vma, &file, &func, &line); if (!line_found) { return; } /* * If we find a line, we will want to continue calling bfd_find_inliner_info * to capture any inlined functions that don't have their own stack frames. */ do { data->found++; /* file can possibly be null even with a success result from bfd_find_nearest_line */ file = file ? file : ""; fn = strrchr(file, '/'); #define FMT_INLINED "[%s] %s %s:%u %s()" #define FMT_NOT_INLINED "[%p] %s %s:%u %s()" snprintf(data->msg, MSG_BUFF_LEN, inlined ? FMT_INLINED : FMT_NOT_INLINED, inlined ? "inlined" : (char *)(uintptr_t) data->pc, data->libname, fn ? fn + 1 : file, line, S_OR(func, "???")); if (AST_VECTOR_APPEND(data->return_strings, strdup(data->msg))) { return; } inlined++; /* Let's see if there are any inlined functions */ } while (bfd_find_inliner_info(bfdobj, &file, &func, &line)); }
const char *ast_cel_get_ama_flag_name(enum ast_cel_ama_flag flag) { if (flag < 0 || flag >= ARRAY_LEN(cel_ama_flags)) { ast_log(LOG_WARNING, "Invalid AMA flag: %d\n", flag); return "Unknown"; } return S_OR(cel_ama_flags[flag], "Unknown"); }
/*! * \internal \brief Handle reading RTP information */ static int channel_read_rtp(struct ast_channel *chan, const char *type, const char *field, char *buf, size_t buflen) { struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(chan); struct chan_pjsip_pvt *pvt; struct ast_sip_session_media *media = NULL; struct ast_sockaddr addr; if (!channel) { ast_log(AST_LOG_WARNING, "Channel %s has no pvt!\n", ast_channel_name(chan)); return -1; } pvt = channel->pvt; if (!pvt) { ast_log(AST_LOG_WARNING, "Channel %s has no chan_pjsip pvt!\n", ast_channel_name(chan)); return -1; } if (ast_strlen_zero(type)) { ast_log(AST_LOG_WARNING, "You must supply a type field for 'rtp' information\n"); return -1; } if (ast_strlen_zero(field) || !strcmp(field, "audio")) { media = pvt->media[SIP_MEDIA_AUDIO]; } else if (!strcmp(field, "video")) { media = pvt->media[SIP_MEDIA_VIDEO]; } else { ast_log(AST_LOG_WARNING, "Unknown media type field '%s' for 'rtp' information\n", field); return -1; } if (!media || !media->rtp) { ast_log(AST_LOG_WARNING, "Channel %s has no %s media/RTP session\n", ast_channel_name(chan), S_OR(field, "audio")); return -1; } if (!strcmp(type, "src")) { ast_rtp_instance_get_local_address(media->rtp, &addr); ast_copy_string(buf, ast_sockaddr_stringify(&addr), buflen); } else if (!strcmp(type, "dest")) { ast_rtp_instance_get_remote_address(media->rtp, &addr); ast_copy_string(buf, ast_sockaddr_stringify(&addr), buflen); } else if (!strcmp(type, "direct")) { ast_copy_string(buf, ast_sockaddr_stringify(&media->direct_media_addr), buflen); } else if (!strcmp(type, "secure")) { snprintf(buf, buflen, "%d", media->srtp ? 1 : 0); } else if (!strcmp(type, "hold")) { snprintf(buf, buflen, "%d", media->remotely_held ? 1 : 0); } else { ast_log(AST_LOG_WARNING, "Unknown type field '%s' specified for 'rtp' information\n", type); return -1; } return 0; }
int stasis_app_control_continue(struct stasis_app_control *control, const char *context, const char *extension, int priority) { struct stasis_app_control_continue_data *continue_data; if (!(continue_data = ast_calloc(1, sizeof(*continue_data)))) { return -1; } ast_copy_string(continue_data->context, S_OR(context, ""), sizeof(continue_data->context)); ast_copy_string(continue_data->extension, S_OR(extension, ""), sizeof(continue_data->extension)); if (priority > 0) { continue_data->priority = priority; } else { continue_data->priority = -1; } stasis_app_send_command_async(control, app_control_continue, continue_data); return 0; }
/*! * \brief Callback handler for Stasis application messages. * * \internal * * \param data Void pointer to the event session (\ref event_session). * \param app_name Name of the Stasis application that dispatched the message. * \param message The dispatched message. */ static void stasis_app_message_handler( void *data, const char *app_name, struct ast_json *message) { struct event_session *session = data; const char *msg_type, *msg_application; ast_assert(session != NULL); ao2_lock(session); msg_type = S_OR(ast_json_string_get(ast_json_object_get(message, "type")), ""); msg_application = S_OR( ast_json_string_get(ast_json_object_get(message, "application")), ""); /* If we've been replaced, remove the application from our local websocket_apps container */ if (strcmp(msg_type, "ApplicationReplaced") == 0 && strcmp(msg_application, app_name) == 0) { ao2_find(session->websocket_apps, msg_application, OBJ_UNLINK | OBJ_NODATA); } /* Now, we need to determine our state to see how we will handle the message */ if (ast_json_object_set(message, "application", ast_json_string_create(app_name))) { /* We failed to add an application element to our json message */ ast_log(LOG_WARNING, "Failed to dispatch '%s' message from Stasis app '%s'; could not update message\n", msg_type, msg_application); } else if (!session->ws_session) { /* If the websocket is NULL, the message goes to the queue */ AST_VECTOR_APPEND(&session->message_queue, message); ast_log(LOG_WARNING, "Queued '%s' message for Stasis app '%s'; websocket is not ready\n", msg_type, msg_application); } else { /* We are ready to publish the message */ ast_ari_websocket_session_write(session->ws_session, message); } ao2_unlock(session); }
int ast_sip_format_contact_ami(void *obj, void *arg, int flags) { struct ast_sip_contact_wrapper *wrapper = obj; struct ast_sip_contact *contact = wrapper->contact; struct ast_sip_ami *ami = arg; struct ast_sip_contact_status *status; struct ast_str *buf; const struct ast_sip_endpoint *endpoint = ami->arg; buf = ast_sip_create_ami_event("ContactStatusDetail", ami); if (!buf) { return -1; } status = ast_sorcery_retrieve_by_id( ast_sip_get_sorcery(), CONTACT_STATUS, ast_sorcery_object_get_id(contact)); ast_str_append(&buf, 0, "AOR: %s\r\n", wrapper->aor_id); ast_str_append(&buf, 0, "URI: %s\r\n", contact->uri); ast_str_append(&buf, 0, "UserAgent: %s\r\n", contact->user_agent); ast_str_append(&buf, 0, "RegExpire: %ld\r\n", contact->expiration_time.tv_sec); if (!ast_strlen_zero(contact->via_addr)) { ast_str_append(&buf, 0, "ViaAddress: %s", contact->via_addr); if (contact->via_port) { ast_str_append(&buf, 0, ":%d", contact->via_port); } ast_str_append(&buf, 0, "\r\n"); } if (!ast_strlen_zero(contact->call_id)) { ast_str_append(&buf, 0, "CallID: %s\r\n", contact->call_id); } ast_str_append(&buf, 0, "Status: %s\r\n", ast_sip_get_contact_status_label(status->status)); if (status->status == UNKNOWN) { ast_str_append(&buf, 0, "RoundtripUsec: N/A\r\n"); } else { ast_str_append(&buf, 0, "RoundtripUsec: %" PRId64 "\r\n", status->rtt); } ast_str_append(&buf, 0, "EndpointName: %s\r\n", endpoint ? ast_sorcery_object_get_id(endpoint) : S_OR(contact->endpoint_name, "")); ast_str_append(&buf, 0, "ID: %s\r\n", ast_sorcery_object_get_id(contact)); ast_str_append(&buf, 0, "AuthenticateQualify: %d\r\n", contact->authenticate_qualify); ast_str_append(&buf, 0, "OutboundProxy: %s\r\n", contact->outbound_proxy); ast_str_append(&buf, 0, "Path: %s\r\n", contact->path); ast_str_append(&buf, 0, "QualifyFrequency: %u\r\n", contact->qualify_frequency); ast_str_append(&buf, 0, "QualifyTimeout: %.3f\r\n", contact->qualify_timeout); astman_append(ami->s, "%s\r\n", ast_str_buffer(buf)); ami->count++; ast_free(buf); ao2_cleanup(status); return 0; }
/*! * \internal * \brief Converts a pjsip_rx_data structure to an ast_msg structure. * * \details Attempts to fill in as much information as possible into the given * msg structure copied from the given request data. * * \param rdata The SIP request * \param msg The asterisk message structure to fill in. */ static enum pjsip_status_code rx_data_to_ast_msg(pjsip_rx_data *rdata, struct ast_msg *msg) { #define CHECK_RES(z_) do { if (z_) { ast_msg_destroy(msg); \ return PJSIP_SC_INTERNAL_SERVER_ERROR; } } while (0) int size; char buf[MAX_BODY_SIZE]; pjsip_name_addr *name_addr; const char *field; pjsip_status_code code; struct ast_sip_endpoint *endpt = ast_pjsip_rdata_get_endpoint(rdata); const char *context = S_OR(endpt->message_context, endpt->context); /* make sure there is an appropriate context and extension*/ if ((code = get_destination(rdata, context, buf)) != PJSIP_SC_OK) { return code; } CHECK_RES(ast_msg_set_context(msg, "%s", context)); CHECK_RES(ast_msg_set_exten(msg, "%s", buf)); /* to header */ name_addr = (pjsip_name_addr *)rdata->msg_info.to->uri; if ((size = pjsip_uri_print(PJSIP_URI_IN_FROMTO_HDR, name_addr, buf, sizeof(buf)-1)) > 0) { buf[size] = '\0'; /* prepend the tech */ CHECK_RES(ast_msg_set_to(msg, "%s", sip_to_pjsip(buf, ++size, sizeof(buf)-1))); } /* from header */ name_addr = (pjsip_name_addr *)rdata->msg_info.from->uri; if ((size = pjsip_uri_print(PJSIP_URI_IN_FROMTO_HDR, name_addr, buf, sizeof(buf)-1)) > 0) { buf[size] = '\0'; CHECK_RES(ast_msg_set_from(msg, "%s", buf)); } /* receive address */ field = pj_sockaddr_print(&rdata->pkt_info.src_addr, buf, sizeof(buf)-1, 1); CHECK_RES(ast_msg_set_var(msg, "PJSIP_RECVADDR", field)); /* body */ if (print_body(rdata, buf, sizeof(buf) - 1) > 0) { CHECK_RES(ast_msg_set_body(msg, "%s", buf)); } /* endpoint name */ if (endpt->id.self.name.valid) { CHECK_RES(ast_msg_set_var(msg, "PJSIP_PEERNAME", endpt->id.self.name.str)); } CHECK_RES(headers_to_vars(rdata, msg)); return PJSIP_SC_OK; }
/*! \brief Create a call structure */ static struct local_pvt *local_alloc(const char *data, struct ast_format_cap *cap) { struct local_pvt *pvt; char *parse; char *context; char *opts; pvt = (struct local_pvt *) ast_unreal_alloc(sizeof(*pvt), local_pvt_destructor, cap); if (!pvt) { return NULL; } pvt->base.callbacks = &local_unreal_callbacks; parse = ast_strdupa(data); /* * Local channels intercept MOH by default. * * This is a silly default because it represents state held by * the local channels. Unless local channel optimization is * disabled, the state will dissapear when the local channels * optimize out. */ ast_set_flag(&pvt->base, AST_UNREAL_MOH_INTERCEPT); /* Look for options */ if ((opts = strchr(parse, '/'))) { *opts++ = '\0'; if (strchr(opts, 'n')) { ast_set_flag(&pvt->base, AST_UNREAL_NO_OPTIMIZATION); } if (strchr(opts, 'j')) { if (ast_test_flag(&pvt->base, AST_UNREAL_NO_OPTIMIZATION)) { ast_set_flag(&pvt->base.jb_conf, AST_JB_ENABLED); } else { ast_log(LOG_ERROR, "You must use the 'n' option with the 'j' option to enable the jitter buffer\n"); } } if (strchr(opts, 'm')) { ast_clear_flag(&pvt->base, AST_UNREAL_MOH_INTERCEPT); } } /* Look for a context */ if ((context = strchr(parse, '@'))) { *context++ = '\0'; } ast_copy_string(pvt->context, S_OR(context, "default"), sizeof(pvt->context)); ast_copy_string(pvt->exten, parse, sizeof(pvt->exten)); snprintf(pvt->base.name, sizeof(pvt->base.name), "%s@%s", pvt->exten, pvt->context); return pvt; /* this is returned with a ref */ }
static int manager_park(struct mansession *s, const struct message *m) { const char *channel = astman_get_header(m, "Channel"); const char *timeout_channel = S_OR(astman_get_header(m, "TimeoutChannel"), astman_get_header(m, "Channel2")); const char *timeout = astman_get_header(m, "Timeout"); const char *parkinglot = astman_get_header(m, "Parkinglot"); char buf[BUFSIZ]; int timeout_override = -1; RAII_VAR(struct ast_channel *, chan, NULL, ao2_cleanup); RAII_VAR(struct ast_bridge *, parking_bridge, NULL, ao2_cleanup); if (ast_strlen_zero(channel)) { astman_send_error(s, m, "Channel not specified"); return 0; } if (!ast_strlen_zero(timeout)) { if (sscanf(timeout, "%30d", &timeout_override) != 1 || timeout < 0) { astman_send_error(s, m, "Invalid Timeout value."); return 0; } if (timeout_override > 0) { /* If greater than zero, convert to seconds for internal use. Must be >= 1 second. */ timeout_override = MAX(1, timeout_override / 1000); } } if (!(chan = ast_channel_get_by_name(channel))) { snprintf(buf, sizeof(buf), "Channel does not exist: %s", channel); astman_send_error(s, m, buf); return 0; } ast_channel_lock(chan); if (!ast_strlen_zero(timeout_channel)) { pbx_builtin_setvar_helper(chan, "BLINDTRANSFER", timeout_channel); } ast_channel_unlock(chan); if (!(parking_bridge = park_common_setup(chan, chan, parkinglot, NULL, 0, 0, timeout_override, 0))) { astman_send_error(s, m, "Park action failed\n"); return 0; } if (ast_bridge_add_channel(parking_bridge, chan, NULL, 0, NULL)) { astman_send_error(s, m, "Park action failed\n"); return 0; } astman_send_ack(s, m, "Park successful\n"); return 0; }
/*! * \internal * \brief Publish a hangup handler related message to \ref stasis */ static void publish_hangup_handler_message(const char *action, struct ast_channel *chan, const char *handler) { RAII_VAR(struct ast_json *, blob, NULL, ast_json_unref); blob = ast_json_pack("{s: s, s: s}", "type", action, "handler", S_OR(handler, "")); if (!blob) { return; } ast_channel_publish_blob(chan, ast_channel_hangup_handler_type(), blob); }
int ast_sockaddr_resolve(struct ast_sockaddr **addrs, const char *str, int flags, int family) { struct addrinfo hints, *res, *ai; char *s, *host, *port; int e, i, res_cnt; if (!str) { return 0; } s = ast_strdupa(str); if (!ast_sockaddr_split_hostport(s, &host, &port, flags)) { return 0; } memset(&hints, 0, sizeof(hints)); hints.ai_family = family; hints.ai_socktype = SOCK_DGRAM; if ((e = getaddrinfo(host, port, &hints, &res))) { ast_log(LOG_ERROR, "getaddrinfo(\"%s\", \"%s\", ...): %s\n", host, S_OR(port, "(null)"), gai_strerror(e)); return 0; } res_cnt = 0; for (ai = res; ai; ai = ai->ai_next) { res_cnt++; } if (res_cnt == 0) { goto cleanup; } if ((*addrs = ast_malloc(res_cnt * sizeof(struct ast_sockaddr))) == NULL) { res_cnt = 0; goto cleanup; } i = 0; for (ai = res; ai; ai = ai->ai_next) { (*addrs)[i].len = ai->ai_addrlen; memcpy(&(*addrs)[i].ss, ai->ai_addr, ai->ai_addrlen); ++i; } cleanup: freeaddrinfo(res); return res_cnt; }
/*! * \brief Performs common setup for a bridge playback operation * with both new controls and when existing controls are found. * * \param args_media medias to play * \param args_media_count number of media items in \c media * \param args_lang language string split from arguments * \param args_offset_ms milliseconds offset split from arguments * \param args_playback_id string to use for playback split from * arguments (null valid) * \param response ARI response being built * \param bridge Bridge the playback is being peformed on * \param control Control being used for the playback channel * \param json contents of the response to ARI * \param playback_url stores playback URL for use with response * * \retval -1 operation failed * \retval operation was successful */ static int ari_bridges_play_helper(const char **args_media, size_t args_media_count, const char *args_lang, int args_offset_ms, int args_skipms, const char *args_playback_id, struct ast_ari_response *response, struct ast_bridge *bridge, struct stasis_app_control *control, struct ast_json **json, char **playback_url) { RAII_VAR(struct ast_channel_snapshot *, snapshot, NULL, ao2_cleanup); RAII_VAR(struct stasis_app_playback *, playback, NULL, ao2_cleanup); const char *language; snapshot = stasis_app_control_get_snapshot(control); if (!snapshot) { ast_ari_response_error( response, 500, "Internal Error", "Failed to get control snapshot"); return -1; } language = S_OR(args_lang, snapshot->language); playback = stasis_app_control_play_uri(control, args_media, args_media_count, language, bridge->uniqueid, STASIS_PLAYBACK_TARGET_BRIDGE, args_skipms, args_offset_ms, args_playback_id); if (!playback) { ast_ari_response_alloc_failed(response); return -1; } if (ast_asprintf(playback_url, "/playbacks/%s", stasis_app_playback_get_id(playback)) == -1) { playback_url = NULL; ast_ari_response_alloc_failed(response); return -1; } *json = stasis_app_playback_to_json(playback); if (!*json) { ast_ari_response_alloc_failed(response); return -1; } return 0; }
int ast_sockaddr_parse(struct ast_sockaddr *addr, const char *str, int flags) { struct addrinfo hints; struct addrinfo *res; char *s; char *host; char *port; int e; s = ast_strdupa(str); if (!ast_sockaddr_split_hostport(s, &host, &port, flags)) { return 0; } memset(&hints, 0, sizeof(hints)); /* Hint to get only one entry from getaddrinfo */ hints.ai_socktype = SOCK_DGRAM; #ifdef AI_NUMERICSERV hints.ai_flags = AI_NUMERICHOST | AI_NUMERICSERV; #else hints.ai_flags = AI_NUMERICHOST; #endif if ((e = getaddrinfo(host, port, &hints, &res))) { if (e != EAI_NONAME) { /* if this was just a host name rather than a ip address, don't print error */ ast_log(LOG_ERROR, "getaddrinfo(\"%s\", \"%s\", ...): %s\n", host, S_OR(port, "(null)"), gai_strerror(e)); } return 0; } /* * I don't see how this could be possible since we're not resolving host * names. But let's be careful... */ if (res->ai_next != NULL) { ast_log(LOG_WARNING, "getaddrinfo() returned multiple " "addresses. Ignoring all but the first.\n"); } if (addr) { addr->len = res->ai_addrlen; memcpy(&addr->ss, res->ai_addr, addr->len); } freeaddrinfo(res); return 1; }
static int end_session(struct respoke_session *session, enum respoke_status status, const struct respoke_message *message) { const char *endpoint, *type, *app; if (!session->channel) { return 0; } endpoint = respoke_message_redirected_endpoint_get(message); type = respoke_message_redirected_type_get(message); app = respoke_message_redirected_app_get(message); if (!ast_strlen_zero(endpoint) && !ast_strlen_zero(app)) { if (session->endpoint->redirect == RESPOKE_REDIRECT_INTERNAL) { char id[AST_UUID_STR_LEN]; /* Since we are changing the session-id and because offer adds this session * to the sessions container we need to unlink it now, which bye does */ respoke_session_bye(session, RESPOKE_STATUS_REDIRECTING); session->terminated = 0; ast_string_field_set(session, remote, endpoint); ast_string_field_set(session, remote_type, S_OR(type, "web")); ast_string_field_set(session, remote_appid, app); ast_string_field_set(session, remote_connection, ""); ast_string_field_set(session, session_id, ast_uuid_generate_str(id, sizeof(id))); /* Send a new offer out to the new target, without the caller being any the wiser */ if (!respoke_session_offer(session)) { return 0; } session->terminated = 1; } else if (session->endpoint->redirect == RESPOKE_REDIRECT_CORE) { ast_channel_call_forward_build(session->channel, "Respoke/%s/%s@%s", ast_sorcery_object_get_id(session->endpoint), endpoint, app); } } ast_set_hangupsource(session->channel, ast_channel_name(session->channel), 0); if (!ast_channel_hangupcause(session->channel)) { int cause = hangup_reason_to_cause(status); ast_queue_hangup_with_cause(session->channel, cause); } else { ast_queue_hangup(session->channel); } return 0; }
static int pgsql_reconnect(const char *database) { char my_database[50]; ast_copy_string(my_database, S_OR(database, dbname), sizeof(my_database)); /* mutex lock should have been locked before calling this function. */ if (pgsqlConn && PQstatus(pgsqlConn) != CONNECTION_OK) { PQfinish(pgsqlConn); pgsqlConn = NULL; } if ((!pgsqlConn) && (dbhost || dbsock) && dbuser && dbpass && my_database) { char *connInfo = NULL; unsigned int size = 100 + strlen(dbhost) + strlen(dbuser) + strlen(dbpass) + strlen(my_database); if (!(connInfo = ast_malloc(size))) return 0; sprintf(connInfo, "host=%s port=%d dbname=%s user=%s password=%s", dbhost, dbport, my_database, dbuser, dbpass); ast_log(LOG_DEBUG, "%u connInfo=%s\n", size, connInfo); pgsqlConn = PQconnectdb(connInfo); ast_log(LOG_DEBUG, "%u connInfo=%s\n", size, connInfo); free(connInfo); connInfo = NULL; ast_log(LOG_DEBUG, "pgsqlConn=%p\n", pgsqlConn); if (pgsqlConn && PQstatus(pgsqlConn) == CONNECTION_OK) { ast_log(LOG_DEBUG, "Postgresql RealTime: Successfully connected to database.\n"); connect_time = time(NULL); return 1; } else { ast_log(LOG_ERROR, "Postgresql RealTime: Failed to connect database server %s on %s. Check debug for more info.\n", dbname, dbhost); ast_log(LOG_DEBUG, "Postgresql RealTime: Cannot Connect: %s\n", PQresultErrorMessage(NULL)); return 0; } } else { ast_log(LOG_DEBUG, "Postgresql RealTime: Everything is fine.\n"); return 1; } }
int __ast_codec_register(struct ast_codec *codec, struct ast_module *mod) { SCOPED_AO2WRLOCK(lock, codecs); struct ast_codec *codec_new; /* Some types have specific requirements */ if (codec->type == AST_MEDIA_TYPE_UNKNOWN) { ast_log(LOG_ERROR, "A media type must be specified for codec '%s'\n", codec->name); return -1; } else if (codec->type == AST_MEDIA_TYPE_AUDIO) { if (!codec->sample_rate) { ast_log(LOG_ERROR, "A sample rate must be specified for codec '%s' of type '%s'\n", codec->name, ast_codec_media_type2str(codec->type)); return -1; } } codec_new = ao2_find(codecs, codec, OBJ_SEARCH_OBJECT | OBJ_NOLOCK); if (codec_new) { ast_log(LOG_ERROR, "A codec with name '%s' of type '%s' and sample rate '%u' is already registered\n", codec->name, ast_codec_media_type2str(codec->type), codec->sample_rate); ao2_ref(codec_new, -1); return -1; } codec_new = ao2_t_alloc_options(sizeof(*codec_new), codec_dtor, AO2_ALLOC_OPT_LOCK_NOLOCK, S_OR(codec->description, "")); if (!codec_new) { ast_log(LOG_ERROR, "Could not allocate a codec with name '%s' of type '%s' and sample rate '%u'\n", codec->name, ast_codec_media_type2str(codec->type), codec->sample_rate); return -1; } *codec_new = *codec; codec_new->id = codec_id++; ao2_link_flags(codecs, codec_new, OBJ_NOLOCK); /* Once registered a codec can not be unregistered, and the module must persist until shutdown */ ast_module_shutdown_ref(mod); ast_verb(2, "Registered '%s' codec '%s' at sample rate '%u' with id '%u'\n", ast_codec_media_type2str(codec->type), codec->name, codec->sample_rate, codec_new->id); ao2_ref(codec_new, -1); return 0; }
static int pgsql_reconnect(const char *database) { char my_database[50]; ast_copy_string(my_database, S_OR(database, dbname), sizeof(my_database)); /* mutex lock should have been locked before calling this function. */ if (pgsqlConn && PQstatus(pgsqlConn) != CONNECTION_OK) { PQfinish(pgsqlConn); pgsqlConn = NULL; } /* DB password can legitimately be 0-length */ if ((!pgsqlConn) && (!ast_strlen_zero(dbhost) || !ast_strlen_zero(dbsock)) && !ast_strlen_zero(dbuser) && !ast_strlen_zero(my_database)) { struct ast_str *connInfo = ast_str_create(32); ast_str_set(&connInfo, 0, "host=%s port=%d dbname=%s user=%s", dbhost, dbport, my_database, dbuser); if (!ast_strlen_zero(dbpass)) ast_str_append(&connInfo, 0, " password=%s", dbpass); ast_debug(1, "%u connInfo=%s\n", (unsigned int)connInfo->len, connInfo->str); pgsqlConn = PQconnectdb(connInfo->str); ast_debug(1, "%u connInfo=%s\n", (unsigned int)connInfo->len, connInfo->str); ast_free(connInfo); connInfo = NULL; ast_debug(1, "pgsqlConn=%p\n", pgsqlConn); if (pgsqlConn && PQstatus(pgsqlConn) == CONNECTION_OK) { ast_debug(1, "PostgreSQL RealTime: Successfully connected to database.\n"); connect_time = time(NULL); return 1; } else { ast_log(LOG_ERROR, "PostgreSQL RealTime: Failed to connect database %s on %s: %s\n", dbname, dbhost, PQresultErrorMessage(NULL)); return 0; } } else { ast_debug(1, "PostgreSQL RealTime: One or more of the parameters in the config does not pass our validity checks.\n"); return 1; } }
static int process_config(int reload) { struct ast_config *config; struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 }; const char *bindaddr; const char *bindport; const char *prefix; const char *enabled; config = ast_config_load("http.conf", config_flags); if (!config || config == CONFIG_STATUS_FILEINVALID) { return -1; } else if (config == CONFIG_STATUS_FILEUNCHANGED) { return 0; } enabled = ast_config_option(config, "general", "enabled"); if (!enabled || ast_false(enabled)) { ast_config_destroy(config); return -1; } /* Construct our Server URI */ bindaddr = ast_config_option(config, "general", "bindaddr"); if (!bindaddr) { ast_config_destroy(config); return -1; } bindport = ast_config_option(config, "general", "bindport"); if (!bindport) { bindport = "8088"; } prefix = ast_config_option(config, "general", "prefix"); snprintf(server_uri, sizeof(server_uri), "http://%s:%s%s/%s", bindaddr, bindport, S_OR(prefix, ""), TEST_URI); ast_config_destroy(config); return 0; }