static switch_status_t my_on_reporting(switch_core_session_t *session) { switch_channel_t *channel = switch_core_session_get_channel(session); switch_status_t status = SWITCH_STATUS_SUCCESS; const char *template_str = NULL; char *expanded_vars = NULL, *sql = NULL; if (globals.shutdown) { return SWITCH_STATUS_SUCCESS; } if (!((globals.legs & CDR_LEG_A) && (globals.legs & CDR_LEG_B))) { if ((globals.legs & CDR_LEG_A)) { if (switch_channel_get_originator_caller_profile(channel)) { return SWITCH_STATUS_SUCCESS; } } else { if (switch_channel_get_originatee_caller_profile(channel)) { return SWITCH_STATUS_SUCCESS; } } } if (globals.debug) { switch_event_t *event; if (switch_event_create_plain(&event, SWITCH_EVENT_CHANNEL_DATA) == SWITCH_STATUS_SUCCESS) { char *buf; switch_channel_event_set_data(channel, event); switch_event_serialize(event, &buf, SWITCH_FALSE); switch_assert(buf); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "CHANNEL_DATA:\n%s\n", buf); switch_event_destroy(&event); switch_safe_free(buf); } } template_str = (const char *) switch_core_hash_find(globals.template_hash, globals.default_template); if (!template_str) { template_str = default_template; } expanded_vars = switch_channel_expand_variables(channel, template_str); if (!expanded_vars) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error expanding CDR variables.\n"); return SWITCH_STATUS_FALSE; } sql = switch_mprintf("INSERT INTO %s VALUES (%s)", globals.db_table, expanded_vars); assert(sql); write_cdr(sql); switch_safe_free(sql); if (expanded_vars != template_str) { switch_safe_free(expanded_vars); } return status; }
static switch_status_t my_on_reporting(switch_core_session_t *session) { switch_channel_t *channel = switch_core_session_get_channel(session); switch_status_t status = SWITCH_STATUS_SUCCESS; const char *log_dir = NULL, *accountcode = NULL, *a_template_str = NULL, *g_template_str = NULL; char *log_line, *path = NULL; if (globals.shutdown) { return SWITCH_STATUS_SUCCESS; } if (!((globals.legs & CDR_LEG_A) && (globals.legs & CDR_LEG_B))) { if ((globals.legs & CDR_LEG_A)) { if (switch_channel_get_originator_caller_profile(channel)) { return SWITCH_STATUS_SUCCESS; } } else { if (switch_channel_get_originatee_caller_profile(channel)) { return SWITCH_STATUS_SUCCESS; } } } if (!(log_dir = switch_channel_get_variable(channel, "cdr_csv_base"))) { log_dir = globals.log_dir; } if (switch_dir_make_recursive(log_dir, SWITCH_DEFAULT_DIR_PERMS, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error creating %s\n", log_dir); return SWITCH_STATUS_FALSE; } if (globals.debug) { switch_event_t *event; if (switch_event_create_plain(&event, SWITCH_EVENT_CHANNEL_DATA) == SWITCH_STATUS_SUCCESS) { char *buf; switch_channel_event_set_data(channel, event); switch_event_serialize(event, &buf, SWITCH_FALSE); switch_assert(buf); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "CHANNEL_DATA:\n%s\n", buf); switch_event_destroy(&event); free(buf); } } g_template_str = (const char *) switch_core_hash_find(globals.template_hash, globals.default_template); if ((accountcode = switch_channel_get_variable(channel, "ACCOUNTCODE"))) { a_template_str = (const char *) switch_core_hash_find(globals.template_hash, accountcode); } if (!g_template_str) { g_template_str = "\"${accountcode}\",\"${caller_id_number}\",\"${destination_number}\",\"${context}\",\"${caller_id}\",\"${channel_name}\",\"${bridge_channel}\",\"${last_app}\",\"${last_arg}\",\"${start_stamp}\",\"${answer_stamp}\",\"${end_stamp}\",\"${duration}\",\"${billsec}\",\"${hangup_cause}\",\"${amaflags}\",\"${uuid}\",\"${userfield}\";"; } if (!a_template_str) { a_template_str = g_template_str; } log_line = switch_channel_expand_variables(channel, a_template_str); if ((accountcode) && (!globals.masterfileonly)) { path = switch_mprintf("%s%s%s.csv", log_dir, SWITCH_PATH_SEPARATOR, accountcode); assert(path); write_cdr(path, log_line); free(path); } if (g_template_str != a_template_str) { if (log_line != a_template_str) { switch_safe_free(log_line); } log_line = switch_channel_expand_variables(channel, g_template_str); } if (!log_line) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error creating cdr\n"); return SWITCH_STATUS_FALSE; } path = switch_mprintf("%s%sMaster.csv", log_dir, SWITCH_PATH_SEPARATOR); assert(path); write_cdr(path, log_line); free(path); if (log_line != g_template_str) { free(log_line); } return status; }
void conference_event_call_setup_handler(switch_event_t *event) { switch_status_t status = SWITCH_STATUS_FALSE; conference_obj_t *conference = NULL; char *conf = switch_event_get_header(event, "Target-Component"); char *domain = switch_event_get_header(event, "Target-Domain"); char *dial_str = switch_event_get_header(event, "Request-Target"); char *dial_uri = switch_event_get_header(event, "Request-Target-URI"); char *action = switch_event_get_header(event, "Request-Action"); char *ext = switch_event_get_header(event, "Request-Target-Extension"); char *ext_domain = switch_event_get_header(event, "Request-Target-Domain"); char *full_url = switch_event_get_header(event, "full_url"); char *call_id = switch_event_get_header(event, "Request-Call-ID"); if (!ext) ext = dial_str; if (!zstr(conf) && !zstr(dial_str) && !zstr(action) && (conference = conference_find(conf, domain))) { switch_event_t *var_event; switch_event_header_t *hp; if (conference_utils_test_flag(conference, CFLAG_RFC4579)) { char *key = switch_mprintf("conference_%s_%s_%s_%s", conference->name, conference->domain, ext, ext_domain); char *expanded = NULL, *ostr = dial_str;; if (!strcasecmp(action, "call")) { if((conference->max_members > 0) && (conference->count >= conference->max_members)) { // Conference member limit has been reached; do not proceed with setup request status = SWITCH_STATUS_FALSE; } else { if (switch_event_create_plain(&var_event, SWITCH_EVENT_CHANNEL_DATA) != SWITCH_STATUS_SUCCESS) { abort(); } for(hp = event->headers; hp; hp = hp->next) { if (!strncasecmp(hp->name, "var_", 4)) { switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, hp->name + 4, hp->value); } } switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, "conference_call_key", key); switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, "conference_destination_number", ext); switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, "conference_invite_uri", dial_uri); switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, "conference_track_status", "true"); switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, "conference_track_call_id", call_id); switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, "sip_invite_domain", domain); switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, "sip_invite_contact_params", "~isfocus"); if (!strncasecmp(ostr, "url+", 4)) { ostr += 4; } else if (!switch_true(full_url) && conference->outcall_templ) { if ((expanded = switch_event_expand_headers(var_event, conference->outcall_templ))) { ostr = expanded; } } status = conference_outcall_bg(conference, NULL, NULL, ostr, 60, NULL, NULL, NULL, NULL, NULL, NULL, &var_event); if (expanded && expanded != conference->outcall_templ) { switch_safe_free(expanded); } } } else if (!strcasecmp(action, "end")) { if (switch_core_session_hupall_matching_var("conference_call_key", key, SWITCH_CAUSE_NORMAL_CLEARING)) { conference_send_notify(conference, "SIP/2.0 200 OK\r\n", call_id, SWITCH_TRUE); } else { conference_send_notify(conference, "SIP/2.0 481 Failure\r\n", call_id, SWITCH_TRUE); } status = SWITCH_STATUS_SUCCESS; } switch_safe_free(key); } else { // Conference found but doesn't support referral. status = SWITCH_STATUS_FALSE; } switch_thread_rwlock_unlock(conference->rwlock); } else { // Couldn't find associated conference. Indicate failure on refer subscription status = SWITCH_STATUS_FALSE; } if(status != SWITCH_STATUS_SUCCESS) { // Unable to setup call, need to generate final NOTIFY if (switch_event_create(&event, SWITCH_EVENT_CONFERENCE_DATA) == SWITCH_STATUS_SUCCESS) { event->flags |= EF_UNIQ_HEADERS; switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "conference-name", conf); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "conference-domain", domain); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "conference-event", "refer"); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "call_id", call_id); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "final", "true"); switch_event_add_body(event, "%s", "SIP/2.0 481 Failure\r\n"); switch_event_fire(&event); } } }
static switch_bool_t fsk_detect_callback(switch_media_bug_t *bug, void *user_data, switch_abc_type_t type) { switch_fsk_detect_t *pvt = (switch_fsk_detect_t *) user_data; //switch_frame_t *frame = NULL; switch_channel_t *channel = switch_core_session_get_channel(pvt->session); switch (type) { case SWITCH_ABC_TYPE_INIT: { switch_codec_implementation_t read_impl = { 0 }; switch_core_session_get_read_impl(pvt->session, &read_impl); if (fsk_demod_init(&pvt->fsk_data, read_impl.actual_samples_per_second, pvt->fbuf, sizeof(pvt->fbuf))) { return SWITCH_FALSE; } break; } case SWITCH_ABC_TYPE_CLOSE: { fsk_demod_destroy(&pvt->fsk_data); } break; case SWITCH_ABC_TYPE_WRITE_REPLACE: case SWITCH_ABC_TYPE_READ_REPLACE: { switch_frame_t *rframe; if (type == SWITCH_ABC_TYPE_READ_REPLACE) { rframe = switch_core_media_bug_get_read_replace_frame(bug); } else { rframe = switch_core_media_bug_get_write_replace_frame(bug); } if (!pvt->skip && fsk_demod_feed(&pvt->fsk_data, rframe->data, rframe->datalen / 2) != SWITCH_STATUS_SUCCESS) { char str[1024] = ""; size_t type, mlen; char *sp; switch_event_t *event; const char *app_var; int total = 0; switch_event_create_plain(&event, SWITCH_EVENT_CHANNEL_DATA); while(fsk_data_parse(&pvt->fsk_data, &type, &sp, &mlen) == SWITCH_STATUS_SUCCESS) { char *varname = NULL, *val, *p; switch_copy_string(str, sp, mlen+1); *(str+mlen) = '\0'; switch_clean_string(str); //printf("TYPE %u LEN %u VAL [%s]\n", (unsigned)type, (unsigned)mlen, str); val = str; switch(type) { case MDMF_DATETIME: varname = "fsk_datetime"; break; case MDMF_PHONE_NAME: varname = "fsk_phone_name"; break; case MDMF_PHONE_NUM: varname = "fsk_phone_num"; break; case MDMF_NAME_VALUE: varname = switch_core_session_sprintf(pvt->session, "fsk_%s", val); if ((p = strchr(varname, ':'))) { *p++ = '\0'; val = p; } break; default: break; } if (varname && val) { total++; switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(pvt->session), SWITCH_LOG_DEBUG, "%s setting FSK var [%s][%s]\n", switch_channel_get_name(channel), varname, val); switch_channel_set_variable(channel, varname, val); if (event) { switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, varname, val); } } } if (event) { if (switch_core_session_queue_event(pvt->session, &event) != SWITCH_STATUS_SUCCESS) { switch_event_destroy(&event); } } if (total && (app_var = switch_channel_get_variable(channel, "execute_on_fsk"))) { char *app_arg; switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(pvt->session), SWITCH_LOG_DEBUG, "%s processing execute_on_fsk [%s]\n", switch_channel_get_name(channel), app_var); if ((app_arg = strchr(app_var, ' '))) { *app_arg++ = '\0'; } switch_core_session_execute_application(pvt->session, app_var, app_arg); } pvt->skip = 10; } memset(rframe->data, 255, rframe->datalen); if (type == SWITCH_ABC_TYPE_READ_REPLACE) { switch_core_media_bug_set_read_replace_frame(bug, rframe); } else { switch_core_media_bug_set_write_replace_frame(bug, rframe); } if (pvt->skip && !--pvt->skip) { return SWITCH_FALSE; } } break; case SWITCH_ABC_TYPE_WRITE: default: break; } return SWITCH_TRUE; }
/** * Encode log as GELF */ static char *to_gelf(const switch_log_node_t *node, switch_log_level_t log_level) { char *gelf_text = NULL; cJSON *gelf = cJSON_CreateObject(); char *hostname; char timestamp[32]; char *full_message = node->content; char short_message[151]; char *short_message_end = NULL; char *parsed_full_message = NULL; char *field_name = NULL; switch_event_t *log_fields = NULL; switch_core_session_t *session = NULL; cJSON_AddItemToObject(gelf, "version", cJSON_CreateString("1.1")); if ((hostname = switch_core_get_variable("hostname")) && !zstr(hostname)) { cJSON_AddItemToObject(gelf, "host", cJSON_CreateString(hostname)); } else if ((hostname = switch_core_get_variable("local_ip_v4")) && !zstr(hostname)) { cJSON_AddItemToObject(gelf, "host", cJSON_CreateString(hostname)); } switch_snprintf(timestamp, 32, "%"SWITCH_UINT64_T_FMT".%d", (uint64_t)(node->timestamp / 1000000), (node->timestamp % 1000000) / 1000); cJSON_AddItemToObject(gelf, "timestamp", cJSON_CreateString(timestamp)); cJSON_AddItemToObject(gelf, "_microtimestamp", cJSON_CreateNumber(node->timestamp)); cJSON_AddItemToObject(gelf, "level", cJSON_CreateNumber(to_graylog2_level(log_level))); cJSON_AddItemToObject(gelf, "_ident", cJSON_CreateString("freeswitch")); cJSON_AddItemToObject(gelf, "_pid", cJSON_CreateNumber((int)getpid())); if (!zstr(node->userdata)) { cJSON_AddItemToObject(gelf, "_uuid", cJSON_CreateString(node->userdata)); } if (!zstr_buf(node->file)) { cJSON_AddItemToObject(gelf, "_file", cJSON_CreateString(node->file)); cJSON_AddItemToObject(gelf, "_line", cJSON_CreateNumber(node->line)); } if (!zstr_buf(node->func)) { cJSON_AddItemToObject(gelf, "_function", cJSON_CreateString(node->func)); } /* skip initial space and new line */ if (*full_message == ' ') { full_message++; } if (*full_message == '\n') { full_message++; } /* get fields from channel data, if configured */ if (!zstr(node->userdata) && (session = switch_core_session_locate(node->userdata))) { switch_channel_t *channel = switch_core_session_get_channel(session); switch_event_header_t *hp; /* session_fields name mapped to variable name */ for (hp = globals.session_fields->headers; hp; hp = hp->next) { if (!zstr(hp->name) && !zstr(hp->value)) { const char *val = switch_channel_get_variable(channel, hp->value); if (!zstr(val)) { if (!log_fields) { switch_event_create_plain(&log_fields, SWITCH_EVENT_CHANNEL_DATA); } switch_event_add_header_string(log_fields, SWITCH_STACK_BOTTOM, hp->name, val); } } } switch_core_session_rwunlock(session); } /* parse list of fields from message text, if any */ if (strncmp(full_message, "LOG_FIELDS", 10) == 0) { switch_event_create_brackets(full_message+10, '[', ']', ',', &log_fields, &parsed_full_message, SWITCH_TRUE); full_message = parsed_full_message; } /* add additional fields */ if (log_fields) { switch_event_header_t *hp; for (hp = log_fields->headers; hp; hp = hp->next) { if (!zstr(hp->name) && !zstr(hp->value)) { if (strncmp(hp->name, "@#", 2) == 0) { field_name = switch_mprintf("_%s", hp->name + 2); cJSON_AddItemToObject(gelf, field_name, cJSON_CreateNumber(strtod(hp->value, NULL))); } else { field_name = switch_mprintf("_%s", hp->name); cJSON_AddItemToObject(gelf, field_name, cJSON_CreateString(hp->value)); } free(field_name); } } switch_event_destroy(&log_fields); } cJSON_AddItemToObject(gelf, "full_message", cJSON_CreateString(full_message)); switch_snprintf(short_message, sizeof(short_message) - 1, "%s", full_message); if ((short_message_end = strchr(short_message, '\n'))) { *short_message_end = '\0'; } cJSON_AddItemToObject(gelf, "short_message", cJSON_CreateString(short_message)); gelf_text = cJSON_PrintUnformatted(gelf); cJSON_Delete(gelf); switch_safe_free(parsed_full_message); return gelf_text; }