Ejemplo n.º 1
0
static int manager_log(struct ast_cdr *cdr)
{
	struct ast_tm timeresult;
	char strStartTime[80] = "";
	char strAnswerTime[80] = "";
	char strEndTime[80] = "";
	char buf[CUSTOM_FIELDS_BUF_SIZE];

	if (!enablecdr)
		return 0;

	ast_localtime(&cdr->start, &timeresult, NULL);
	ast_strftime(strStartTime, sizeof(strStartTime), DATE_FORMAT, &timeresult);

	if (cdr->answer.tv_sec)	{
		ast_localtime(&cdr->answer, &timeresult, NULL);
		ast_strftime(strAnswerTime, sizeof(strAnswerTime), DATE_FORMAT, &timeresult);
	}

	ast_localtime(&cdr->end, &timeresult, NULL);
	ast_strftime(strEndTime, sizeof(strEndTime), DATE_FORMAT, &timeresult);

	buf[0] = '\0';
	ast_rwlock_rdlock(&customfields_lock);
	if (customfields && ast_str_strlen(customfields)) {
		struct ast_channel *dummy = ast_dummy_channel_alloc();
		if (!dummy) {
			ast_log(LOG_ERROR, "Unable to allocate channel for variable substitution.\n");
			return 0;
		}
		dummy->cdr = ast_cdr_dup(cdr);
		pbx_substitute_variables_helper(dummy, ast_str_buffer(customfields), buf, sizeof(buf) - 1);
		ast_channel_unref(dummy);
	}
	ast_rwlock_unlock(&customfields_lock);

	manager_event(EVENT_FLAG_CDR, "Cdr",
	    "AccountCode: %s\r\n"
	    "Source: %s\r\n"
	    "Destination: %s\r\n"
	    "DestinationContext: %s\r\n"
	    "CallerID: %s\r\n"
	    "Channel: %s\r\n"
	    "DestinationChannel: %s\r\n"
	    "LastApplication: %s\r\n"
	    "LastData: %s\r\n"
	    "StartTime: %s\r\n"
	    "AnswerTime: %s\r\n"
	    "EndTime: %s\r\n"
	    "Duration: %ld\r\n"
	    "BillableSeconds: %ld\r\n"
	    "Disposition: %s\r\n"
	    "AMAFlags: %s\r\n"
	    "UniqueID: %s\r\n"
	    "UserField: %s\r\n"
	    "%s",
	    cdr->accountcode, cdr->src, cdr->dst, cdr->dcontext, cdr->clid, cdr->channel,
	    cdr->dstchannel, cdr->lastapp, cdr->lastdata, strStartTime, strAnswerTime, strEndTime,
	    cdr->duration, cdr->billsec, ast_cdr_disp2str(cdr->disposition),
	    ast_cdr_flags2str(cdr->amaflags), cdr->uniqueid, cdr->userfield,buf);

	return 0;
}
Ejemplo n.º 2
0
struct ast_channel *ast_cel_fabricate_channel_from_event(const struct ast_event *event)
{
    struct varshead *headp;
    struct ast_var_t *newvariable;
    const char *mixed_name;
    char timebuf[30];
    struct ast_channel *tchan;
    struct ast_cel_event_record record = {
        .version = AST_CEL_EVENT_RECORD_VERSION,
    };

    /* do not call ast_channel_alloc because this is not really a real channel */
    if (!(tchan = ast_dummy_channel_alloc())) {
        return NULL;
    }

    headp = ast_channel_varshead(tchan);

    /* first, get the variables from the event */
    if (ast_cel_fill_record(event, &record)) {
        ast_channel_unref(tchan);
        return NULL;
    }

    /* next, fill the channel with their data */
    mixed_name = (record.event_type == AST_CEL_USER_DEFINED)
                 ? record.user_defined_name : record.event_name;
    if ((newvariable = ast_var_assign("eventtype", mixed_name))) {
        AST_LIST_INSERT_HEAD(headp, newvariable, entries);
    }

    if (ast_strlen_zero(cel_dateformat)) {
        snprintf(timebuf, sizeof(timebuf), "%ld.%06ld", (long) record.event_time.tv_sec,
                 (long) record.event_time.tv_usec);
    } else {
        struct ast_tm tm;
        ast_localtime(&record.event_time, &tm, NULL);
        ast_strftime(timebuf, sizeof(timebuf), cel_dateformat, &tm);
    }

    if ((newvariable = ast_var_assign("eventtime", timebuf))) {
        AST_LIST_INSERT_HEAD(headp, newvariable, entries);
    }

    if ((newvariable = ast_var_assign("eventenum", record.event_name))) {
        AST_LIST_INSERT_HEAD(headp, newvariable, entries);
    }
    if ((newvariable = ast_var_assign("userdeftype", record.user_defined_name))) {
        AST_LIST_INSERT_HEAD(headp, newvariable, entries);
    }
    if ((newvariable = ast_var_assign("eventextra", record.extra))) {
        AST_LIST_INSERT_HEAD(headp, newvariable, entries);
    }

    ast_channel_caller(tchan)->id.name.valid = 1;
    ast_channel_caller(tchan)->id.name.str = ast_strdup(record.caller_id_name);
    ast_channel_caller(tchan)->id.number.valid = 1;
    ast_channel_caller(tchan)->id.number.str = ast_strdup(record.caller_id_num);
    ast_channel_caller(tchan)->ani.number.valid = 1;
    ast_channel_caller(tchan)->ani.number.str = ast_strdup(record.caller_id_ani);
    ast_channel_redirecting(tchan)->from.number.valid = 1;
    ast_channel_redirecting(tchan)->from.number.str = ast_strdup(record.caller_id_rdnis);
    ast_channel_dialed(tchan)->number.str = ast_strdup(record.caller_id_dnid);

    ast_channel_exten_set(tchan, record.extension);
    ast_channel_context_set(tchan, record.context);
    ast_channel_name_set(tchan, record.channel_name);
    ast_channel_uniqueid_set(tchan, record.unique_id);
    ast_channel_linkedid_set(tchan, record.linked_id);
    ast_channel_accountcode_set(tchan, record.account_code);
    ast_channel_peeraccount_set(tchan, record.peer_account);
    ast_channel_userfield_set(tchan, record.user_field);

    if ((newvariable = ast_var_assign("BRIDGEPEER", record.peer))) {
        AST_LIST_INSERT_HEAD(headp, newvariable, entries);
    }

    ast_channel_appl_set(tchan, ast_strdup(record.application_name));
    ast_channel_data_set(tchan, ast_strdup(record.application_data));
    ast_channel_amaflags_set(tchan, record.amaflag);

    return tchan;
}
Ejemplo n.º 3
0
struct ast_channel *ast_cel_fabricate_channel_from_event(const struct ast_event *event)
{
	struct varshead *headp;
	struct ast_var_t *newvariable;
	char timebuf[30];
	struct ast_channel *tchan;
	struct ast_cel_event_record record = {
		.version = AST_CEL_EVENT_RECORD_VERSION,
	};

	/* do not call ast_channel_alloc because this is not really a real channel */
	if (!(tchan = ast_dummy_channel_alloc())) {
		return NULL;
	}

	headp = &tchan->varshead;

	/* first, get the variables from the event */
	if (ast_cel_fill_record(event, &record)) {
		ast_channel_release(tchan);
		return NULL;
	}

	/* next, fill the channel with their data */
	if ((newvariable = ast_var_assign("eventtype", record.event_name))) {
		AST_LIST_INSERT_HEAD(headp, newvariable, entries);
	}

	if (ast_strlen_zero(cel_dateformat)) {
		snprintf(timebuf, sizeof(timebuf), "%ld.%06ld", (long) record.event_time.tv_sec,
				(long) record.event_time.tv_usec);
	} else {
		struct ast_tm tm;
		ast_localtime(&record.event_time, &tm, NULL);
		ast_strftime(timebuf, sizeof(timebuf), cel_dateformat, &tm);
	}

	if ((newvariable = ast_var_assign("eventtime", timebuf))) {
		AST_LIST_INSERT_HEAD(headp, newvariable, entries);
	}

	if ((newvariable = ast_var_assign("eventextra", record.extra))) {
		AST_LIST_INSERT_HEAD(headp, newvariable, entries);
	}

	tchan->caller.id.name.valid = 1;
	tchan->caller.id.name.str = ast_strdup(record.caller_id_name);
	tchan->caller.id.number.valid = 1;
	tchan->caller.id.number.str = ast_strdup(record.caller_id_num);
	tchan->caller.ani.number.valid = 1;
	tchan->caller.ani.number.str = ast_strdup(record.caller_id_ani);
	tchan->redirecting.from.number.valid = 1;
	tchan->redirecting.from.number.str = ast_strdup(record.caller_id_rdnis);
	tchan->dialed.number.str = ast_strdup(record.caller_id_dnid);

	ast_copy_string(tchan->exten, record.extension, sizeof(tchan->exten));
	ast_copy_string(tchan->context, record.context, sizeof(tchan->context));
	ast_string_field_set(tchan, name, record.channel_name);
	ast_string_field_set(tchan, uniqueid, record.unique_id);
	ast_string_field_set(tchan, linkedid, record.linked_id);
	ast_string_field_set(tchan, accountcode, record.account_code);
	ast_string_field_set(tchan, peeraccount, record.peer_account);
	ast_string_field_set(tchan, userfield, record.user_field);

	pbx_builtin_setvar_helper(tchan, "BRIDGEPEER", record.peer);

	tchan->appl = ast_strdup(record.application_name);
	tchan->data = ast_strdup(record.application_data);
	tchan->amaflags = record.amaflag;

	return tchan;
}
Ejemplo n.º 4
0
struct ast_channel *ast_cel_fabricate_channel_from_event(const struct ast_event *event)
{
	struct varshead *headp;
	struct ast_var_t *newvariable;
	const char *mixed_name;
	char timebuf[30];
	struct ast_channel *tchan;
	struct ast_cel_event_record record = {
		.version = AST_CEL_EVENT_RECORD_VERSION,
	};
	struct ast_datastore *datastore;
	char *app_data;

	/* do not call ast_channel_alloc because this is not really a real channel */
	if (!(tchan = ast_dummy_channel_alloc())) {
		return NULL;
	}

	headp = ast_channel_varshead(tchan);

	/* first, get the variables from the event */
	if (ast_cel_fill_record(event, &record)) {
		ast_channel_unref(tchan);
		return NULL;
	}

	/* next, fill the channel with their data */
	mixed_name = (record.event_type == AST_CEL_USER_DEFINED)
		? record.user_defined_name : record.event_name;
	if ((newvariable = ast_var_assign("eventtype", mixed_name))) {
		AST_LIST_INSERT_HEAD(headp, newvariable, entries);
	}

	if (ast_strlen_zero(cel_dateformat)) {
		snprintf(timebuf, sizeof(timebuf), "%ld.%06ld", (long) record.event_time.tv_sec,
				(long) record.event_time.tv_usec);
	} else {
		struct ast_tm tm;
		ast_localtime(&record.event_time, &tm, NULL);
		ast_strftime(timebuf, sizeof(timebuf), cel_dateformat, &tm);
	}

	if ((newvariable = ast_var_assign("eventtime", timebuf))) {
		AST_LIST_INSERT_HEAD(headp, newvariable, entries);
	}

	if ((newvariable = ast_var_assign("eventenum", record.event_name))) {
		AST_LIST_INSERT_HEAD(headp, newvariable, entries);
	}
	if ((newvariable = ast_var_assign("userdeftype", record.user_defined_name))) {
		AST_LIST_INSERT_HEAD(headp, newvariable, entries);
	}
	if ((newvariable = ast_var_assign("eventextra", record.extra))) {
		AST_LIST_INSERT_HEAD(headp, newvariable, entries);
	}

	ast_channel_caller(tchan)->id.name.valid = 1;
	ast_channel_caller(tchan)->id.name.str = ast_strdup(record.caller_id_name);
	ast_channel_caller(tchan)->id.number.valid = 1;
	ast_channel_caller(tchan)->id.number.str = ast_strdup(record.caller_id_num);
	ast_channel_caller(tchan)->ani.number.valid = 1;
	ast_channel_caller(tchan)->ani.number.str = ast_strdup(record.caller_id_ani);
	ast_channel_redirecting(tchan)->from.number.valid = 1;
	ast_channel_redirecting(tchan)->from.number.str = ast_strdup(record.caller_id_rdnis);
	ast_channel_dialed(tchan)->number.str = ast_strdup(record.caller_id_dnid);

	ast_channel_exten_set(tchan, record.extension);
	ast_channel_context_set(tchan, record.context);
	ast_channel_name_set(tchan, record.channel_name);
	ast_channel_uniqueid_set(tchan, record.unique_id);
	ast_channel_linkedid_set(tchan, record.linked_id);
	ast_channel_accountcode_set(tchan, record.account_code);
	ast_channel_peeraccount_set(tchan, record.peer_account);
	ast_channel_userfield_set(tchan, record.user_field);

	if ((newvariable = ast_var_assign("BRIDGEPEER", record.peer))) {
		AST_LIST_INSERT_HEAD(headp, newvariable, entries);
	}

	ast_channel_amaflags_set(tchan, record.amaflag);

	/* We need to store an 'application name' and 'application
	 * data' on the channel for logging purposes, but the channel
	 * structure only provides a place to store pointers, and it
	 * expects these pointers to be pointing to data that does not
	 * need to be freed. This means that the channel's destructor
	 * does not attempt to free any storage that these pointers
	 * point to. However, we can't provide data in that form directly for
	 * these structure members. In order to ensure that these data
	 * elements have a lifetime that matches the channel's
	 * lifetime, we'll put them in a datastore attached to the
	 * channel, and set's the channel's pointers to point into the
	 * datastore.  The datastore will then be automatically destroyed
	 * when the channel is destroyed.
	 */

	if (!(datastore = ast_datastore_alloc(&fabricated_channel_datastore, NULL))) {
		ast_channel_unref(tchan);
		return NULL;
	}

	if (!(app_data = ast_malloc(strlen(record.application_name) + strlen(record.application_data) + 2))) {
		ast_datastore_free(datastore);
		ast_channel_unref(tchan);
		return NULL;
	}

	ast_channel_appl_set(tchan, strcpy(app_data, record.application_name));
	ast_channel_data_set(tchan, strcpy(app_data + strlen(record.application_name) + 1,
		record.application_data));

	datastore->data = app_data;
	ast_channel_datastore_add(tchan, datastore);

	return tchan;
}