of a Mailbox or Password, will, if it exists, jump to the 'a' extension in
the current dialplan context.
+* The CALLERPRES() dialplan function is deprecated in favor of
+ CALLERID(num-pres) and CALLERID(name-pres).
+
* Environment variables that start with "AST_" are reserved to the system and
may no longer be set from the dialplan.
}
ast_mutex_lock(&p->lock);
ast_set_flag(p, H323_OUTGOING);
- if (ast->connected.id.number) {
- if(p->callerid_num) free(p->callerid_num);
- p->callerid_num = strdup(ast->connected.id.number);
- }
-
- if (ast->connected.id.name) {
- if(p->callerid_name)
- free(p->callerid_name);
- p->callerid_name = strdup(ast->connected.id.name);
- } else if (ast->connected.id.number) {
- if(p->callerid_name)
- free(p->callerid_name);
- p->callerid_name = strdup(ast->connected.id.number);
+ if (ast->connected.id.number.valid && ast->connected.id.number.str) {
+ free(p->callerid_num);
+ p->callerid_num = strdup(ast->connected.id.number.str);
+ }
+
+ if (ast->connected.id.name.valid && ast->connected.id.name.str) {
+ free(p->callerid_name);
+ p->callerid_name = strdup(ast->connected.id.name.str);
+ } else if (ast->connected.id.number.valid && ast->connected.id.number.str) {
+ free(p->callerid_name);
+ p->callerid_name = strdup(ast->connected.id.number.str);
} else {
- ast->connected.id.name = strdup(gCallerID);
- if(p->callerid_name)
- free(p->callerid_name);
- p->callerid_name = strdup(ast->connected.id.name);
+ ast->connected.id.name.valid = 1;
+ free(ast->connected.id.name.str);
+ ast->connected.id.name.str = strdup(gCallerID);
+ free(p->callerid_name);
+ p->callerid_name = strdup(ast->connected.id.name.str);
}
/* Retrieve vars */
case AST_CONTROL_SRCCHANGE:
ast_rtp_instance_change_source(p->rtp);
break;
- case AST_CONTROL_CONNECTED_LINE:
- if (!ast_strlen_zero(ast->connected.id.name)) {
- if (gH323Debug)
- ast_log(LOG_DEBUG, "Sending connected line info for %s (%s)\n",
- callToken, ast->connected.id.name);
- ooSetANI(callToken, ast->connected.id.name);
+ case AST_CONTROL_CONNECTED_LINE:
+ if (!ast->connected.id.name.valid
+ || ast_strlen_zero(ast->connected.id.name.str)) {
+ break;
}
+ if (gH323Debug)
+ ast_log(LOG_DEBUG, "Sending connected line info for %s (%s)\n",
+ callToken, ast->connected.id.name.str);
+ ooSetANI(callToken, ast->connected.id.name.str);
break;
case AST_CONTROL_T38_PARAMETERS:
if (call->remoteDisplayName) {
struct ast_party_connected_line connected;
+ struct ast_set_party_connected_line update_connected;
+
+ memset(&update_connected, 0, sizeof(update_connected));
+ update_connected.id.name = 1;
ast_party_connected_line_init(&connected);
- connected.id.name = (char *) call->remoteDisplayName;
+ connected.id.name.valid = 1;
+ connected.id.name.str = (char *) call->remoteDisplayName;
connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
- ast_channel_queue_connected_line_update(c, &connected);
+ ast_channel_queue_connected_line_update(c, &connected, &update_connected);
}
if (c->_state != AST_STATE_UP)
ast_setstate(c, AST_STATE_RINGING);
if (call->remoteDisplayName) {
struct ast_party_connected_line connected;
+ struct ast_set_party_connected_line update_connected;
+
+ memset(&update_connected, 0, sizeof(update_connected));
+ update_connected.id.name = 1;
ast_party_connected_line_init(&connected);
- connected.id.name = (char *) call->remoteDisplayName;
+ connected.id.name.valid = 1;
+ connected.id.name.str = (char *) call->remoteDisplayName;
connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
- ast_channel_queue_connected_line_update(c, &connected);
+ ast_channel_queue_connected_line_update(c, &connected, &update_connected);
}
if (c->_state != AST_STATE_UP)
ast_setstate(c, AST_STATE_RINGING);
if (call->remoteDisplayName) {
struct ast_party_connected_line connected;
+ struct ast_set_party_connected_line update_connected;
+
+ memset(&update_connected, 0, sizeof(update_connected));
+ update_connected.id.name = 1;
ast_party_connected_line_init(&connected);
- connected.id.name = (char *) call->remoteDisplayName;
+ connected.id.name.valid = 1;
+ connected.id.name.str = (char *) call->remoteDisplayName;
connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
- ast_channel_queue_connected_line_update(c, &connected);
+ ast_channel_queue_connected_line_update(c, &connected, &update_connected);
}
ast_queue_control(c, AST_CONTROL_ANSWER);
int res = 0;
struct timeval t;
struct ast_tm now;
- char *cl,*cn;
+ char *cl;
+ char *cn;
char workstring[80];
char timestamp[80];
/* Extract the caller ID location */
- if (chan->cid.cid_num)
- ast_copy_string(workstring, chan->cid.cid_num, sizeof(workstring));
- workstring[sizeof(workstring) - 1] = '\0';
-
- ast_callerid_parse(workstring, &cn, &cl);
- if (cl)
- ast_shrink_phone_number(cl);
+ ast_copy_string(workstring,
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, ""),
+ sizeof(workstring));
+ ast_shrink_phone_number(workstring);
+ if (ast_strlen_zero(workstring)) {
+ cl = "<unknown>";
+ } else {
+ cl = workstring;
+ }
+ cn = S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, "<unknown>");
/* Get the current time */
t = ast_tvnow();
ast_strftime(timestamp, sizeof(timestamp), time_stamp_format, &now);
res = fprintf(logfile, "\n\n[metadata]\n\n");
-
- if (res >= 0)
+ if (res >= 0) {
res = fprintf(logfile, "PROTOCOL=%s\n", signalling_type);
-
- if (res >= 0)
- res = fprintf(logfile, "CALLINGFROM=%s\n", (!cl) ? "<unknown>" : cl);
-
- if (res >- 0)
- res = fprintf(logfile, "CALLERNAME=%s\n", (!cn) ? "<unknown>" : cn);
-
- if (res >= 0)
+ }
+ if (res >= 0) {
+ res = fprintf(logfile, "CALLINGFROM=%s\n", cl);
+ }
+ if (res >= 0) {
+ res = fprintf(logfile, "CALLERNAME=%s\n", cn);
+ }
+ if (res >= 0) {
res = fprintf(logfile, "TIMESTAMP=%s\n\n", timestamp);
-
- if (res >= 0)
+ }
+ if (res >= 0) {
res = fprintf(logfile, "[events]\n\n");
-
+ }
if (res < 0) {
ast_verb(3, "AlarmReceiver: can't write metadata\n");
ast_debug(1,"AlarmReceiver: can't write metadata\n");
- } else
+ } else {
res = 0;
+ }
return res;
}
AST_APP_ARG(argMaximumWordLength);
);
- ast_verb(3, "AMD: %s %s %s (Fmt: %s)\n", chan->name, chan->cid.cid_ani,
- chan->redirecting.from.number, ast_getformatname(chan->readformat));
+ ast_verb(3, "AMD: %s %s %s (Fmt: %s)\n", chan->name,
+ S_OR(chan->caller.ani, "(N/A)"),
+ S_COR(chan->redirecting.from.number.valid, chan->redirecting.from.number.str, "(N/A)"),
+ ast_getformatname(chan->readformat));
/* Lets parse the arguments. */
if (!ast_strlen_zero(parse)) {
}
}
-/*! \brief free the buffer if allocated, and set the pointer to the second arg */
-#define S_REPLACE(s, new_val) \
- do { \
- ast_free(s); \
- s = (new_val); \
- } while (0)
-
static int onedigit_goto(struct ast_channel *chan, const char *context, char exten, int pri)
{
char rexten[2] = { exten, '\0' };
"UniqueID: %s\r\n"
"DestUniqueID: %s\r\n"
"Dialstring: %s\r\n",
- src->name, dst->name, S_OR(src->cid.cid_num, "<unknown>"),
- S_OR(src->cid.cid_name, "<unknown>"), src->uniqueid,
- dst->uniqueid, dialstring ? dialstring : "");
+ src->name, dst->name,
+ S_COR(src->caller.id.number.valid, src->caller.id.number.str, "<unknown>"),
+ S_COR(src->caller.id.name.valid, src->caller.id.name.str, "<unknown>"),
+ src->uniqueid, dst->uniqueid,
+ dialstring ? dialstring : "");
}
static void senddialendevent(struct ast_channel *src, const char *dialstatus)
ast_rtp_instance_early_bridge_make_compatible(c, in);
}
- ast_channel_set_redirecting(c, &original->redirecting);
+ ast_channel_set_redirecting(c, &original->redirecting, NULL);
ast_channel_lock(c);
while (ast_channel_trylock(in)) {
CHANNEL_DEADLOCK_AVOIDANCE(c);
}
- if (ast_strlen_zero(c->redirecting.from.number)) {
+ if (!c->redirecting.from.number.valid
+ || ast_strlen_zero(c->redirecting.from.number.str)) {
/*
* The call was not previously redirected so it is
* now redirected from this number.
*/
- S_REPLACE(c->redirecting.from.number,
- ast_strdup(S_OR(in->macroexten, in->exten)));
+ ast_party_number_free(&c->redirecting.from.number);
+ ast_party_number_init(&c->redirecting.from.number);
+ c->redirecting.from.number.valid = 1;
+ c->redirecting.from.number.str =
+ ast_strdup(S_OR(in->macroexten, in->exten));
}
- c->cid.cid_tns = in->cid.cid_tns;
+ c->dialed.transit_network_select = in->dialed.transit_network_select;
if (ast_test_flag64(o, OPT_FORCECLID)) {
- S_REPLACE(c->cid.cid_num, ast_strdup(S_OR(in->macroexten, in->exten)));
- S_REPLACE(c->cid.cid_name, NULL);
+ ast_party_id_free(&c->caller.id);
+ ast_party_id_init(&c->caller.id);
+ c->caller.id.number.valid = 1;
+ c->caller.id.number.str = ast_strdup(S_OR(in->macroexten, in->exten));
ast_string_field_set(c, accountcode, c->accountcode);
} else {
- ast_party_caller_copy(&c->cid, &in->cid);
+ ast_party_caller_copy(&c->caller, &in->caller);
ast_string_field_set(c, accountcode, in->accountcode);
}
ast_party_connected_line_copy(&c->connected, &original->connected);
while (ast_channel_trylock(c)) {
CHANNEL_DEADLOCK_AVOIDANCE(in);
}
- ast_channel_update_redirecting(in, &c->redirecting);
+ ast_channel_update_redirecting(in, &c->redirecting, NULL);
ast_channel_unlock(c);
}
if (!ast_test_flag64(peerflags, OPT_IGNORE_CONNECTEDLINE) && !ast_test_flag64(outgoing, DIAL_CALLERID_ABSENT)) {
ast_channel_lock(outgoing->chan);
- ast_connected_line_copy_from_caller(&connected_caller, &outgoing->chan->cid);
+ ast_connected_line_copy_from_caller(&connected_caller, &outgoing->chan->caller);
ast_channel_unlock(outgoing->chan);
connected_caller.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
- ast_channel_update_connected_line(in, &connected_caller);
+ ast_channel_update_connected_line(in, &connected_caller, NULL);
ast_party_connected_line_free(&connected_caller);
}
}
if (!single && !ast_test_flag64(peerflags, OPT_IGNORE_CONNECTEDLINE)) {
if (o->pending_connected_update) {
if (ast_channel_connected_line_macro(c, in, &o->connected, 1, 0)) {
- ast_channel_update_connected_line(in, &o->connected);
+ ast_channel_update_connected_line(in, &o->connected, NULL);
}
} else if (!ast_test_flag64(o, DIAL_CALLERID_ABSENT)) {
ast_channel_lock(c);
- ast_connected_line_copy_from_caller(&connected_caller, &c->cid);
+ ast_connected_line_copy_from_caller(&connected_caller, &c->caller);
ast_channel_unlock(c);
connected_caller.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
- ast_channel_update_connected_line(in, &connected_caller);
+ ast_channel_update_connected_line(in, &connected_caller, NULL);
ast_party_connected_line_free(&connected_caller);
}
}
if (!single && !ast_test_flag64(peerflags, OPT_IGNORE_CONNECTEDLINE)) {
if (o->pending_connected_update) {
if (ast_channel_connected_line_macro(c, in, &o->connected, 1, 0)) {
- ast_channel_update_connected_line(in, &o->connected);
+ ast_channel_update_connected_line(in, &o->connected, NULL);
}
} else if (!ast_test_flag64(o, DIAL_CALLERID_ABSENT)) {
ast_channel_lock(c);
- ast_connected_line_copy_from_caller(&connected_caller, &c->cid);
+ ast_connected_line_copy_from_caller(&connected_caller, &c->caller);
ast_channel_unlock(c);
connected_caller.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
- ast_channel_update_connected_line(in, &connected_caller);
+ ast_channel_update_connected_line(in, &connected_caller, NULL);
ast_party_connected_line_free(&connected_caller);
}
}
ast_verb(3, "%s connected line has changed. Saving it until answer for %s\n", c->name, in->name);
ast_party_connected_line_set_init(&connected, &o->connected);
ast_connected_line_parse_data(f->data.ptr, f->datalen, &connected);
- ast_party_connected_line_set(&o->connected, &connected);
+ ast_party_connected_line_set(&o->connected, &connected, NULL);
ast_party_connected_line_free(&connected);
o->pending_connected_update = 1;
} else {
char *l;
int silencethreshold;
- if (!ast_strlen_zero(chan->cid.cid_num)) {
- l = ast_strdupa(chan->cid.cid_num);
+ if (chan->caller.id.number.valid
+ && !ast_strlen_zero(chan->caller.id.number.str)) {
+ l = ast_strdupa(chan->caller.id.number.str);
ast_shrink_phone_number(l);
if (ast_test_flag64(opts, OPT_PRIVACY) ) {
ast_verb(3, "Privacy DB is '%s', clid is '%s'\n", opt_args[OPT_ARG_PRIVACY], l);
memset(&tc->whentohangup, 0, sizeof(tc->whentohangup));
/* If the new channel has no callerid, try to guess what it should be */
- if (ast_strlen_zero(tc->cid.cid_num)) {
- if (!ast_strlen_zero(chan->connected.id.number)) {
- ast_set_callerid(tc, chan->connected.id.number, chan->connected.id.name, chan->connected.ani);
- } else if (!ast_strlen_zero(chan->cid.cid_dnid)) {
- ast_set_callerid(tc, chan->cid.cid_dnid, NULL, NULL);
+ if (!tc->caller.id.number.valid) {
+ if (chan->connected.id.number.valid) {
+ struct ast_party_caller caller;
+
+ ast_party_caller_set_init(&caller, &tc->caller);
+ caller.id = chan->connected.id;
+ caller.ani = chan->connected.ani;
+ ast_channel_set_caller_event(tc, &caller, NULL);
+ } else if (!ast_strlen_zero(chan->dialed.number.str)) {
+ ast_set_callerid(tc, chan->dialed.number.str, NULL, NULL);
} else if (!ast_strlen_zero(S_OR(chan->macroexten, chan->exten))) {
ast_set_callerid(tc, S_OR(chan->macroexten, chan->exten), NULL, NULL);
}
int pres;
ast_party_connected_line_set_init(&connected, &tmp->chan->connected);
- connected.id.number = cid_num;
- connected.id.name = cid_name;
- connected.id.tag = cid_tag;
if (cid_pres) {
pres = ast_parse_caller_presentation(cid_pres);
- if (pres >= 0) {
- connected.id.number_presentation = pres;
+ if (pres < 0) {
+ pres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN;
}
} else {
- connected.id.number_presentation = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN;
+ pres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN;
+ }
+ if (cid_num) {
+ connected.id.number.valid = 1;
+ connected.id.number.str = cid_num;
+ connected.id.number.presentation = pres;
}
- ast_channel_set_connected_line(tmp->chan, &connected);
+ if (cid_name) {
+ connected.id.name.valid = 1;
+ connected.id.name.str = cid_name;
+ connected.id.name.presentation = pres;
+ }
+ connected.id.tag = cid_tag;
+ ast_channel_set_connected_line(tmp->chan, &connected, NULL);
} else {
- ast_connected_line_copy_from_caller(&tc->connected, &chan->cid);
+ ast_connected_line_copy_from_caller(&tc->connected, &chan->caller);
}
ast_party_redirecting_copy(&tc->redirecting, &chan->redirecting);
- tc->cid.cid_tns = chan->cid.cid_tns;
+ tc->dialed.transit_network_select = chan->dialed.transit_network_select;
if (!ast_strlen_zero(chan->accountcode)) {
ast_string_field_set(tc, peeraccount, chan->accountcode);
strcpy(peer->context, chan->context);
- if (ast_test_flag64(&opts, OPT_PEER_H) && ast_exists_extension(peer, peer->context, "h", 1, peer->cid.cid_num)) {
+ if (ast_test_flag64(&opts, OPT_PEER_H)
+ && ast_exists_extension(peer, peer->context, "h", 1,
+ S_COR(peer->caller.id.number.valid, peer->caller.id.number.str, NULL))) {
int autoloopflag;
int found;
int res9;
autoloopflag = ast_test_flag(peer, AST_FLAG_IN_AUTOLOOP); /* save value to restore at the end */
ast_set_flag(peer, AST_FLAG_IN_AUTOLOOP);
- while ((res9 = ast_spawn_extension(peer, peer->context, peer->exten, peer->priority, peer->cid.cid_num, &found, 1)) == 0)
+ while ((res9 = ast_spawn_extension(peer, peer->context, peer->exten,
+ peer->priority,
+ S_COR(peer->caller.id.number.valid, peer->caller.id.number.str, NULL),
+ &found, 1)) == 0) {
peer->priority++;
+ }
if (found && res9) {
/* Something bad happened, or a hangup has been requested. */
ast_party_connected_line_copy(&connected_caller, &target->connected);
connected_caller.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
if (ast_channel_connected_line_macro(NULL, chan, &connected_caller, 0, 0)) {
- ast_channel_update_connected_line(chan, &connected_caller);
+ ast_channel_update_connected_line(chan, &connected_caller, NULL);
}
ast_party_connected_line_free(&connected_caller);
ast_channel_lock(chan);
- ast_connected_line_copy_from_caller(&connected_caller, &chan->cid);
+ ast_connected_line_copy_from_caller(&connected_caller, &chan->caller);
ast_channel_unlock(chan);
connected_caller.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
- ast_channel_queue_connected_line_update(chan, &connected_caller);
+ ast_channel_queue_connected_line_update(chan, &connected_caller, NULL);
ast_party_connected_line_free(&connected_caller);
if ((res = ast_answer(chan))) {
}
} else {
if (j == '#') { /* end of extension .. maybe */
- if (i == 0 &&
- (ast_matchmore_extension(chan, args.context, "#", 1, chan->cid.cid_num) ||
- ast_exists_extension(chan, args.context, "#", 1, chan->cid.cid_num)) ) {
+ if (i == 0
+ && (ast_matchmore_extension(chan, args.context, "#", 1,
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))
+ || ast_exists_extension(chan, args.context, "#", 1,
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) ) {
/* Let the # be the part of, or the entire extension */
} else {
break;
}
/* if can do some more, do it */
- if (!ast_matchmore_extension(chan,args.context,exten,1, chan->cid.cid_num)) {
+ if (!ast_matchmore_extension(chan, args.context, exten, 1,
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) {
break;
}
}
int recheck = 0;
struct ast_flags cdr_flags = { AST_CDR_FLAG_POSTED };
- if (!ast_exists_extension(chan, args.context, exten, 1, chan->cid.cid_num)) {
+ if (!ast_exists_extension(chan, args.context, exten, 1,
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) {
pbx_builtin_setvar_helper(chan, "INVALID_EXTEN", exten);
exten[0] = 'i';
exten[1] = '\0';
recheck = 1;
}
- if (!recheck || ast_exists_extension(chan, args.context, exten, 1, chan->cid.cid_num)) {
+ if (!recheck
+ || ast_exists_extension(chan, args.context, exten, 1,
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) {
ast_playtones_stop(chan);
/* We're authenticated and have a target extension */
if (!ast_strlen_zero(args.cid)) {
c->name,
c->tech->type,
c->uniqueid,
- S_OR(c->cid.cid_num, "(N/A)"),
- S_OR(c->cid.cid_name, "(N/A)"),
- S_OR(c->cid.cid_dnid, "(N/A)"),
- S_OR(c->redirecting.from.number, "(N/A)"),
+ S_COR(c->caller.id.number.valid, c->caller.id.number.str, "(N/A)"),
+ S_COR(c->caller.id.name.valid, c->caller.id.name.str, "(N/A)"),
+ S_OR(c->dialed.number.str, "(N/A)"),
+ S_COR(c->redirecting.from.number.valid, c->redirecting.from.number.str, "(N/A)"),
c->parkinglot,
c->language,
ast_state2str(c->_state),
ast_debug(1, " Transfer Rate: %d\n", stat.bit_rate);
ast_manager_event(s->chan, EVENT_FLAG_CALL,
- s->direction ? "FaxSent" : "FaxReceived",
- "Channel: %s\r\n"
- "Exten: %s\r\n"
- "CallerID: %s\r\n"
- "RemoteStationID: %s\r\n"
- "LocalStationID: %s\r\n"
- "PagesTransferred: %d\r\n"
- "Resolution: %d\r\n"
- "TransferRate: %d\r\n"
- "FileName: %s\r\n",
- s->chan->name,
- s->chan->exten,
- S_OR(s->chan->cid.cid_num, ""),
- far_ident,
- local_ident,
- pages_transferred,
- stat.y_resolution,
- stat.bit_rate,
- s->file_name);
+ s->direction ? "FaxSent" : "FaxReceived",
+ "Channel: %s\r\n"
+ "Exten: %s\r\n"
+ "CallerID: %s\r\n"
+ "RemoteStationID: %s\r\n"
+ "LocalStationID: %s\r\n"
+ "PagesTransferred: %d\r\n"
+ "Resolution: %d\r\n"
+ "TransferRate: %d\r\n"
+ "FileName: %s\r\n",
+ s->chan->name,
+ s->chan->exten,
+ S_COR(s->chan->caller.id.number.valid, s->chan->caller.id.number.str, ""),
+ far_ident,
+ local_ident,
+ pages_transferred,
+ stat.y_resolution,
+ stat.bit_rate,
+ s->file_name);
}
/* === Helper functions to configure fax === */
outbound = ast_request("Local", ast_best_codec(caller->nativeformats), caller, dialarg, &dg);
if (outbound) {
- ast_set_callerid(outbound, caller->cid.cid_num, caller->cid.cid_name, caller->cid.cid_num);
+ ast_set_callerid(outbound,
+ S_COR(caller->caller.id.number.valid, caller->caller.id.number.str, NULL),
+ S_COR(caller->caller.id.name.valid, caller->caller.id.name.str, NULL),
+ S_COR(caller->caller.id.number.valid, caller->caller.id.number.str, NULL));
ast_channel_inherit_variables(tpargs->chan, outbound);
ast_channel_datastore_inherit(tpargs->chan, outbound);
ast_string_field_set(outbound, language, tpargs->chan->language);
}
snprintf(fullmacro, sizeof(fullmacro), "macro-%s", macro);
- if (!ast_exists_extension(chan, fullmacro, "s", 1, chan->cid.cid_num)) {
+ if (!ast_exists_extension(chan, fullmacro, "s", 1,
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) {
if (!ast_context_find(fullmacro))
ast_log(LOG_WARNING, "No such context '%s' for macro '%s'\n", fullmacro, macro);
else
ast_channel_unlock(chan);
autoloopflag = ast_test_flag(chan, AST_FLAG_IN_AUTOLOOP);
ast_set_flag(chan, AST_FLAG_IN_AUTOLOOP);
- while(ast_exists_extension(chan, chan->context, chan->exten, chan->priority, chan->cid.cid_num)) {
+ while (ast_exists_extension(chan, chan->context, chan->exten, chan->priority,
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) {
struct ast_context *c;
struct ast_exten *e;
int foundx;
if (ast_rdlock_context(c)) {
ast_log(LOG_WARNING, "Unable to lock context?\n");
} else {
- e = find_matching_priority(c, chan->exten, chan->priority, chan->cid.cid_num);
+ e = find_matching_priority(c, chan->exten, chan->priority,
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL));
if (e) { /* This will only be undefined for pbx_realtime, which is majorly broken. */
ast_copy_string(runningapp, ast_get_extension_app(e), sizeof(runningapp));
ast_copy_string(runningdata, ast_get_extension_app_data(e), sizeof(runningdata));
/* Reset the macro depth, if it was changed in the last iteration */
pbx_builtin_setvar_helper(chan, "MACRO_DEPTH", depthc);
- if ((res = ast_spawn_extension(chan, chan->context, chan->exten, chan->priority, chan->cid.cid_num, &foundx,1))) {
+ res = ast_spawn_extension(chan, chan->context, chan->exten, chan->priority,
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL),
+ &foundx, 1);
+ if (res) {
/* Something bad happened, or a hangup has been requested. */
if (((res >= '0') && (res <= '9')) || ((res >= 'A') && (res <= 'F')) ||
(res == '*') || (res == '#')) {
/* Handle macro offset if it's set by checking the availability of step n + offset + 1, otherwise continue
normally if there is any problem */
if (sscanf(offsets, "%30d", &offset) == 1) {
- if (ast_exists_extension(chan, chan->context, chan->exten, chan->priority + offset + 1, chan->cid.cid_num)) {
+ if (ast_exists_extension(chan, chan->context, chan->exten,
+ chan->priority + offset + 1,
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) {
chan->priority += offset;
}
}
if (!concise) {
ast_cli(a->fd, "User #: %-2.2d %12.12s %-20.20s Channel: %s %s %s %s %s %s %02d:%02d:%02d\n",
user->user_no,
- S_OR(user->chan->cid.cid_num, "<unknown>"),
- S_OR(user->chan->cid.cid_name, "<no name>"),
+ S_COR(user->chan->caller.id.number.valid, user->chan->caller.id.number.str, "<unknown>"),
+ S_COR(user->chan->caller.id.name.valid, user->chan->caller.id.name.str, "<no name>"),
user->chan->name,
ast_test_flag64(&user->userflags, CONFFLAG_ADMIN) ? "(Admin)" : "",
ast_test_flag64(&user->userflags, CONFFLAG_MONITOR) ? "(Listen only)" : "",
} else {
ast_cli(a->fd, "%d!%s!%s!%s!%s!%s!%s!%s!%d!%02d:%02d:%02d\n",
user->user_no,
- S_OR(user->chan->cid.cid_num, ""),
- S_OR(user->chan->cid.cid_name, ""),
+ S_COR(user->chan->caller.id.number.valid, user->chan->caller.id.number.str, ""),
+ S_COR(user->chan->caller.id.name.valid, user->chan->caller.id.name.str, ""),
user->chan->name,
ast_test_flag64(&user->userflags, CONFFLAG_ADMIN) ? "1" : "",
ast_test_flag64(&user->userflags, CONFFLAG_MONITOR) ? "1" : "",
if (!sent_event) {
ast_manager_event(chan, EVENT_FLAG_CALL, "MeetmeJoin",
- "Channel: %s\r\n"
- "Uniqueid: %s\r\n"
- "Meetme: %s\r\n"
- "Usernum: %d\r\n"
- "CallerIDnum: %s\r\n"
- "CallerIDname: %s\r\n",
- chan->name, chan->uniqueid, conf->confno,
- user->user_no,
- S_OR(user->chan->cid.cid_num, "<unknown>"),
- S_OR(user->chan->cid.cid_name, "<unknown>")
- );
+ "Channel: %s\r\n"
+ "Uniqueid: %s\r\n"
+ "Meetme: %s\r\n"
+ "Usernum: %d\r\n"
+ "CallerIDnum: %s\r\n"
+ "CallerIDname: %s\r\n",
+ chan->name, chan->uniqueid, conf->confno,
+ user->user_no,
+ S_COR(user->chan->caller.id.number.valid, user->chan->caller.id.number.str, "<unknown>"),
+ S_COR(user->chan->caller.id.name.valid, user->chan->caller.id.name.str, "<unknown>")
+ );
sent_event = 1;
}
if (sent_event) {
ast_manager_event(chan, EVENT_FLAG_CALL, "MeetmeLeave",
- "Channel: %s\r\n"
- "Uniqueid: %s\r\n"
- "Meetme: %s\r\n"
- "Usernum: %d\r\n"
- "CallerIDNum: %s\r\n"
- "CallerIDName: %s\r\n"
- "Duration: %ld\r\n",
- chan->name, chan->uniqueid, conf->confno,
- user->user_no,
- S_OR(user->chan->cid.cid_num, "<unknown>"),
- S_OR(user->chan->cid.cid_name, "<unknown>"),
- (long)(now.tv_sec - user->jointime));
+ "Channel: %s\r\n"
+ "Uniqueid: %s\r\n"
+ "Meetme: %s\r\n"
+ "Usernum: %d\r\n"
+ "CallerIDNum: %s\r\n"
+ "CallerIDName: %s\r\n"
+ "Duration: %ld\r\n",
+ chan->name, chan->uniqueid, conf->confno,
+ user->user_no,
+ S_COR(user->chan->caller.id.number.valid, user->chan->caller.id.number.str, "<unknown>"),
+ S_COR(user->chan->caller.id.name.valid, user->chan->caller.id.name.str, "<unknown>"),
+ (long)(now.tv_sec - user->jointime));
}
if (setusercount) {
while ((user = ao2_iterator_next(&user_iter))) {
total++;
astman_append(s,
- "Event: MeetmeList\r\n"
- "%s"
- "Conference: %s\r\n"
- "UserNumber: %d\r\n"
- "CallerIDNum: %s\r\n"
- "CallerIDName: %s\r\n"
- "Channel: %s\r\n"
- "Admin: %s\r\n"
- "Role: %s\r\n"
- "MarkedUser: %s\r\n"
- "Muted: %s\r\n"
- "Talking: %s\r\n"
- "\r\n",
- idText,
- cnf->confno,
- user->user_no,
- S_OR(user->chan->cid.cid_num, "<unknown>"),
- S_OR(user->chan->cid.cid_name, "<no name>"),
- user->chan->name,
- ast_test_flag64(&user->userflags, CONFFLAG_ADMIN) ? "Yes" : "No",
- ast_test_flag64(&user->userflags, CONFFLAG_MONITOR) ? "Listen only" : ast_test_flag64(&user->userflags, CONFFLAG_TALKER) ? "Talk only" : "Talk and listen",
- ast_test_flag64(&user->userflags, CONFFLAG_MARKEDUSER) ? "Yes" : "No",
- user->adminflags & ADMINFLAG_MUTED ? "By admin" : user->adminflags & ADMINFLAG_SELFMUTED ? "By self" : "No",
- user->talking > 0 ? "Yes" : user->talking == 0 ? "No" : "Not monitored");
+ "Event: MeetmeList\r\n"
+ "%s"
+ "Conference: %s\r\n"
+ "UserNumber: %d\r\n"
+ "CallerIDNum: %s\r\n"
+ "CallerIDName: %s\r\n"
+ "Channel: %s\r\n"
+ "Admin: %s\r\n"
+ "Role: %s\r\n"
+ "MarkedUser: %s\r\n"
+ "Muted: %s\r\n"
+ "Talking: %s\r\n"
+ "\r\n",
+ idText,
+ cnf->confno,
+ user->user_no,
+ S_COR(user->chan->caller.id.number.valid, user->chan->caller.id.number.str, "<unknown>"),
+ S_COR(user->chan->caller.id.name.valid, user->chan->caller.id.name.str, "<no name>"),
+ user->chan->name,
+ ast_test_flag64(&user->userflags, CONFFLAG_ADMIN) ? "Yes" : "No",
+ ast_test_flag64(&user->userflags, CONFFLAG_MONITOR) ? "Listen only" : ast_test_flag64(&user->userflags, CONFFLAG_TALKER) ? "Talk only" : "Talk and listen",
+ ast_test_flag64(&user->userflags, CONFFLAG_MARKEDUSER) ? "Yes" : "No",
+ user->adminflags & ADMINFLAG_MUTED ? "By admin" : user->adminflags & ADMINFLAG_SELFMUTED ? "By self" : "No",
+ user->talking > 0 ? "Yes" : user->talking == 0 ? "No" : "Not monitored");
ao2_ref(user, -1);
}
ao2_iterator_destroy(&user_iter);
char *tech, *tech_data;
struct ast_dial *dial;
struct sla_ringing_station *ringing_station;
- const char *cid_name = NULL, *cid_num = NULL;
enum ast_dial_result res;
+ int caller_is_saved;
+ struct ast_party_caller caller;
if (!(dial = ast_dial_create()))
return -1;
return -1;
}
- if (!sla.attempt_callerid && !ast_strlen_zero(ringing_trunk->trunk->chan->cid.cid_name)) {
- cid_name = ast_strdupa(ringing_trunk->trunk->chan->cid.cid_name);
- ast_free(ringing_trunk->trunk->chan->cid.cid_name);
- ringing_trunk->trunk->chan->cid.cid_name = NULL;
- }
- if (!sla.attempt_callerid && !ast_strlen_zero(ringing_trunk->trunk->chan->cid.cid_num)) {
- cid_num = ast_strdupa(ringing_trunk->trunk->chan->cid.cid_num);
- ast_free(ringing_trunk->trunk->chan->cid.cid_num);
- ringing_trunk->trunk->chan->cid.cid_num = NULL;
+ /* Do we need to save off the caller ID data? */
+ caller_is_saved = 0;
+ if (!sla.attempt_callerid) {
+ caller_is_saved = 1;
+ caller = ringing_trunk->trunk->chan->caller;
+ ast_party_caller_init(&ringing_trunk->trunk->chan->caller);
}
res = ast_dial_run(dial, ringing_trunk->trunk->chan, 1);
- if (cid_name)
- ringing_trunk->trunk->chan->cid.cid_name = ast_strdup(cid_name);
- if (cid_num)
- ringing_trunk->trunk->chan->cid.cid_num = ast_strdup(cid_num);
+ /* Restore saved caller ID */
+ if (caller_is_saved) {
+ ast_party_caller_free(&ringing_trunk->trunk->chan->caller);
+ ringing_trunk->trunk->chan->caller = caller;
+ }
if (res != AST_DIAL_RESULT_TRYING) {
struct sla_failed_station *failed_station;
struct ast_conference *conf;
struct ast_flags64 conf_flags = { 0 };
struct sla_trunk_ref *trunk_ref = args->trunk_ref;
- const char *cid_name = NULL, *cid_num = NULL;
+ int caller_is_saved;
+ struct ast_party_caller caller;
if (!(dial = ast_dial_create())) {
ast_mutex_lock(args->cond_lock);
return NULL;
}
- if (!sla.attempt_callerid && !ast_strlen_zero(trunk_ref->chan->cid.cid_name)) {
- cid_name = ast_strdupa(trunk_ref->chan->cid.cid_name);
- ast_free(trunk_ref->chan->cid.cid_name);
- trunk_ref->chan->cid.cid_name = NULL;
- }
- if (!sla.attempt_callerid && !ast_strlen_zero(trunk_ref->chan->cid.cid_num)) {
- cid_num = ast_strdupa(trunk_ref->chan->cid.cid_num);
- ast_free(trunk_ref->chan->cid.cid_num);
- trunk_ref->chan->cid.cid_num = NULL;
+ /* Do we need to save of the caller ID data? */
+ caller_is_saved = 0;
+ if (!sla.attempt_callerid) {
+ caller_is_saved = 1;
+ caller = trunk_ref->chan->caller;
+ ast_party_caller_init(&trunk_ref->chan->caller);
}
dial_res = ast_dial_run(dial, trunk_ref->chan, 1);
- if (cid_name)
- trunk_ref->chan->cid.cid_name = ast_strdup(cid_name);
- if (cid_num)
- trunk_ref->chan->cid.cid_num = ast_strdup(cid_num);
+ /* Restore saved caller ID */
+ if (caller_is_saved) {
+ ast_party_caller_free(&trunk_ref->chan->caller);
+ trunk_ref->chan->caller = caller;
+ }
if (dial_res != AST_DIAL_RESULT_TRYING) {
ast_mutex_lock(args->cond_lock);
snprintf(arguments, sizeof(arguments), "%s %s@%s %s %s&",
ast_strlen_zero(vmu->externnotify) ? global_externnotify : vmu->externnotify,
vmu->username, vmu->domain,
- chan->cid.cid_name, chan->cid.cid_num);
+ (chan->caller.id.name.valid && chan->caller.id.name.str)
+ ? chan->caller.id.name.str : "",
+ (chan->caller.id.number.valid && chan->caller.id.number.str)
+ ? chan->caller.id.number.str : "");
ast_debug(1, "Executing: %s\n", arguments);
ast_safe_system(arguments);
ast_localtime(&now, &tm, NULL);
ast_strftime(timebuf, sizeof(timebuf), "%H:%M:%S", &tm);
+ ast_callerid_merge(callerid, sizeof(callerid),
+ S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL),
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL),
+ "Unknown");
snprintf(logbuf, sizeof(logbuf),
/* "Mailbox:domain:macrocontext:exten:priority:callerchan:callerid:origdate:origtime:duration:durationstatus:accountcode" */
"%s:%s:%s:%s:%d:%s:%s:%s:%s:%d:%s:%s\n",
chan->exten,
chan->priority,
chan->name,
- ast_callerid_merge(callerid, sizeof(callerid), chan->cid.cid_name, chan->cid.cid_num, "Unknown"),
+ callerid,
date,
timebuf,
duration,
duration_string = ast_strdupa(duration_string);
}
ast_channel_unlock(chan);
- res = notify_new_message(chan, template, vmu, filename, atoi(duration_string), format, chan->cid.cid_num, chan->cid.cid_name);
+ res = notify_new_message(chan, template, vmu, filename, atoi(duration_string),
+ format,
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL),
+ S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL));
}
pbx_builtin_setvar_helper(chan, "MVM_NOTIFY_STATUS", res == 0 ? "SUCCESS" : "FAILED");
/* Check current or macro-calling context for special extensions */
if (ast_test_flag(vmu, MVM_OPERATOR)) {
if (!ast_strlen_zero(vmu->exit)) {
- if (ast_exists_extension(chan, vmu->exit, "o", 1, chan->cid.cid_num)) {
+ if (ast_exists_extension(chan, vmu->exit, "o", 1,
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) {
strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1);
ouseexten = 1;
}
- } else if (ast_exists_extension(chan, chan->context, "o", 1, chan->cid.cid_num)) {
+ } else if (ast_exists_extension(chan, chan->context, "o", 1,
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) {
strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1);
ouseexten = 1;
}
- else if (!ast_strlen_zero(chan->macrocontext) && ast_exists_extension(chan, chan->macrocontext, "o", 1, chan->cid.cid_num)) {
+ else if (!ast_strlen_zero(chan->macrocontext)
+ && ast_exists_extension(chan, chan->macrocontext, "o", 1,
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) {
strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1);
ousemacro = 1;
}
}
if (!ast_strlen_zero(vmu->exit)) {
- if (ast_exists_extension(chan, vmu->exit, "a", 1, chan->cid.cid_num))
+ if (ast_exists_extension(chan, vmu->exit, "a", 1,
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) {
strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1);
- } else if (ast_exists_extension(chan, chan->context, "a", 1, chan->cid.cid_num))
+ }
+ } else if (ast_exists_extension(chan, chan->context, "a", 1,
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) {
strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1);
- else if (!ast_strlen_zero(chan->macrocontext) && ast_exists_extension(chan, chan->macrocontext, "a", 1, chan->cid.cid_num)) {
+ } else if (!ast_strlen_zero(chan->macrocontext)
+ && ast_exists_extension(chan, chan->macrocontext, "a", 1,
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) {
strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1);
ausemacro = 1;
}
ast_debug(1, "OSPAuth: source '%s'\n", source);
ast_debug(1, "OSPAuth: token size '%zd'\n", strlen(token));
- if ((res = osp_auth(provider, &handle, source, chan->cid.cid_num, chan->exten, token, &timelimit)) > 0) {
+ res = osp_auth(provider, &handle, source,
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL),
+ chan->exten, token, &timelimit);
+ if (res > 0) {
status = AST_OSP_SUCCESS;
} else {
timelimit = OSP_DEF_TIMELIMIT;
return OSP_AST_ERROR;
}
- if ((res = osp_lookup(provider, callidtypes, actualsrc, srcdev, chan->cid.cid_num, args.exten, snetid, &np, &div, cinfo, &results)) > 0) {
+ res = osp_lookup(provider, callidtypes, actualsrc, srcdev,
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL),
+ args.exten, snetid, &np, &div, cinfo, &results);
+ if (res > 0) {
status = AST_OSP_SUCCESS;
} else {
results.tech[0] = '\0';
ast_parseable_goto(chan, args.return_context);
}
- ast_verb(3, "Return Context: (%s,%s,%d) ID: %s\n", chan->context, chan->exten, chan->priority, chan->cid.cid_num);
- if (!ast_exists_extension(chan, chan->context, chan->exten, chan->priority, chan->cid.cid_num)) {
+ ast_verb(3, "Return Context: (%s,%s,%d) ID: %s\n", chan->context, chan->exten,
+ chan->priority,
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, ""));
+ if (!ast_exists_extension(chan, chan->context, chan->exten, chan->priority,
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) {
ast_verb(3, "Warning: Return Context Invalid, call will return to default|s\n");
- }
+ }
/* we are using masq_park here to protect * from touching the channel once we park it. If the channel comes out of timeout
before we are done announcing and the channel is messed with, Kablooeee. So we use Masq to prevent this. */
snprintf(buf, sizeof(buf), "%d", lot);
oh.parent_channel = chan;
oh.vars = ast_variable_new("_PARKEDAT", buf, "");
- dchan = __ast_request_and_dial(dialtech, AST_FORMAT_SLINEAR, chan, args.dial, 30000, &outstate, chan->cid.cid_num, chan->cid.cid_name, &oh);
-
+ dchan = __ast_request_and_dial(dialtech, AST_FORMAT_SLINEAR, chan, args.dial, 30000,
+ &outstate,
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL),
+ S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL),
+ &oh);
if (dchan) {
if (dchan->_state == AST_STATE_UP) {
ast_verb(4, "Channel %s was answered.\n", dchan->name);
AST_APP_ARG(checkcontext);
);
- if (!ast_strlen_zero(chan->cid.cid_num)) {
- ast_verb(3, "CallerID Present: Skipping\n");
+ if (chan->caller.id.number.valid
+ && !ast_strlen_zero(chan->caller.id.number.str)) {
+ ast_verb(3, "CallerID number present: Skipping\n");
} else {
/*Answer the channel if it is not already*/
if (chan->_state != AST_STATE_UP) {
res = ast_waitstream(chan, "");
}
- ast_set_callerid(chan, phone, "Privacy Manager", NULL);
-
- /* Clear the unavailable presence bit so if it came in on PRI
- * the caller id will now be passed out to other channels
+ /*
+ * This is a caller entered number that is going to be used locally.
+ * Therefore, the given number presentation is allowed and should
+ * be passed out to other channels. This is the point of the
+ * privacy application.
*/
- chan->cid.cid_pres &= (AST_PRES_UNAVAILABLE ^ 0xFF);
+ chan->caller.id.name.presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
+ chan->caller.id.number.presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
+ chan->caller.id.number.plan = 0;/* Unknown */
+
+ ast_set_callerid(chan, phone, "Privacy Manager", NULL);
- ast_verb(3, "Changed Caller*ID to '%s', callerpres to %d\n", phone, chan->cid.cid_pres);
+ ast_verb(3, "Changed Caller*ID number to '%s'\n", phone);
pbx_builtin_setvar_helper(chan, "PRIVACYMGRSTATUS", "SUCCESS");
} else {
ast_manager_event(qe->chan, EVENT_FLAG_CALL, "Join",
"Channel: %s\r\nCallerIDNum: %s\r\nCallerIDName: %s\r\nQueue: %s\r\nPosition: %d\r\nCount: %d\r\nUniqueid: %s\r\n",
qe->chan->name,
- S_OR(qe->chan->cid.cid_num, "unknown"), /* XXX somewhere else it is <unknown> */
- S_OR(qe->chan->cid.cid_name, "unknown"),
+ S_COR(qe->chan->caller.id.number.valid, qe->chan->caller.id.number.str, "unknown"),/* XXX somewhere else it is <unknown> */
+ S_COR(qe->chan->caller.id.name.valid, qe->chan->caller.id.name.str, "unknown"),
q->name, qe->pos, q->count, qe->chan->uniqueid );
ast_debug(1, "Queue '%s' Join, Channel '%s', Position '%d'\n", q->name, qe->chan->name, qe->pos );
}
return 0;
/* If the extension is bad, then reset the digits to blank */
- if (!ast_canmatch_extension(qe->chan, qe->context, qe->digits, 1, qe->chan->cid.cid_num)) {
+ if (!ast_canmatch_extension(qe->chan, qe->context, qe->digits, 1,
+ S_COR(qe->chan->caller.id.number.valid, qe->chan->caller.id.number.str, NULL))) {
qe->digits[0] = '\0';
return 0;
}
memset(&tmp->chan->whentohangup, 0, sizeof(tmp->chan->whentohangup));
/* If the new channel has no callerid, try to guess what it should be */
- if (ast_strlen_zero(tmp->chan->cid.cid_num)) {
- if (!ast_strlen_zero(qe->chan->connected.id.number)) {
- ast_set_callerid(tmp->chan, qe->chan->connected.id.number, qe->chan->connected.id.name, qe->chan->connected.ani);
- tmp->chan->cid.cid_pres = qe->chan->connected.id.number_presentation;
- } else if (!ast_strlen_zero(qe->chan->cid.cid_dnid)) {
- ast_set_callerid(tmp->chan, qe->chan->cid.cid_dnid, NULL, NULL);
+ if (!tmp->chan->caller.id.number.valid) {
+ if (qe->chan->connected.id.number.valid) {
+ struct ast_party_caller caller;
+
+ ast_party_caller_set_init(&caller, &tmp->chan->caller);
+ caller.id = qe->chan->connected.id;
+ caller.ani = qe->chan->connected.ani;
+ ast_channel_set_caller_event(tmp->chan, &caller, NULL);
+ } else if (!ast_strlen_zero(qe->chan->dialed.number.str)) {
+ ast_set_callerid(tmp->chan, qe->chan->dialed.number.str, NULL, NULL);
} else if (!ast_strlen_zero(S_OR(qe->chan->macroexten, qe->chan->exten))) {
ast_set_callerid(tmp->chan, S_OR(qe->chan->macroexten, qe->chan->exten), NULL, NULL);
}
ast_party_redirecting_copy(&tmp->chan->redirecting, &qe->chan->redirecting);
- tmp->chan->cid.cid_tns = qe->chan->cid.cid_tns;
+ tmp->chan->dialed.transit_network_select = qe->chan->dialed.transit_network_select;
- ast_connected_line_copy_from_caller(&tmp->chan->connected, &qe->chan->cid);
+ ast_connected_line_copy_from_caller(&tmp->chan->connected, &qe->chan->caller);
/* Inherit specially named variables from parent channel */
ast_channel_inherit_variables(qe->chan, tmp->chan);
char vars[2048];
manager_event(EVENT_FLAG_AGENT, "AgentCalled",
- "Queue: %s\r\n"
- "AgentCalled: %s\r\n"
- "AgentName: %s\r\n"
- "ChannelCalling: %s\r\n"
- "DestinationChannel: %s\r\n"
- "CallerIDNum: %s\r\n"
- "CallerIDName: %s\r\n"
- "Context: %s\r\n"
- "Extension: %s\r\n"
- "Priority: %d\r\n"
- "Uniqueid: %s\r\n"
- "%s",
- qe->parent->name, tmp->interface, tmp->member->membername, qe->chan->name, tmp->chan->name,
- tmp->chan->cid.cid_num ? tmp->chan->cid.cid_num : "unknown",
- tmp->chan->cid.cid_name ? tmp->chan->cid.cid_name : "unknown",
- qe->chan->context, qe->chan->exten, qe->chan->priority, qe->chan->uniqueid,
- qe->parent->eventwhencalled == QUEUE_EVENT_VARIABLES ? vars2manager(qe->chan, vars, sizeof(vars)) : "");
+ "Queue: %s\r\n"
+ "AgentCalled: %s\r\n"
+ "AgentName: %s\r\n"
+ "ChannelCalling: %s\r\n"
+ "DestinationChannel: %s\r\n"
+ "CallerIDNum: %s\r\n"
+ "CallerIDName: %s\r\n"
+ "Context: %s\r\n"
+ "Extension: %s\r\n"
+ "Priority: %d\r\n"
+ "Uniqueid: %s\r\n"
+ "%s",
+ qe->parent->name, tmp->interface, tmp->member->membername, qe->chan->name, tmp->chan->name,
+ S_COR(tmp->chan->caller.id.number.valid, tmp->chan->caller.id.number.str, "unknown"),
+ S_COR(tmp->chan->caller.id.name.valid, tmp->chan->caller.id.name.str, "unknown"),
+ qe->chan->context, qe->chan->exten, qe->chan->priority, qe->chan->uniqueid,
+ qe->parent->eventwhencalled == QUEUE_EVENT_VARIABLES ? vars2manager(qe->chan, vars, sizeof(vars)) : "");
ast_verb(3, "Called %s\n", tmp->interface);
}
ast_channel_unlock(tmp->chan);
if (update_connectedline) {
if (o->pending_connected_update) {
if (ast_channel_connected_line_macro(o->chan, in, &o->connected, 1, 0)) {
- ast_channel_update_connected_line(in, &o->connected);
+ ast_channel_update_connected_line(in, &o->connected, NULL);
}
} else if (!o->dial_callerid_absent) {
ast_channel_lock(o->chan);
- ast_connected_line_copy_from_caller(&connected_caller, &o->chan->cid);
+ ast_connected_line_copy_from_caller(&connected_caller, &o->chan->caller);
ast_channel_unlock(o->chan);
connected_caller.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
- ast_channel_update_connected_line(in, &connected_caller);
+ ast_channel_update_connected_line(in, &connected_caller, NULL);
ast_party_connected_line_free(&connected_caller);
}
}
ast_string_field_set(o->chan, accountcode, in->accountcode);
- ast_channel_set_redirecting(o->chan, &original->redirecting);
- if (ast_strlen_zero(o->chan->redirecting.from.number)) {
+ ast_channel_set_redirecting(o->chan, &original->redirecting, NULL);
+ if (!o->chan->redirecting.from.number.valid
+ || ast_strlen_zero(o->chan->redirecting.from.number.str)) {
/*
* The call was not previously redirected so it is
* now redirected from this number.
*/
- ast_free(o->chan->redirecting.from.number);
- o->chan->redirecting.from.number =
+ ast_party_number_free(&o->chan->redirecting.from.number);
+ ast_party_number_init(&o->chan->redirecting.from.number);
+ o->chan->redirecting.from.number.valid = 1;
+ o->chan->redirecting.from.number.str =
ast_strdup(S_OR(in->macroexten, in->exten));
}
- o->chan->cid.cid_tns = in->cid.cid_tns;
+ o->chan->dialed.transit_network_select = in->dialed.transit_network_select;
- ast_party_caller_copy(&o->chan->cid, &in->cid);
+ ast_party_caller_copy(&o->chan->caller, &in->caller);
ast_party_connected_line_copy(&o->chan->connected, &original->connected);
/*
CHANNEL_DEADLOCK_AVOIDANCE(in);
}
if (res) {
- ast_channel_update_redirecting(in, &o->chan->redirecting);
+ ast_channel_update_redirecting(in, &o->chan->redirecting, NULL);
}
update_connectedline = 1;
if (update_connectedline) {
if (o->pending_connected_update) {
if (ast_channel_connected_line_macro(o->chan, in, &o->connected, 1, 0)) {
- ast_channel_update_connected_line(in, &o->connected);
+ ast_channel_update_connected_line(in, &o->connected, NULL);
}
} else if (!o->dial_callerid_absent) {
ast_channel_lock(o->chan);
- ast_connected_line_copy_from_caller(&connected_caller, &o->chan->cid);
+ ast_connected_line_copy_from_caller(&connected_caller, &o->chan->caller);
ast_channel_unlock(o->chan);
connected_caller.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
- ast_channel_update_connected_line(in, &connected_caller);
+ ast_channel_update_connected_line(in, &connected_caller, NULL);
ast_party_connected_line_free(&connected_caller);
}
}
ast_verb(3, "%s connected line has changed. Saving it until answer for %s\n", ochan_name, inchan_name);
ast_party_connected_line_set_init(&connected, &o->connected);
ast_connected_line_parse_data(f->data.ptr, f->datalen, &connected);
- ast_party_connected_line_set(&o->connected, &connected);
+ ast_party_connected_line_set(&o->connected, &connected, NULL);
ast_party_connected_line_free(&connected);
o->pending_connected_update = 1;
} else {
set_queue_result(chan, reason);
return 0;
}
- ast_queue_log(args.queuename, chan->uniqueid, "NONE", "ENTERQUEUE", "%s|%s|%d", S_OR(args.url, ""),
- S_OR(chan->cid.cid_num, ""), qe.opos);
+ ast_queue_log(args.queuename, chan->uniqueid, "NONE", "ENTERQUEUE", "%s|%s|%d",
+ S_OR(args.url, ""),
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, ""),
+ qe.opos);
copy_rules(&qe, args.rule);
qe.pr = AST_LIST_FIRST(&qe.qe_rules);
check_turns:
"%s"
"\r\n",
q->name, pos++, qe->chan->name, qe->chan->uniqueid,
- S_OR(qe->chan->cid.cid_num, "unknown"),
- S_OR(qe->chan->cid.cid_name, "unknown"),
+ S_COR(qe->chan->caller.id.number.valid, qe->chan->caller.id.number.str, "unknown"),
+ S_COR(qe->chan->caller.id.name.valid, qe->chan->caller.id.name.str, "unknown"),
(long) (now - qe->start), idText);
}
}
}
exten[x] = res;
- if (!ast_matchmore_extension(chan, arglist.context, exten, 1 /* priority */, chan->cid.cid_num)) {
- if (!ast_exists_extension(chan, arglist.context, exten, 1, chan->cid.cid_num) && res == '#') {
+ if (!ast_matchmore_extension(chan, arglist.context, exten, 1 /* priority */,
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) {
+ if (!ast_exists_extension(chan, arglist.context, exten, 1,
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))
+ && res == '#') {
exten[x] = '\0';
}
break;
if (!ast_strlen_zero(status))
break;
- if (ast_exists_extension(chan, arglist.context, exten, 1, chan->cid.cid_num)) {
+ if (ast_exists_extension(chan, arglist.context, exten, 1,
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) {
ast_debug(3, "User entered valid extension '%s'\n", exten);
pbx_builtin_setvar_helper(chan, arglist.variable, exten);
status = "OK";
else
priority_int = atoi(args.priority);
- if (ast_exists_extension(chan, args.context, args.extension, priority_int, chan->cid.cid_num))
+ if (ast_exists_extension(chan, args.context, args.extension, priority_int,
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) {
ast_copy_string(buffer, "1", buflen);
- else
+ } else {
ast_copy_string(buffer, "0", buflen);
+ }
return 0;
}
if(instr){
ast_callerid_parse(instr, &name, &loc);
if(loc){
- if(mychannel->cid.cid_num)
- ast_free(mychannel->cid.cid_num);
- mychannel->cid.cid_num = ast_strdup(loc);
+ mychannel->caller.id.number.valid = 1;
+ ast_free(mychannel->caller.id.number.str);
+ mychannel->caller.id.number.str = ast_strdup(loc);
}
if(name){
- if(mychannel->cid.cid_name)
- ast_free(mychannel->cid.cid_name);
- mychannel->cid.cid_name = ast_strdup(name);
+ mychannel->caller.id.name.valid = 1;
+ ast_free(mychannel->caller.id.name.str);
+ mychannel->caller.id.name.str = ast_strdup(name);
}
ast_free(instr);
}
if (debug > 3)
ast_log(LOG_NOTICE, "rpt (remote) initiating call to %s/%s on %s\n",
deststr, tele, l->chan->name);
- if(l->chan->cid.cid_num)
- ast_free(l->chan->cid.cid_num);
- l->chan->cid.cid_num = ast_strdup(myrpt->name);
+ l->chan->caller.id.number.valid = 1;
+ ast_free(l->chan->caller.id.number.str);
+ l->chan->caller.id.number.str = ast_strdup(myrpt->name);
ast_call(l->chan,tele,999);
}
else {
if (option_verbose > 2)
ast_verbose(VERBOSE_PREFIX_3 "rpt (attempt_reconnect) initiating call to %s/%s on %s\n",
deststr, tele, l->chan->name);
- if(l->chan->cid.cid_num)
- ast_free(l->chan->cid.cid_num);
- l->chan->cid.cid_num = ast_strdup(myrpt->name);
+ l->chan->caller.id.number.valid = 1;
+ ast_free(l->chan->caller.id.number.str);
+ l->chan->caller.id.number.str = ast_strdup(myrpt->name);
ast_call(l->chan,tele,999);
}
}
if(option_verbose > 2) {
- ast_verbose( VERBOSE_PREFIX_3 "Return Context: (%s,%s,%d) ID: %s\n", chan->context,chan->exten, chan->priority, chan->cid.cid_num);
- if(!ast_exists_extension(chan, chan->context, chan->exten, chan->priority, chan->cid.cid_num)) {
+ ast_verbose(VERBOSE_PREFIX_3 "Return Context: (%s,%s,%d) ID: %s\n",
+ chan->context, chan->exten, chan->priority,
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, ""));
+ if(!ast_exists_extension(chan, chan->context, chan->exten, chan->priority,
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) {
ast_verbose( VERBOSE_PREFIX_3 "Warning: Return Context Invalid, call will return to default|s\n");
}
}
char hisip[100],nodeip[100],*val, *s, *s1, *s2, *s3, *b,*b1;
/* look at callerid to see what node this comes from */
- if (!chan->cid.cid_num) /* if doesn't have caller id */
+ b = S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL);
+ if (!b) /* if doesn't have caller id */
{
ast_log(LOG_WARNING, "Does not have callerid on %s\n",tmp);
return -1;
return -1;
}
- ast_callerid_parse(chan->cid.cid_num,&b,&b1);
+ b1 = ast_strdupa(b);
ast_shrink_phone_number(b1);
if (!strcmp(myrpt->name,b1))
{
return -1;
}
/* look at callerid to see what node this comes from */
- if (!chan->cid.cid_num) /* if doesn't have caller id */
+ b = S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL);
+ if (!b) /* if doesn't have caller id */
{
ast_log(LOG_WARNING, "Doesnt have callerid on %s\n",tmp);
return -1;
}
- ast_callerid_parse(chan->cid.cid_num,&b,&b1);
+ b1 = ast_strdupa(b);
ast_shrink_phone_number(b1);
if (!strcmp(myrpt->name,b1))
{
ast_cli_command(nullfd,mycmd);
} else ast_cli_command(nullfd,mycmd);
/* look at callerid to see what node this comes from */
- if (!chan->cid.cid_num) /* if doesn't have caller id */
+ b = S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL);
+ if (!b) /* if doesn't have caller id */
{
b1 = "0";
} else {
- ast_callerid_parse(chan->cid.cid_num,&b,&b1);
+ b1 = ast_strdupa(b);
ast_shrink_phone_number(b1);
}
sprintf(mycmd,"CONNECT,%s",b1);
char mycmd[100],*b,*b1;
/* look at callerid to see what node this comes from */
- if (!chan->cid.cid_num) /* if doesn't have caller id */
+ b = S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL);
+ if (!b) /* if doesn't have caller id */
{
b1 = "0";
} else {
- ast_callerid_parse(chan->cid.cid_num,&b,&b1);
+ b1 = ast_strdupa(b);
ast_shrink_phone_number(b1);
}
sprintf(mycmd,"DISCONNECT,%s",b1);
return 0;
}
- chan->cid.cid_pres = pres;
+ /* Set the combined caller id presentation. */
+ chan->caller.id.name.presentation = pres;
+ chan->caller.id.number.presentation = pres;
return 0;
}
h.ipc0 = h.ipc1 = 20; /* phase for cosine */
h.dcs = 0xF1; /* default */
- if (chan->cid.cid_num)
- ast_copy_string(h.cli, chan->cid.cid_num, sizeof(h.cli));
+ ast_copy_string(h.cli,
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, ""),
+ sizeof(h.cli));
if (ast_strlen_zero(sms_args.queue)) {
ast_log(LOG_ERROR, "Requires queue name\n");
return -1;
}
- if (!ast_exists_extension(chan, chan->context, chan->exten, ast_test_flag(chan, AST_FLAG_IN_AUTOLOOP) ? chan->priority + 1 : chan->priority, chan->cid.cid_num)) {
+ if (!ast_exists_extension(chan, chan->context, chan->exten,
+ ast_test_flag(chan, AST_FLAG_IN_AUTOLOOP) ? chan->priority + 1 : chan->priority,
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) {
ast_log(LOG_ERROR, "Attempt to reach a non-existent destination for gosub: (Context:%s, Extension:%s, Priority:%d)\n",
chan->context, chan->exten, ast_test_flag(chan, AST_FLAG_IN_AUTOLOOP) ? chan->priority + 1 : chan->priority);
ast_copy_string(chan->context, newframe->context, sizeof(chan->context));
if (sscanf(argv[3], "%30d", &priority) != 1 || priority < 1) {
/* Lookup the priority label */
- if ((priority = ast_findlabel_extension(chan, argv[1], argv[2], argv[3], chan->cid.cid_num)) < 0) {
+ priority = ast_findlabel_extension(chan, argv[1], argv[2], argv[3],
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL));
+ if (priority < 0) {
ast_log(LOG_ERROR, "Priority '%s' not found in '%s@%s'\n", argv[3], argv[2], argv[1]);
ast_agi_send(agi->fd, chan, "200 result=-1 Gosub label not found\n");
return RESULT_FAILURE;
}
- } else if (!ast_exists_extension(chan, argv[1], argv[2], priority, chan->cid.cid_num)) {
+ } else if (!ast_exists_extension(chan, argv[1], argv[2], priority,
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) {
ast_agi_send(agi->fd, chan, "200 result=-1 Gosub label not found\n");
return RESULT_FAILURE;
}
char t[2];
t[0] = fr->subclass.integer;
t[1] = '\0';
- if (ast_canmatch_extension(chan, chan->context, t, 1, chan->cid.cid_num)) {
+ if (ast_canmatch_extension(chan, chan->context, t, 1,
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) {
/* They entered a valid extension, or might be anyhow */
res = fr->subclass.integer;
ast_frfree(fr);
imap_delete_old_greeting(fn, vms);
}
- make_email_file(p, myserveremail, vmu, msgnum, vmu->context, vmu->mailbox, "INBOX", S_OR(chan->cid.cid_num, NULL), S_OR(chan->cid.cid_name, NULL), fn, introfn, fmt, duration, 1, chan, NULL, 1, flag);
+ make_email_file(p, myserveremail, vmu, msgnum, vmu->context, vmu->mailbox, "INBOX",
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL),
+ S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL),
+ fn, introfn, fmt, duration, 1, chan, NULL, 1, flag);
/* read mail file to memory */
len = ftell(p);
rewind(p);
res = -1;
}
ast_unlock_path(todir);
- notify_new_message(chan, recip, NULL, recipmsgnum, duration, fmt, S_OR(chan->cid.cid_num, NULL), S_OR(chan->cid.cid_name, NULL), flag);
+ notify_new_message(chan, recip, NULL, recipmsgnum, duration, fmt,
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL),
+ S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL),
+ flag);
return res;
}
/* Check current or macro-calling context for special extensions */
if (ast_test_flag(vmu, VM_OPERATOR)) {
if (!ast_strlen_zero(vmu->exit)) {
- if (ast_exists_extension(chan, vmu->exit, "o", 1, chan->cid.cid_num)) {
+ if (ast_exists_extension(chan, vmu->exit, "o", 1,
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) {
strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1);
ouseexten = 1;
}
- } else if (ast_exists_extension(chan, chan->context, "o", 1, chan->cid.cid_num)) {
+ } else if (ast_exists_extension(chan, chan->context, "o", 1,
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) {
strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1);
ouseexten = 1;
- } else if (!ast_strlen_zero(chan->macrocontext) && ast_exists_extension(chan, chan->macrocontext, "o", 1, chan->cid.cid_num)) {
+ } else if (!ast_strlen_zero(chan->macrocontext)
+ && ast_exists_extension(chan, chan->macrocontext, "o", 1,
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) {
strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1);
ousemacro = 1;
}
}
if (!ast_strlen_zero(vmu->exit)) {
- if (ast_exists_extension(chan, vmu->exit, "a", 1, chan->cid.cid_num))
+ if (ast_exists_extension(chan, vmu->exit, "a", 1,
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) {
strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1);
- } else if (ast_exists_extension(chan, chan->context, "a", 1, chan->cid.cid_num))
+ }
+ } else if (ast_exists_extension(chan, chan->context, "a", 1,
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) {
strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1);
- else if (!ast_strlen_zero(chan->macrocontext) && ast_exists_extension(chan, chan->macrocontext, "a", 1, chan->cid.cid_num)) {
+ } else if (!ast_strlen_zero(chan->macrocontext)
+ && ast_exists_extension(chan, chan->macrocontext, "a", 1,
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) {
strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1);
ausemacro = 1;
}
for (code = alldtmf; *code; code++) {
char e[2] = "";
e[0] = *code;
- if (strchr(ecodes, e[0]) == NULL && ast_canmatch_extension(chan, chan->context, e, 1, chan->cid.cid_num))
+ if (strchr(ecodes, e[0]) == NULL
+ && ast_canmatch_extension(chan, chan->context, e, 1,
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) {
strncat(ecodes, e, sizeof(ecodes) - strlen(ecodes) - 1);
+ }
}
}
snprintf(priority, sizeof(priority), "%d", chan->priority);
snprintf(origtime, sizeof(origtime), "%ld", (long) time(NULL));
get_date(date, sizeof(date));
- ast_store_realtime("voicemail_data", "origmailbox", ext, "context", chan->context, "macrocontext", chan->macrocontext, "exten", chan->exten, "priority", priority, "callerchan", chan->name, "callerid", ast_callerid_merge(callerid, sizeof(callerid), chan->cid.cid_name, chan->cid.cid_num, "Unknown"), "origdate", date, "origtime", origtime, "category", S_OR(category, ""), "filename", tmptxtfile, SENTINEL);
+ ast_callerid_merge(callerid, sizeof(callerid),
+ S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL),
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL),
+ "Unknown");
+ ast_store_realtime("voicemail_data",
+ "origmailbox", ext,
+ "context", chan->context,
+ "macrocontext", chan->macrocontext,
+ "exten", chan->exten,
+ "priority", priority,
+ "callerchan", chan->name,
+ "callerid", callerid,
+ "origdate", date,
+ "origtime", origtime,
+ "category", S_OR(category, ""),
+ "filename", tmptxtfile,
+ SENTINEL);
}
/* Store information */
txt = fdopen(txtdes, "w+");
if (txt) {
get_date(date, sizeof(date));
+ ast_callerid_merge(callerid, sizeof(callerid),
+ S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL),
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL),
+ "Unknown");
fprintf(txt,
";\n"
"; Message Information file\n"
chan->context,
chan->macrocontext,
chan->exten,
- S_OR(chan->redirecting.from.number, "unknown"),
+ S_COR(chan->redirecting.from.number.valid,
+ chan->redirecting.from.number.str, "unknown"),
chan->priority,
chan->name,
- ast_callerid_merge(callerid, sizeof(callerid), S_OR(chan->cid.cid_name, NULL), S_OR(chan->cid.cid_num, NULL), "Unknown"),
+ callerid,
date, (long) time(NULL),
category ? category : "");
} else {
/* Notification needs to happen after the copy, though. */
if (ast_fileexists(fn, NULL, NULL)) {
#ifdef IMAP_STORAGE
- notify_new_message(chan, vmu, vms, msgnum, duration, fmt, S_OR(chan->cid.cid_num, NULL), S_OR(chan->cid.cid_name, NULL), flag);
+ notify_new_message(chan, vmu, vms, msgnum, duration, fmt,
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL),
+ S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL),
+ flag);
#else
- notify_new_message(chan, vmu, NULL, msgnum, duration, fmt, S_OR(chan->cid.cid_num, NULL), S_OR(chan->cid.cid_name, NULL), flag);
+ notify_new_message(chan, vmu, NULL, msgnum, duration, fmt,
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL),
+ S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL),
+ flag);
#endif
}
myserveremail = vmtmp->serveremail;
attach_user_voicemail = ast_test_flag(vmtmp, VM_ATTACH);
/* NULL category for IMAP storage */
- sendmail(myserveremail, vmtmp, todircount, vmtmp->context, vmtmp->mailbox, dstvms->curbox, S_OR(chan->cid.cid_num, NULL), S_OR(chan->cid.cid_name, NULL), vmstmp.fn, vmstmp.introfn, fmt, duration, attach_user_voicemail, chan, NULL, urgent_str);
+ sendmail(myserveremail, vmtmp, todircount, vmtmp->context, vmtmp->mailbox,
+ dstvms->curbox,
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL),
+ S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL),
+ vmstmp.fn, vmstmp.introfn, fmt, duration, attach_user_voicemail, chan,
+ NULL, urgent_str);
#else
copy_msg_result = copy_message(chan, sender, 0, curmsg, duration, vmtmp, fmt, dir, urgent_str);
#endif
return -1;
}
if (ast_strlen_zero(mailbox)) {
- if (chan->cid.cid_num) {
- ast_copy_string(mailbox, chan->cid.cid_num, mailbox_size);
+ if (chan->caller.id.number.valid && chan->caller.id.number.str) {
+ ast_copy_string(mailbox, chan->caller.id.number.str, mailbox_size);
} else {
ast_verb(3, "Username not entered\n");
return -1;
}
} else if (mailbox[0] == '*') {
/* user entered '*' */
- if (ast_exists_extension(chan, chan->context, "a", 1, chan->cid.cid_num)) {
+ if (ast_exists_extension(chan, chan->context, "a", 1,
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) {
return -1;
}
mailbox[0] = '\0';
return -1;
} else if (password[0] == '*') {
/* user entered '*' */
- if (ast_exists_extension(chan, chan->context, "a", 1, chan->cid.cid_num)) {
+ if (ast_exists_extension(chan, chan->context, "a", 1,
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) {
mailbox[0] = '*';
return -1;
}
/* This is the matching context we want */
int cur_priority = chan->priority + 1, level=1;
- for (e = find_matching_priority(c, chan->exten, cur_priority, chan->cid.cid_num); e; e = find_matching_priority(c, chan->exten, ++cur_priority, chan->cid.cid_num)) {
+ for (e = find_matching_priority(c, chan->exten, cur_priority,
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL));
+ e;
+ e = find_matching_priority(c, chan->exten, ++cur_priority,
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) {
if (!strcasecmp(ast_get_extension_app(e), "WHILE")) {
level++;
} else if (!strcasecmp(ast_get_extension_app(e), "ENDWHILE")) {
res = ast_safe_sleep(chan, 500);
}
- if (!ast_strlen_zero(chan->cid.cid_num) && nocallerid)
+ if (nocallerid /* Zap caller if no caller id. */
+ && chan->caller.id.number.valid
+ && !ast_strlen_zero(chan->caller.id.number.str)) {
+ /* We have caller id. */
return res;
+ }
if (!res)
res = ast_tonepair(chan, 950, 0, 330, 0);
if (p->chan) {
loginChan = ast_strdupa(p->chan->name);
if (p->owner && p->owner->_bridge) {
- talkingto = p->chan->cid.cid_num;
+ talkingto = S_COR(p->chan->caller.id.number.valid,
+ p->chan->caller.id.number.str, "n/a");
if (ast_bridged_channel(p->owner))
talkingtoChan = ast_strdupa(ast_bridged_channel(p->owner)->name);
else
talkingtoChan = "n/a";
- status = "AGENT_ONCALL";
+ status = "AGENT_ONCALL";
} else {
talkingto = "n/a";
talkingtoChan = "n/a";
- status = "AGENT_IDLE";
+ status = "AGENT_IDLE";
}
} else {
loginChan = "n/a";
if (strchr(data, 'c'))
changeoutgoing = 1;
}
- if (chan->cid.cid_num) {
+ if (chan->caller.id.number.valid
+ && !ast_strlen_zero(chan->caller.id.number.str)) {
const char *tmp;
char agentvar[AST_MAX_BUF];
- snprintf(agentvar, sizeof(agentvar), "%s_%s", GETAGENTBYCALLERID, chan->cid.cid_num);
+ snprintf(agentvar, sizeof(agentvar), "%s_%s", GETAGENTBYCALLERID,
+ chan->caller.id.number.str);
if ((tmp = pbx_builtin_getvar_helper(NULL, agentvar))) {
struct agent_pvt *p;
ast_copy_string(agent, tmp, sizeof(agent));
enum ast_control_frame_type ctrl;
ast_verb(1, V_BEGIN "Call to device '%s' on console from '%s' <%s>" V_END,
- dest, c->cid.cid_name, c->cid.cid_num);
+ dest,
+ S_COR(c->caller.id.name.valid, c->caller.id.name.str, ""),
+ S_COR(c->caller.id.number.valid, c->caller.id.number.str, ""));
console_pvt_lock(pvt);
return 0;
}
-static int my_send_callerid(void *pvt, int cwcid, struct ast_callerid *cid)
+static int my_send_callerid(void *pvt, int cwcid, struct ast_party_caller *caller)
{
struct dahdi_pvt *p = pvt;
if ((p->cidspill = ast_malloc(MAX_CALLERID_SIZE))) {
if (cwcid == 0) {
- p->cidlen = ast_callerid_generate(p->cidspill, cid->cid_name, cid->cid_num, AST_LAW(p));
+ p->cidlen = ast_callerid_generate(p->cidspill,
+ caller->id.name.str,
+ caller->id.number.str,
+ AST_LAW(p));
} else {
p->callwaitcas = 0;
p->cidcwexpire = 0;
- p->cidlen = ast_callerid_callwaiting_generate(p->cidspill, cid->cid_name, cid->cid_num, AST_LAW(p));
+ p->cidlen = ast_callerid_callwaiting_generate(p->cidspill,
+ caller->id.name.str,
+ caller->id.number.str,
+ AST_LAW(p));
p->cidlen += READ_SIZE * 4;
}
p->cidpos = 0;
*/
ast_mutex_unlock(&p->lock);
ast_channel_unlock(ast);
- if (ast_exists_extension(ast, target_context, "fax", 1, ast->cid.cid_num)) {
+ if (ast_exists_extension(ast, target_context, "fax", 1,
+ S_COR(ast->caller.id.number.valid, ast->caller.id.number.str, NULL))) {
ast_channel_lock(ast);
ast_mutex_lock(&p->lock);
ast_verb(3, "Redirecting %s to fax extension\n", ast->name);
{
struct dahdi_pvt *p = pvt;
- ast_copy_string(p->cid_num, S_OR(caller->id.number, ""), sizeof(p->cid_num));
- ast_copy_string(p->cid_name, S_OR(caller->id.name, ""), sizeof(p->cid_name));
+ ast_copy_string(p->cid_num,
+ S_COR(caller->id.number.valid, caller->id.number.str, ""),
+ sizeof(p->cid_num));
+ ast_copy_string(p->cid_name,
+ S_COR(caller->id.name.valid, caller->id.name.str, ""),
+ sizeof(p->cid_name));
if (caller->id.subaddress.valid) {
ast_copy_string(p->cid_subaddr, S_OR(caller->id.subaddress.str, ""),
sizeof(p->cid_subaddr));
} else {
p->cid_subaddr[0] = '\0';
}
- p->cid_ton = caller->id.number_type;
- p->callingpres = caller->id.number_presentation;
+ p->cid_ton = caller->id.number.plan;
+ p->callingpres = ast_party_id_presentation(&caller->id);
if (caller->id.tag) {
ast_copy_string(p->cid_tag, caller->id.tag, sizeof(p->cid_tag));
}
c = "";
}
if (!p->hidecallerid) {
- l = ast->cid.cid_num;
+ l = ast->caller.id.number.valid ? ast->caller.id.number.str : NULL;
} else {
l = NULL;
}
*/
ast_mutex_unlock(&p->lock);
ast_channel_unlock(ast);
- if (ast_exists_extension(ast, target_context, "fax", 1, ast->cid.cid_num)) {
+ if (ast_exists_extension(ast, target_context, "fax", 1,
+ S_COR(ast->caller.id.number.valid, ast->caller.id.number.str, NULL))) {
ast_channel_lock(ast);
ast_mutex_lock(&p->lock);
ast_verb(3, "Redirecting %s to fax extension\n", ast->name);
cid_num[0] = 0;
cid_name[0] = 0;
if (p->dahditrcallerid && p->owner) {
- if (p->owner->cid.cid_num)
- ast_copy_string(cid_num, p->owner->cid.cid_num, sizeof(cid_num));
- if (p->owner->cid.cid_name)
- ast_copy_string(cid_name, p->owner->cid.cid_name, sizeof(cid_name));
+ if (p->owner->caller.id.number.valid
+ && p->owner->caller.id.number.str) {
+ ast_copy_string(cid_num, p->owner->caller.id.number.str,
+ sizeof(cid_num));
+ }
+ if (p->owner->caller.id.name.valid
+ && p->owner->caller.id.name.str) {
+ ast_copy_string(cid_name, p->owner->caller.id.name.str,
+ sizeof(cid_name));
+ }
}
/* XXX This section needs much more error checking!!! XXX */
/* Start a 3-way call if feasible */
case SIG_FEATDMF_TA:
switch (p->whichwink) {
case 0:
- ast_debug(1, "ANI2 set to '%d' and ANI is '%s'\n", p->owner->cid.cid_ani2, p->owner->cid.cid_ani);
- snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*%d%s#", p->owner->cid.cid_ani2, p->owner->cid.cid_ani);
+ ast_debug(1, "ANI2 set to '%d' and ANI is '%s'\n", p->owner->caller.ani2,
+ S_OR(p->owner->caller.ani, ""));
+ snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*%d%s#",
+ p->owner->caller.ani2,
+ S_OR(p->owner->caller.ani, ""));
break;
case 1:
ast_copy_string(p->dop.dialstr, p->finaldial, sizeof(p->dop.dialstr));
tmp->adsicpe = AST_ADSI_UNAVAILABLE;
if (!ast_strlen_zero(i->exten))
ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten));
- if (!ast_strlen_zero(i->rdnis))
- tmp->redirecting.from.number = ast_strdup(i->rdnis);
- if (!ast_strlen_zero(i->dnid))
- tmp->cid.cid_dnid = ast_strdup(i->dnid);
+ if (!ast_strlen_zero(i->rdnis)) {
+ tmp->redirecting.from.number.valid = 1;
+ tmp->redirecting.from.number.str = ast_strdup(i->rdnis);
+ }
+ if (!ast_strlen_zero(i->dnid)) {
+ tmp->dialed.number.str = ast_strdup(i->dnid);
+ }
/* Don't use ast_set_callerid() here because it will
* generate a needless NewCallerID event */
#if defined(HAVE_PRI) || defined(HAVE_SS7)
if (!ast_strlen_zero(i->cid_ani))
- tmp->cid.cid_ani = ast_strdup(i->cid_ani);
+ tmp->caller.ani = ast_strdup(i->cid_ani);
else
- tmp->cid.cid_ani = ast_strdup(i->cid_num);
+ tmp->caller.ani = ast_strdup(i->cid_num);
#else
- tmp->cid.cid_ani = ast_strdup(i->cid_num);
+ tmp->caller.ani = ast_strdup(i->cid_num);
#endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */
- tmp->cid.cid_pres = i->callingpres;
- tmp->cid.cid_ton = i->cid_ton;
- tmp->cid.cid_ani2 = i->cid_ani2;
- tmp->cid.cid_tag = ast_strdup(i->cid_tag);
+ tmp->caller.id.name.presentation = i->callingpres;
+ tmp->caller.id.number.presentation = i->callingpres;
+ tmp->caller.id.number.plan = i->cid_ton;
+ tmp->caller.ani2 = i->cid_ani2;
+ tmp->caller.id.tag = ast_strdup(i->cid_tag);
/* clear the fake event in case we posted one before we had ast_channel */
i->fake_event = 0;
/* Assure there is no confmute on this channel */
}
}
- if (ast_exists_extension(chan, chan->context, exten, 1, chan->cid.cid_num)) {
+ if (ast_exists_extension(chan, chan->context, exten, 1,
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) {
ast_copy_string(chan->exten, exten, sizeof(chan->exten));
if (p->dsp) ast_dsp_digitreset(p->dsp);
res = ast_pbx_run(chan);
ast_verb(3, "Disabling Caller*ID on %s\n", chan->name);
/* Disable Caller*ID if enabled */
p->hidecallerid = 1;
- if (chan->cid.cid_num)
- ast_free(chan->cid.cid_num);
- chan->cid.cid_num = NULL;
- if (chan->cid.cid_name)
- ast_free(chan->cid.cid_name);
- chan->cid.cid_name = NULL;
+ ast_party_number_free(&chan->caller.id.number);
+ ast_party_number_init(&chan->caller.id.number);
+ ast_party_name_free(&chan->caller.id.name);
+ ast_party_name_init(&chan->caller.id.name);
res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALRECALL);
if (res) {
ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n",
ast_verb(3, "Enabling Caller*ID on %s\n", chan->name);
/* Enable Caller*ID if enabled */
p->hidecallerid = 0;
- if (chan->cid.cid_num)
- ast_free(chan->cid.cid_num);
- chan->cid.cid_num = NULL;
- if (chan->cid.cid_name)
- ast_free(chan->cid.cid_name);
- chan->cid.cid_name = NULL;
ast_set_callerid(chan, p->cid_num, p->cid_name, NULL);
res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALRECALL);
if (res) {
ast_hangup(chan);
goto quit;
}
- } else if (!ast_canmatch_extension(chan, chan->context, exten, 1, chan->cid.cid_num) &&
- ((exten[0] != '*') || (strlen(exten) > 2))) {
- ast_debug(1, "Can't match %s from '%s' in context %s\n", exten, chan->cid.cid_num ? chan->cid.cid_num : "<Unknown Caller>", chan->context);
+ } else if (!ast_canmatch_extension(chan, chan->context, exten, 1,
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))
+ && ((exten[0] != '*') || (strlen(exten) > 2))) {
+ ast_debug(1, "Can't match %s from '%s' in context %s\n", exten,
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, "<Unknown Caller>"),
+ chan->context);
break;
}
if (!timeout)
tmp->callgroup = client->callgroup;
tmp->pickupgroup = client->pickupgroup;
- tmp->cid.cid_pres = client->callingpres;
+ tmp->caller.id.name.presentation = client->callingpres;
+ tmp->caller.id.number.presentation = client->callingpres;
if (!ast_strlen_zero(client->accountcode))
ast_string_field_set(tmp, accountcode, client->accountcode);
if (client->amaflags)
ast_copy_string(tmp->context, client->context, sizeof(tmp->context));
ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten));
- if (!ast_strlen_zero(i->exten) && strcmp(i->exten, "s"))
- tmp->cid.cid_dnid = ast_strdup(i->exten);
+ if (!ast_strlen_zero(i->exten) && strcmp(i->exten, "s")) {
+ tmp->dialed.number.str = ast_strdup(i->exten);
+ }
tmp->priority = 1;
if (i->rtp)
ast_jb_configure(tmp, &global_jbconf);
/* make sure null terminated */
called_addr[sizeof(called_addr) - 1] = '\0';
- if (c->connected.id.number)
- ast_copy_string(pvt->options.cid_num, c->connected.id.number, sizeof(pvt->options.cid_num));
+ if (c->connected.id.number.valid && c->connected.id.number.str) {
+ ast_copy_string(pvt->options.cid_num, c->connected.id.number.str, sizeof(pvt->options.cid_num));
+ }
- if (c->connected.id.name)
- ast_copy_string(pvt->options.cid_name, c->connected.id.name, sizeof(pvt->options.cid_name));
+ if (c->connected.id.name.valid && c->connected.id.name.str) {
+ ast_copy_string(pvt->options.cid_name, c->connected.id.name.str, sizeof(pvt->options.cid_name));
+ }
- if (c->redirecting.from.number) {
- ast_copy_string(pvt->options.cid_rdnis, c->redirecting.from.number, sizeof(pvt->options.cid_rdnis));
+ if (c->redirecting.from.number.valid && c->redirecting.from.number.str) {
+ ast_copy_string(pvt->options.cid_rdnis, c->redirecting.from.number.str, sizeof(pvt->options.cid_rdnis));
}
- pvt->options.presentation = c->connected.id.number_presentation;
- pvt->options.type_of_number = c->connected.id.number_type;
+ pvt->options.presentation = ast_party_id_presentation(c->connected.id);
+ pvt->options.type_of_number = c->connected.id.number.plan;
if ((addr = pbx_builtin_getvar_helper(c, "PRIREDIRECTREASON"))) {
if (!strcasecmp(addr, "UNKNOWN"))
/* Don't use ast_set_callerid() here because it will
* generate a needless NewCallerID event */
- ch->cid.cid_ani = ast_strdup(cid_num);
+ ch->caller.ani = ast_strdup(cid_num);
if (pvt->cd.redirect_reason >= 0) {
- ch->redirecting.from.number = ast_strdup(pvt->cd.redirect_number);
+ ch->redirecting.from.number.valid = 1;
+ ch->redirecting.from.number.str = ast_strdup(pvt->cd.redirect_number);
pbx_builtin_setvar_helper(ch, "PRIREDIRECTREASON", redirectingreason2str(pvt->cd.redirect_reason));
}
- ch->cid.cid_pres = pvt->cd.presentation;
- ch->cid.cid_ton = pvt->cd.type_of_number;
+ ch->caller.id.name.presentation = pvt->cd.presentation;
+ ch->caller.id.number.presentation = pvt->cd.presentation;
+ ch->caller.id.number.plan = pvt->cd.type_of_number;
if (!ast_strlen_zero(pvt->exten) && strcmp(pvt->exten, "s")) {
- ch->cid.cid_dnid = ast_strdup(pvt->exten);
+ ch->dialed.number.str = ast_strdup(pvt->exten);
}
if (pvt->cd.transfer_capability >= 0)
ch->transfercapability = pvt->cd.transfer_capability;
if (pds.port)
sin.sin_port = htons(atoi(pds.port));
- l = c->connected.id.number;
- n = c->connected.id.name;
+ l = c->connected.id.number.valid ? c->connected.id.number.str : NULL;
+ n = c->connected.id.name.valid ? c->connected.id.name.str : NULL;
/* Now build request */
memset(&ied, 0, sizeof(ied));
if (l) {
iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, l);
- iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->connected.id.number_presentation);
+ iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES,
+ ast_party_id_presentation(&c->connected.id));
+ } else if (n) {
+ iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES,
+ ast_party_id_presentation(&c->connected.id));
} else {
- if (n)
- iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->connected.id.number_presentation);
- else
- iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, AST_PRES_NUMBER_NOT_AVAILABLE);
+ iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, AST_PRES_NUMBER_NOT_AVAILABLE);
}
- iax_ie_append_byte(&ied, IAX_IE_CALLINGTON, c->connected.id.number_type);
- iax_ie_append_short(&ied, IAX_IE_CALLINGTNS, c->cid.cid_tns);
+ iax_ie_append_byte(&ied, IAX_IE_CALLINGTON, c->connected.id.number.plan);
+ iax_ie_append_short(&ied, IAX_IE_CALLINGTNS, c->dialed.transit_network_select);
if (n)
iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, n);
if (!ast_strlen_zero(c->language))
iax_ie_append_str(&ied, IAX_IE_LANGUAGE, c->language);
- if (!ast_strlen_zero(c->cid.cid_dnid))
- iax_ie_append_str(&ied, IAX_IE_DNID, c->cid.cid_dnid);
- if (!ast_strlen_zero(c->redirecting.from.number))
- iax_ie_append_str(&ied, IAX_IE_RDNIS, c->redirecting.from.number);
+ if (!ast_strlen_zero(c->dialed.number.str)) {
+ iax_ie_append_str(&ied, IAX_IE_DNID, c->dialed.number.str);
+ }
+ if (c->redirecting.from.number.valid
+ && !ast_strlen_zero(c->redirecting.from.number.str)) {
+ iax_ie_append_str(&ied, IAX_IE_RDNIS, c->redirecting.from.number.str);
+ }
if (pds.context)
iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.context);
ast_string_field_set(tmp, parkinglot, i->parkinglot);
/* Don't use ast_set_callerid() here because it will
* generate a NewCallerID event before the NewChannel event */
- if (!ast_strlen_zero(i->ani))
- tmp->cid.cid_ani = ast_strdup(i->ani);
- else
- tmp->cid.cid_ani = ast_strdup(i->cid_num);
- tmp->cid.cid_dnid = ast_strdup(i->dnid);
- tmp->redirecting.from.number = ast_strdup(i->rdnis);
- tmp->cid.cid_pres = i->calling_pres;
- tmp->cid.cid_ton = i->calling_ton;
- tmp->cid.cid_tns = i->calling_tns;
+ if (!ast_strlen_zero(i->ani)) {
+ tmp->caller.ani = ast_strdup(i->ani);
+ } else {
+ tmp->caller.ani = ast_strdup(i->cid_num);
+ }
+ tmp->dialed.number.str = ast_strdup(i->dnid);
+ tmp->redirecting.from.number.valid = 1;
+ tmp->redirecting.from.number.str = ast_strdup(i->rdnis);
+ tmp->caller.id.name.presentation = i->calling_pres;
+ tmp->caller.id.number.presentation = i->calling_pres;
+ tmp->caller.id.number.plan = i->calling_ton;
+ tmp->dialed.transit_network_select = i->calling_tns;
if (!ast_strlen_zero(i->language))
ast_string_field_set(tmp, language, i->language);
if (!ast_strlen_zero(i->accountcode))
/* Initialize defaults */
ast_party_connected_line_init(&connected);
- connected.id.number_presentation = iaxs[fr->callno]->calling_pres;
+ connected.id.number.presentation = iaxs[fr->callno]->calling_pres;
+ connected.id.name.presentation = iaxs[fr->callno]->calling_pres;
if (!ast_connected_line_parse_data(f.data.ptr, f.datalen, &connected)) {
- ast_string_field_set(iaxs[fr->callno], cid_num, connected.id.number);
- ast_string_field_set(iaxs[fr->callno], cid_name, connected.id.name);
- iaxs[fr->callno]->calling_pres = connected.id.number_presentation;
+ ast_string_field_set(iaxs[fr->callno], cid_num, connected.id.number.str);
+ ast_string_field_set(iaxs[fr->callno], cid_name, connected.id.name.str);
+ iaxs[fr->callno]->calling_pres = ast_party_id_presentation(&connected.id);
if (iaxs[fr->callno]->owner) {
- ast_set_callerid(iaxs[fr->callno]->owner, S_OR(connected.id.number, ""), S_OR(connected.id.name, ""), NULL);
- iaxs[fr->callno]->owner->cid.cid_pres = connected.id.number_presentation;
+ ast_set_callerid(iaxs[fr->callno]->owner,
+ S_COR(connected.id.number.valid, connected.id.number.str, ""),
+ S_COR(connected.id.name.valid, connected.id.name.str, ""),
+ NULL);
+ iaxs[fr->callno]->owner->caller.id.number.presentation = connected.id.number.presentation;
+ iaxs[fr->callno]->owner->caller.id.name.presentation = connected.id.name.presentation;
}
}
ast_party_connected_line_free(&connected);
tmp->callgroup = client->callgroup;
tmp->pickupgroup = client->pickupgroup;
- tmp->cid.cid_pres = client->callingpres;
+ tmp->caller.id.name.presentation = client->callingpres;
+ tmp->caller.id.number.presentation = client->callingpres;
if (!ast_strlen_zero(client->accountcode))
ast_string_field_set(tmp, accountcode, client->accountcode);
if (client->amaflags)
ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten));
/* Don't use ast_set_callerid() here because it will
* generate an unnecessary NewCallerID event */
- tmp->cid.cid_ani = ast_strdup(i->cid_num);
- if (!ast_strlen_zero(i->exten) && strcmp(i->exten, "s"))
- tmp->cid.cid_dnid = ast_strdup(i->exten);
+ tmp->caller.ani = ast_strdup(i->cid_num);
+ if (!ast_strlen_zero(i->exten) && strcmp(i->exten, "s")) {
+ tmp->dialed.number.str = ast_strdup(i->exten);
+ }
tmp->priority = 1;
if (i->rtp)
ast_jb_configure(tmp, &global_jbconf);
unsigned char frame_data[1024];
if (condition == AST_CONTROL_CONNECTED_LINE) {
if (isoutbound) {
- ast_connected_line_copy_to_caller(&the_other_channel->cid, &this_channel->connected);
+ ast_connected_line_copy_to_caller(&the_other_channel->caller, &this_channel->connected);
}
- f.datalen = ast_connected_line_build_data(frame_data, sizeof(frame_data), &this_channel->connected);
+ f.datalen = ast_connected_line_build_data(frame_data, sizeof(frame_data), &this_channel->connected, NULL);
} else {
- f.datalen = ast_redirecting_build_data(frame_data, sizeof(frame_data), &this_channel->redirecting);
+ f.datalen = ast_redirecting_build_data(frame_data, sizeof(frame_data), &this_channel->redirecting, NULL);
}
f.subclass.integer = condition;
f.data.ptr = frame_data;
*/
ast_party_redirecting_copy(&p->chan->redirecting, &p->owner->redirecting);
- ast_free(p->chan->cid.cid_dnid);
- p->chan->cid.cid_dnid = ast_strdup(p->owner->cid.cid_dnid);
- if (!p->chan->cid.cid_dnid && p->owner->cid.cid_dnid) {
- /* Allocation failure */
- ast_mutex_unlock(&p->lock);
- ast_channel_unlock(p->chan);
- return -1;
- }
- p->chan->cid.cid_tns = p->owner->cid.cid_tns;
+ ast_party_dialed_copy(&p->chan->dialed, &p->owner->dialed);
- ast_connected_line_copy_to_caller(&p->chan->cid, &p->owner->connected);
- ast_connected_line_copy_from_caller(&p->chan->connected, &p->owner->cid);
+ ast_connected_line_copy_to_caller(&p->chan->caller, &p->owner->connected);
+ ast_connected_line_copy_from_caller(&p->chan->connected, &p->owner->caller);
ast_string_field_set(p->chan, language, p->owner->language);
ast_string_field_set(p->chan, accountcode, p->owner->accountcode);
ast_channel_cc_params_init(p->chan, ast_channel_get_cc_config_params(p->owner));
- if (!ast_exists_extension(NULL, p->chan->context, p->chan->exten, 1, p->owner->cid.cid_num)) {
+ if (!ast_exists_extension(NULL, p->chan->context, p->chan->exten, 1,
+ S_COR(p->owner->caller.id.number.valid, p->owner->caller.id.number.str, NULL))) {
ast_log(LOG_NOTICE, "No such extension/context %s@%s while calling Local channel\n", p->chan->exten, p->chan->context);
ast_mutex_unlock(&p->lock);
ast_channel_unlock(p->chan);
transmit_modify_request(sub->next);
}
- transmit_notify_request_with_callerid(sub, tone, ast->connected.id.number, ast->connected.id.name);
+ transmit_notify_request_with_callerid(sub, tone,
+ S_COR(ast->connected.id.number.valid, ast->connected.id.number.str, ""),
+ S_COR(ast->connected.id.name.valid, ast->connected.id.name.str, ""));
ast_setstate(ast, AST_STATE_RINGING);
if (sub->next->owner && !ast_strlen_zero(sub->next->cxident) && !ast_strlen_zero(sub->next->callid)) {
{
struct mgcp_subchannel *sub = ast->tech_pvt;
struct mgcp_endpoint *p = sub->parent;
+ struct ast_channel *bridged;
ast_debug(1, "mgcp_hangup(%s)\n", ast->name);
if (!ast->tech_pvt) {
if (p->hookstate == MGCP_OFFHOOK) {
if (sub->next->owner && ast_bridged_channel(sub->next->owner)) {
/* ncs fix! */
- transmit_notify_request_with_callerid(p->sub, (p->ncs ? "L/wt1" : "L/wt"), ast_bridged_channel(sub->next->owner)->cid.cid_num, ast_bridged_channel(sub->next->owner)->cid.cid_name);
+ bridged = ast_bridged_channel(sub->next->owner);
+ transmit_notify_request_with_callerid(p->sub, (p->ncs ? "L/wt1" : "L/wt"),
+ S_COR(bridged->caller.id.number.valid, bridged->caller.id.number.str, ""),
+ S_COR(bridged->caller.id.name.valid, bridged->caller.id.name.str, ""));
}
} else {
/* set our other connection as the primary and swith over to it */
p->sub->cxmode = MGCP_CX_RECVONLY;
transmit_modify_request(p->sub);
if (sub->next->owner && ast_bridged_channel(sub->next->owner)) {
- transmit_notify_request_with_callerid(p->sub, "L/rg", ast_bridged_channel(sub->next->owner)->cid.cid_num, ast_bridged_channel(sub->next->owner)->cid.cid_name);
+ bridged = ast_bridged_channel(sub->next->owner);
+ transmit_notify_request_with_callerid(p->sub, "L/rg",
+ S_COR(bridged->caller.id.number.valid, bridged->caller.id.number.str, ""),
+ S_COR(bridged->caller.id.name.valid, bridged->caller.id.name.str, ""));
}
}
/* Don't use ast_set_callerid() here because it will
* generate a needless NewCallerID event */
- tmp->cid.cid_ani = ast_strdup(i->cid_num);
+ tmp->caller.ani = ast_strdup(i->cid_num);
if (!i->adsi) {
tmp->adsicpe = AST_ADSI_UNAVAILABLE;
/*res = tone_zone_play_tone(p->subs[index].zfd, -1);*/
ast_indicate(chan, -1);
ast_copy_string(chan->exten, p->dtmf_buf, sizeof(chan->exten));
- chan->cid.cid_dnid = ast_strdup(p->dtmf_buf);
+ chan->dialed.number.str = ast_strdup(p->dtmf_buf);
memset(p->dtmf_buf, 0, sizeof(p->dtmf_buf));
ast_set_callerid(chan,
p->hidecallerid ? "" : p->cid_num,
p->hidecallerid ? "" : p->cid_name,
- chan->cid.cid_ani ? NULL : p->cid_num);
+ chan->caller.ani ? NULL : p->cid_num);
ast_setstate(chan, AST_STATE_RING);
/*dahdi_enable_ec(p);*/
if (p->dtmfmode & MGCP_DTMF_HYBRID) {
len = 0;
memset(p->dtmf_buf, 0, sizeof(p->dtmf_buf));
timeout = firstdigittimeout;
- } else if (!ast_canmatch_extension(chan, chan->context, p->dtmf_buf, 1, chan->cid.cid_num) &&
- ((p->dtmf_buf[0] != '*') || (strlen(p->dtmf_buf) > 2))) {
- ast_debug(1, "Can't match %s from '%s' in context %s\n", p->dtmf_buf, chan->cid.cid_num ? chan->cid.cid_num : "<Unknown Caller>", chan->context);
+ } else if (!ast_canmatch_extension(chan, chan->context, p->dtmf_buf, 1,
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))
+ && ((p->dtmf_buf[0] != '*') || (strlen(p->dtmf_buf) > 2))) {
+ ast_debug(1, "Can't match %s from '%s' in context %s\n", p->dtmf_buf,
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, "<Unknown Caller>"),
+ chan->context);
break;
}
if (!timeout)
bc->nt ? "NT" : "TE",
help->originator == ORG_AST ? "*" : "I",
ast ? ast->exten : "",
- (ast && ast->cid.cid_name) ? ast->cid.cid_name : "",
- (ast && ast->cid.cid_num) ? ast->cid.cid_num : "",
+ (ast && ast->caller.id.name.valid && ast->caller.id.name.str)
+ ? ast->caller.id.name.str : "",
+ (ast && ast->caller.id.number.valid && ast->caller.id.number.str)
+ ? ast->caller.id.number.str : "",
bc->redirecting.from.name,
bc->redirecting.from.number,
bc->redirecting.to.name,
" --> hold_channel: %d\n",
help->l3id,
ast->exten,
- ast->cid.cid_name ? ast->cid.cid_name : "",
- ast->cid.cid_num ? ast->cid.cid_num : "",
+ S_COR(ast->caller.id.name.valid, ast->caller.id.name.str, ""),
+ S_COR(ast->caller.id.number.valid, ast->caller.id.number.str, ""),
help->hold.port,
help->hold.channel
);
} else {
- ast_cli(a->fd, "* Channel in unknown STATE !!! Exten:%s, Callerid:%s\n", ast->exten, ast->cid.cid_num);
+ ast_cli(a->fd, "* Channel in unknown STATE !!! Exten:%s, Callerid:%s\n",
+ ast->exten,
+ S_COR(ast->caller.id.number.valid, ast->caller.id.number.str, ""));
}
}
}
chan_misdn_log(2, port, " --> pres: %d screen: %d\n", pres, screen);
if (pres < 0 || screen < 0) {
- chan_misdn_log(2, port, " --> pres: %x\n", ast->connected.id.number_presentation);
+ chan_misdn_log(2, port, " --> pres: %x\n", ast->connected.id.number.presentation);
- bc->caller.presentation = ast_to_misdn_pres(ast->connected.id.number_presentation);
+ bc->caller.presentation = ast_to_misdn_pres(ast->connected.id.number.presentation);
chan_misdn_log(2, port, " --> PRES: %s(%d)\n", misdn_to_str_pres(bc->caller.presentation), bc->caller.presentation);
- bc->caller.screening = ast_to_misdn_screen(ast->connected.id.number_presentation);
+ bc->caller.screening = ast_to_misdn_screen(ast->connected.id.number.presentation);
chan_misdn_log(2, port, " --> SCREEN: %s(%d)\n", misdn_to_str_screen(bc->caller.screening), bc->caller.screening);
} else {
bc->caller.screening = screen;
static void misdn_queue_connected_line_update(struct ast_channel *ast, const struct misdn_party_id *id, enum AST_CONNECTED_LINE_UPDATE_SOURCE source, char *cid_tag)
{
struct ast_party_connected_line connected;
+ struct ast_set_party_connected_line update_connected;
ast_party_connected_line_init(&connected);
- connected.id.number = (char *) id->number;
- connected.id.number_type = misdn_to_ast_ton(id->number_type)
+ memset(&update_connected, 0, sizeof(update_connected));
+ update_connected.id.number = 1;
+ connected.id.number.valid = 1;
+ connected.id.number.str = (char *) id->number;
+ connected.id.number.plan = misdn_to_ast_ton(id->number_type)
| misdn_to_ast_plan(id->number_plan);
- connected.id.number_presentation = misdn_to_ast_pres(id->presentation)
+ connected.id.number.presentation = misdn_to_ast_pres(id->presentation)
| misdn_to_ast_screen(id->screening);
connected.id.tag = cid_tag;
connected.source = source;
- ast_channel_queue_connected_line_update(ast, &connected);
+ ast_channel_queue_connected_line_update(ast, &connected, &update_connected);
}
/*!
if (originator == ORG_MISDN) {
/* ORIGINATOR MISDN (incoming call) */
- ast_copy_string(bc->connected.name, S_OR(ast->connected.id.name, ""), sizeof(bc->connected.name));
- ast_copy_string(bc->connected.number, S_OR(ast->connected.id.number, ""), sizeof(bc->connected.number));
- bc->connected.presentation = ast_to_misdn_pres(ast->connected.id.number_presentation);
- bc->connected.screening = ast_to_misdn_screen(ast->connected.id.number_presentation);
+ ast_copy_string(bc->connected.name,
+ S_COR(ast->connected.id.name.valid, ast->connected.id.name.str, ""),
+ sizeof(bc->connected.name));
+ if (ast->connected.id.number.valid) {
+ ast_copy_string(bc->connected.number, S_OR(ast->connected.id.number.str, ""),
+ sizeof(bc->connected.number));
+ bc->connected.presentation = ast_to_misdn_pres(ast->connected.id.number.presentation);
+ bc->connected.screening = ast_to_misdn_screen(ast->connected.id.number.presentation);
+ bc->connected.number_type = ast_to_misdn_ton(ast->connected.id.number.plan);
+ bc->connected.number_plan = ast_to_misdn_plan(ast->connected.id.number.plan);
+ } else {
+ bc->connected.number[0] = '\0';
+ bc->connected.presentation = 0;/* Allowed */
+ bc->connected.screening = 0;/* Unscreened */
+ bc->connected.number_type = NUMTYPE_UNKNOWN;
+ bc->connected.number_plan = NUMPLAN_UNKNOWN;
+ }
misdn_cfg_get(bc->port, MISDN_CFG_CPNDIALPLAN, &number_type, sizeof(number_type));
- if (number_type < 0) {
- bc->connected.number_type = ast_to_misdn_ton(ast->connected.id.number_type);
- bc->connected.number_plan = ast_to_misdn_plan(ast->connected.id.number_type);
- } else {
+ if (0 <= number_type) {
/* Force us to send in CONNECT message */
bc->connected.number_type = number_type;
bc->connected.number_plan = NUMPLAN_ISDN;
} else {
/* ORIGINATOR Asterisk (outgoing call) */
- ast_copy_string(bc->caller.name, S_OR(ast->connected.id.name, ""), sizeof(bc->caller.name));
- ast_copy_string(bc->caller.number, S_OR(ast->connected.id.number, ""), sizeof(bc->caller.number));
- bc->caller.presentation = ast_to_misdn_pres(ast->connected.id.number_presentation);
- bc->caller.screening = ast_to_misdn_screen(ast->connected.id.number_presentation);
+ ast_copy_string(bc->caller.name,
+ S_COR(ast->connected.id.name.valid, ast->connected.id.name.str, ""),
+ sizeof(bc->caller.name));
+ if (ast->connected.id.number.valid) {
+ ast_copy_string(bc->caller.number, S_OR(ast->connected.id.number.str, ""),
+ sizeof(bc->caller.number));
+ bc->caller.presentation = ast_to_misdn_pres(ast->connected.id.number.presentation);
+ bc->caller.screening = ast_to_misdn_screen(ast->connected.id.number.presentation);
+ bc->caller.number_type = ast_to_misdn_ton(ast->connected.id.number.plan);
+ bc->caller.number_plan = ast_to_misdn_plan(ast->connected.id.number.plan);
+ } else {
+ bc->caller.number[0] = '\0';
+ bc->caller.presentation = 0;/* Allowed */
+ bc->caller.screening = 0;/* Unscreened */
+ bc->caller.number_type = NUMTYPE_UNKNOWN;
+ bc->caller.number_plan = NUMPLAN_UNKNOWN;
+ }
misdn_cfg_get(bc->port, MISDN_CFG_LOCALDIALPLAN, &number_type, sizeof(number_type));
- if (number_type < 0) {
- bc->caller.number_type = ast_to_misdn_ton(ast->connected.id.number_type);
- bc->caller.number_plan = ast_to_misdn_plan(ast->connected.id.number_type);
- } else {
+ if (0 <= number_type) {
/* Force us to send in SETUP message */
bc->caller.number_type = number_type;
bc->caller.number_plan = NUMPLAN_ISDN;
*/
static void misdn_copy_redirecting_from_ast(struct misdn_bchannel *bc, struct ast_channel *ast)
{
- ast_copy_string(bc->redirecting.from.name, S_OR(ast->redirecting.from.name, ""), sizeof(bc->redirecting.from.name));
- ast_copy_string(bc->redirecting.from.number, S_OR(ast->redirecting.from.number, ""), sizeof(bc->redirecting.from.number));
- bc->redirecting.from.presentation = ast_to_misdn_pres(ast->redirecting.from.number_presentation);
- bc->redirecting.from.screening = ast_to_misdn_screen(ast->redirecting.from.number_presentation);
- bc->redirecting.from.number_type = ast_to_misdn_ton(ast->redirecting.from.number_type);
- bc->redirecting.from.number_plan = ast_to_misdn_plan(ast->redirecting.from.number_type);
-
- ast_copy_string(bc->redirecting.to.name, S_OR(ast->redirecting.to.name, ""), sizeof(bc->redirecting.to.name));
- ast_copy_string(bc->redirecting.to.number, S_OR(ast->redirecting.to.number, ""), sizeof(bc->redirecting.to.number));
- bc->redirecting.to.presentation = ast_to_misdn_pres(ast->redirecting.to.number_presentation);
- bc->redirecting.to.screening = ast_to_misdn_screen(ast->redirecting.to.number_presentation);
- bc->redirecting.to.number_type = ast_to_misdn_ton(ast->redirecting.to.number_type);
- bc->redirecting.to.number_plan = ast_to_misdn_plan(ast->redirecting.to.number_type);
+ ast_copy_string(bc->redirecting.from.name,
+ S_COR(ast->redirecting.from.name.valid, ast->redirecting.from.name.str, ""),
+ sizeof(bc->redirecting.from.name));
+ if (ast->redirecting.from.number.valid) {
+ ast_copy_string(bc->redirecting.from.number, S_OR(ast->redirecting.from.number.str, ""),
+ sizeof(bc->redirecting.from.number));
+ bc->redirecting.from.presentation = ast_to_misdn_pres(ast->redirecting.from.number.presentation);
+ bc->redirecting.from.screening = ast_to_misdn_screen(ast->redirecting.from.number.presentation);
+ bc->redirecting.from.number_type = ast_to_misdn_ton(ast->redirecting.from.number.plan);
+ bc->redirecting.from.number_plan = ast_to_misdn_plan(ast->redirecting.from.number.plan);
+ } else {
+ bc->redirecting.from.number[0] = '\0';
+ bc->redirecting.from.presentation = 0;/* Allowed */
+ bc->redirecting.from.screening = 0;/* Unscreened */
+ bc->redirecting.from.number_type = NUMTYPE_UNKNOWN;
+ bc->redirecting.from.number_plan = NUMPLAN_UNKNOWN;
+ }
+
+ ast_copy_string(bc->redirecting.to.name,
+ S_COR(ast->redirecting.to.name.valid, ast->redirecting.to.name.str, ""),
+ sizeof(bc->redirecting.to.name));
+ if (ast->redirecting.to.number.valid) {
+ ast_copy_string(bc->redirecting.to.number, S_OR(ast->redirecting.to.number.str, ""),
+ sizeof(bc->redirecting.to.number));
+ bc->redirecting.to.presentation = ast_to_misdn_pres(ast->redirecting.to.number.presentation);
+ bc->redirecting.to.screening = ast_to_misdn_screen(ast->redirecting.to.number.presentation);
+ bc->redirecting.to.number_type = ast_to_misdn_ton(ast->redirecting.to.number.plan);
+ bc->redirecting.to.number_plan = ast_to_misdn_plan(ast->redirecting.to.number.plan);
+ } else {
+ bc->redirecting.to.number[0] = '\0';
+ bc->redirecting.to.presentation = 0;/* Allowed */
+ bc->redirecting.to.screening = 0;/* Unscreened */
+ bc->redirecting.to.number_type = NUMTYPE_UNKNOWN;
+ bc->redirecting.to.number_plan = NUMPLAN_UNKNOWN;
+ }
bc->redirecting.reason = ast_to_misdn_reason(ast->redirecting.reason);
bc->redirecting.count = ast->redirecting.count;
static void misdn_copy_redirecting_to_ast(struct ast_channel *ast, const struct misdn_party_redirecting *redirect, char *tag)
{
struct ast_party_redirecting redirecting;
+ struct ast_set_party_redirecting update_redirecting;
ast_party_redirecting_set_init(&redirecting, &ast->redirecting);
+ memset(&update_redirecting, 0, sizeof(update_redirecting));
- redirecting.from.number = (char *) redirect->from.number;
- redirecting.from.number_type =
+ update_redirecting.from.number = 1;
+ redirecting.from.number.valid = 1;
+ redirecting.from.number.str = (char *) redirect->from.number;
+ redirecting.from.number.plan =
misdn_to_ast_ton(redirect->from.number_type)
| misdn_to_ast_plan(redirect->from.number_plan);
- redirecting.from.number_presentation =
+ redirecting.from.number.presentation =
misdn_to_ast_pres(redirect->from.presentation)
| misdn_to_ast_screen(redirect->from.screening);
redirecting.from.tag = tag;
- redirecting.to.number = (char *) redirect->to.number;
- redirecting.to.number_type =
+ update_redirecting.to.number = 1;
+ redirecting.to.number.valid = 1;
+ redirecting.to.number.str = (char *) redirect->to.number;
+ redirecting.to.number.plan =
misdn_to_ast_ton(redirect->to.number_type)
| misdn_to_ast_plan(redirect->to.number_plan);
- redirecting.to.number_presentation =
+ redirecting.to.number.presentation =
misdn_to_ast_pres(redirect->to.presentation)
| misdn_to_ast_screen(redirect->to.screening);
redirecting.to.tag = tag;
redirecting.reason = misdn_to_ast_reason(redirect->reason);
redirecting.count = redirect->count;
- ast_channel_set_redirecting(ast, &redirecting);
+ ast_channel_set_redirecting(ast, &redirecting, &update_redirecting);
}
/*!
ast_copy_string(ast->exten, args.ext, sizeof(ast->exten));
ast_copy_string(newbc->dialed.number, args.ext, sizeof(newbc->dialed.number));
- if (ast_strlen_zero(newbc->caller.name) && !ast_strlen_zero(ast->connected.id.name)) {
- ast_copy_string(newbc->caller.name, ast->connected.id.name, sizeof(newbc->caller.name));
+ if (ast_strlen_zero(newbc->caller.name)
+ && ast->connected.id.name.valid
+ && !ast_strlen_zero(ast->connected.id.name.str)) {
+ ast_copy_string(newbc->caller.name, ast->connected.id.name.str, sizeof(newbc->caller.name));
chan_misdn_log(3, port, " --> * set caller:\"%s\" <%s>\n", newbc->caller.name, newbc->caller.number);
}
- if (ast_strlen_zero(newbc->caller.number) && !ast_strlen_zero(ast->connected.id.number)) {
- ast_copy_string(newbc->caller.number, ast->connected.id.number, sizeof(newbc->caller.number));
+ if (ast_strlen_zero(newbc->caller.number)
+ && ast->connected.id.number.valid
+ && !ast_strlen_zero(ast->connected.id.number.str)) {
+ ast_copy_string(newbc->caller.number, ast->connected.id.number.str, sizeof(newbc->caller.number));
chan_misdn_log(3, port, " --> * set caller:\"%s\" <%s>\n", newbc->caller.name, newbc->caller.number);
}
strncat(newbc->incoming_cid_tag, newbc->caller.number, sizeof(newbc->incoming_cid_tag) - strlen(newbc->incoming_cid_tag) - 1);
}
- ast->cid.cid_tag = ast_strdup(newbc->incoming_cid_tag);
+ ast->caller.id.tag = ast_strdup(newbc->incoming_cid_tag);
misdn_cfg_get(port, MISDN_CFG_LOCALDIALPLAN, &number_type, sizeof(number_type));
if (number_type < 0) {
- newbc->caller.number_type = ast_to_misdn_ton(ast->connected.id.number_type);
- newbc->caller.number_plan = ast_to_misdn_plan(ast->connected.id.number_type);
+ if (ast->connected.id.number.valid) {
+ newbc->caller.number_type = ast_to_misdn_ton(ast->connected.id.number.plan);
+ newbc->caller.number_plan = ast_to_misdn_plan(ast->connected.id.number.plan);
+ } else {
+ newbc->caller.number_type = NUMTYPE_UNKNOWN;
+ newbc->caller.number_plan = NUMPLAN_ISDN;
+ }
} else {
/* Force us to send in SETUP message */
newbc->caller.number_type = number_type;
bc->pid,
ast->context,
ast->exten,
- ast->cid.cid_name ? ast->cid.cid_name : "",
- ast->cid.cid_num ? ast->cid.cid_num : "",
+ (ast->caller.id.name.valid && ast->caller.id.name.str)
+ ? ast->caller.id.name.str : "",
+ (ast->caller.id.number.valid && ast->caller.id.number.str)
+ ? ast->caller.id.number.str : "",
misdn_get_ch_state(p));
chan_misdn_log(3, bc->port, " --> l3id:%x\n", p->l3id);
chan_misdn_log(3, bc->port, " --> cause:%d\n", bc->cause);
char context_tmp[BUFFERSIZE];
misdn_cfg_get(tmp->bc->port, MISDN_CFG_FAXDETECT_CONTEXT, &context_tmp, sizeof(context_tmp));
context = ast_strlen_zero(context_tmp) ? (ast_strlen_zero(ast->macrocontext) ? ast->context : ast->macrocontext) : context_tmp;
- if (ast_exists_extension(ast, context, "fax", 1, ast->cid.cid_num)) {
+ if (ast_exists_extension(ast, context, "fax", 1,
+ S_COR(ast->caller.id.number.valid, ast->caller.id.number.str, NULL))) {
ast_verb(3, "Redirecting %s to fax extension (context:%s)\n", ast->name, context);
/* Save the DID/DNIS when we transfer the fax call to a "fax" extension */
pbx_builtin_setvar_helper(ast,"FAXEXTEN",ast->exten);
if (!ch->dropped_frame_cnt) {
chan_misdn_log(5, ch->bc->port,
"BC not active (nor bridged) dropping: %d frames addr:%x exten:%s cid:%s ch->state:%s bc_state:%d l3id:%x\n",
- frame->samples, ch->bc->addr, ast->exten, ast->cid.cid_num, misdn_get_ch_state(ch), ch->bc->bc_state, ch->bc->l3_id);
+ frame->samples, ch->bc->addr, ast->exten,
+ S_COR(ast->caller.id.number.valid, ast->caller.id.number.str, ""),
+ misdn_get_ch_state(ch), ch->bc->bc_state, ch->bc->l3_id);
}
if (++ch->dropped_frame_cnt > 100) {
if (callerid) {
/* Don't use ast_set_callerid() here because it will
* generate a needless NewCallerID event */
- tmp->cid.cid_ani = ast_strdup(cid_num);
+ tmp->caller.ani = ast_strdup(cid_num);
}
if (pipe(chlist->pipe) < 0) {
bc->pid,
ast->context,
ast->exten,
- ast->cid.cid_name ? ast->cid.cid_name : "",
- ast->cid.cid_num ? ast->cid.cid_num : "");
+ (ast->caller.id.name.valid && ast->caller.id.name.str)
+ ? ast->caller.id.name.str : "",
+ (ast->caller.id.number.valid && ast->caller.id.number.str)
+ ? ast->caller.id.number.str : "");
if (ast->_state != AST_STATE_RESERVED) {
chan_misdn_log(3, bc->port, " --> Setting AST State to down\n");
"* Starting Ast context:%s dialed:%s caller:\"%s\" <%s> with 's' extension\n",
ast->context,
ast->exten,
- ast->cid.cid_name ? ast->cid.cid_name : "",
- ast->cid.cid_num ? ast->cid.cid_num : "");
+ (ast->caller.id.name.valid && ast->caller.id.name.str)
+ ? ast->caller.id.name.str : "",
+ (ast->caller.id.number.valid && ast->caller.id.number.str)
+ ? ast->caller.id.number.str : "");
strcpy(ast->exten, "s");
return;
}
chan->priority = notify->priority;
- if (chan->cid.cid_dnid) {
- ast_free(chan->cid.cid_dnid);
- }
- chan->cid.cid_dnid = ast_strdup(notify->exten);
+ ast_free(chan->dialed.number.str);
+ chan->dialed.number.str = ast_strdup(notify->exten);
if (ast_pbx_start(chan)) {
ast_log(LOG_WARNING, "Unable to start pbx channel %s!\n", chan->name);
bc->div_leg_3_rx_wanted = 0;
if (ch && ch->ast) {
- ch->ast->redirecting.to.number_presentation =
+ ch->ast->redirecting.to.number.presentation =
bc->fac_in.u.DivertingLegInformation3.PresentationAllowedIndicator
? AST_PRES_ALLOWED | AST_PRES_USER_NUMBER_UNSCREENED
: AST_PRES_RESTRICTED | AST_PRES_USER_NUMBER_UNSCREENED;
- ast_channel_queue_redirecting_update(ch->ast, &ch->ast->redirecting);
+ ast_channel_queue_redirecting_update(ch->ast, &ch->ast->redirecting, NULL);
}
}
break;
/* Update asterisk channel caller information */
chan_misdn_log(2, bc->port, " --> TON: %s(%d)\n", misdn_to_str_ton(bc->caller.number_type), bc->caller.number_type);
chan_misdn_log(2, bc->port, " --> PLAN: %s(%d)\n", misdn_to_str_plan(bc->caller.number_plan), bc->caller.number_plan);
- chan->cid.cid_ton = misdn_to_ast_ton(bc->caller.number_type)
+ chan->caller.id.number.plan = misdn_to_ast_ton(bc->caller.number_type)
| misdn_to_ast_plan(bc->caller.number_plan);
chan_misdn_log(2, bc->port, " --> PRES: %s(%d)\n", misdn_to_str_pres(bc->caller.presentation), bc->caller.presentation);
chan_misdn_log(2, bc->port, " --> SCREEN: %s(%d)\n", misdn_to_str_screen(bc->caller.screening), bc->caller.screening);
- chan->cid.cid_pres = misdn_to_ast_pres(bc->caller.presentation)
+ chan->caller.id.number.presentation = misdn_to_ast_pres(bc->caller.presentation)
| misdn_to_ast_screen(bc->caller.screening);
ast_set_callerid(chan, bc->caller.number, NULL, bc->caller.number);
}
ast_channel_lock(chan);
- chan->cid.cid_tag = ast_strdup(bc->incoming_cid_tag);
+ chan->caller.id.tag = ast_strdup(bc->incoming_cid_tag);
ast_channel_unlock(chan);
if (!ast_strlen_zero(bc->redirecting.from.number)) {
bc->div_leg_3_rx_wanted = 0;
if (ch->ast) {
- ch->ast->redirecting.to.number_presentation =
+ ch->ast->redirecting.to.number.presentation =
AST_PRES_RESTRICTED | AST_PRES_USER_NUMBER_UNSCREENED;
- ast_channel_queue_redirecting_update(ch->ast, &ch->ast->redirecting);
+ ast_channel_queue_redirecting_update(ch->ast, &ch->ast->redirecting, NULL);
}
}
#endif /* defined(AST_MISDN_ENHANCEMENTS) */
break;
}
misdn_copy_redirecting_to_ast(ch->ast, &bc->redirecting, bc->incoming_cid_tag);
- ast_channel_queue_redirecting_update(ch->ast, &ch->ast->redirecting);
+ ast_channel_queue_redirecting_update(ch->ast, &ch->ast->redirecting,
+ NULL);
}
}
break;
AST_NONSTANDARD_APP_ARGS(args, parse, '/');
ast_verbose(" << Call to device '%s' dnid '%s' rdnis '%s' on console from '%s' <%s> >>\n",
- dest, c->cid.cid_dnid, c->redirecting.from.number, c->cid.cid_name, c->cid.cid_num);
+ dest,
+ S_OR(c->dialed.number.str, ""),
+ S_COR(c->redirecting.from.number.valid, c->redirecting.from.number.str, ""),
+ S_COR(c->caller.id.name.valid, c->caller.id.name.str, ""),
+ S_COR(c->caller.id.number.valid, c->caller.id.number.str, ""));
if (!ast_strlen_zero(args.flags) && strcasecmp(args.flags, "answer") == 0) {
f.subclass.integer = AST_CONTROL_ANSWER;
ast_queue_frame(c, &f);
ast_string_field_set(c, language, o->language);
/* Don't use ast_set_callerid() here because it will
* generate a needless NewCallerID event */
- c->cid.cid_ani = ast_strdup(o->cid_num);
- if (!ast_strlen_zero(ext))
- c->cid.cid_dnid = ast_strdup(ext);
+ c->caller.ani = ast_strdup(o->cid_num);
+ if (!ast_strlen_zero(ext)) {
+ c->dialed.number.str = ast_strdup(ext);
+ }
o->owner = c;
ast_module_ref(ast_module_info->self);
tmp = ast_ext_ctx(a->argv[2], &ext, &ctx);
if (ctx == NULL) /* supply default context if needed */
ctx = o->owner->context;
- if (!ast_exists_extension(b, ctx, ext, 1, b->cid.cid_num))
+ if (!ast_exists_extension(b, ctx, ext, 1,
+ S_COR(b->caller.id.number.valid, b->caller.id.number.str, NULL))) {
ast_cli(a->fd, "No such extension exists\n");
- else {
+ } else {
ast_cli(a->fd, "Whee, transferring %s to %s@%s.\n", b->name, ext, ctx);
if (ast_async_goto(b, ctx, ext, 1))
ast_cli(a->fd, "Failed to transfer :(\n");
snprintf(cid.min, sizeof(cid.min), "%02d", tm.tm_min);
}
/* the standard format of ast->callerid is: "name" <number>, but not always complete */
- if (ast_strlen_zero(ast->connected.id.name))
+ if (!ast->connected.id.name.valid
+ || ast_strlen_zero(ast->connected.id.name.str)) {
strcpy(cid.name, DEFAULT_CALLER_ID);
- else
- ast_copy_string(cid.name, ast->connected.id.name, sizeof(cid.name));
+ } else {
+ ast_copy_string(cid.name, ast->connected.id.name.str, sizeof(cid.name));
+ }
- if (ast->connected.id.number)
- ast_copy_string(cid.number, ast->connected.id.number, sizeof(cid.number));
+ if (ast->connected.id.number.valid && ast->connected.id.number.str) {
+ ast_copy_string(cid.number, ast->connected.id.number.str, sizeof(cid.number));
+ }
p = ast->tech_pvt;
/* Don't use ast_set_callerid() here because it will
* generate a NewCallerID event before the NewChannel event */
- tmp->cid.cid_ani = ast_strdup(i->cid_num);
+ tmp->caller.ani = ast_strdup(i->cid_num);
i->owner = tmp;
ast_module_ref(ast_module_info->self);
static int transmit_state_notify(struct sip_pvt *p, int state, int full, int timeout);
static void update_connectedline(struct sip_pvt *p, const void *data, size_t datalen);
static void update_redirecting(struct sip_pvt *p, const void *data, size_t datalen);
-static void change_redirecting_information(struct sip_pvt *p, struct sip_request *req, struct ast_party_redirecting *redirecting, int set_call_forward);
static int get_domain(const char *str, char *domain, int len);
static void get_realm(struct sip_pvt *p, const struct sip_request *req);
ast->hangupcause = AST_CAUSE_USER_BUSY;
return res;
}
- p->callingpres = ast->cid.cid_pres;
+ p->callingpres = ast_party_id_presentation(&ast->caller.id);
p->jointcapability = ast_rtp_instance_available_formats(p->rtp, p->capability, p->prefcodec);
p->jointnoncodeccapability = p->noncodeccapability;
ast_channel_lock(tmp);
sip_pvt_lock(i);
ast_channel_cc_params_init(tmp, i->cc_params);
- tmp->cid.cid_tag = ast_strdup(i->cid_tag);
+ tmp->caller.id.tag = ast_strdup(i->cid_tag);
ast_channel_unlock(tmp);
tmp->tech = ( ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_INFO || ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_SHORTINFO) ? &sip_tech_info : &sip_tech;
tmp->callgroup = i->callgroup;
tmp->pickupgroup = i->pickupgroup;
- tmp->cid.cid_pres = i->callingpres;
+ tmp->caller.id.name.presentation = i->callingpres;
+ tmp->caller.id.number.presentation = i->callingpres;
if (!ast_strlen_zero(i->parkinglot))
ast_string_field_set(tmp, parkinglot, i->parkinglot);
if (!ast_strlen_zero(i->accountcode))
/* Don't use ast_set_callerid() here because it will
* generate an unnecessary NewCallerID event */
- tmp->cid.cid_ani = ast_strdup(i->cid_num);
- if (!ast_strlen_zero(i->rdnis))
- tmp->redirecting.from.number = ast_strdup(i->rdnis);
-
- if (!ast_strlen_zero(i->exten) && strcmp(i->exten, "s"))
- tmp->cid.cid_dnid = ast_strdup(i->exten);
+ tmp->caller.ani = ast_strdup(i->cid_num);
+ if (!ast_strlen_zero(i->rdnis)) {
+ tmp->redirecting.from.number.valid = 1;
+ tmp->redirecting.from.number.str = ast_strdup(i->rdnis);
+ }
+
+ if (!ast_strlen_zero(i->exten) && strcmp(i->exten, "s")) {
+ tmp->dialed.number.str = ast_strdup(i->exten);
+ }
tmp->priority = 1;
if (!ast_strlen_zero(i->uri))
if (strcmp(ast->exten, "fax")) {
const char *target_context = S_OR(ast->macrocontext, ast->context);
ast_channel_unlock(ast);
- if (ast_exists_extension(ast, target_context, "fax", 1, ast->cid.cid_num)) {
+ if (ast_exists_extension(ast, target_context, "fax", 1,
+ S_COR(ast->caller.id.number.valid, ast->caller.id.number.str, NULL))) {
ast_verbose(VERBOSE_PREFIX_2 "Redirecting '%s' to fax extension due to CNG detection\n", ast->name);
pbx_builtin_setvar_helper(ast, "FAXEXTEN", ast->exten);
if (ast_async_goto(ast, target_context, "fax", 1)) {
fr = &ast_null_frame;
} else {
ast_log(LOG_NOTICE, "FAX CNG detected but no fax extension\n");
- }
+ }
} else {
ast_channel_unlock(ast);
- }
- }
+ }
+ }
/* Only allow audio through if they sent progress with SDP, or if the channel is actually answered */
if (fr && fr->frametype == AST_FRAME_VOICE && p->invitestate != INV_EARLY_MEDIA && ast->_state != AST_STATE_UP) {
if (strcmp(p->owner->exten, "fax")) {
const char *target_context = S_OR(p->owner->macrocontext, p->owner->context);
ast_channel_unlock(p->owner);
- if (ast_exists_extension(p->owner, target_context, "fax", 1, p->owner->cid.cid_num)) {
+ if (ast_exists_extension(p->owner, target_context, "fax", 1,
+ S_COR(p->owner->caller.id.number.valid, p->owner->caller.id.number.str, NULL))) {
ast_verbose(VERBOSE_PREFIX_2 "Redirecting '%s' to fax extension due to peer T.38 re-INVITE\n", p->owner->name);
pbx_builtin_setvar_helper(p->owner, "FAXEXTEN", p->owner->exten);
if (ast_async_goto(p->owner, target_context, "fax", 1)) {
return 0;
}
- if (p->owner && p->owner->connected.id.number)
- lid_num = p->owner->connected.id.number;
- if (p->owner && p->owner->connected.id.name)
- lid_name = p->owner->connected.id.name;
- lid_pres = (p->owner) ? p->owner->connected.id.number_presentation : AST_PRES_NUMBER_NOT_AVAILABLE;
+ if (p->owner && p->owner->connected.id.number.valid
+ && p->owner->connected.id.number.str) {
+ lid_num = p->owner->connected.id.number.str;
+ }
+ if (p->owner && p->owner->connected.id.name.valid
+ && p->owner->connected.id.name.str) {
+ lid_name = p->owner->connected.id.name.str;
+ }
+ lid_pres = (p->owner) ? ast_party_id_presentation(&p->owner->connected.id) : AST_PRES_NUMBER_NOT_AVAILABLE;
if (ast_strlen_zero(lid_num))
return 0;
snprintf(p->lastmsg, sizeof(p->lastmsg), "Init: %s", sip_methods[sipmethod].text);
d = S_OR(p->fromdomain, ast_sockaddr_stringify_host(&p->ourip));
- if (p->owner && (p->owner->connected.id.number_presentation & AST_PRES_RESTRICTION) == AST_PRES_ALLOWED) {
- l = p->owner->connected.id.number;
- n = p->owner->connected.id.name;
- } else if (p->owner && (p->owner->connected.id.number_presentation & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED && (!ast_test_flag(&p->flags[0], SIP_SENDRPID))) {
- /* if we are not sending RPID and user wants his callerid restricted */
- l = CALLERID_UNKNOWN;
- n = l;
- d = FROMDOMAIN_INVALID;
+ if (p->owner) {
+ if ((ast_party_id_presentation(&p->owner->connected.id) & AST_PRES_RESTRICTION) == AST_PRES_ALLOWED) {
+ l = p->owner->connected.id.number.valid ? p->owner->connected.id.number.str : NULL;
+ n = p->owner->connected.id.name.valid ? p->owner->connected.id.name.str : NULL;
+ } else if (!ast_test_flag(&p->flags[0], SIP_SENDRPID)) {
+ /* if we are not sending RPID and user wants his callerid restricted */
+ l = CALLERID_UNKNOWN;
+ n = l;
+ d = FROMDOMAIN_INVALID;
+ }
}
/* Hey, it's a NOTIFY! See if they've configured a mwi_from.
return;
}
- diverting_number = pvt->owner->redirecting.from.number;
- diverting_name = pvt->owner->redirecting.from.name;
- reason = sip_reason_code_to_str(pvt->owner->redirecting.reason);
-
- if (ast_strlen_zero(diverting_number)) {
+ diverting_number = pvt->owner->redirecting.from.number.str;
+ if (!pvt->owner->redirecting.from.number.valid
+ || ast_strlen_zero(diverting_number)) {
return;
}
+ reason = sip_reason_code_to_str(pvt->owner->redirecting.reason);
+
/* We at least have a number to place in the Diversion header, which is enough */
- if (ast_strlen_zero(diverting_name)) {
+ diverting_name = pvt->owner->redirecting.from.name.str;
+ if (!pvt->owner->redirecting.from.name.valid
+ || ast_strlen_zero(diverting_name)) {
snprintf(header_text, sizeof(header_text), "<sip:%s@%s>;reason=%s", diverting_number,
ast_sockaddr_stringify_host(&pvt->ourip), reason);
} else {
struct ast_channel *caller;
if ((caller = ast_channel_callback(find_calling_channel, NULL, p, 0))) {
- int need = strlen(caller->cid.cid_num) + strlen(p->fromdomain) + sizeof("sip:@");
- local_target = alloca(need);
+ char *cid_num;
+ int need;
+
ast_channel_lock(caller);
- snprintf(local_target, need, "sip:%s@%s", caller->cid.cid_num, p->fromdomain);
- local_display = ast_strdupa(caller->cid.cid_name);
+ cid_num = S_COR(caller->caller.id.number.valid,
+ caller->caller.id.number.str, "");
+ need = strlen(cid_num) + strlen(p->fromdomain) + sizeof("sip:@");
+ local_target = alloca(need);
+ snprintf(local_target, need, "sip:%s@%s", cid_num, p->fromdomain);
+ local_display = ast_strdupa(S_COR(caller->caller.id.name.valid,
+ caller->caller.id.name.str, ""));
ast_channel_unlock(caller);
caller = ast_channel_unref(caller);
}
if (!ast_test_flag(&p->flags[0], SIP_SENDRPID))
return;
- if (ast_strlen_zero(p->owner->connected.id.number))
+ if (!p->owner->connected.id.number.valid
+ || ast_strlen_zero(p->owner->connected.id.number.str)) {
return;
+ }
- append_history(p, "ConnectedLine", "%s party is now %s <%s>", ast_test_flag(&p->flags[0], SIP_OUTGOING) ? "Calling" : "Called", p->owner->connected.id.name, p->owner->connected.id.number);
+ append_history(p, "ConnectedLine", "%s party is now %s <%s>",
+ ast_test_flag(&p->flags[0], SIP_OUTGOING) ? "Calling" : "Called",
+ S_COR(p->owner->connected.id.name.valid, p->owner->connected.id.name.str, ""),
+ S_COR(p->owner->connected.id.number.valid, p->owner->connected.id.number.str, ""));
if (p->owner->_state == AST_STATE_UP || ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
struct sip_request req;
if (p->owner) {
ast_set_callerid(p->owner, cid_num, cid_name, NULL);
- p->owner->cid.cid_pres = callingpres;
+ p->owner->caller.id.name.presentation = callingpres;
+ p->owner->caller.id.number.presentation = callingpres;
}
return 1;
if (p->owner) {
ast_set_callerid(p->owner, cid_num, cid_name, NULL);
- p->owner->cid.cid_pres = callingpres;
+ p->owner->caller.id.name.presentation = callingpres;
+ p->owner->caller.id.number.presentation = callingpres;
}
return 1;
/*! \brief update redirecting information for a channel based on headers
*
*/
-static void change_redirecting_information(struct sip_pvt *p, struct sip_request *req, struct ast_party_redirecting *redirecting, int set_call_forward)
+static void change_redirecting_information(struct sip_pvt *p, struct sip_request *req,
+ struct ast_party_redirecting *redirecting,
+ struct ast_set_party_redirecting *update_redirecting, int set_call_forward)
{
char *redirecting_from_name = NULL;
char *redirecting_from_number = NULL;
}
if (!ast_strlen_zero(redirecting_from_number)) {
- if (redirecting->from.number) {
- ast_free(redirecting->from.number);
- }
ast_debug(3, "Got redirecting from number %s\n", redirecting_from_number);
- redirecting->from.number = redirecting_from_number;
+ update_redirecting->from.number = 1;
+ redirecting->from.number.valid = 1;
+ ast_free(redirecting->from.number.str);
+ redirecting->from.number.str = redirecting_from_number;
}
if (!ast_strlen_zero(redirecting_from_name)) {
- if (redirecting->from.name) {
- ast_free(redirecting->from.name);
- }
ast_debug(3, "Got redirecting from name %s\n", redirecting_from_name);
- redirecting->from.name = redirecting_from_name;
+ update_redirecting->from.name = 1;
+ redirecting->from.name.valid = 1;
+ ast_free(redirecting->from.name.str);
+ redirecting->from.name.str = redirecting_from_name;
}
if (!ast_strlen_zero(p->cid_tag)) {
- if (redirecting->from.tag) {
- ast_free(redirecting->from.tag);
- }
+ ast_free(redirecting->from.tag);
redirecting->from.tag = ast_strdup(p->cid_tag);
- if (redirecting->to.tag) {
- ast_free(redirecting->to.tag);
- }
+ ast_free(redirecting->to.tag);
redirecting->to.tag = ast_strdup(p->cid_tag);
}
if (!ast_strlen_zero(redirecting_to_number)) {
- if (redirecting->to.number) {
- ast_free(redirecting->to.number);
- }
ast_debug(3, "Got redirecting to number %s\n", redirecting_to_number);
- redirecting->to.number = redirecting_to_number;
+ update_redirecting->to.number = 1;
+ redirecting->to.number.valid = 1;
+ ast_free(redirecting->to.number.str);
+ redirecting->to.number.str = redirecting_to_number;
}
if (!ast_strlen_zero(redirecting_to_name)) {
- if (redirecting->to.name) {
- ast_free(redirecting->to.name);
- }
ast_debug(3, "Got redirecting to name %s\n", redirecting_from_number);
- redirecting->to.name = 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;
}
redirecting->reason = reason;
}
char *p_hdrval;
int rtn;
struct ast_party_connected_line connected;
+ struct ast_set_party_connected_line update_connected;
if (reinvite)
ast_debug(4, "SIP response %d to RE-invite on %s call %s\n", resp, outgoing ? "outgoing" : "incoming", p->callid);
if (!req->ignore && p->owner) {
if (get_rpid(p, req)) {
ast_party_connected_line_init(&connected);
- connected.id.number = (char *) p->cid_num;
- connected.id.name = (char *) p->cid_name;
+ memset(&update_connected, 0, sizeof(update_connected));
+ if (p->cid_num) {
+ update_connected.id.number = 1;
+ connected.id.number.valid = 1;
+ connected.id.number.str = (char *) p->cid_num;
+ connected.id.number.presentation = p->callingpres;
+ }
+ if (p->cid_name) {
+ update_connected.id.name = 1;
+ connected.id.name.valid = 1;
+ connected.id.name.str = (char *) p->cid_name;
+ connected.id.name.presentation = p->callingpres;
+ }
connected.id.tag = (char *) p->cid_tag;
- connected.id.number_presentation = p->callingpres;
connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
- ast_channel_queue_connected_line_update(p->owner, &connected);
+ ast_channel_queue_connected_line_update(p->owner, &connected,
+ &update_connected);
}
sip_handle_cc(p, req, AST_CC_CCNR);
ast_queue_control(p->owner, AST_CONTROL_RINGING);
if (!req->ignore && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p))
ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n");
if (!req->ignore && p->owner) {
- struct ast_party_redirecting redirecting = {{0,},};
- change_redirecting_information(p, req, &redirecting, FALSE);
- ast_channel_queue_redirecting_update(p->owner, &redirecting);
+ struct ast_party_redirecting redirecting;
+ struct ast_set_party_redirecting update_redirecting;
+
+ ast_party_redirecting_init(&redirecting);
+ memset(&update_redirecting, 0, sizeof(update_redirecting));
+ change_redirecting_information(p, req, &redirecting, &update_redirecting,
+ FALSE);
+ ast_channel_queue_redirecting_update(p->owner, &redirecting,
+ &update_redirecting);
ast_party_redirecting_free(&redirecting);
sip_handle_cc(p, req, AST_CC_CCNR);
}
if (get_rpid(p, req)) {
/* Queue a connected line update */
ast_party_connected_line_init(&connected);
- connected.id.number = (char *) p->cid_num;
- connected.id.name = (char *) p->cid_name;
+ memset(&update_connected, 0, sizeof(update_connected));
+ if (p->cid_num) {
+ update_connected.id.number = 1;
+ connected.id.number.valid = 1;
+ connected.id.number.str = (char *) p->cid_num;
+ connected.id.number.presentation = p->callingpres;
+ }
+ if (p->cid_name) {
+ update_connected.id.name = 1;
+ connected.id.name.valid = 1;
+ connected.id.name.str = (char *) p->cid_name;
+ connected.id.name.presentation = p->callingpres;
+ }
connected.id.tag = (char *) p->cid_tag;
- connected.id.number_presentation = p->callingpres;
connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
- ast_channel_queue_connected_line_update(p->owner, &connected);
+ ast_channel_queue_connected_line_update(p->owner, &connected,
+ &update_connected);
}
sip_handle_cc(p, req, AST_CC_CCNR);
}
if (!req->ignore && p->owner && (get_rpid(p, req) || !reinvite)) {
/* Queue a connected line update */
ast_party_connected_line_init(&connected);
- connected.id.number = (char *) p->cid_num;
- connected.id.name = (char *) p->cid_name;
+ memset(&update_connected, 0, sizeof(update_connected));
+ if (p->cid_num) {
+ update_connected.id.number = 1;
+ connected.id.number.valid = 1;
+ connected.id.number.str = (char *) p->cid_num;
+ connected.id.number.presentation = p->callingpres;
+ }
+ if (p->cid_name) {
+ update_connected.id.name = 1;
+ connected.id.name.valid = 1;
+ connected.id.name.str = (char *) p->cid_name;
+ connected.id.name.presentation = p->callingpres;
+ }
connected.id.tag = (char *) p->cid_tag;
- connected.id.number_presentation = p->callingpres;
connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
- ast_channel_queue_connected_line_update(p->owner, &connected);
+ ast_channel_queue_connected_line_update(p->owner, &connected,
+ &update_connected);
}
/* Parse contact header for continued conversation */
case 302: /* Moved temporarily */
case 305: /* Use Proxy */
if (p->owner) {
- struct ast_party_redirecting redirecting = {{0,},};
- change_redirecting_information(p, req, &redirecting, TRUE);
- ast_channel_set_redirecting(p->owner, &redirecting);
+ struct ast_party_redirecting redirecting;
+ struct ast_set_party_redirecting update_redirecting;
+
+ ast_party_redirecting_init(&redirecting);
+ change_redirecting_information(p, req, &redirecting,
+ &update_redirecting, TRUE);
+ ast_channel_set_redirecting(p->owner, &redirecting,
+ &update_redirecting);
ast_party_redirecting_free(&redirecting);
}
/* Fall through */
}
if (get_rpid(p, req)) {
struct ast_party_connected_line connected;
+ struct ast_set_party_connected_line update_connected;
ast_party_connected_line_init(&connected);
- connected.id.number = (char *) p->cid_num;
- connected.id.name = (char *) p->cid_name;
+ memset(&update_connected, 0, sizeof(update_connected));
+ if (p->cid_num) {
+ update_connected.id.number = 1;
+ connected.id.number.valid = 1;
+ connected.id.number.str = (char *) p->cid_num;
+ connected.id.number.presentation = p->callingpres;
+ }
+ if (p->cid_name) {
+ update_connected.id.name = 1;
+ connected.id.name.valid = 1;
+ connected.id.name.str = (char *) p->cid_name;
+ connected.id.name.presentation = p->callingpres;
+ }
connected.id.tag = (char *) p->cid_tag;
- connected.id.number_presentation = p->callingpres;
connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER;
- ast_channel_queue_connected_line_update(p->owner, &connected);
+ ast_channel_queue_connected_line_update(p->owner, &connected, &update_connected);
}
transmit_response(p, "200 OK", req);
return 0;
struct sip_peer *authpeer = NULL; /* Matching Peer */
int reinvite = 0;
int rtn;
+ struct ast_party_redirecting redirecting;
+ struct ast_set_party_redirecting update_redirecting;
const char *p_uac_se_hdr; /* UAC's Session-Expires header string */
const char *p_uac_min_se; /* UAC's requested Min-SE interval (char string) */
ast_clear_flag(&p->flags[0], SIP_OUTGOING); /* This is now an inbound dialog */
if (get_rpid(p, req)) {
struct ast_party_connected_line connected;
+ struct ast_set_party_connected_line update_connected;
ast_party_connected_line_init(&connected);
- connected.id.number = (char *) p->cid_num;
- connected.id.name = (char *) p->cid_name;
+ memset(&update_connected, 0, sizeof(update_connected));
+ if (p->cid_num) {
+ update_connected.id.number = 1;
+ connected.id.number.valid = 1;
+ connected.id.number.str = (char *) p->cid_num;
+ connected.id.number.presentation = p->callingpres;
+ }
+ if (p->cid_name) {
+ update_connected.id.name = 1;
+ connected.id.name.valid = 1;
+ connected.id.name.str = (char *) p->cid_name;
+ connected.id.name.presentation = p->callingpres;
+ }
connected.id.tag = (char *) p->cid_tag;
- connected.id.number_presentation = p->callingpres;
connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER;
- ast_channel_queue_connected_line_update(p->owner, &connected);
+ ast_channel_queue_connected_line_update(p->owner, &connected,
+ &update_connected);
}
/* Handle SDP here if we already have an owner */
if (find_sdp(req)) {
build_route(p, req, 0);
if (c) {
- struct ast_party_redirecting redirecting = { { 0, }, };
+ ast_party_redirecting_init(&redirecting);
+ memset(&update_redirecting, 0, sizeof(update_redirecting));
/* Pre-lock the call */
ast_channel_lock(c);
- change_redirecting_information(p, req, &redirecting, FALSE); /*Will return immediately if no Diversion header is present */
- ast_channel_set_redirecting(c, &redirecting);
+ change_redirecting_information(p, req, &redirecting, &update_redirecting,
+ FALSE); /*Will return immediately if no Diversion header is present */
+ ast_channel_set_redirecting(c, &redirecting, &update_redirecting);
ast_party_redirecting_free(&redirecting);
}
}
} else {
- struct ast_party_redirecting redirecting = {{0,},};
+ ast_party_redirecting_init(&redirecting);
+ memset(&update_redirecting, 0, sizeof(update_redirecting));
if (sipdebug) {
if (!req->ignore)
ast_debug(2, "Got a SIP re-invite for call %s\n", p->callid);
if (!req->ignore)
reinvite = 1;
c = p->owner;
- change_redirecting_information(p, req, &redirecting, FALSE); /*Will return immediately if no Diversion header is present */
+ change_redirecting_information(p, req, &redirecting, &update_redirecting, FALSE); /*Will return immediately if no Diversion header is present */
if (c) {
- ast_channel_set_redirecting(c, &redirecting);
+ ast_channel_set_redirecting(c, &redirecting, &update_redirecting);
}
ast_party_redirecting_free(&redirecting);
}
ast_indicate(target.chan1, AST_CONTROL_UNHOLD);
if (target.chan2) {
- ast_channel_queue_connected_line_update(target.chan1, &connected_to_transferee);
- ast_channel_queue_connected_line_update(target.chan2, &connected_to_target);
+ ast_channel_queue_connected_line_update(target.chan1, &connected_to_transferee, NULL);
+ ast_channel_queue_connected_line_update(target.chan2, &connected_to_target, NULL);
} else {
/* Since target.chan1 isn't actually connected to another channel, there is no way for us
* to queue a frame so that its connected line status will be updated.
int payload_size;
int frame_size;
unsigned char connected_line_data[1024];
- payload_size = ast_connected_line_build_data(connected_line_data, sizeof(connected_line_data), &connected_to_target);
+ payload_size = ast_connected_line_build_data(connected_line_data,
+ sizeof(connected_line_data), &connected_to_target, NULL);
frame_size = payload_size + sizeof(*frame_payload);
if (payload_size != -1 && (frame_payload = alloca(frame_size))) {
frame_payload->payload_size = payload_size;
* will be updated, we also are going to queue a plain old connected line update on target.chan1. This
* way, either Dial or Queue can apply this connected line update to the outgoing ringing channel.
*/
- ast_channel_queue_connected_line_update(target.chan1, &connected_to_transferee);
+ ast_channel_queue_connected_line_update(target.chan1, &connected_to_transferee, NULL);
}
ast_channel_unref(current->chan1);
struct skinny_line *l = sub->parent;
struct skinny_device *d = l->device;
- if (ast_strlen_zero(c->cid.cid_num) || ast_strlen_zero(c->connected.id.number))
+ if (!c->caller.id.number.valid
+ || ast_strlen_zero(c->caller.id.number.str)
+ || !c->connected.id.number.valid
+ || ast_strlen_zero(c->connected.id.number.str))
return;
if (sub->owner->_state == AST_STATE_UP) {
transmit_callstate(d, l->instance, sub->callid, SKINNY_CONNECTED);
transmit_displaypromptstatus(d, "Connected", 0, l->instance, sub->callid);
if (sub->outgoing)
- transmit_callinfo(d, c->connected.id.name, c->connected.id.number, l->cid_name, l->cid_num, l->instance, sub->callid, 1);
+ transmit_callinfo(d,
+ S_COR(c->connected.id.name.valid, c->connected.id.name.str, ""),
+ c->connected.id.number.str,
+ l->cid_name, l->cid_num, l->instance, sub->callid, 1);
else
- transmit_callinfo(d, l->cid_name, l->cid_num, c->connected.id.name, c->connected.id.number, l->instance, sub->callid, 2);
+ transmit_callinfo(d, l->cid_name, l->cid_num,
+ S_COR(c->connected.id.name.valid, c->connected.id.name.str, ""),
+ c->connected.id.number.str,
+ l->instance, sub->callid, 2);
} else {
if (sub->outgoing) {
transmit_callstate(d, l->instance, sub->callid, SKINNY_RINGIN);
transmit_displaypromptstatus(d, "Ring-In", 0, l->instance, sub->callid);
- transmit_callinfo(d, c->connected.id.name, c->connected.id.number, l->cid_name, l->cid_num, l->instance, sub->callid, 1);
+ transmit_callinfo(d,
+ S_COR(c->connected.id.name.valid, c->connected.id.name.str, ""),
+ c->connected.id.number.str,
+ l->cid_name, l->cid_num, l->instance, sub->callid, 1);
} else {
if (!sub->ringing) {
transmit_callstate(d, l->instance, sub->callid, SKINNY_RINGOUT);
sub->progress = 1;
}
- transmit_callinfo(d, l->cid_name, l->cid_num, c->connected.id.name, c->connected.id.number, l->instance, sub->callid, 2);
+ transmit_callinfo(d, l->cid_name, l->cid_num,
+ S_COR(c->connected.id.name.valid, c->connected.id.name.str, ""),
+ c->connected.id.number.str,
+ l->instance, sub->callid, 2);
}
}
}
ast_set_callerid(c,
l->hidecallerid ? "" : l->cid_num,
l->hidecallerid ? "" : l->cid_name,
- c->cid.cid_ani ? NULL : l->cid_num);
- c->connected.id.number = ast_strdup(c->exten);
- c->connected.id.name = NULL;
+ c->caller.ani ? NULL : l->cid_num);
+#if 1 /* XXX This code is probably not necessary */
+ ast_party_number_free(&c->connected.id.number);
+ ast_party_number_init(&c->connected.id.number);
+ c->connected.id.number.valid = 1;
+ c->connected.id.number.str = ast_strdup(c->exten);
+ ast_party_name_free(&c->connected.id.name);
+ ast_party_name_init(&c->connected.id.name);
+#endif
ast_setstate(c, AST_STATE_RING);
if (!sub->rtp) {
start_rtp(sub);
ast_hangup(c);
}
return NULL;
- } else if (!ast_canmatch_extension(c, c->context, d->exten, 1, c->cid.cid_num) &&
- ((d->exten[0] != '*') || (!ast_strlen_zero(d->exten) > 2))) {
- ast_log(LOG_WARNING, "Can't match [%s] from '%s' in context %s\n", d->exten, c->cid.cid_num ? c->cid.cid_num : "<Unknown Caller>", c->context);
+ } else if (!ast_canmatch_extension(c, c->context, d->exten, 1,
+ S_COR(c->caller.id.number.valid, c->caller.id.number.str, NULL))
+ && ((d->exten[0] != '*') || (!ast_strlen_zero(d->exten) > 2))) {
+ ast_log(LOG_WARNING, "Can't match [%s] from '%s' in context %s\n", d->exten,
+ S_COR(c->caller.id.number.valid, c->caller.id.number.str, "<Unknown Caller>"),
+ c->context);
memset(d->exten, 0, sizeof(d->exten));
if (l->hookstate == SKINNY_OFFHOOK) {
transmit_start_tone(d, SKINNY_REORDER, l->instance, sub->callid);
transmit_callstate(d, sub->parent->instance, sub->callid, SKINNY_RINGIN);
transmit_selectsoftkeys(d, l->instance, sub->callid, KEYDEF_RINGIN);
transmit_displaypromptstatus(d, "Ring-In", 0, l->instance, sub->callid);
- transmit_callinfo(d, ast->connected.id.name, ast->connected.id.number, l->cid_name, l->cid_num, l->instance, sub->callid, 1);
+ transmit_callinfo(d,
+ S_COR(ast->connected.id.name.valid, ast->connected.id.name.str, ""),
+ S_COR(ast->connected.id.number.valid, ast->connected.id.number.str, ""),
+ l->cid_name, l->cid_num, l->instance, sub->callid, 1);
transmit_lamp_indication(d, STIMULUS_LINE, l->instance, SKINNY_LAMP_BLINK);
transmit_ringer_mode(d, SKINNY_RING_INSIDE);
/* order matters here...
for some reason, transmit_callinfo must be before transmit_callstate,
or you won't get keypad messages in some situations. */
- transmit_callinfo(d, ast->connected.id.name, ast->connected.id.number, l->lastnumberdialed, l->lastnumberdialed, l->instance, sub->callid, 2);
+ transmit_callinfo(d,
+ S_COR(ast->connected.id.name.valid, ast->connected.id.name.str, ""),
+ S_COR(ast->connected.id.number.valid, ast->connected.id.number.str, ""),
+ l->lastnumberdialed, l->lastnumberdialed, l->instance, sub->callid, 2);
transmit_callstate(d, sub->parent->instance, sub->callid, SKINNY_CONNECTED);
transmit_selectsoftkeys(d, l->instance, sub->callid, KEYDEF_CONNECTED);
transmit_dialednumber(d, l->lastnumberdialed, l->instance, sub->callid);
transmit_callstate(d, sub->parent->instance, sub->callid, SKINNY_RINGOUT);
transmit_dialednumber(d, l->lastnumberdialed, l->instance, sub->callid);
transmit_displaypromptstatus(d, "Ring Out", 0, l->instance, sub->callid);
- transmit_callinfo(d, ast->cid.cid_name, ast->cid.cid_num, S_OR(ast->connected.id.name, l->lastnumberdialed), S_OR(ast->connected.id.number, l->lastnumberdialed), l->instance, sub->callid, 2); /* 2 = outgoing from phone */
+ transmit_callinfo(d,
+ S_COR(ast->caller.id.name.valid, ast->caller.id.name.str, ""),
+ S_COR(ast->caller.id.number.valid, ast->caller.id.number.str, ""),
+ S_COR(ast->connected.id.name.valid, ast->connected.id.name.str, l->lastnumberdialed),
+ S_COR(ast->connected.id.number.valid, ast->connected.id.number.str, l->lastnumberdialed),
+ l->instance, sub->callid, 2); /* 2 = outgoing from phone */
sub->ringing = 1;
if (!d->earlyrtp) {
break;
}
transmit_callstate(d, sub->parent->instance, sub->callid, SKINNY_PROGRESS);
transmit_displaypromptstatus(d, "Call Progress", 0, l->instance, sub->callid);
- transmit_callinfo(d, ast->cid.cid_name, ast->cid.cid_num, S_OR(ast->connected.id.name, l->lastnumberdialed), S_OR(ast->connected.id.number, l->lastnumberdialed), l->instance, sub->callid, 2); /* 2 = outgoing from phone */
+ transmit_callinfo(d,
+ S_COR(ast->caller.id.name.valid, ast->caller.id.name.str, ""),
+ S_COR(ast->caller.id.number.valid, ast->caller.id.number.str, ""),
+ S_COR(ast->connected.id.name.valid, ast->connected.id.name.str, l->lastnumberdialed),
+ S_COR(ast->connected.id.number.valid, ast->connected.id.number.str, l->lastnumberdialed),
+ l->instance, sub->callid, 2); /* 2 = outgoing from phone */
sub->progress = 1;
if (!d->earlyrtp) {
break;
/* Don't use ast_set_callerid() here because it will
* generate a needless NewCallerID event */
- tmp->cid.cid_ani = ast_strdup(l->cid_num);
+ tmp->caller.ani = ast_strdup(l->cid_num);
tmp->priority = 1;
tmp->adsicpe = AST_ADSI_UNAVAILABLE;
send_text(TEXT_LINE1, TEXT_NORMAL, pte, "and press Call");
}
send_text_status(pte, "Call Redial BackSpcErase");
-
}
if (pte->device->height == 1) {
send_text(TEXT_LINE2, TEXT_NORMAL, pte, "previous call.");
}
send_text_status(pte, "Hangup Transf");
-
} else
show_main_page(pte);
break;
Sendicon(TEXT_LINE0, FAV_ICON_NONE, session);
if (sub->owner) {
- if (sub->owner->connected.id.number) {
+ if (sub->owner->connected.id.number.valid
+ && sub->owner->connected.id.number.str) {
if (session->device->height == 1) {
- send_text(TEXT_LINE0, TEXT_NORMAL, session, sub->owner->connected.id.number);
+ send_text(TEXT_LINE0, TEXT_NORMAL, session, sub->owner->connected.id.number.str);
} else {
- send_text(TEXT_LINE1, TEXT_NORMAL, session, sub->owner->connected.id.number);
+ send_text(TEXT_LINE1, TEXT_NORMAL, session, sub->owner->connected.id.number.str);
}
- change_callerid(session, 0, sub->owner->connected.id.number);
+ change_callerid(session, 0, sub->owner->connected.id.number.str);
} else {
if (session->device->height == 1) {
send_text(TEXT_LINE0, TEXT_NORMAL, session, DEFAULTCALLERID);
}
change_callerid(session, 0, DEFAULTCALLERID);
}
- if (sub->owner->connected.id.name) {
- send_text(TEXT_LINE0, TEXT_NORMAL, session, sub->owner->connected.id.name);
- change_callerid(session, 1, sub->owner->connected.id.name);
+ if (sub->owner->connected.id.name.valid
+ && sub->owner->connected.id.name.str) {
+ send_text(TEXT_LINE0, TEXT_NORMAL, session, sub->owner->connected.id.name.str);
+ change_callerid(session, 1, sub->owner->connected.id.name.str);
} else {
send_text(TEXT_LINE0, TEXT_NORMAL, session, DEFAULTCALLERNAME);
change_callerid(session, 1, DEFAULTCALLERNAME);
}
}
-
send_text(TEXT_LINE2, TEXT_NORMAL, session, "is calling you.");
send_text_status(session, "Accept Ignore");
instr = ast_strdup(l->cid_num);
if (instr) {
ast_callerid_parse(instr, &name, &loc);
- tmp->cid.cid_num = ast_strdup(loc);
- tmp->cid.cid_name = ast_strdup(name);
+ tmp->caller.id.number.valid = 1;
+ ast_free(tmp->caller.id.number.str);
+ tmp->caller.id.number.str = ast_strdup(loc);
+ tmp->caller.id.name.valid = 1;
+ ast_free(tmp->caller.id.name.str);
+ tmp->caller.id.name.str = ast_strdup(name);
ast_free(instr);
}
}
ast_string_field_set(c, language, o->language);
/* Don't use ast_set_callerid() here because it will
* generate a needless NewCallerID event */
- c->cid.cid_num = ast_strdup(o->cid_num);
- c->cid.cid_ani = ast_strdup(o->cid_num);
- c->cid.cid_name = ast_strdup(o->cid_name);
- if (!ast_strlen_zero(ext))
- c->cid.cid_dnid = ast_strdup(ext);
+ c->caller.ani = ast_strdup(o->cid_num);
+ if (!ast_strlen_zero(ext)) {
+ c->dialed.number.str = ast_strdup(ext);
+ }
o->owner = c;
ast_module_ref(ast_module_info->self);
strcpy(p->cid_num, cli_struct->cldn);
strcpy(p->cid_name, cli_struct->cn);
}
- ast_verb(4, "CID record - got [%s] [%s]\n", owner->cid.cid_num, owner->cid.cid_name);
+ ast_verb(4, "CID record - got [%s] [%s]\n",
+ S_COR(owner->caller.id.number.valid, owner->caller.id.number.str, ""),
+ S_COR(owner->caller.id.name.valid, owner->caller.id.name.str, ""));
snprintf(p->callerid, sizeof(p->callerid), "%s %s", cli_struct->cldn, cli_struct->cn);
} else {
ast_log(LOG_ERROR, "CID record - No caller id avalable on %s \n", p->dev);
} else {
ast_log(LOG_ERROR, "%s: Failed to create Caller ID struct\n", p->dev);
}
- if (owner->cid.cid_num) {
- ast_free(owner->cid.cid_num);
- owner->cid.cid_num = NULL;
- }
- if (owner->cid.cid_name) {
- ast_free(owner->cid.cid_name);
- owner->cid.cid_name = NULL;
- }
+ ast_party_number_free(&owner->caller.id.number);
+ ast_party_number_init(&owner->caller.id.number);
+ ast_party_name_free(&owner->caller.id.name);
+ ast_party_name_init(&owner->caller.id.name);
if (number)
ast_shrink_phone_number(number);
ast_set_callerid(owner,
number, name,
- owner->cid.cid_ani ? NULL : number);
+ owner->caller.ani ? NULL : number);
if (!ast_strlen_zero(name)){
snprintf(p->callerid, sizeof(p->callerid), "%s %s", number, name);
} else {
if (strcmp(p->owner->exten, "fax")) {
const char *target_context = S_OR(p->owner->macrocontext, p->owner->context);
- if (ast_exists_extension(p->owner, target_context, "fax", 1, p->owner->cid.cid_num)) {
+ if (ast_exists_extension(p->owner, target_context, "fax", 1,
+ S_COR(p->owner->caller.id.number.valid, p->owner->caller.id.number.str, NULL))) {
ast_verb(3, "Redirecting %s to fax extension\n", p->owner->name);
/* Save the DID/DNIS when we transfer the fax call to a "fax" extension */
pbx_builtin_setvar_helper(p->owner, "FAXEXTEN", p->owner->exten);
return 0;
}
-static int analog_send_callerid(struct analog_pvt *p, int cwcid, struct ast_callerid *cid)
+static int analog_send_callerid(struct analog_pvt *p, int cwcid, struct ast_party_caller *caller)
{
- ast_debug(1, "Sending callerid. CID_NAME: '%s' CID_NUM: '%s'\n", cid->cid_name, cid->cid_num);
+ ast_debug(1, "Sending callerid. CID_NAME: '%s' CID_NUM: '%s'\n",
+ caller->id.name.str,
+ caller->id.number.str);
if (cwcid) {
p->callwaitcas = 0;
}
if (p->calls->send_callerid) {
- return p->calls->send_callerid(p->chan_pvt, cwcid, cid);
+ return p->calls->send_callerid(p->chan_pvt, cwcid, caller);
}
return 0;
}
char *c, *n, *l;
char dest[256]; /* must be same length as p->dialdest */
- ast_log(LOG_DEBUG, "CALLING CID_NAME: %s CID_NUM:: %s\n", ast->connected.id.name, ast->connected.id.number);
+ ast_log(LOG_DEBUG, "CALLING CID_NAME: %s CID_NUM:: %s\n",
+ S_COR(ast->connected.id.name.valid, ast->connected.id.name.str, ""),
+ S_COR(ast->connected.id.number.valid, ast->connected.id.number.str, ""));
ast_copy_string(dest, rdest, sizeof(dest));
ast_copy_string(p->dialdest, rdest, sizeof(p->dialdest));
}
analog_set_dialing(p, 1);
} else {
- if (ast->connected.id.number) {
- ast_copy_string(p->callwait_num, ast->connected.id.number, sizeof(p->callwait_num));
+ if (ast->connected.id.number.valid && ast->connected.id.number.str) {
+ ast_copy_string(p->callwait_num, ast->connected.id.number.str, sizeof(p->callwait_num));
} else {
p->callwait_num[0] = '\0';
}
- if (ast->connected.id.name) {
- ast_copy_string(p->callwait_name, ast->connected.id.name, sizeof(p->callwait_name));
+ if (ast->connected.id.name.valid && ast->connected.id.name.str) {
+ ast_copy_string(p->callwait_name, ast->connected.id.name.str, sizeof(p->callwait_name));
} else {
p->callwait_name[0] = '\0';
}
}
}
- n = ast->connected.id.name;
- l = ast->connected.id.number;
+ n = ast->connected.id.name.valid ? ast->connected.id.name.str : NULL;
+ l = ast->connected.id.number.valid ? ast->connected.id.number.str : NULL;
if (l) {
ast_copy_string(p->lastcid_num, l, sizeof(p->lastcid_num));
} else {
}
if (p->use_callerid) {
- p->cid.cid_name = p->lastcid_name;
- p->cid.cid_num = p->lastcid_num;
+ p->caller.id.name.str = p->lastcid_name;
+ p->caller.id.number.str = p->lastcid_num;
}
ast_setstate(ast, AST_STATE_RINGING);
switch (mysig) {
case ANALOG_SIG_FEATD:
- l = ast->connected.id.number;
+ l = ast->connected.id.number.valid ? ast->connected.id.number.str : NULL;
if (l) {
snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T*%s*%s*", l, c);
} else {
}
break;
case ANALOG_SIG_FEATDMF:
- l = ast->connected.id.number;
+ l = ast->connected.id.number.valid ? ast->connected.id.number.str : NULL;
if (l) {
snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*00%s#*%s#", l, c);
} else {
if (p->callwaitcas) {
if ((f->subclass.integer == 'A') || (f->subclass.integer == 'D')) {
ast_debug(1, "Got some DTMF, but it's for the CAS\n");
- p->cid.cid_name = p->callwait_name;
- p->cid.cid_num = p->callwait_num;
- analog_send_callerid(p, 1, &p->cid);
+ p->caller.id.name.str = p->callwait_name;
+ p->caller.id.number.str = p->callwait_num;
+ analog_send_callerid(p, 1, &p->caller);
}
if (analog_handles_digit(f))
p->callwaitcas = 0;
analog_dsp_set_digitmode(p, ANALOG_DIGITMODE_DTMF);
- if (ast_exists_extension(chan, chan->context, exten, 1, chan->cid.cid_num)) {
+ if (ast_exists_extension(chan, chan->context, exten, 1,
+ chan->caller.id.number.valid ? chan->caller.id.number.str : NULL)) {
ast_copy_string(chan->exten, exten, sizeof(chan->exten));
analog_dsp_reset_and_flush_digits(p);
res = ast_pbx_run(chan);
ast_verb(3, "Disabling Caller*ID on %s\n", chan->name);
/* Disable Caller*ID if enabled */
p->hidecallerid = 1;
- if (chan->cid.cid_num) {
- free(chan->cid.cid_num);
- }
- chan->cid.cid_num = NULL;
- if (chan->cid.cid_name) {
- free(chan->cid.cid_name);
- }
- chan->cid.cid_name = NULL;
+ ast_party_number_free(&chan->caller.id.number);
+ ast_party_number_init(&chan->caller.id.number);
+ ast_party_name_free(&chan->caller.id.name);
+ ast_party_name_init(&chan->caller.id.name);
res = analog_play_tone(p, index, ANALOG_TONE_DIALRECALL);
if (res) {
ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n",
ast_verb(3, "Enabling Caller*ID on %s\n", chan->name);
/* Enable Caller*ID if enabled */
p->hidecallerid = 0;
- if (chan->cid.cid_num) {
- free(chan->cid.cid_num);
- }
- chan->cid.cid_num = NULL;
- if (chan->cid.cid_name) {
- free(chan->cid.cid_name);
- }
- chan->cid.cid_name = NULL;
ast_set_callerid(chan, p->cid_num, p->cid_name, NULL);
res = analog_play_tone(p, index, ANALOG_TONE_DIALRECALL);
if (res) {
ast_hangup(chan);
goto quit;
}
- } else if (!ast_canmatch_extension(chan, chan->context, exten, 1, chan->cid.cid_num) &&
- ((exten[0] != '*') || (strlen(exten) > 2))) {
- ast_debug(1, "Can't match %s from '%s' in context %s\n", exten, chan->cid.cid_num ? chan->cid.cid_num : "<Unknown Caller>", chan->context);
+ } else if (!ast_canmatch_extension(chan, chan->context, exten, 1,
+ chan->caller.id.number.valid ? chan->caller.id.number.str : NULL)
+ && ((exten[0] != '*') || (strlen(exten) > 2))) {
+ ast_debug(1, "Can't match %s from '%s' in context %s\n", exten,
+ chan->caller.id.number.valid && chan->caller.id.number.str
+ ? chan->caller.id.number.str : "<Unknown Caller>",
+ chan->context);
break;
}
if (!timeout) {
if (p->inalarm) break;
ast->rings++;
if (ast->rings == p->cidrings) {
- analog_send_callerid(p, 0, &p->cid);
+ analog_send_callerid(p, 0, &p->caller);
}
if (ast->rings > p->cidrings) {
}
ast_queue_control(p->subs[ANALOG_SUB_REAL].owner, AST_CONTROL_UNHOLD);
} else if (!p->subs[ANALOG_SUB_THREEWAY].owner) {
- char cid_num[256];
- char cid_name[256];
-
if (!p->threewaycalling) {
/* Just send a flash if no 3-way calling */
ast_queue_control(p->subs[ANALOG_SUB_REAL].owner, AST_CONTROL_FLASH);
goto winkflashdone;
} else if (!analog_check_for_conference(p)) {
+ char cid_num[256];
+ char cid_name[256];
+
+ cid_num[0] = '\0';
+ cid_name[0] = '\0';
if (p->dahditrcallerid && p->owner) {
- if (p->owner->cid.cid_num) {
- ast_copy_string(cid_num, p->owner->cid.cid_num, sizeof(cid_num));
+ if (p->owner->caller.id.number.valid
+ && p->owner->caller.id.number.str) {
+ ast_copy_string(cid_num, p->owner->caller.id.number.str,
+ sizeof(cid_num));
}
- if (p->owner->cid.cid_name) {
- ast_copy_string(cid_name, p->owner->cid.cid_name, sizeof(cid_name));
+ if (p->owner->caller.id.name.valid
+ && p->owner->caller.id.name.str) {
+ ast_copy_string(cid_name, p->owner->caller.id.name.str,
+ sizeof(cid_name));
}
}
/* XXX This section needs much more error checking!!! XXX */
case ANALOG_SIG_FEATDMF_TA:
switch (p->whichwink) {
case 0:
- ast_debug(1, "ANI2 set to '%d' and ANI is '%s'\n", p->owner->cid.cid_ani2, p->owner->cid.cid_ani);
- snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*%d%s#", p->owner->cid.cid_ani2, p->owner->cid.cid_ani);
+ ast_debug(1, "ANI2 set to '%d' and ANI is '%s'\n", p->owner->caller.ani2,
+ S_OR(p->owner->caller.ani, ""));
+ snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*%d%s#",
+ p->owner->caller.ani2,
+ S_OR(p->owner->caller.ani, ""));
break;
case 1:
ast_copy_string(p->dop.dialstr, p->finaldial, sizeof(p->dop.dialstr));
int (* const train_echocanceller)(void *pvt);
int (* const dsp_set_digitmode)(void *pvt, enum analog_dsp_digitmode mode);
int (* const dsp_reset_and_flush_digits)(void *pvt);
- int (* const send_callerid)(void *pvt, int cwcid, struct ast_callerid *cid);
+ int (* const send_callerid)(void *pvt, int cwcid, struct ast_party_caller *caller);
/* Returns 0 if CID received. Returns 1 if event received, and -1 if error. name and num are size ANALOG_MAX_CID */
int (* const get_callerid)(void *pvt, char *name, char *num, enum analog_event *ev, size_t timeout);
/* Start CID detection */
char callwait_name[AST_MAX_EXTENSION];
char lastcid_num[AST_MAX_EXTENSION];
char lastcid_name[AST_MAX_EXTENSION];
- struct ast_callerid cid;
+ struct ast_party_caller caller;
int cidrings; /*!< Which ring to deliver CID on */
char echorest[20];
int polarity;
if (p->calls->set_callerid) {
ast_party_caller_init(&caller);
- caller.id.number = p->cid_num;
- caller.id.name = p->cid_name;
+
+ caller.id.name.str = p->cid_name;
+ caller.id.name.presentation = p->callingpres;
+ caller.id.name.valid = 1;
+
+ caller.id.number.str = p->cid_num;
+ caller.id.number.plan = p->cid_ton;
+ caller.id.number.presentation = p->callingpres;
+ caller.id.number.valid = 1;
+
if (!ast_strlen_zero(p->cid_subaddr)) {
caller.id.subaddress.valid = 1;
//caller.id.subaddress.type = 0;/* nsap */
//caller.id.subaddress.odd_even_indicator = 0;
caller.id.subaddress.str = p->cid_subaddr;
}
- caller.id.number_type = p->cid_ton;
- caller.id.number_presentation = p->callingpres;
caller.id.tag = p->user_tag;
caller.ani = p->cid_ani;
caller.ani2 = p->cid_ani2;
/*!
* \internal
- * \brief Determine the overall presentation value for the given party.
+ * \brief Convert PRI name char_set to asterisk version.
* \since 1.8
*
- * \param id Party to determine the overall presentation value.
+ * \param pri_char_set PRI name char_set.
*
- * \return Overall presentation value for the given party converted to ast values.
+ * \return Equivalent asterisk name char_set value.
*/
-static int overall_ast_presentation(const struct pri_party_id *id)
-{
- int number_priority;
- int number_value;
- int number_screening;
- int name_priority;
- int name_value;
-
- /* Determine name presentation priority. */
- if (!id->name.valid) {
- name_value = PRI_PRES_UNAVAILABLE;
- name_priority = 3;
- } else {
- name_value = id->name.presentation & PRI_PRES_RESTRICTION;
- switch (name_value) {
- case PRI_PRES_RESTRICTED:
- name_priority = 0;
- break;
- case PRI_PRES_ALLOWED:
- name_priority = 1;
- break;
- case PRI_PRES_UNAVAILABLE:
- name_priority = 2;
- break;
- default:
- name_value = PRI_PRES_UNAVAILABLE;
- name_priority = 3;
- break;
- }
- }
+static enum AST_PARTY_CHAR_SET pri_to_ast_char_set(int pri_char_set)
+{
+ enum AST_PARTY_CHAR_SET ast_char_set;
- /* Determine number presentation priority. */
- if (!id->number.valid) {
- number_screening = PRI_PRES_USER_NUMBER_UNSCREENED;
- number_value = PRI_PRES_UNAVAILABLE;
- number_priority = 3;
- } else {
- number_screening = id->number.presentation & PRI_PRES_NUMBER_TYPE;
- number_value = id->number.presentation & PRI_PRES_RESTRICTION;
- switch (number_value) {
- case PRI_PRES_RESTRICTED:
- number_priority = 0;
- break;
- case PRI_PRES_ALLOWED:
- number_priority = 1;
- break;
- case PRI_PRES_UNAVAILABLE:
- number_priority = 2;
- break;
- default:
- number_screening = PRI_PRES_USER_NUMBER_UNSCREENED;
- number_value = PRI_PRES_UNAVAILABLE;
- number_priority = 3;
- break;
- }
+ switch (pri_char_set) {
+ default:
+ case PRI_CHAR_SET_UNKNOWN:
+ ast_char_set = AST_PARTY_CHAR_SET_UNKNOWN;
+ break;
+ case PRI_CHAR_SET_ISO8859_1:
+ ast_char_set = AST_PARTY_CHAR_SET_ISO8859_1;
+ break;
+ case PRI_CHAR_SET_WITHDRAWN:
+ ast_char_set = AST_PARTY_CHAR_SET_WITHDRAWN;
+ break;
+ case PRI_CHAR_SET_ISO8859_2:
+ ast_char_set = AST_PARTY_CHAR_SET_ISO8859_2;
+ break;
+ case PRI_CHAR_SET_ISO8859_3:
+ ast_char_set = AST_PARTY_CHAR_SET_ISO8859_3;
+ break;
+ case PRI_CHAR_SET_ISO8859_4:
+ ast_char_set = AST_PARTY_CHAR_SET_ISO8859_4;
+ break;
+ case PRI_CHAR_SET_ISO8859_5:
+ ast_char_set = AST_PARTY_CHAR_SET_ISO8859_5;
+ break;
+ case PRI_CHAR_SET_ISO8859_7:
+ ast_char_set = AST_PARTY_CHAR_SET_ISO8859_7;
+ break;
+ case PRI_CHAR_SET_ISO10646_BMPSTRING:
+ ast_char_set = AST_PARTY_CHAR_SET_ISO10646_BMPSTRING;
+ break;
+ case PRI_CHAR_SET_ISO10646_UTF_8STRING:
+ ast_char_set = AST_PARTY_CHAR_SET_ISO10646_UTF_8STRING;
+ break;
}
- /* Select the wining presentation value. */
- if (name_priority < number_priority) {
- number_value = name_value;
+ return ast_char_set;
+}
+
+/*!
+ * \internal
+ * \brief Convert asterisk name char_set to PRI version.
+ * \since 1.8
+ *
+ * \param ast_char_set Asterisk name char_set.
+ *
+ * \return Equivalent PRI name char_set value.
+ */
+static int ast_to_pri_char_set(enum AST_PARTY_CHAR_SET ast_char_set)
+{
+ int pri_char_set;
+
+ switch (ast_char_set) {
+ default:
+ case AST_PARTY_CHAR_SET_UNKNOWN:
+ pri_char_set = PRI_CHAR_SET_UNKNOWN;
+ break;
+ case AST_PARTY_CHAR_SET_ISO8859_1:
+ pri_char_set = PRI_CHAR_SET_ISO8859_1;
+ break;
+ case AST_PARTY_CHAR_SET_WITHDRAWN:
+ pri_char_set = PRI_CHAR_SET_WITHDRAWN;
+ break;
+ case AST_PARTY_CHAR_SET_ISO8859_2:
+ pri_char_set = PRI_CHAR_SET_ISO8859_2;
+ break;
+ case AST_PARTY_CHAR_SET_ISO8859_3:
+ pri_char_set = PRI_CHAR_SET_ISO8859_3;
+ break;
+ case AST_PARTY_CHAR_SET_ISO8859_4:
+ pri_char_set = PRI_CHAR_SET_ISO8859_4;
+ break;
+ case AST_PARTY_CHAR_SET_ISO8859_5:
+ pri_char_set = PRI_CHAR_SET_ISO8859_5;
+ break;
+ case AST_PARTY_CHAR_SET_ISO8859_7:
+ pri_char_set = PRI_CHAR_SET_ISO8859_7;
+ break;
+ case AST_PARTY_CHAR_SET_ISO10646_BMPSTRING:
+ pri_char_set = PRI_CHAR_SET_ISO10646_BMPSTRING;
+ break;
+ case AST_PARTY_CHAR_SET_ISO10646_UTF_8STRING:
+ pri_char_set = PRI_CHAR_SET_ISO10646_UTF_8STRING;
+ break;
}
- return pri_to_ast_presentation(number_value | number_screening);
+ return pri_char_set;
}
#if defined(HAVE_PRI_SUBADDR)
}
#endif /* defined(HAVE_PRI_SUBADDR) */
+/*!
+ * \internal
+ * \brief Fill in the PRI party name from the given asterisk party name.
+ * \since 1.8
+ *
+ * \param pri_name PRI party name structure.
+ * \param ast_name Asterisk party name structure.
+ *
+ * \return Nothing
+ *
+ * \note Assumes that pri_name has been previously memset to zero.
+ */
+static void sig_pri_party_name_from_ast(struct pri_party_name *pri_name, const struct ast_party_name *ast_name)
+{
+ if (!ast_name->valid) {
+ return;
+ }
+ pri_name->valid = 1;
+ pri_name->presentation = ast_to_pri_presentation(ast_name->presentation);
+ pri_name->char_set = ast_to_pri_char_set(ast_name->char_set);
+ if (!ast_strlen_zero(ast_name->str)) {
+ ast_copy_string(pri_name->str, ast_name->str, sizeof(pri_name->str));
+ }
+}
+
+/*!
+ * \internal
+ * \brief Fill in the PRI party number from the given asterisk party number.
+ * \since 1.8
+ *
+ * \param pri_number PRI party number structure.
+ * \param ast_number Asterisk party number structure.
+ *
+ * \return Nothing
+ *
+ * \note Assumes that pri_number has been previously memset to zero.
+ */
+static void sig_pri_party_number_from_ast(struct pri_party_number *pri_number, const struct ast_party_number *ast_number)
+{
+ if (!ast_number->valid) {
+ return;
+ }
+ pri_number->valid = 1;
+ pri_number->presentation = ast_to_pri_presentation(ast_number->presentation);
+ pri_number->plan = ast_number->plan;
+ if (!ast_strlen_zero(ast_number->str)) {
+ ast_copy_string(pri_number->str, ast_number->str, sizeof(pri_number->str));
+ }
+}
+
/*!
* \internal
* \brief Fill in the PRI party id from the given asterisk party id.
*/
static void sig_pri_party_id_from_ast(struct pri_party_id *pri_id, const struct ast_party_id *ast_id)
{
- int presentation;
-
- presentation = ast_to_pri_presentation(ast_id->number_presentation);
- if (!ast_strlen_zero(ast_id->name)) {
- pri_id->name.valid = 1;
- pri_id->name.presentation = presentation;
- pri_id->name.char_set = PRI_CHAR_SET_ISO8859_1;
- ast_copy_string(pri_id->name.str, ast_id->name, sizeof(pri_id->name.str));
- }
- if (!ast_strlen_zero(ast_id->number)) {
- pri_id->number.valid = 1;
- pri_id->number.presentation = presentation;
- pri_id->number.plan = ast_id->number_type;
- ast_copy_string(pri_id->number.str, ast_id->number, sizeof(pri_id->number.str));
- }
+ sig_pri_party_name_from_ast(&pri_id->name, &ast_id->name);
+ sig_pri_party_number_from_ast(&pri_id->number, &ast_id->number);
#if defined(HAVE_PRI_SUBADDR)
sig_pri_party_subaddress_from_ast(&pri_id->subaddress, &ast_id->subaddress);
#endif /* defined(HAVE_PRI_SUBADDR) */
exten[0] = 's';
exten[1] = '\0';
} else {
- if (chan->cid.cid_dnid) {
- ast_free(chan->cid.cid_dnid);
- }
- chan->cid.cid_dnid = ast_strdup(exten);
+ ast_free(chan->dialed.number.str);
+ chan->dialed.number.str = ast_strdup(exten);
if (p->pri->append_msn_to_user_tag && p->pri->nodetype != PRI_NETWORK) {
/*
*/
snprintf(p->user_tag, sizeof(p->user_tag), "%s_%s", p->pri->initial_user_tag,
exten);
- ast_free(chan->cid.cid_tag);
- chan->cid.cid_tag = ast_strdup(p->user_tag);
+ ast_free(chan->caller.id.tag);
+ chan->caller.id.tag = ast_strdup(p->user_tag);
}
}
sig_pri_play_tone(p, -1);
pri_restart(pri->dchans[index]);
}
+/*!
+ * \internal
+ * \brief Convert libpri party name into asterisk party name.
+ * \since 1.8
+ *
+ * \param ast_name Asterisk party name structure to fill. Must already be set initialized.
+ * \param pri_name libpri party name structure containing source information.
+ *
+ * \note The filled in ast_name structure needs to be destroyed by
+ * ast_party_name_free() when it is no longer needed.
+ *
+ * \return Nothing
+ */
+static void sig_pri_party_name_convert(struct ast_party_name *ast_name, const struct pri_party_name *pri_name)
+{
+ ast_name->str = ast_strdup(pri_name->str);
+ ast_name->char_set = pri_to_ast_char_set(pri_name->char_set);
+ ast_name->presentation = pri_to_ast_presentation(pri_name->presentation);
+ ast_name->valid = 1;
+}
+
+/*!
+ * \internal
+ * \brief Convert libpri party number into asterisk party number.
+ * \since 1.8
+ *
+ * \param ast_number Asterisk party number structure to fill. Must already be set initialized.
+ * \param pri_number libpri party number structure containing source information.
+ * \param pri Span controlling structure.
+ *
+ * \note The filled in ast_number structure needs to be destroyed by
+ * ast_party_number_free() when it is no longer needed.
+ *
+ * \return Nothing
+ */
+static void sig_pri_party_number_convert(struct ast_party_number *ast_number, const struct pri_party_number *pri_number, struct sig_pri_pri *pri)
+{
+ char number[AST_MAX_EXTENSION];
+
+ apply_plan_to_number(number, sizeof(number), pri, pri_number->str, pri_number->plan);
+ ast_number->str = ast_strdup(number);
+ ast_number->plan = pri_number->plan;
+ ast_number->presentation = pri_to_ast_presentation(pri_number->presentation);
+ ast_number->valid = 1;
+}
+
/*!
* \internal
* \brief Convert libpri party id into asterisk party id.
*
* \return Nothing
*/
-static void sig_pri_party_id_convert(struct ast_party_id *ast_id,
- const struct pri_party_id *pri_id, struct sig_pri_pri *pri)
+static void sig_pri_party_id_convert(struct ast_party_id *ast_id, const struct pri_party_id *pri_id, struct sig_pri_pri *pri)
{
- char number[AST_MAX_EXTENSION];
-
if (pri_id->name.valid) {
- ast_id->name = ast_strdup(pri_id->name.str);
+ sig_pri_party_name_convert(&ast_id->name, &pri_id->name);
}
if (pri_id->number.valid) {
- apply_plan_to_number(number, sizeof(number), pri, pri_id->number.str,
- pri_id->number.plan);
- ast_id->number = ast_strdup(number);
- ast_id->number_type = pri_id->number.plan;
- }
- if (pri_id->name.valid || pri_id->number.valid) {
- ast_id->number_presentation = overall_ast_presentation(pri_id);
+ sig_pri_party_number_convert(&ast_id->number, &pri_id->number, pri);
}
#if defined(HAVE_PRI_SUBADDR)
if (pri_id->subaddress.valid) {
*/
static void sig_pri_event_party_id(struct ast_str **msg, const char *prefix, struct ast_party_id *party)
{
- ast_str_append(msg, 0, "%sPres: %d (%s)\r\n", prefix,
- party->number_presentation,
- ast_describe_caller_presentation(party->number_presentation));
- ast_str_append(msg, 0, "%sNum: %s\r\n", prefix, S_OR(party->number, ""));
- ast_str_append(msg, 0, "%ston: %d\r\n", prefix, party->number_type);
- ast_str_append(msg, 0, "%sName: %s\r\n", prefix, S_OR(party->name, ""));
+ int pres;
+
+ /* Combined party presentation */
+ pres = ast_party_id_presentation(party);
+ ast_str_append(msg, 0, "%sPres: %d (%s)\r\n", prefix, pres,
+ ast_describe_caller_presentation(pres));
+
+ /* Party number */
+ ast_str_append(msg, 0, "%sNumValid: %d\r\n", prefix,
+ (unsigned) party->number.valid);
+ ast_str_append(msg, 0, "%sNum: %s\r\n", prefix,
+ S_COR(party->number.valid, party->number.str, ""));
+ ast_str_append(msg, 0, "%ston: %d\r\n", prefix, party->number.plan);
+ if (party->number.valid) {
+ ast_str_append(msg, 0, "%sNumPlan: %d\r\n", prefix, party->number.plan);
+ ast_str_append(msg, 0, "%sNumPres: %d (%s)\r\n", prefix,
+ party->number.presentation,
+ ast_describe_caller_presentation(party->number.presentation));
+ }
+
+ /* Party name */
+ ast_str_append(msg, 0, "%sNameValid: %d\r\n", prefix,
+ (unsigned) party->name.valid);
+ ast_str_append(msg, 0, "%sName: %s\r\n", prefix,
+ S_COR(party->name.valid, party->name.str, ""));
+ if (party->name.valid) {
+ ast_str_append(msg, 0, "%sNameCharSet: %s\r\n", prefix,
+ ast_party_name_charset_describe(party->name.char_set));
+ ast_str_append(msg, 0, "%sNamePres: %d (%s)\r\n", prefix,
+ party->name.presentation,
+ ast_describe_caller_presentation(party->name.presentation));
+ }
+
#if defined(HAVE_PRI_SUBADDR)
+ /* Party subaddress */
if (party->subaddress.valid) {
static const char subaddress[] = "Subaddr";
ast_connected.id.tag = ast_strdup(pri->pvts[chanpos]->user_tag);
caller_id_update = 0;
- if (ast_connected.id.name) {
+ if (ast_connected.id.name.str) {
/* Save name for Caller-ID update */
ast_copy_string(pri->pvts[chanpos]->cid_name,
- ast_connected.id.name, sizeof(pri->pvts[chanpos]->cid_name));
+ ast_connected.id.name.str, sizeof(pri->pvts[chanpos]->cid_name));
caller_id_update = 1;
}
- if (ast_connected.id.number) {
+ if (ast_connected.id.number.str) {
/* Save number for Caller-ID update */
- ast_copy_string(pri->pvts[chanpos]->cid_num, ast_connected.id.number,
- sizeof(pri->pvts[chanpos]->cid_num));
- pri->pvts[chanpos]->cid_ton = ast_connected.id.number_type;
+ ast_copy_string(pri->pvts[chanpos]->cid_num,
+ ast_connected.id.number.str, sizeof(pri->pvts[chanpos]->cid_num));
+ pri->pvts[chanpos]->cid_ton = ast_connected.id.number.plan;
caller_id_update = 1;
} else {
- ast_connected.id.number = ast_strdup("");
+ ast_connected.id.number.valid = 1;
+ ast_connected.id.number.str = ast_strdup("");
}
ast_connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
pri->pvts[chanpos]->cid_subaddr[0] = '\0';
#if defined(HAVE_PRI_SUBADDR)
if (ast_connected.id.subaddress.valid) {
- ast_party_subaddress_set(&owner->cid.subaddress,
+ ast_party_subaddress_set(&owner->caller.id.subaddress,
&ast_connected.id.subaddress);
if (ast_connected.id.subaddress.str) {
ast_copy_string(pri->pvts[chanpos]->cid_subaddr,
#endif /* defined(HAVE_PRI_SUBADDR) */
if (caller_id_update) {
pri->pvts[chanpos]->callingpres =
- ast_connected.id.number_presentation;
+ ast_party_id_presentation(&ast_connected.id);
sig_pri_set_caller_id(pri->pvts[chanpos]);
- ast_set_callerid(owner, S_OR(ast_connected.id.number, NULL),
- S_OR(ast_connected.id.name, NULL),
- S_OR(ast_connected.id.number, NULL));
+ ast_set_callerid(owner, S_OR(ast_connected.id.number.str, NULL),
+ S_OR(ast_connected.id.name.str, NULL),
+ S_OR(ast_connected.id.number.str, NULL));
}
/* Update the connected line information on the other channel */
if (event_id != PRI_EVENT_RING) {
/* This connected_line update was not from a SETUP message. */
- ast_channel_queue_connected_line_update(owner, &ast_connected);
+ ast_channel_queue_connected_line_update(owner, &ast_connected, NULL);
}
ast_party_connected_line_free(&ast_connected);
/*! \todo XXX Original called data can be put in a channel data store that is inherited. */
- ast_channel_set_redirecting(owner, &ast_redirecting);
+ ast_channel_set_redirecting(owner, &ast_redirecting, NULL);
if (event_id != PRI_EVENT_RING) {
/* This redirection was not from a SETUP message. */
- ast_channel_queue_redirecting_update(owner, &ast_redirecting);
+ ast_channel_queue_redirecting_update(owner, &ast_redirecting, NULL);
}
ast_party_redirecting_free(&ast_redirecting);
&owner->redirecting, pri);
ast_redirecting.from.tag = ast_strdup(pri->pvts[chanpos]->user_tag);
ast_redirecting.to.tag = ast_strdup(pri->pvts[chanpos]->user_tag);
- ast_channel_set_redirecting(owner, &ast_redirecting);
+ ast_channel_set_redirecting(owner, &ast_redirecting, NULL);
ast_party_redirecting_free(&ast_redirecting);
/*
/* Set Calling Subaddress */
sig_pri_lock_owner(pri, chanpos);
sig_pri_set_subaddress(
- &pri->pvts[chanpos]->owner->cid.subaddress,
+ &pri->pvts[chanpos]->owner->caller.id.subaddress,
&e->ring.calling.subaddress);
if (!e->ring.calling.subaddress.type
&& !ast_strlen_zero(
/* Set Called Subaddress */
sig_pri_lock_owner(pri, chanpos);
sig_pri_set_subaddress(
- &pri->pvts[chanpos]->owner->cid.dialed_subaddress,
+ &pri->pvts[chanpos]->owner->dialed.subaddress,
&e->ring.called_subaddress);
if (!e->ring.called_subaddress.type
&& !ast_strlen_zero(
/* Set Calling Subaddress */
sig_pri_lock_owner(pri, chanpos);
sig_pri_set_subaddress(
- &pri->pvts[chanpos]->owner->cid.subaddress,
+ &pri->pvts[chanpos]->owner->caller.id.subaddress,
&e->ring.calling.subaddress);
if (!e->ring.calling.subaddress.type
&& !ast_strlen_zero(
/* Set Called Subaddress */
sig_pri_lock_owner(pri, chanpos);
sig_pri_set_subaddress(
- &pri->pvts[chanpos]->owner->cid.dialed_subaddress,
+ &pri->pvts[chanpos]->owner->dialed.subaddress,
&e->ring.called_subaddress);
if (!e->ring.called_subaddress.type
&& !ast_strlen_zero(
struct ast_flags opts;
char *opt_args[OPT_ARG_ARRAY_SIZE];
- ast_log(LOG_DEBUG, "CALLING CID_NAME: %s CID_NUM:: %s\n", ast->cid.cid_name, ast->cid.cid_num);
+ ast_log(LOG_DEBUG, "CALLER NAME: %s NUM: %s\n",
+ S_COR(ast->connected.id.name.valid, ast->connected.id.name.str, ""),
+ S_COR(ast->connected.id.number.valid, ast->connected.id.number.str, ""));
if (!p->pri) {
ast_log(LOG_ERROR, "Could not find pri on channel %d\n", p->channel);
l = NULL;
n = NULL;
if (!p->hidecallerid) {
- l = ast->connected.id.number;
+ l = ast->connected.id.number.valid ? ast->connected.id.number.str : NULL;
if (!p->hidecalleridname) {
- n = ast->connected.id.name;
+ n = ast->connected.id.name.valid ? ast->connected.id.name.str : NULL;
}
}
snprintf(p->user_tag, sizeof(p->user_tag), "%s_%s", p->pri->initial_user_tag,
p->pri->nodetype == PRI_NETWORK
? c + p->stripmsd + dp_strip
- : S_OR(ast->connected.id.number, ""));
+ : S_COR(ast->connected.id.number.valid,
+ ast->connected.id.number.str, ""));
} else {
ast_copy_string(p->user_tag, p->pri->initial_user_tag, sizeof(p->user_tag));
}
* Replace the caller id tag from the channel creation
* with the actual tag value.
*/
- ast_free(ast->cid.cid_tag);
- ast->cid.cid_tag = ast_strdup(p->user_tag);
+ ast_free(ast->caller.id.tag);
+ ast->caller.id.tag = ast_strdup(p->user_tag);
ldp_strip = 0;
prilocaldialplan = p->pri->localdialplan - 1;
}
}
pri_sr_set_caller(sr, l ? (l + ldp_strip) : NULL, n, prilocaldialplan,
- p->use_callingpres ? ast->connected.id.number_presentation : (l ? PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN : PRES_NUMBER_NOT_AVAILABLE));
+ p->use_callingpres ? ast->connected.id.number.presentation : (l ? PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN : PRES_NUMBER_NOT_AVAILABLE));
#if defined(HAVE_PRI_SUBADDR)
if (ast->connected.id.subaddress.valid) {
if (p->calls->set_callerid) {
ast_party_caller_init(&caller);
- caller.id.number = p->cid_num;
- caller.id.name = p->cid_name;
+
+ caller.id.name.str = p->cid_name;
+ caller.id.name.presentation = p->callingpres;
+ caller.id.name.valid = 1;
+
+ caller.id.number.str = p->cid_num;
+ caller.id.number.plan = p->cid_ton;
+ caller.id.number.presentation = p->callingpres;
+ caller.id.number.valid = 1;
+
if (!ast_strlen_zero(p->cid_subaddr)) {
caller.id.subaddress.valid = 1;
//caller.id.subaddress.type = 0;/* nsap */
//caller.id.subaddress.odd_even_indicator = 0;
caller.id.subaddress.str = p->cid_subaddr;
}
- caller.id.number_type = p->cid_ton;
- caller.id.number_presentation = p->callingpres;
caller.ani = p->cid_ani;
caller.ani2 = p->cid_ani2;
p->calls->set_callerid(p->chan_pvt, &caller);
}
if (!p->hidecallerid) {
- l = ast->connected.id.number;
+ l = ast->connected.id.number.valid ? ast->connected.id.number.str : NULL;
} else {
l = NULL;
}
}
}
isup_set_calling(p->ss7call, l ? (l + calling_nai_strip) : NULL, ss7_calling_nai,
- p->use_callingpres ? cid_pres2ss7pres(ast->connected.id.number_presentation) : (l ? SS7_PRESENTATION_ALLOWED : SS7_PRESENTATION_RESTRICTED),
- p->use_callingpres ? cid_pres2ss7screen(ast->connected.id.number_presentation) : SS7_SCREENING_USER_PROVIDED );
+ p->use_callingpres ? cid_pres2ss7pres(ast->connected.id.number.presentation) : (l ? SS7_PRESENTATION_ALLOWED : SS7_PRESENTATION_RESTRICTED),
+ p->use_callingpres ? cid_pres2ss7screen(ast->connected.id.number.presentation) : SS7_SCREENING_USER_PROVIDED);
isup_set_oli(p->ss7call, ast->connected.ani2);
isup_init_call(p->ss7->ss7, p->ss7call, p->cic, p->dpc);
char blacklist[1];
int bl = 0;
- if (chan->cid.cid_num) {
- if (!ast_db_get("blacklist", chan->cid.cid_num, blacklist, sizeof (blacklist)))
+ if (chan->caller.id.number.valid && chan->caller.id.number.str) {
+ if (!ast_db_get("blacklist", chan->caller.id.number.str, blacklist, sizeof (blacklist)))
bl = 1;
}
- if (chan->cid.cid_name) {
- if (!ast_db_get("blacklist", chan->cid.cid_name, blacklist, sizeof (blacklist)))
+ if (chan->caller.id.name.valid && chan->caller.id.name.str) {
+ if (!ast_db_get("blacklist", chan->caller.id.name.str, blacklist, sizeof (blacklist)))
bl = 1;
}
/*
* Asterisk -- An open source telephony toolkit.
*
- * Copyright (C) 1999-2006, Digium, Inc.
+ * Copyright (C) 1999-2010, Digium, Inc.
*
* See http://www.asterisk.org for more information about
* the Asterisk project. Please do not directly contact
/*! \file
*
- * \brief Caller ID related dialplan functions
+ * \brief Party ID related dialplan functions (Caller-ID, Connected-line, Redirecting)
*
* \ingroup functions
+ *
+ * See Also:
+ * \arg \ref AstCREDITS
*/
#include "asterisk.h"
#include "asterisk/app.h"
#include "asterisk/callerid.h"
+/*
+ * Do not document the CALLERID(pres) datatype.
+ * The name and number now have their own presentation value. The pres
+ * option will simply live on as a historical relic with as best
+ * as can be managed backward compatible meaning.
+ *
+ * Do not document the CALLERID(ton) datatype.
+ * It is an alias for num-plan.
+ *
+ * Do not document the CONNECTEDLINE(source) datatype.
+ * It has turned out to not be needed. The source value is really
+ * only useful as a possible tracing aid.
+ *
+ * Do not document the CONNECTEDLINE(pres) datatype.
+ * The name and number now have their own presentation value. The pres
+ * option will simply live on as a historical relic with as best
+ * as can be managed backward compatible meaning.
+ *
+ * Do not document the CONNECTEDLINE(ton) datatype.
+ * It is an alias for num-plan.
+ *
+ * Do not document the REDIRECTING(pres) datatype.
+ * It has turned out that the from-pres and to-pres values must be kept
+ * separate. They represent two different parties and there is a case when
+ * they are active at the same time. The plain pres option will simply
+ * live on as a historical relic.
+ *
+ * Do not document the REDIRECTING(from-pres) or REDIRECTING(to-pres) datatypes.
+ * The name and number now have their own presentation value. The from-pres
+ * and to-pres options will simply live on as a historical relic with as best
+ * as can be managed backward compatible meaning.
+ *
+ * Do not document the REDIRECTING(from-ton) or REDIRECTING(to-ton) datatypes.
+ * They are aliases for from-num-plan and to-num-plan respectively.
+ */
/*** DOCUMENTATION
<function name="CALLERID" language="en_US">
<synopsis>
<parameter name="datatype" required="true">
<para>The allowable datatypes are:</para>
<enumlist>
- <enum name="all" />
- <enum name="num" />
- <enum name="name" />
- <enum name="tag" />
- <enum name="ANI" />
- <enum name="DNID" />
- <enum name="RDNIS" />
- <enum name="pres" />
- <enum name="ton" />
- <enum name="subaddr[-valid]|[-type]|[-odd]">
- <para>ISDN Calling Subaddress</para>
- </enum>
- <enum name="dnid-subaddr[-valid]|[-type]|[-odd]">
- <para>ISDN Called Subaddress</para>
- </enum>
+ <enum name = "all" />
+ <enum name = "name" />
+ <enum name = "name-valid" />
+ <enum name = "name-charset" />
+ <enum name = "name-pres" />
+ <enum name = "num" />
+ <enum name = "num-valid" />
+ <enum name = "num-plan" />
+ <enum name = "num-pres" />
+ <enum name = "subaddr" />
+ <enum name = "subaddr-valid" />
+ <enum name = "subaddr-type" />
+ <enum name = "subaddr-odd" />
+ <enum name = "tag" />
+ <enum name = "ANI" />
+ <enum name = "RDNIS" />
+ <enum name = "DNID" />
+ <enum name = "dnid-num-plan" />
+ <enum name = "dnid-subaddr" />
+ <enum name = "dnid-subaddr-valid" />
+ <enum name = "dnid-subaddr-type" />
+ <enum name = "dnid-subaddr-odd" />
</enumlist>
</parameter>
<parameter name="CID">
</parameter>
</syntax>
<description>
- <para>Gets or sets Caller*ID data on the channel. Uses channel callerid by default or optional
- callerid, if specified.</para>
+ <para>Gets or sets Caller*ID data on the channel. Uses channel callerid by
+ default or optional callerid, if specified.</para>
+ <para>The allowable values for the <replaceable>name-charset</replaceable>
+ field are the following:</para>
+ <enumlist>
+ <enum name = "unknown"><para>Unknown</para></enum>
+ <enum name = "iso8859-1"><para>ISO8859-1</para></enum>
+ <enum name = "withdrawn"><para>Withdrawn</para></enum>
+ <enum name = "iso8859-2"><para>ISO8859-2</para></enum>
+ <enum name = "iso8859-3"><para>ISO8859-3</para></enum>
+ <enum name = "iso8859-4"><para>ISO8859-4</para></enum>
+ <enum name = "iso8859-5"><para>ISO8859-5</para></enum>
+ <enum name = "iso8859-7"><para>ISO8859-7</para></enum>
+ <enum name = "bmp"><para>ISO10646 Bmp String</para></enum>
+ <enum name = "utf8"><para>ISO10646 UTF-8 String</para></enum>
+ </enumlist>
</description>
</function>
<function name="CALLERPRES" language="en_US">
</synopsis>
<syntax />
<description>
- <para>Gets or sets Caller*ID presentation on the channel. The following values
- are valid:</para>
+ <para>Gets or sets Caller*ID presentation on the channel.
+ This function is deprecated in favor of CALLERID(num-pres)
+ and CALLERID(name-pres).
+ The following values are valid:</para>
<enumlist>
<enum name="allowed_not_screened">
<para>Presentation Allowed, Not Screened.</para>
</enumlist>
</description>
</function>
+ <function name="CONNECTEDLINE" language="en_US">
+ <synopsis>
+ Gets or sets Connected Line data on the channel.
+ </synopsis>
+ <syntax>
+ <parameter name="datatype" required="true">
+ <para>The allowable datatypes are:</para>
+ <enumlist>
+ <enum name = "all" />
+ <enum name = "name" />
+ <enum name = "name-valid" />
+ <enum name = "name-charset" />
+ <enum name = "name-pres" />
+ <enum name = "num" />
+ <enum name = "num-valid" />
+ <enum name = "num-plan" />
+ <enum name = "num-pres" />
+ <enum name = "subaddr" />
+ <enum name = "subaddr-valid" />
+ <enum name = "subaddr-type" />
+ <enum name = "subaddr-odd" />
+ <enum name = "tag" />
+ </enumlist>
+ </parameter>
+ <parameter name="i">
+ <para>If set, this will prevent the channel from sending out protocol
+ messages because of the value being set</para>
+ </parameter>
+ </syntax>
+ <description>
+ <para>Gets or sets Connected Line data on the channel.</para>
+ <para>The allowable values for the <replaceable>name-charset</replaceable>
+ field are the following:</para>
+ <enumlist>
+ <enum name = "unknown"><para>Unknown</para></enum>
+ <enum name = "iso8859-1"><para>ISO8859-1</para></enum>
+ <enum name = "withdrawn"><para>Withdrawn</para></enum>
+ <enum name = "iso8859-2"><para>ISO8859-2</para></enum>
+ <enum name = "iso8859-3"><para>ISO8859-3</para></enum>
+ <enum name = "iso8859-4"><para>ISO8859-4</para></enum>
+ <enum name = "iso8859-5"><para>ISO8859-5</para></enum>
+ <enum name = "iso8859-7"><para>ISO8859-7</para></enum>
+ <enum name = "bmp"><para>ISO10646 Bmp String</para></enum>
+ <enum name = "utf8"><para>ISO10646 UTF-8 String</para></enum>
+ </enumlist>
+ </description>
+ </function>
+ <function name="REDIRECTING" language="en_US">
+ <synopsis>
+ Gets or sets Redirecting data on the channel.
+ </synopsis>
+ <syntax>
+ <parameter name="datatype" required="true">
+ <para>The allowable datatypes are:</para>
+ <enumlist>
+ <enum name = "from-all" />
+ <enum name = "from-name" />
+ <enum name = "from-name-valid" />
+ <enum name = "from-name-charset" />
+ <enum name = "from-name-pres" />
+ <enum name = "from-num" />
+ <enum name = "from-num-valid" />
+ <enum name = "from-num-plan" />
+ <enum name = "from-num-pres" />
+ <enum name = "from-subaddr" />
+ <enum name = "from-subaddr-valid" />
+ <enum name = "from-subaddr-type" />
+ <enum name = "from-subaddr-odd" />
+ <enum name = "from-tag" />
+ <enum name = "to-all" />
+ <enum name = "to-name" />
+ <enum name = "to-name-valid" />
+ <enum name = "to-name-charset" />
+ <enum name = "to-name-pres" />
+ <enum name = "to-num" />
+ <enum name = "to-num-valid" />
+ <enum name = "to-num-plan" />
+ <enum name = "to-num-pres" />
+ <enum name = "to-subaddr" />
+ <enum name = "to-subaddr-valid" />
+ <enum name = "to-subaddr-type" />
+ <enum name = "to-subaddr-odd" />
+ <enum name = "to-tag" />
+ <enum name = "reason" />
+ <enum name = "count" />
+ </enumlist>
+ </parameter>
+ <parameter name="i">
+ <para>If set, this will prevent the channel from sending out protocol
+ messages because of the value being set</para>
+ </parameter>
+ </syntax>
+ <description>
+ <para>Gets or sets Redirecting data on the channel.</para>
+ <para>The allowable values for the <replaceable>reason</replaceable>
+ field are the following:</para>
+ <enumlist>
+ <enum name = "unknown"><para>Unknown</para></enum>
+ <enum name = "cfb"><para>Call Forwarding Busy</para></enum>
+ <enum name = "cfnr"><para>Call Forwarding No Reply</para></enum>
+ <enum name = "unavailable"><para>Callee is Unavailable</para></enum>
+ <enum name = "time_of_day"><para>Time of Day</para></enum>
+ <enum name = "dnd"><para>Do Not Disturb</para></enum>
+ <enum name = "deflection"><para>Call Deflection</para></enum>
+ <enum name = "follow_me"><para>Follow Me</para></enum>
+ <enum name = "out_of_order"><para>Called DTE Out-Of-Order</para></enum>
+ <enum name = "away"><para>Callee is Away</para></enum>
+ <enum name = "cf_dte"><para>Call Forwarding By The Called DTE</para></enum>
+ <enum name = "cfu"><para>Call Forwarding Unconditional</para></enum>
+ </enumlist>
+ <para>The allowable values for the <replaceable>xxx-name-charset</replaceable>
+ field are the following:</para>
+ <enumlist>
+ <enum name = "unknown"><para>Unknown</para></enum>
+ <enum name = "iso8859-1"><para>ISO8859-1</para></enum>
+ <enum name = "withdrawn"><para>Withdrawn</para></enum>
+ <enum name = "iso8859-2"><para>ISO8859-2</para></enum>
+ <enum name = "iso8859-3"><para>ISO8859-3</para></enum>
+ <enum name = "iso8859-4"><para>ISO8859-4</para></enum>
+ <enum name = "iso8859-5"><para>ISO8859-5</para></enum>
+ <enum name = "iso8859-7"><para>ISO8859-7</para></enum>
+ <enum name = "bmp"><para>ISO10646 Bmp String</para></enum>
+ <enum name = "utf8"><para>ISO10646 UTF-8 String</para></enum>
+ </enumlist>
+ </description>
+ </function>
***/
+enum ID_FIELD_STATUS {
+ ID_FIELD_VALID,
+ ID_FIELD_INVALID,
+ ID_FIELD_UNKNOWN
+};
+
+AST_DEFINE_APP_ARGS_TYPE(ast_party_func_args,
+ AST_APP_ARG(member); /*!< Member name */
+ AST_APP_ARG(opts); /*!< Options token */
+ AST_APP_ARG(other); /*!< Any remining unused arguments */
+ );
+
+AST_DEFINE_APP_ARGS_TYPE(ast_party_members,
+ AST_APP_ARG(subnames[10]); /*!< Option member subnames */
+ );
+
+enum CONNECTED_LINE_OPT_FLAGS {
+ CONNECTED_LINE_OPT_INHIBIT = (1 << 0),
+};
+enum CONNECTED_LINE_OPT_ARGS {
+ CONNECTED_LINE_OPT_DUMMY, /*!< Delete this if CONNECTED_LINE ever gets an option with parameters. */
+
+ /*! \note This entry _MUST_ be the last one in the enum */
+ CONNECTED_LINE_OPT_ARG_ARRAY_SIZE
+};
+
+AST_APP_OPTIONS(connectedline_opts, BEGIN_OPTIONS
+ AST_APP_OPTION('i', CONNECTED_LINE_OPT_INHIBIT),
+END_OPTIONS);
+
+enum REDIRECTING_OPT_FLAGS {
+ REDIRECTING_OPT_INHIBIT = (1 << 0),
+};
+enum REDIRECTING_OPT_ARGS {
+ REDIRECTING_OPT_DUMMY, /*!< Delete this if REDIRECTING ever gets an option with parameters. */
+
+ /*! \note This entry _MUST_ be the last one in the enum */
+ REDIRECTING_OPT_ARG_ARRAY_SIZE
+};
+
+AST_APP_OPTIONS(redirecting_opts, BEGIN_OPTIONS
+ AST_APP_OPTION('i', REDIRECTING_OPT_INHIBIT),
+END_OPTIONS);
+
+/*!
+ * \internal
+ * \brief Read values from the party name struct.
+ * \since 1.8
+ *
+ * \param buf Buffer to fill with read value.
+ * \param len Length of the buffer.
+ * \param argc Number of party member subnames.
+ * \param argv Party member subnames given.
+ * \param name Party name to get values from.
+ *
+ * \retval ID_FIELD_VALID on success.
+ * \retval ID_FIELD_UNKNOWN on unknown field name.
+ */
+static enum ID_FIELD_STATUS party_name_read(char *buf, size_t len, int argc, char *argv[], const struct ast_party_name *name)
+{
+ enum ID_FIELD_STATUS status;
+
+ status = ID_FIELD_VALID;
+
+ if (argc == 0) {
+ /* We want the name string */
+ if (name->valid && name->str) {
+ ast_copy_string(buf, name->str, len);
+ }
+ } else if (argc == 1 && !strcasecmp("valid", argv[0])) {
+ snprintf(buf, len, "%d", name->valid);
+ } else if (argc == 1 && !strcasecmp("charset", argv[0])) {
+ ast_copy_string(buf, ast_party_name_charset_str(name->char_set), len);
+ } else if (argc == 1 && !strncasecmp("pres", argv[0], 4)) {
+ /* Accept pres[entation] */
+ ast_copy_string(buf, ast_named_caller_presentation(name->presentation), len);
+ } else {
+ status = ID_FIELD_UNKNOWN;
+ }
+
+ return status;
+}
+
+/*!
+ * \internal
+ * \brief Read values from the party number struct.
+ * \since 1.8
+ *
+ * \param buf Buffer to fill with read value.
+ * \param len Length of the buffer.
+ * \param argc Number of party member subnames.
+ * \param argv Party member subnames given.
+ * \param number Party number to get values from.
+ *
+ * \retval ID_FIELD_VALID on success.
+ * \retval ID_FIELD_UNKNOWN on unknown field name.
+ */
+static enum ID_FIELD_STATUS party_number_read(char *buf, size_t len, int argc, char *argv[], const struct ast_party_number *number)
+{
+ enum ID_FIELD_STATUS status;
+
+ status = ID_FIELD_VALID;
+
+ if (argc == 0) {
+ /* We want the number string */
+ if (number->valid && number->str) {
+ ast_copy_string(buf, number->str, len);
+ }
+ } else if (argc == 1 && !strcasecmp("valid", argv[0])) {
+ snprintf(buf, len, "%d", number->valid);
+ } else if (argc == 1 && !strcasecmp("plan", argv[0])) {
+ snprintf(buf, len, "%d", number->plan);
+ } else if (argc == 1 && !strncasecmp("pres", argv[0], 4)) {
+ /* Accept pres[entation] */
+ ast_copy_string(buf, ast_named_caller_presentation(number->presentation), len);
+ } else {
+ status = ID_FIELD_UNKNOWN;
+ }
+
+ return status;
+}
+
+/*!
+ * \internal
+ * \brief Read values from the party subaddress struct.
+ * \since 1.8
+ *
+ * \param buf Buffer to fill with read value.
+ * \param len Length of the buffer.
+ * \param argc Number of party member subnames.
+ * \param argv Party member subnames given.
+ * \param subaddress Party subaddress to get values from.
+ *
+ * \retval ID_FIELD_VALID on success.
+ * \retval ID_FIELD_UNKNOWN on unknown field name.
+ */
+static enum ID_FIELD_STATUS party_subaddress_read(char *buf, size_t len, int argc, char *argv[], const struct ast_party_subaddress *subaddress)
+{
+ enum ID_FIELD_STATUS status;
+
+ status = ID_FIELD_VALID;
+
+ if (argc == 0) {
+ /* We want the subaddress string */
+ if (subaddress->str) {
+ ast_copy_string(buf, subaddress->str, len);
+ }
+ } else if (argc == 1 && !strcasecmp("valid", argv[0])) {
+ snprintf(buf, len, "%d", subaddress->valid);
+ } else if (argc == 1 && !strcasecmp("type", argv[0])) {
+ snprintf(buf, len, "%d", subaddress->type);
+ } else if (argc == 1 && !strcasecmp("odd", argv[0])) {
+ snprintf(buf, len, "%d", subaddress->odd_even_indicator);
+ } else {
+ status = ID_FIELD_UNKNOWN;
+ }
+
+ return status;
+}
+
+/*!
+ * \internal
+ * \brief Read values from the party id struct.
+ * \since 1.8
+ *
+ * \param buf Buffer to fill with read value.
+ * \param len Length of the buffer.
+ * \param argc Number of party member subnames.
+ * \param argv Party member subnames given.
+ * \param id Party id to get values from.
+ *
+ * \retval ID_FIELD_VALID on success.
+ * \retval ID_FIELD_UNKNOWN on unknown field name.
+ */
+static enum ID_FIELD_STATUS party_id_read(char *buf, size_t len, int argc, char *argv[], const struct ast_party_id *id)
+{
+ enum ID_FIELD_STATUS status;
+
+ if (argc == 0) {
+ /* Must have at least one subname. */
+ return ID_FIELD_UNKNOWN;
+ }
+
+ status = ID_FIELD_VALID;
+
+ if (argc == 1 && !strcasecmp("all", argv[0])) {
+ snprintf(buf, len, "\"%s\" <%s>",
+ S_COR(id->name.valid, id->name.str, ""),
+ S_COR(id->number.valid, id->number.str, ""));
+ } else if (!strcasecmp("name", argv[0])) {
+ status = party_name_read(buf, len, argc - 1, argv + 1, &id->name);
+ } else if (!strncasecmp("num", argv[0], 3)) {
+ /* Accept num[ber] */
+ status = party_number_read(buf, len, argc - 1, argv + 1, &id->number);
+ } else if (!strncasecmp("subaddr", argv[0], 7)) {
+ /* Accept subaddr[ess] */
+ status = party_subaddress_read(buf, len, argc - 1, argv + 1, &id->subaddress);
+ } else if (argc == 1 && !strcasecmp("tag", argv[0])) {
+ if (id->tag) {
+ ast_copy_string(buf, id->tag, len);
+ }
+ } else if (argc == 1 && !strcasecmp("ton", argv[0])) {
+ /* ton is an alias for num-plan */
+ snprintf(buf, len, "%d", id->number.plan);
+ } else if (argc == 1 && !strncasecmp("pres", argv[0], 4)) {
+ /*
+ * Accept pres[entation]
+ * This is the combined name/number presentation.
+ */
+ ast_copy_string(buf,
+ ast_named_caller_presentation(ast_party_id_presentation(id)), len);
+ } else {
+ status = ID_FIELD_UNKNOWN;
+ }
+
+ return status;
+}
+
+/*!
+ * \internal
+ * \brief Write new values to the party name struct
+ * \since 1.8
+ *
+ * \param name Party name struct to write values
+ * \param argc Number of party member subnames.
+ * \param argv Party member subnames given.
+ * \param value Value to assign to the party name.
+ *
+ * \retval ID_FIELD_VALID on success.
+ * \retval ID_FIELD_INVALID on error with field value.
+ * \retval ID_FIELD_UNKNOWN on unknown field name.
+ */
+static enum ID_FIELD_STATUS party_name_write(struct ast_party_name *name, int argc, char *argv[], const char *value)
+{
+ char *val;
+ enum ID_FIELD_STATUS status;
+
+ status = ID_FIELD_VALID;
+
+ if (argc == 0) {
+ /* We are setting the name string */
+ name->valid = 1;
+ name->str = ast_strdup(value);
+ ast_trim_blanks(name->str);
+ } else if (argc == 1 && !strcasecmp("valid", argv[0])) {
+ name->valid = atoi(value) ? 1 : 0;
+ } else if (argc == 1 && !strcasecmp("charset", argv[0])) {
+ int char_set;
+
+ val = ast_strdupa(value);
+ ast_trim_blanks(val);
+
+ if (('0' <= val[0]) && (val[0] <= '9')) {
+ char_set = atoi(val);
+ } else {
+ char_set = ast_party_name_charset_parse(val);
+ }
+
+ if (char_set < 0) {
+ ast_log(LOG_ERROR,
+ "Unknown name char-set '%s', value unchanged\n", val);
+ status = ID_FIELD_INVALID;
+ } else {
+ name->char_set = char_set;
+ }
+ } else if (argc == 1 && !strncasecmp("pres", argv[0], 4)) {
+ int pres;
+
+ /* Accept pres[entation] */
+ val = ast_strdupa(value);
+ ast_trim_blanks(val);
+
+ if (('0' <= val[0]) && (val[0] <= '9')) {
+ pres = atoi(val);
+ } else {
+ pres = ast_parse_caller_presentation(val);
+ }
+
+ if (pres < 0) {
+ ast_log(LOG_ERROR,
+ "Unknown name presentation '%s', value unchanged\n", val);
+ status = ID_FIELD_INVALID;
+ } else {
+ name->presentation = pres;
+ }
+ } else {
+ status = ID_FIELD_UNKNOWN;
+ }
+
+ return status;
+}
+
+/*!
+ * \internal
+ * \brief Write new values to the party number struct
+ * \since 1.8
+ *
+ * \param number Party number struct to write values
+ * \param argc Number of party member subnames.
+ * \param argv Party member subnames given.
+ * \param value Value to assign to the party number.
+ *
+ * \retval ID_FIELD_VALID on success.
+ * \retval ID_FIELD_INVALID on error with field value.
+ * \retval ID_FIELD_UNKNOWN on unknown field name.
+ */
+static enum ID_FIELD_STATUS party_number_write(struct ast_party_number *number, int argc, char *argv[], const char *value)
+{
+ char *val;
+ enum ID_FIELD_STATUS status;
+
+ status = ID_FIELD_VALID;
+
+ if (argc == 0) {
+ /* We are setting the number string */
+ number->valid = 1;
+ number->str = ast_strdup(value);
+ ast_trim_blanks(number->str);
+ } else if (argc == 1 && !strcasecmp("valid", argv[0])) {
+ number->valid = atoi(value) ? 1 : 0;
+ } else if (argc == 1 && !strcasecmp("plan", argv[0])) {
+ val = ast_strdupa(value);
+ ast_trim_blanks(val);
+
+ if (('0' <= val[0]) && (val[0] <= '9')) {
+ number->plan = atoi(val);
+ } else {
+ ast_log(LOG_ERROR,
+ "Unknown type-of-number/numbering-plan '%s', value unchanged\n", val);
+ status = ID_FIELD_INVALID;
+ }
+ } else if (argc == 1 && !strncasecmp("pres", argv[0], 4)) {
+ int pres;
+
+ /* Accept pres[entation] */
+ val = ast_strdupa(value);
+ ast_trim_blanks(val);
+
+ if (('0' <= val[0]) && (val[0] <= '9')) {
+ pres = atoi(val);
+ } else {
+ pres = ast_parse_caller_presentation(val);
+ }
+
+ if (pres < 0) {
+ ast_log(LOG_ERROR,
+ "Unknown number presentation '%s', value unchanged\n", val);
+ status = ID_FIELD_INVALID;
+ } else {
+ number->presentation = pres;
+ }
+ } else {
+ status = ID_FIELD_UNKNOWN;
+ }
+
+ return status;
+}
+
+/*!
+ * \internal
+ * \brief Write new values to the party subaddress struct
+ * \since 1.8
+ *
+ * \param subaddress Party subaddress struct to write values
+ * \param argc Number of party member subnames.
+ * \param argv Party member subnames given.
+ * \param value Value to assign to the party subaddress.
+ *
+ * \retval ID_FIELD_VALID on success.
+ * \retval ID_FIELD_INVALID on error with field value.
+ * \retval ID_FIELD_UNKNOWN on unknown field name.
+ */
+static enum ID_FIELD_STATUS party_subaddress_write(struct ast_party_subaddress *subaddress, int argc, char *argv[], const char *value)
+{
+ enum ID_FIELD_STATUS status;
+
+ status = ID_FIELD_VALID;
+
+ if (argc == 0) {
+ /* We are setting the subaddress string */
+ subaddress->str = ast_strdup(value);
+ ast_trim_blanks(subaddress->str);
+ } else if (argc == 1 && !strcasecmp("valid", argv[0])) {
+ subaddress->valid = atoi(value) ? 1 : 0;
+ } else if (argc == 1 && !strcasecmp("type", argv[0])) {
+ subaddress->type = atoi(value) ? 2 : 0;
+ } else if (argc == 1 && !strcasecmp("odd", argv[0])) {
+ subaddress->odd_even_indicator = atoi(value) ? 1 : 0;
+ } else {
+ status = ID_FIELD_UNKNOWN;
+ }
+
+ return status;
+}
+
+/*!
+ * \internal
+ * \brief Write new values to the party id struct
+ * \since 1.8
+ *
+ * \param id Party ID struct to write values
+ * \param argc Number of party member subnames.
+ * \param argv Party member subnames given.
+ * \param value Value to assign to the party id.
+ *
+ * \retval ID_FIELD_VALID on success.
+ * \retval ID_FIELD_INVALID on error with field value.
+ * \retval ID_FIELD_UNKNOWN on unknown field name.
+ */
+static enum ID_FIELD_STATUS party_id_write(struct ast_party_id *id, int argc, char *argv[], const char *value)
+{
+ char *val;
+ enum ID_FIELD_STATUS status;
+
+ if (argc == 0) {
+ /* Must have at least one subname. */
+ return ID_FIELD_UNKNOWN;
+ }
+
+ status = ID_FIELD_VALID;
+
+ if (argc == 1 && !strcasecmp("all", argv[0])) {
+ char name[256];
+ char num[256];
+
+ ast_callerid_split(value, name, sizeof(name), num, sizeof(num));
+ id->name.valid = 1;
+ id->name.str = ast_strdup(name);
+ if (!id->name.str) {
+ return ID_FIELD_INVALID;
+ }
+ id->number.valid = 1;
+ id->number.str = ast_strdup(num);
+ if (!id->number.str) {
+ return ID_FIELD_INVALID;
+ }
+ } else if (!strcasecmp("name", argv[0])) {
+ status = party_name_write(&id->name, argc - 1, argv + 1, value);
+ } else if (!strncasecmp("num", argv[0], 3)) {
+ /* Accept num[ber] */
+ status = party_number_write(&id->number, argc - 1, argv + 1, value);
+ } else if (!strncasecmp("subaddr", argv[0], 7)) {
+ /* Accept subaddr[ess] */
+ status = party_subaddress_write(&id->subaddress, argc - 1, argv + 1, value);
+ } else if (argc == 1 && !strcasecmp("tag", argv[0])) {
+ id->tag = ast_strdup(value);
+ ast_trim_blanks(id->tag);
+ } else if (argc == 1 && !strcasecmp("ton", argv[0])) {
+ /* ton is an alias for num-plan */
+ argv[0] = "plan";
+ status = party_number_write(&id->number, argc, argv, value);
+ } else if (argc == 1 && !strncasecmp("pres", argv[0], 4)) {
+ int pres;
+
+ /*
+ * Accept pres[entation]
+ * This is the combined name/number presentation.
+ */
+ val = ast_strdupa(value);
+ ast_trim_blanks(val);
+
+ if (('0' <= val[0]) && (val[0] <= '9')) {
+ pres = atoi(val);
+ } else {
+ pres = ast_parse_caller_presentation(val);
+ }
+
+ if (pres < 0) {
+ ast_log(LOG_ERROR,
+ "Unknown combined presentation '%s', value unchanged\n", val);
+ status = ID_FIELD_INVALID;
+ } else {
+ id->name.presentation = pres;
+ id->number.presentation = pres;
+ }
+ } else {
+ status = ID_FIELD_UNKNOWN;
+ }
+
+ return status;
+}
+
+/*! TRUE if we have already notified about CALLERPRES being deprecated. */
+static int callerpres_deprecate_notify;
+
+/*!
+ * \internal
+ * \brief Read values from the caller-id presentation information struct.
+ *
+ * \param chan Asterisk channel to read
+ * \param cmd Not used
+ * \param data Caller-id presentation function datatype string
+ * \param buf Buffer to fill with read value.
+ * \param len Length of the buffer
+ *
+ * \retval 0 on success.
+ * \retval -1 on error.
+ */
static int callerpres_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
{
- ast_copy_string(buf, ast_named_caller_presentation(chan->cid.cid_pres), len);
+ if (!callerpres_deprecate_notify) {
+ callerpres_deprecate_notify = 1;
+ ast_log(LOG_WARNING, "CALLERPRES is deprecated."
+ " Use CALLERID(name-pres) or CALLERID(num-pres) instead.\n");
+ }
+ ast_copy_string(buf,
+ ast_named_caller_presentation(ast_party_id_presentation(&chan->caller.id)), len);
return 0;
}
+/*!
+ * \internal
+ * \brief Write new values to the caller-id presentation information struct.
+ *
+ * \param chan Asterisk channel to update
+ * \param cmd Not used
+ * \param data Caller-id presentation function datatype string
+ * \param value Value to assign to the caller-id presentation information struct.
+ *
+ * \retval 0 on success.
+ * \retval -1 on error.
+ */
static int callerpres_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
{
- int pres = ast_parse_caller_presentation(value);
- if (pres < 0)
+ int pres;
+
+ if (!callerpres_deprecate_notify) {
+ callerpres_deprecate_notify = 1;
+ ast_log(LOG_WARNING, "CALLERPRES is deprecated."
+ " Use CALLERID(name-pres) or CALLERID(num-pres) instead.\n");
+ }
+
+ pres = ast_parse_caller_presentation(value);
+ if (pres < 0) {
ast_log(LOG_WARNING, "'%s' is not a valid presentation (see 'show function CALLERPRES')\n", value);
- else
- chan->cid.cid_pres = pres;
+ } else {
+ chan->caller.id.name.presentation = pres;
+ chan->caller.id.number.presentation = pres;
+ }
return 0;
}
-static int callerid_read(struct ast_channel *chan, const char *cmd, char *data,
- char *buf, size_t len)
+/*!
+ * \internal
+ * \brief Read values from the caller-id information struct.
+ *
+ * \param chan Asterisk channel to read
+ * \param cmd Not used
+ * \param data Caller-id function datatype string
+ * \param buf Buffer to fill with read value.
+ * \param len Length of the buffer
+ *
+ * \retval 0 on success.
+ * \retval -1 on error.
+ */
+static int callerid_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
{
- char *opt = data;
+ enum ID_FIELD_STATUS status;
+ char *parms;
+ struct ast_party_members member;
+ AST_DECLARE_APP_ARGS(args,
+ AST_APP_ARG(member); /*!< Member name */
+ AST_APP_ARG(cid); /*!< Optional caller id to parse instead of from the channel. */
+ );
/* Ensure that the buffer is empty */
*buf = 0;
- if (!chan)
+ if (!chan) {
return -1;
+ }
- if (strchr(opt, ',')) {
- char name[80], num[80];
+ parms = ast_strdupa(data);
+ AST_STANDARD_APP_ARGS(args, parms);
+ if (args.argc == 0) {
+ /* Must have at least one argument. */
+ return -1;
+ }
+
+ AST_NONSTANDARD_APP_ARGS(member, args.member, '-');
+ if (member.argc == 0 || ARRAY_LEN(member.subnames) <= member.argc) {
+ /* Too few or too many subnames */
+ return -1;
+ }
- data = strsep(&opt, ",");
- ast_callerid_split(opt, name, sizeof(name), num, sizeof(num));
+ if (args.argc == 2) {
+ char name[80];
+ char num[80];
- if (!strncasecmp("all", data, 3)) {
+ ast_callerid_split(args.cid, name, sizeof(name), num, sizeof(num));
+
+ if (member.argc == 1 && !strcasecmp("all", member.argv[0])) {
snprintf(buf, len, "\"%s\" <%s>", name, num);
- } else if (!strncasecmp("name", data, 4)) {
+ } else if (member.argc == 1 && !strcasecmp("name", member.argv[0])) {
ast_copy_string(buf, name, len);
- } else if (!strncasecmp("num", data, 3)) {
- /* also matches "number" */
+ } else if (member.argc == 1 && !strncasecmp("num", member.argv[0], 3)) {
+ /* Accept num[ber] */
ast_copy_string(buf, num, len);
} else {
ast_log(LOG_ERROR, "Unknown callerid data type '%s'.\n", data);
} else {
ast_channel_lock(chan);
- 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("tag", data, 3)) {
- if (chan->cid.cid_tag) {
- ast_copy_string(buf, chan->cid.cid_tag, len);
+ if (member.argc == 1 && !strcasecmp("rdnis", member.argv[0])) {
+ if (chan->redirecting.from.number.valid
+ && chan->redirecting.from.number.str) {
+ ast_copy_string(buf, chan->redirecting.from.number.str, len);
}
- } else if (!strncasecmp("num", data, 3)) {
- /* also matches "number" */
- if (chan->cid.cid_num) {
- ast_copy_string(buf, chan->cid.cid_num, len);
+ } else if (!strcasecmp("dnid", member.argv[0])) {
+ if (member.argc == 1) {
+ /* Setup as if user had given dnid-num instead. */
+ member.argc = 2;
+ member.argv[1] = "num";
}
- } else if (!strncasecmp("ani", data, 3)) {
- if (!strncasecmp(data + 3, "2", 1)) {
- snprintf(buf, len, "%d", chan->cid.cid_ani2);
- } else if (chan->cid.cid_ani) {
- ast_copy_string(buf, chan->cid.cid_ani, len);
- }
- } else if (!strncasecmp("dnid", data, 4)) {
- /* Called parties info */
-
- /* also matches dnid-subaddr-valid, dnid-subaddr-type, dnid-subaddr-odd, dnid-subaddr */
- if (!strncasecmp(data + 4 ,"-subaddr", 8)) {
- if (!strncasecmp(data + 12 ,"-valid", 6)) { /* dnid-subaddr-valid */
- snprintf(buf, len, "%d", chan->cid.dialed_subaddress.valid);
- } else if (!strncasecmp(data + 12 ,"-type", 5)) { /* dnid-subaddr-type */
- snprintf(buf, len, "%d", chan->cid.dialed_subaddress.type);
- } else if (!strncasecmp(data + 12 ,"-odd", 4)) { /* dnid-subaddr-odd */
- snprintf(buf, len, "%d", chan->cid.dialed_subaddress.odd_even_indicator);
- } else { /* dnid-subaddr */
- if (chan->cid.dialed_subaddress.str) {
- ast_copy_string(buf, chan->cid.dialed_subaddress.str, len);
+ if (!strncasecmp("num", member.argv[1], 3)) {
+ /*
+ * Accept num[ber]
+ * dnid-num...
+ */
+ if (member.argc == 2) {
+ /* dnid-num */
+ if (chan->dialed.number.str) {
+ ast_copy_string(buf, chan->dialed.number.str, len);
}
+ } else if (member.argc == 3 && !strcasecmp("plan", member.argv[2])) {
+ /* dnid-num-plan */
+ snprintf(buf, len, "%d", chan->dialed.number.plan);
+ } else {
+ ast_log(LOG_ERROR, "Unknown callerid data type '%s'.\n", data);
}
- } else { /* dnid */
- if (chan->cid.cid_dnid) {
- ast_copy_string(buf, chan->cid.cid_dnid, len);
+ } else if (!strncasecmp("subaddr", member.argv[1], 7)) {
+ /*
+ * Accept subaddr[ess]
+ * dnid-subaddr...
+ */
+ status = party_subaddress_read(buf, len, member.argc - 2, member.argv + 2,
+ &chan->dialed.subaddress);
+ switch (status) {
+ case ID_FIELD_VALID:
+ case ID_FIELD_INVALID:
+ break;
+ default:
+ ast_log(LOG_ERROR, "Unknown callerid data type '%s'.\n", data);
+ break;
}
+ } else {
+ ast_log(LOG_ERROR, "Unknown callerid data type '%s'.\n", data);
}
- } else if (!strncasecmp("subaddr", data, 7)) {
- /* Calling parties info */
-
- /* also matches subaddr-valid, subaddr-type, subaddr-odd, subaddr */
- if (!strncasecmp(data + 7 ,"-valid", 6)) { /* subaddr-valid */
- snprintf(buf, len, "%d", chan->cid.subaddress.valid);
- } else if (!strncasecmp(data + 7 ,"-type", 5)) { /* subaddr-type */
- snprintf(buf, len, "%d", chan->cid.subaddress.type);
- } else if (!strncasecmp(data + 7 ,"-odd", 4)) { /* subaddr-odd */
- snprintf(buf, len, "%d", chan->cid.subaddress.odd_even_indicator);
- } else { /* subaddr */
- if (chan->cid.subaddress.str) {
- ast_copy_string(buf, chan->cid.subaddress.str, len);
- }
+ } else if (member.argc == 1 && !strcasecmp("ani2", member.argv[0])) {
+ snprintf(buf, len, "%d", chan->caller.ani2);
+ } else if (member.argc == 1 && !strcasecmp("ani", member.argv[0])) {
+ if (chan->caller.ani) {
+ ast_copy_string(buf, chan->caller.ani, len);
}
- } else if (!strncasecmp("rdnis", data, 5)) {
- if (chan->redirecting.from.number) {
- ast_copy_string(buf, chan->redirecting.from.number, len);
- }
- } else if (!strncasecmp("pres", data, 4)) {
- ast_copy_string(buf, ast_named_caller_presentation(chan->cid.cid_pres), len);
- } else if (!strncasecmp("ton", data, 3)) {
- snprintf(buf, len, "%d", chan->cid.cid_ton);
} else {
- ast_log(LOG_ERROR, "Unknown callerid data type '%s'.\n", data);
+ status = party_id_read(buf, len, member.argc, member.argv, &chan->caller.id);
+ switch (status) {
+ case ID_FIELD_VALID:
+ case ID_FIELD_INVALID:
+ break;
+ default:
+ ast_log(LOG_ERROR, "Unknown callerid data type '%s'.\n", data);
+ break;
+ }
}
ast_channel_unlock(chan);
return 0;
}
-static int callerid_write(struct ast_channel *chan, const char *cmd, char *data,
- const char *value)
+/*!
+ * \internal
+ * \brief Write new values to the caller-id information struct.
+ *
+ * \param chan Asterisk channel to update
+ * \param cmd Not used
+ * \param data Caller-id function datatype string
+ * \param value Value to assign to the caller-id information struct.
+ *
+ * \retval 0 on success.
+ * \retval -1 on error.
+ */
+static int callerid_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
{
- if (!value || !chan)
+ struct ast_party_caller caller;
+ struct ast_party_dialed dialed;
+ enum ID_FIELD_STATUS status;
+ char *val;
+ char *parms;
+ struct ast_party_func_args args;
+ struct ast_party_members member;
+
+ if (!value || !chan) {
return -1;
+ }
- value = ast_skip_blanks(value);
+ parms = ast_strdupa(data);
+ AST_STANDARD_APP_ARGS(args, parms);
+ if (args.argc == 0) {
+ /* Must have at least one argument. */
+ return -1;
+ }
- if (!strncasecmp("all", data, 3)) {
- char name[256];
- char num[256];
+ AST_NONSTANDARD_APP_ARGS(member, args.member, '-');
+ if (member.argc == 0 || ARRAY_LEN(member.subnames) <= member.argc) {
+ /* Too few or too many subnames */
+ return -1;
+ }
- ast_callerid_split(value, name, sizeof(name), num, sizeof(num));
- ast_set_callerid(chan, num, name, num);
- if (chan->cdr) {
- ast_cdr_setcid(chan->cdr, chan);
- }
- } else if (!strncasecmp("name", data, 4)) {
- ast_set_callerid(chan, NULL, value, NULL);
+ value = ast_skip_blanks(value);
+
+ ast_channel_lock(chan);
+ if (member.argc == 1 && !strcasecmp("rdnis", member.argv[0])) {
+ chan->redirecting.from.number.valid = 1;
+ ast_free(chan->redirecting.from.number.str);
+ chan->redirecting.from.number.str = ast_strdup(value);
if (chan->cdr) {
ast_cdr_setcid(chan->cdr, chan);
}
- } else if (!strncasecmp("num", data, 3)) {
- /* also matches "number" */
- ast_set_callerid(chan, value, NULL, NULL);
- if (chan->cdr) {
- ast_cdr_setcid(chan->cdr, chan);
+ } else if (!strcasecmp("dnid", member.argv[0])) {
+ ast_party_dialed_set_init(&dialed, &chan->dialed);
+ if (member.argc == 1) {
+ /* Setup as if user had given dnid-num instead. */
+ member.argc = 2;
+ member.argv[1] = "num";
}
- } else if (!strncasecmp("tag", data, 3)) {
- ast_channel_lock(chan);
- if (chan->cid.cid_tag) {
- ast_free(chan->cid.cid_tag);
+ if (!strncasecmp("num", member.argv[1], 3)) {
+ /*
+ * Accept num[ber]
+ * dnid-num...
+ */
+ if (member.argc == 2) {
+ /* dnid-num */
+ dialed.number.str = ast_strdup(value);
+ ast_trim_blanks(dialed.number.str);
+ ast_party_dialed_set(&chan->dialed, &dialed);
+ if (chan->cdr) {
+ ast_cdr_setcid(chan->cdr, chan);
+ }
+ } else if (member.argc == 3 && !strcasecmp("plan", member.argv[2])) {
+ /* dnid-num-plan */
+ val = ast_strdupa(value);
+ ast_trim_blanks(val);
+
+ if (('0' <= val[0]) && (val[0] <= '9')) {
+ chan->dialed.number.plan = atoi(val);
+ if (chan->cdr) {
+ ast_cdr_setcid(chan->cdr, chan);
+ }
+ } else {
+ ast_log(LOG_ERROR,
+ "Unknown type-of-number/numbering-plan '%s', value unchanged\n", val);
+ }
+ } else {
+ ast_log(LOG_ERROR, "Unknown callerid data type '%s'.\n", data);
+ }
+ } else if (!strncasecmp("subaddr", member.argv[1], 7)) {
+ /*
+ * Accept subaddr[ess]
+ * dnid-subaddr...
+ */
+ status = party_subaddress_write(&dialed.subaddress, member.argc - 2,
+ member.argv + 2, value);
+ switch (status) {
+ case ID_FIELD_VALID:
+ ast_party_dialed_set(&chan->dialed, &dialed);
+ if (chan->cdr) {
+ ast_cdr_setcid(chan->cdr, chan);
+ }
+ break;
+ case ID_FIELD_INVALID:
+ break;
+ default:
+ ast_log(LOG_ERROR, "Unknown callerid data type '%s'.\n", data);
+ break;
+ }
+ } else {
+ ast_log(LOG_ERROR, "Unknown callerid data type '%s'.\n", data);
}
- chan->cid.cid_tag = ast_strdup(value);
- ast_channel_unlock(chan);
- } else if (!strncasecmp("ani", data, 3)) {
- if (!strncasecmp(data + 3, "2", 1)) {
- chan->cid.cid_ani2 = atoi(value);
+ ast_party_dialed_free(&dialed);
+ } else if (member.argc == 1 && !strcasecmp("ani2", member.argv[0])) {
+ val = ast_strdupa(value);
+ ast_trim_blanks(val);
+
+ if (('0' <= val[0]) && (val[0] <= '9')) {
+ chan->caller.ani2 = atoi(val);
+ if (chan->cdr) {
+ ast_cdr_setcid(chan->cdr, chan);
+ }
} else {
- ast_set_callerid(chan, NULL, NULL, value);
+ ast_log(LOG_ERROR, "Unknown callerid ani2 '%s', value unchanged\n", val);
}
+ } else if (member.argc == 1 && !strcasecmp("ani", member.argv[0])) {
+ ast_party_caller_set_init(&caller, &chan->caller);
+ caller.ani = ast_strdup(value);
+ ast_trim_blanks(caller.ani);
+ ast_party_caller_set(&chan->caller, &caller, NULL);
if (chan->cdr) {
ast_cdr_setcid(chan->cdr, chan);
}
- } else if (!strncasecmp("dnid", data, 4)) {
- ast_channel_lock(chan);
- /* also matches dnid-subaddr-valid, dnid-subaddr-type, dnid-subaddr-odd, dnid-subaddr */
- if (!strncasecmp(data + 4 ,"-subaddr", 8)) {
- if (!strncasecmp(data + 12 ,"-valid", 6)) { /* dnid-subaddr-valid */
- chan->cid.dialed_subaddress.valid = atoi(value) ? 1 : 0;
- } else if (!strncasecmp(data + 12 ,"-type", 5)) { /* dnid-subaddr-type */
- chan->cid.dialed_subaddress.type = atoi(value) ? 2 : 0;
- } else if (!strncasecmp(data + 12 ,"-odd", 4)) { /* dnid-subaddr-odd */
- chan->cid.dialed_subaddress.odd_even_indicator = atoi(value) ? 1 : 0;
- } else { /* dnid-subaddr */
- if (chan->cid.dialed_subaddress.str) {
- ast_free(chan->cid.dialed_subaddress.str);
- }
- chan->cid.dialed_subaddress.str = ast_strdup(value);
- }
- } else { /* dnid */
- if (chan->cid.cid_dnid) {
- ast_free(chan->cid.cid_dnid);
+ ast_party_caller_free(&caller);
+ } else {
+ ast_party_caller_set_init(&caller, &chan->caller);
+ status = party_id_write(&caller.id, member.argc, member.argv, value);
+ switch (status) {
+ case ID_FIELD_VALID:
+ ast_channel_set_caller_event(chan, &caller, NULL);
+ if (chan->cdr) {
+ ast_cdr_setcid(chan->cdr, chan);
}
- chan->cid.cid_dnid = ast_strdup(value);
+ break;
+ case ID_FIELD_INVALID:
+ break;
+ default:
+ ast_log(LOG_ERROR, "Unknown callerid data type '%s'.\n", data);
+ break;
}
+ ast_party_caller_free(&caller);
+ }
+ ast_channel_unlock(chan);
- if (chan->cdr) {
- ast_cdr_setcid(chan->cdr, chan);
+ return 0;
+}
+
+/*!
+ * \internal
+ * \brief Read values from the connected line information struct.
+ *
+ * \param chan Asterisk channel to read
+ * \param cmd Not used
+ * \param data Connected line function datatype string
+ * \param buf Buffer to fill with read value.
+ * \param len Length of the buffer
+ *
+ * \retval 0 on success.
+ * \retval -1 on error.
+ */
+static int connectedline_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
+{
+ struct ast_party_members member;
+ char *read_what;
+ enum ID_FIELD_STATUS status;
+
+ /* Ensure that the buffer is empty */
+ *buf = 0;
+
+ if (!chan) {
+ return -1;
+ }
+
+ read_what = ast_strdupa(data);
+ AST_NONSTANDARD_APP_ARGS(member, read_what, '-');
+ if (member.argc == 0 || ARRAY_LEN(member.subnames) <= member.argc) {
+ /* Too few or too many subnames */
+ return -1;
+ }
+
+ ast_channel_lock(chan);
+
+ if (member.argc == 1 && !strcasecmp("source", member.argv[0])) {
+ ast_copy_string(buf, ast_connected_line_source_name(chan->connected.source), len);
+ } else {
+ status = party_id_read(buf, len, member.argc, member.argv, &chan->connected.id);
+ switch (status) {
+ case ID_FIELD_VALID:
+ case ID_FIELD_INVALID:
+ break;
+ default:
+ ast_log(LOG_ERROR, "Unknown connectedline data type '%s'.\n", data);
+ break;
}
- ast_channel_unlock(chan);
- } else if (!strncasecmp("subaddr", data, 7)) {
- ast_channel_lock(chan);
- /* also matches subaddr-valid, subaddr-type, subaddr-odd, subaddr */
- if (!strncasecmp(data + 7 ,"-valid", 6)) { /* subaddr-valid */
- chan->cid.subaddress.valid = atoi(value) ? 1 : 0;
- } else if (!strncasecmp(data + 7 ,"-type", 5)) { /* subaddr-type */
- chan->cid.subaddress.type = atoi(value) ? 2 : 0;
- } else if (!strncasecmp(data + 7 ,"-odd", 4)) { /* subaddr-odd */
- chan->cid.subaddress.odd_even_indicator = atoi(value) ? 1 : 0;
- } else { /* subaddr */
- if (chan->cid.subaddress.str) {
- ast_free(chan->cid.subaddress.str);
- }
- chan->cid.subaddress.str = ast_strdup(value);
+ }
+
+ ast_channel_unlock(chan);
+
+ return 0;
+}
+
+/*!
+ * \internal
+ * \brief Write new values to the connected line information struct.
+ *
+ * \param chan Asterisk channel to update
+ * \param cmd Not used
+ * \param data Connected line function datatype string
+ * \param value Value to assign to the connected line information struct.
+ *
+ * \retval 0 on success.
+ * \retval -1 on error.
+ */
+static int connectedline_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
+{
+ struct ast_party_connected_line connected;
+ enum ID_FIELD_STATUS status;
+ char *val;
+ char *parms;
+ void (*set_it)(struct ast_channel *chan, const struct ast_party_connected_line *connected, const struct ast_set_party_connected_line *update);
+ struct ast_party_func_args args;
+ struct ast_party_members member;
+ struct ast_flags opts;
+ char *opt_args[CONNECTED_LINE_OPT_ARG_ARRAY_SIZE];
+
+ if (!value || !chan) {
+ return -1;
+ }
+
+ parms = ast_strdupa(data);
+ AST_STANDARD_APP_ARGS(args, parms);
+ if (args.argc == 0) {
+ /* Must have at least one argument. */
+ return -1;
+ }
+
+ AST_NONSTANDARD_APP_ARGS(member, args.member, '-');
+ if (member.argc == 0 || ARRAY_LEN(member.subnames) <= member.argc) {
+ /* Too few or too many subnames */
+ return -1;
+ }
+
+ if (ast_app_parse_options(connectedline_opts, &opts, opt_args, args.opts)) {
+ /* General invalid option syntax. */
+ return -1;
+ }
+
+ /* Determine if the update indication inhibit option is present */
+ if (ast_test_flag(&opts, CONNECTED_LINE_OPT_INHIBIT)) {
+ set_it = ast_channel_set_connected_line;
+ } else {
+ set_it = ast_channel_update_connected_line;
+ }
+
+ ast_channel_lock(chan);
+ ast_party_connected_line_set_init(&connected, &chan->connected);
+ ast_channel_unlock(chan);
+
+ value = ast_skip_blanks(value);
+
+ if (member.argc == 1 && !strcasecmp("source", member.argv[0])) {
+ int source;
+
+ val = ast_strdupa(value);
+ ast_trim_blanks(val);
+
+ if (('0' <= val[0]) && (val[0] <= '9')) {
+ source = atoi(val);
+ } else {
+ source = ast_connected_line_source_parse(val);
}
- if (chan->cdr) {
- ast_cdr_setcid(chan->cdr, chan);
+
+ if (source < 0) {
+ ast_log(LOG_ERROR, "Unknown connectedline source '%s', value unchanged\n", val);
+ } else {
+ connected.source = source;
+ set_it(chan, &connected, NULL);
}
- ast_channel_unlock(chan);
- } else if (!strncasecmp("rdnis", data, 5)) {
- ast_channel_lock(chan);
- ast_free(chan->redirecting.from.number);
- chan->redirecting.from.number = ast_strdup(value);
- if (chan->cdr) {
- ast_cdr_setcid(chan->cdr, chan);
+ } else {
+ status = party_id_write(&connected.id, member.argc, member.argv, value);
+ switch (status) {
+ case ID_FIELD_VALID:
+ set_it(chan, &connected, NULL);
+ break;
+ case ID_FIELD_INVALID:
+ break;
+ default:
+ ast_log(LOG_ERROR, "Unknown connectedline data type '%s'.\n", data);
+ break;
}
- ast_channel_unlock(chan);
- } else if (!strncasecmp("pres", data, 4)) {
- int i;
- char *val;
+ ast_party_connected_line_free(&connected);
+ }
+
+ return 0;
+}
+
+/*!
+ * \internal
+ * \brief Read values from the redirecting information struct.
+ *
+ * \param chan Asterisk channel to read
+ * \param cmd Not used
+ * \param data Redirecting function datatype string
+ * \param buf Buffer to fill with read value.
+ * \param len Length of the buffer
+ *
+ * \retval 0 on success.
+ * \retval -1 on error.
+ */
+static int redirecting_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
+{
+ struct ast_party_members member;
+ char *read_what;
+ enum ID_FIELD_STATUS status;
+
+ /* Ensure that the buffer is empty */
+ *buf = 0;
+
+ if (!chan) {
+ return -1;
+ }
+
+ read_what = ast_strdupa(data);
+ AST_NONSTANDARD_APP_ARGS(member, read_what, '-');
+ if (member.argc == 0 || ARRAY_LEN(member.subnames) <= member.argc) {
+ /* Too few or too many subnames */
+ return -1;
+ }
+
+ ast_channel_lock(chan);
+
+ if (!strcasecmp("from", member.argv[0])) {
+ status = party_id_read(buf, len, member.argc - 1, member.argv + 1,
+ &chan->redirecting.from);
+ switch (status) {
+ case ID_FIELD_VALID:
+ case ID_FIELD_INVALID:
+ break;
+ default:
+ ast_log(LOG_ERROR, "Unknown redirecting data type '%s'.\n", data);
+ break;
+ }
+ } else if (!strcasecmp("to", member.argv[0])) {
+ status = party_id_read(buf, len, member.argc - 1, member.argv + 1,
+ &chan->redirecting.to);
+ switch (status) {
+ case ID_FIELD_VALID:
+ case ID_FIELD_INVALID:
+ break;
+ default:
+ ast_log(LOG_ERROR, "Unknown redirecting data type '%s'.\n", data);
+ break;
+ }
+ } else if (member.argc == 1 && !strncasecmp("pres", member.argv[0], 4)) {
+ /*
+ * Accept pres[entation]
+ * This is the combined from name/number presentation.
+ */
+ ast_copy_string(buf,
+ ast_named_caller_presentation(
+ ast_party_id_presentation(&chan->redirecting.from)), len);
+ } else if (member.argc == 1 && !strcasecmp("reason", member.argv[0])) {
+ ast_copy_string(buf, ast_redirecting_reason_name(chan->redirecting.reason), len);
+ } else if (member.argc == 1 && !strcasecmp("count", member.argv[0])) {
+ snprintf(buf, len, "%d", chan->redirecting.count);
+ } else {
+ ast_log(LOG_ERROR, "Unknown redirecting data type '%s'.\n", data);
+ }
+
+ ast_channel_unlock(chan);
+
+ return 0;
+}
+
+/*!
+ * \internal
+ * \brief Write new values to the redirecting information struct.
+ *
+ * \param chan Asterisk channel to update
+ * \param cmd Not used
+ * \param data Redirecting function datatype string
+ * \param value Value to assign to the redirecting information struct.
+ *
+ * \retval 0 on success.
+ * \retval -1 on error.
+ */
+static int redirecting_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
+{
+ struct ast_party_redirecting redirecting;
+ enum ID_FIELD_STATUS status;
+ char *val;
+ char *parms;
+ void (*set_it)(struct ast_channel *chan, const struct ast_party_redirecting *redirecting, const struct ast_set_party_redirecting *update);
+ struct ast_party_func_args args;
+ struct ast_party_members member;
+ struct ast_flags opts;
+ char *opt_args[REDIRECTING_OPT_ARG_ARRAY_SIZE];
+
+ if (!value || !chan) {
+ return -1;
+ }
+
+ parms = ast_strdupa(data);
+ AST_STANDARD_APP_ARGS(args, parms);
+ if (args.argc == 0) {
+ /* Must have at least one argument. */
+ return -1;
+ }
+
+ AST_NONSTANDARD_APP_ARGS(member, args.member, '-');
+ if (member.argc == 0 || ARRAY_LEN(member.subnames) <= member.argc) {
+ /* Too few or too many subnames */
+ return -1;
+ }
+
+ if (ast_app_parse_options(redirecting_opts, &opts, opt_args, args.opts)) {
+ /* General invalid option syntax. */
+ return -1;
+ }
+
+ /* Determine if the update indication inhibit option is present */
+ if (ast_test_flag(&opts, REDIRECTING_OPT_INHIBIT)) {
+ set_it = ast_channel_set_redirecting;
+ } else {
+ set_it = ast_channel_update_redirecting;
+ }
+
+ ast_channel_lock(chan);
+ ast_party_redirecting_set_init(&redirecting, &chan->redirecting);
+ ast_channel_unlock(chan);
+
+ value = ast_skip_blanks(value);
+
+ if (!strcasecmp("from", member.argv[0])) {
+ status = party_id_write(&redirecting.from, member.argc - 1, member.argv + 1,
+ value);
+ switch (status) {
+ case ID_FIELD_VALID:
+ set_it(chan, &redirecting, NULL);
+ break;
+ case ID_FIELD_INVALID:
+ break;
+ default:
+ ast_log(LOG_ERROR, "Unknown redirecting data type '%s'.\n", data);
+ break;
+ }
+ ast_party_redirecting_free(&redirecting);
+ } else if (!strcasecmp("to", member.argv[0])) {
+ status = party_id_write(&redirecting.to, member.argc - 1, member.argv + 1, value);
+ switch (status) {
+ case ID_FIELD_VALID:
+ set_it(chan, &redirecting, NULL);
+ break;
+ case ID_FIELD_INVALID:
+ break;
+ default:
+ ast_log(LOG_ERROR, "Unknown redirecting data type '%s'.\n", data);
+ break;
+ }
+ ast_party_redirecting_free(&redirecting);
+ } else if (member.argc == 1 && !strncasecmp("pres", member.argv[0], 4)) {
+ int pres;
val = ast_strdupa(value);
ast_trim_blanks(val);
- if ((val[0] >= '0') && (val[0] <= '9')) {
- i = atoi(val);
+ if (('0' <= val[0]) && (val[0] <= '9')) {
+ pres = atoi(val);
+ } else {
+ pres = ast_parse_caller_presentation(val);
+ }
+
+ if (pres < 0) {
+ ast_log(LOG_ERROR,
+ "Unknown redirecting combined presentation '%s', value unchanged\n", val);
+ } else {
+ redirecting.from.name.presentation = pres;
+ redirecting.from.number.presentation = pres;
+ redirecting.to.name.presentation = pres;
+ redirecting.to.number.presentation = pres;
+ set_it(chan, &redirecting, NULL);
+ }
+ } else if (member.argc == 1 && !strcasecmp("reason", member.argv[0])) {
+ int reason;
+
+ val = ast_strdupa(value);
+ ast_trim_blanks(val);
+
+ if (('0' <= val[0]) && (val[0] <= '9')) {
+ reason = atoi(val);
+ } else {
+ reason = ast_redirecting_reason_parse(val);
+ }
+
+ if (reason < 0) {
+ ast_log(LOG_ERROR, "Unknown redirecting reason '%s', value unchanged\n", val);
} else {
- i = ast_parse_caller_presentation(val);
+ redirecting.reason = reason;
+ set_it(chan, &redirecting, NULL);
}
+ } else if (member.argc == 1 && !strcasecmp("count", member.argv[0])) {
+ val = ast_strdupa(value);
+ ast_trim_blanks(val);
- if (i < 0) {
- ast_log(LOG_ERROR, "Unknown calling number presentation '%s', value unchanged\n", val);
+ if (('0' <= val[0]) && (val[0] <= '9')) {
+ redirecting.count = atoi(val);
+ set_it(chan, &redirecting, NULL);
} else {
- chan->cid.cid_pres = i;
+ ast_log(LOG_ERROR, "Unknown redirecting count '%s', value unchanged\n", val);
}
- } else if (!strncasecmp("ton", data, 3)) {
- chan->cid.cid_ton = atoi(value);
} else {
- ast_log(LOG_ERROR, "Unknown callerid data type '%s'.\n", data);
+ ast_log(LOG_ERROR, "Unknown redirecting data type '%s'.\n", data);
}
return 0;
.write = callerpres_write,
};
+static struct ast_custom_function connectedline_function = {
+ .name = "CONNECTEDLINE",
+ .read = connectedline_read,
+ .write = connectedline_write,
+};
+
+static struct ast_custom_function redirecting_function = {
+ .name = "REDIRECTING",
+ .read = redirecting_read,
+ .write = redirecting_write,
+};
+
+/*!
+ * \internal
+ * \brief Unload the function module
+ *
+ * \retval 0 on success.
+ * \retval -1 on error.
+ */
static int unload_module(void)
{
- int res = ast_custom_function_unregister(&callerpres_function);
+ int res;
+
+ res = ast_custom_function_unregister(&callerpres_function);
res |= ast_custom_function_unregister(&callerid_function);
+ res |= ast_custom_function_unregister(&connectedline_function);
+ res |= ast_custom_function_unregister(&redirecting_function);
return res;
}
+/*!
+ * \internal
+ * \brief Load and initialize the function module.
+ *
+ * \retval AST_MODULE_LOAD_SUCCESS on success.
+ * \retval AST_MODULE_LOAD_DECLINE on error.
+ */
static int load_module(void)
{
- int res = ast_custom_function_register(&callerpres_function);
+ int res;
+
+ res = ast_custom_function_register(&callerpres_function);
res |= ast_custom_function_register(&callerid_function);
- return res;
+ res |= ast_custom_function_register(&connectedline_function);
+ res |= ast_custom_function_register(&redirecting_function);
+ return res ? AST_MODULE_LOAD_DECLINE : AST_MODULE_LOAD_SUCCESS;
}
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Caller ID related dialplan functions");
+/* Do not wrap the following line. */
+AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Party ID related dialplan functions (Caller-ID, Connected-line, Redirecting)");
+++ /dev/null
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 2007, Gareth Palmer
- *
- * Gareth Palmer <gareth@acsdata.co.nz>
- *
- * 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 Connected Line dialplan function
- *
- * \ingroup functions
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/types.h>
-
-#include "asterisk/module.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/logger.h"
-#include "asterisk/utils.h"
-#include "asterisk/app.h"
-#include "asterisk/options.h"
-#include "asterisk/callerid.h"
-
-/*
- * Do not document the CONNECTEDLINE(source) datatype.
- * It has turned out to not be needed. The source value is really
- * only useful as a possible tracing aid.
- */
-/*** DOCUMENTATION
- <function name="CONNECTEDLINE" language="en_US">
- <synopsis>
- Gets or sets Connected Line data on the channel.
- </synopsis>
- <syntax>
- <parameter name="datatype" required="true">
- <para>The allowable datatypes are:</para>
- <enumlist>
- <enum name = "all" />
- <enum name = "num" />
- <enum name = "name" />
- <enum name = "tag" />
- <enum name = "ton" />
- <enum name = "pres" />
- <enum name = "subaddr[-valid]|[-type]|[-odd]">
- <para>ISDN Connected line subaddress</para>
- </enum>
- </enumlist>
- </parameter>
- <parameter name="i">
- <para>If set, this will prevent the channel from sending out protocol
- messages because of the value being set</para>
- </parameter>
- </syntax>
- <description>
- <para>Gets or sets Connected Line data on the channel.</para>
- </description>
- </function>
- ***/
-
-static int connectedline_read(struct ast_channel *chan, const char *cmd, char *data,
- char *buf, size_t len)
-{
- /* Ensure that the buffer is empty */
- *buf = 0;
-
- if (!chan)
- return -1;
-
- ast_channel_lock(chan);
-
- if (!strncasecmp("all", data, 3)) {
- snprintf(buf, len, "\"%s\" <%s>",
- S_OR(chan->connected.id.name, ""),
- S_OR(chan->connected.id.number, ""));
- } else if (!strncasecmp("name", data, 4)) {
- if (chan->connected.id.name) {
- ast_copy_string(buf, chan->connected.id.name, len);
- }
- } else if (!strncasecmp("num", data, 3)) {
- if (chan->connected.id.number) {
- ast_copy_string(buf, chan->connected.id.number, len);
- }
- } else if (!strncasecmp("tag", data, 3)) {
- if (chan->connected.id.tag) {
- ast_copy_string(buf, chan->connected.id.tag, len);
- }
- } else if (!strncasecmp("ton", data, 3)) {
- snprintf(buf, len, "%d", chan->connected.id.number_type);
- } else if (!strncasecmp("pres", data, 4)) {
- ast_copy_string(buf, ast_named_caller_presentation(chan->connected.id.number_presentation), len);
- } else if (!strncasecmp("source", data, 6)) {
- ast_copy_string(buf, ast_connected_line_source_name(chan->connected.source), len);
- } else if (!strncasecmp("subaddr", data, 7)) {
- /* also matches subaddr-valid, subaddr-type, subaddr-odd, subaddr */
- if (!strncasecmp(data + 7 ,"-valid", 6)) { /* subaddr-valid */
- snprintf(buf, len, "%d", chan->connected.id.subaddress.valid);
- } else if (!strncasecmp(data + 7 ,"-type", 5)) { /* subaddr-type */
- snprintf(buf, len, "%d", chan->connected.id.subaddress.type);
- } else if (!strncasecmp(data + 7 ,"-odd", 4)) { /* subaddr-odd */
- snprintf(buf, len, "%d", chan->connected.id.subaddress.odd_even_indicator);
- } else { /* subaddr */
- if (chan->connected.id.subaddress.str) {
- ast_copy_string(buf, chan->connected.id.subaddress.str, len);
- }
- }
- } else {
- ast_log(LOG_ERROR, "Unknown connectedline data type '%s'.\n", data);
- }
-
- ast_channel_unlock(chan);
-
- return 0;
-}
-
-static int connectedline_write(struct ast_channel *chan, const char *cmd, char *data,
- const char *value)
-{
- struct ast_party_connected_line connected;
- char *val;
- char *option;
- void (*set_it)(struct ast_channel *chan, const struct ast_party_connected_line *connected);
-
- if (!value || !chan) {
- return -1;
- }
-
- /* Determine if the update indication inhibit option is present */
- option = strchr(data, ',');
- if (option) {
- option = ast_skip_blanks(option + 1);
- switch (*option) {
- case 'i':
- set_it = ast_channel_set_connected_line;
- break;
-
- default:
- ast_log(LOG_ERROR, "Unknown connectedline option '%s'.\n", option);
- return 0;
- }
- }
- else {
- set_it = ast_channel_update_connected_line;
- }
-
- ast_channel_lock(chan);
- ast_party_connected_line_set_init(&connected, &chan->connected);
- ast_channel_unlock(chan);
-
- value = ast_skip_blanks(value);
-
- if (!strncasecmp("all", data, 3)) {
- char name[256];
- char num[256];
-
- ast_callerid_split(value, name, sizeof(name), num, sizeof(num));
- connected.id.name = name;
- connected.id.number = num;
- set_it(chan, &connected);
- } else if (!strncasecmp("name", data, 4)) {
- connected.id.name = ast_strdupa(value);
- ast_trim_blanks(connected.id.name);
- set_it(chan, &connected);
- } else if (!strncasecmp("num", data, 3)) {
- connected.id.number = ast_strdupa(value);
- ast_trim_blanks(connected.id.number);
- set_it(chan, &connected);
- } else if (!strncasecmp("tag", data, 3)) {
- connected.id.tag = ast_strdupa(value);
- ast_trim_blanks(connected.id.tag);
- set_it(chan, &connected);
- } else if (!strncasecmp("ton", data, 3)) {
- val = ast_strdupa(value);
- ast_trim_blanks(val);
-
- if (('0' <= val[0]) && (val[0] <= '9')) {
- connected.id.number_type = atoi(val);
- set_it(chan, &connected);
- } else {
- ast_log(LOG_ERROR, "Unknown connectedline type of number '%s', value unchanged\n", val);
- }
- } else if (!strncasecmp("pres", data, 4)) {
- int pres;
-
- val = ast_strdupa(value);
- ast_trim_blanks(val);
-
- if (('0' <= val[0]) && (val[0] <= '9')) {
- pres = atoi(val);
- } else {
- pres = ast_parse_caller_presentation(val);
- }
-
- if (pres < 0) {
- ast_log(LOG_ERROR, "Unknown connectedline number presentation '%s', value unchanged\n", val);
- } else {
- connected.id.number_presentation = pres;
- set_it(chan, &connected);
- }
- } else if (!strncasecmp("source", data, 6)) {
- int source;
-
- val = ast_strdupa(value);
- ast_trim_blanks(val);
-
- if (('0' <= val[0]) && (val[0] <= '9')) {
- source = atoi(val);
- } else {
- source = ast_connected_line_source_parse(val);
- }
-
- if (source < 0) {
- ast_log(LOG_ERROR, "Unknown connectedline source '%s', value unchanged\n", val);
- } else {
- connected.source = source;
- set_it(chan, &connected);
- }
- } else if (!strncasecmp("subaddr", data, 7)) { /* outbound: set calling subaddress */
- /* also matches subaddr-valid, subaddr-type, subaddr-odd, subaddr */
- if (!strncasecmp(data + 7 ,"-valid", 6)) { /* subaddr-valid */
- connected.id.subaddress.valid = atoi(value) ? 1 : 0;
- } else if (!strncasecmp(data + 7 ,"-type", 5)) { /* subaddr-type */
- connected.id.subaddress.type = atoi(value) ? 2 : 0;
- } else if (!strncasecmp(data + 7 ,"-odd", 4)) { /* subaddr-odd */
- connected.id.subaddress.odd_even_indicator = atoi(value) ? 1 : 0;
- } else { /* subaddr */
- connected.id.subaddress.str = ast_strdupa(value);
- ast_trim_blanks(connected.id.subaddress.str);
- }
- set_it(chan, &connected);
- } else {
- ast_log(LOG_ERROR, "Unknown connectedline data type '%s'.\n", data);
- }
-
- return 0;
-}
-
-static struct ast_custom_function connectedline_function = {
- .name = "CONNECTEDLINE",
- .read = connectedline_read,
- .write = connectedline_write,
-};
-
-static int unload_module(void)
-{
- return ast_custom_function_unregister(&connectedline_function);
-}
-
-static int load_module(void)
-{
- return ast_custom_function_register(&connectedline_function)
- ? AST_MODULE_LOAD_DECLINE
- : AST_MODULE_LOAD_SUCCESS;
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Connected Line dialplan function");
if (sscanf(args.priority, "%30d", &priority_num) == 1 && priority_num > 0) {
int res;
res = ast_exists_extension(chan, args.context, args.exten, priority_num,
- chan->cid.cid_num);
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL));
if (res)
strcpy(buf, "1");
} else {
int res;
- res = ast_findlabel_extension(chan, args.context, args.exten,
- args.priority, chan->cid.cid_num);
+ res = ast_findlabel_extension(chan, args.context, args.exten, args.priority,
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL));
if (res > 0)
strcpy(buf, "1");
}
} else if (!ast_strlen_zero(args.exten)) {
int res;
res = ast_exists_extension(chan, args.context, args.exten, 1,
- chan->cid.cid_num);
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL));
if (res)
strcpy(buf, "1");
} else if (!ast_strlen_zero(args.context)) {
+++ /dev/null
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 2008 Digium, Inc.
- *
- * Richard Mudgett <rmudgett@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 Redirecting data dialplan function
- * \ingroup functions
- *
- * \author Richard Mudgett <rmudgett@digium.com>
- *
- * See Also:
- * \arg \ref AstCREDITS
- */
-
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-/* ------------------------------------------------------------------- */
-
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/types.h>
-
-#include "asterisk/module.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/logger.h"
-#include "asterisk/utils.h"
-#include "asterisk/app.h"
-#include "asterisk/options.h"
-#include "asterisk/callerid.h"
-
-/*
- * Do not document the REDIRECTING(pres) datatype.
- * It has turned out that the from-pres and to-pres values must be kept
- * separate. They represent two different parties and there is a case when
- * they are active at the same time. The plain pres option will simply
- * live on as a historical relic.
- */
-/*** DOCUMENTATION
- <function name="REDIRECTING" language="en_US">
- <synopsis>
- Gets or sets Redirecting data on the channel.
- </synopsis>
- <syntax>
- <parameter name="datatype" required="true">
- <para>The allowable datatypes are:</para>
- <enumlist>
- <enum name = "from-all" />
- <enum name = "from-num" />
- <enum name = "from-name" />
- <enum name = "from-tag" />
- <enum name = "from-ton" />
- <enum name = "from-pres" />
- <enum name = "to-all" />
- <enum name = "to-num" />
- <enum name = "to-name" />
- <enum name = "to-tag" />
- <enum name = "to-ton" />
- <enum name = "to-pres" />
- <enum name = "reason" />
- <enum name = "count" />
- </enumlist>
- </parameter>
- <parameter name="i">
- <para>If set, this will prevent the channel from sending out protocol
- messages because of the value being set</para>
- </parameter>
- </syntax>
- <description>
- <para>Gets or sets Redirecting data on the channel. The allowable values
- for the <replaceable>reason</replaceable> field are the following:</para>
- <enumlist>
- <enum name = "unknown"><para>Unknown</para></enum>
- <enum name = "cfb"><para>Call Forwarding Busy</para></enum>
- <enum name = "cfnr"><para>Call Forwarding No Reply</para></enum>
- <enum name = "unavailable"><para>Callee is Unavailable</para></enum>
- <enum name = "time_of_day"><para>Time of Day</para></enum>
- <enum name = "dnd"><para>Do Not Disturb</para></enum>
- <enum name = "deflection"><para>Call Deflection</para></enum>
- <enum name = "follow_me"><para>Follow Me</para></enum>
- <enum name = "out_of_order"><para>Called DTE Out-Of-Order</para></enum>
- <enum name = "away"><para>Callee is Away</para></enum>
- <enum name = "cf_dte"><para>Call Forwarding By The Called DTE</para></enum>
- <enum name = "cfu"><para>Call Forwarding Unconditional</para></enum>
- </enumlist>
- </description>
- </function>
- ***/
-
-enum ID_FIELD_STATUS {
- ID_FIELD_VALID,
- ID_FIELD_INVALID,
- ID_FIELD_UNKNOWN
-};
-
-
-
-
-/* ******************************************************************* */
-/*!
- * \internal
- * \brief Read values from the party id struct.
- *
- * \param buf Buffer to fill with read value.
- * \param len Length of the buffer
- * \param data Remaining function datatype string
- *
- * \retval ID_FIELD_VALID on success.
- * \retval ID_FIELD_UNKNOWN on unknown field name.
- */
-static enum ID_FIELD_STATUS redirecting_id_read(char *buf, size_t len, char *data, const struct ast_party_id *id)
-{
- enum ID_FIELD_STATUS status;
-
- status = ID_FIELD_VALID;
-
- if (!strncasecmp("all", data, 3)) {
- snprintf(buf, len, "\"%s\" <%s>",
- S_OR(id->name, ""),
- S_OR(id->number, ""));
- } else if (!strncasecmp("name", data, 4)) {
- if (id->name) {
- ast_copy_string(buf, id->name, len);
- }
- } else if (!strncasecmp("num", data, 3)) {
- if (id->number) {
- ast_copy_string(buf, id->number, len);
- }
- } else if (!strncasecmp("tag", data, 3)) {
- if (id->tag) {
- ast_copy_string(buf, id->tag, len);
- }
- } else if (!strncasecmp("ton", data, 3)) {
- snprintf(buf, len, "%d", id->number_type);
- } else if (!strncasecmp("pres", data, 4)) {
- ast_copy_string(buf, ast_named_caller_presentation(id->number_presentation), len);
- } else {
- status = ID_FIELD_UNKNOWN;
- }
-
- return status;
-}
-
-
-
-
-/* ******************************************************************* */
-/*!
- * \internal
- * \brief Read values from the redirecting information struct.
- *
- * \param chan Asterisk channel to read
- * \param cmd Not used
- * \param data Redirecting function datatype string
- * \param buf Buffer to fill with read value.
- * \param len Length of the buffer
- *
- * \retval 0 on success.
- * \retval -1 on error.
- */
-static int redirecting_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
-{
- /* Ensure that the buffer is empty */
- *buf = 0;
-
- if (!chan)
- return -1;
-
- ast_channel_lock(chan);
-
- if (!strncasecmp("from-", data, 5)) {
- switch (redirecting_id_read(buf, len, data + 5, &chan->redirecting.from)) {
- case ID_FIELD_VALID:
- case ID_FIELD_INVALID:
- break;
-
- default:
- ast_log(LOG_ERROR, "Unknown redirecting data type '%s'.\n", data);
- break;
- }
- } else if (!strncasecmp("to-", data, 3)) {
- switch (redirecting_id_read(buf, len, data + 3, &chan->redirecting.to)) {
- case ID_FIELD_VALID:
- case ID_FIELD_INVALID:
- break;
-
- default:
- ast_log(LOG_ERROR, "Unknown redirecting data type '%s'.\n", data);
- break;
- }
- } else if (!strncasecmp("pres", data, 4)) {
- ast_copy_string(buf, ast_named_caller_presentation(chan->redirecting.from.number_presentation), len);
- } else if (!strncasecmp("reason", data, 6)) {
- ast_copy_string(buf, ast_redirecting_reason_name(chan->redirecting.reason), len);
- } else if (!strncasecmp("count", data, 5)) {
- snprintf(buf, len, "%d", chan->redirecting.count);
- } else {
- ast_log(LOG_ERROR, "Unknown redirecting data type '%s'.\n", data);
- }
-
- ast_channel_unlock(chan);
-
- return 0;
-}
-
-
-
-
-/* ******************************************************************* */
-/*!
- * \internal
- * \brief Write new values to the party id struct
- *
- * \param id Party ID struct to write values
- * \param data Remaining function datatype string
- * \param value Value to assign to the party id.
- *
- * \retval ID_FIELD_VALID on success.
- * \retval ID_FIELD_INVALID on error with field value.
- * \retval ID_FIELD_UNKNOWN on unknown field name.
- */
-static enum ID_FIELD_STATUS redirecting_id_write(struct ast_party_id *id, char *data, const char *value)
-{
- char *val;
- enum ID_FIELD_STATUS status;
-
- status = ID_FIELD_VALID;
-
- if (!strncasecmp("all", data, 3)) {
- char name[256];
- char num[256];
-
- ast_callerid_split(value, name, sizeof(name), num, sizeof(num));
- if (!(id->name = ast_strdup(name))) {
- return ID_FIELD_INVALID;
- }
- if (!(id->number = ast_strdup(num))) {
- return ID_FIELD_INVALID;
- }
- } else if (!strncasecmp("name", data, 4)) {
- id->name = ast_strdup(value);
- ast_trim_blanks(id->name);
- } else if (!strncasecmp("num", data, 3)) {
- id->number = ast_strdup(value);
- ast_trim_blanks(id->number);
- } else if (!strncasecmp("tag", data, 3)) {
- id->tag = ast_strdup(value);
- ast_trim_blanks(id->tag);
- } else if (!strncasecmp("ton", data, 3)) {
- val = ast_strdupa(value);
- ast_trim_blanks(val);
-
- if (('0' <= val[0]) && (val[0] <= '9')) {
- id->number_type = atoi(val);
- } else {
- ast_log(LOG_ERROR, "Unknown redirecting type of number '%s', value unchanged\n", val);
- status = ID_FIELD_INVALID;
- }
- } else if (!strncasecmp("pres", data, 4)) {
- int pres;
-
- val = ast_strdupa(value);
- ast_trim_blanks(val);
-
- if (('0' <= val[0]) && (val[0] <= '9')) {
- pres = atoi(val);
- } else {
- pres = ast_parse_caller_presentation(val);
- }
-
- if (pres < 0) {
- ast_log(LOG_ERROR, "Unknown redirecting number presentation '%s', value unchanged\n", val);
- status = ID_FIELD_INVALID;
- } else {
- id->number_presentation = pres;
- }
- } else {
- status = ID_FIELD_UNKNOWN;
- }
-
- return status;
-}
-
-
-
-
-/* ******************************************************************* */
-/*!
- * \internal
- * \brief Write new values to the redirecting information struct.
- *
- * \param chan Asterisk channel to update
- * \param cmd Not used
- * \param data Redirecting function datatype string
- * \param value Value to assign to the redirecting information struct.
- *
- * \retval 0 on success.
- * \retval -1 on error.
- */
-static int redirecting_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
-{
- struct ast_party_redirecting redirecting;
- char *val;
- char *option;
- void (*set_it)(struct ast_channel *chan, const struct ast_party_redirecting *redirecting);
-
- if (!value || !chan) {
- return -1;
- }
-
- /* Determine if the update indication inhibit option is present */
- option = strchr(data, ',');
- if (option) {
- option = ast_skip_blanks(option + 1);
- switch (*option) {
- case 'i':
- set_it = ast_channel_set_redirecting;
- break;
-
- default:
- ast_log(LOG_ERROR, "Unknown redirecting option '%s'.\n", option);
- return 0;
- }
- }
- else {
- set_it = ast_channel_update_redirecting;
- }
-
- ast_channel_lock(chan);
- ast_party_redirecting_set_init(&redirecting, &chan->redirecting);
- ast_channel_unlock(chan);
-
- value = ast_skip_blanks(value);
-
- if (!strncasecmp("from-", data, 5)) {
- switch (redirecting_id_write(&redirecting.from, data + 5, value)) {
- case ID_FIELD_VALID:
- set_it(chan, &redirecting);
- break;
-
- case ID_FIELD_INVALID:
- break;
-
- default:
- ast_log(LOG_ERROR, "Unknown redirecting data type '%s'.\n", data);
- break;
- }
- ast_party_redirecting_free(&redirecting);
- } else if (!strncasecmp("to-", data, 3)) {
- switch (redirecting_id_write(&redirecting.to, data + 3, value)) {
- case ID_FIELD_VALID:
- set_it(chan, &redirecting);
- break;
-
- case ID_FIELD_INVALID:
- break;
-
- default:
- ast_log(LOG_ERROR, "Unknown redirecting data type '%s'.\n", data);
- break;
- }
- ast_party_redirecting_free(&redirecting);
- } else if (!strncasecmp("pres", data, 4)) {
- int pres;
-
- val = ast_strdupa(value);
- ast_trim_blanks(val);
-
- if (('0' <= val[0]) && (val[0] <= '9')) {
- pres = atoi(val);
- } else {
- pres = ast_parse_caller_presentation(val);
- }
-
- if (pres < 0) {
- ast_log(LOG_ERROR, "Unknown redirecting number presentation '%s', value unchanged\n", val);
- } else {
- redirecting.from.number_presentation = pres;
- redirecting.to.number_presentation = pres;
- set_it(chan, &redirecting);
- }
- } else if (!strncasecmp("reason", data, 6)) {
- int reason;
-
- val = ast_strdupa(value);
- ast_trim_blanks(val);
-
- if (('0' <= val[0]) && (val[0] <= '9')) {
- reason = atoi(val);
- } else {
- reason = ast_redirecting_reason_parse(val);
- }
-
- if (reason < 0) {
- ast_log(LOG_ERROR, "Unknown redirecting reason '%s', value unchanged\n", val);
- } else {
- redirecting.reason = reason;
- set_it(chan, &redirecting);
- }
- } else if (!strncasecmp("count", data, 5)) {
- val = ast_strdupa(value);
- ast_trim_blanks(val);
-
- if (('0' <= val[0]) && (val[0] <= '9')) {
- redirecting.count = atoi(val);
- set_it(chan, &redirecting);
- } else {
- ast_log(LOG_ERROR, "Unknown redirecting count '%s', value unchanged\n", val);
- }
- } else {
- ast_log(LOG_ERROR, "Unknown redirecting data type '%s'.\n", data);
- }
-
- return 0;
-}
-
-
-
-
-static struct ast_custom_function redirecting_function = {
- .name = "REDIRECTING",
- .read = redirecting_read,
- .write = redirecting_write,
-};
-
-
-
-
-/* ******************************************************************* */
-/*!
- * \internal
- * \brief Unload the function module
- *
- * \retval 0 on success.
- * \retval -1 on error.
- */
-static int unload_module(void)
-{
- return ast_custom_function_unregister(&redirecting_function);
-}
-
-
-
-
-/* ******************************************************************* */
-/*!
- * \internal
- * \brief Load and initialize the function module.
- *
- * \retval 0 on success.
- * \retval -1 on error.
- */
-static int load_module(void)
-{
- return ast_custom_function_register(&redirecting_function)
- ? AST_MODULE_LOAD_DECLINE
- : AST_MODULE_LOAD_SUCCESS;
-}
-
-
-
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Redirecting data dialplan function");
-
-
-/* ------------------------------------------------------------------- */
-/* end func_redirecting.c */
*/
const char *ast_connected_line_source_name(int data);
+/*!
+ * \since 1.8
+ * \brief Convert ast_party_name.char_set text code to value (used in config file parsing)
+ *
+ * \param data text string from config file
+ *
+ * \retval AST_PARTY_CHAR_SET from channel.h
+ * \retval -1 if not in table
+ */
+int ast_party_name_charset_parse(const char *data);
+
+/*!
+ * \since 1.8
+ * \brief Convert ast_party_name.char_set value to explanatory string
+ *
+ * \param data AST_PARTY_CHAR_SET from channel.h
+ *
+ * \return string for human presentation
+ */
+const char *ast_party_name_charset_describe(int data);
+
+/*!
+ * \since 1.8
+ * \brief Convert ast_party_name.char_set value to text code
+ *
+ * \param data AST_PARTY_CHAR_SET from channel.h
+ *
+ * \return string for config file
+ */
+const char *ast_party_name_charset_str(int data);
+
#endif /* _ASTERISK_CALLERID_H */
void (*digit)(struct ast_channel *chan, char digit);
};
+/*! Party name character set enumeration values (values from Q.SIG) */
+enum AST_PARTY_CHAR_SET {
+ AST_PARTY_CHAR_SET_UNKNOWN = 0,
+ AST_PARTY_CHAR_SET_ISO8859_1 = 1,
+ AST_PARTY_CHAR_SET_WITHDRAWN = 2,/* ITU withdrew this enum value. */
+ AST_PARTY_CHAR_SET_ISO8859_2 = 3,
+ AST_PARTY_CHAR_SET_ISO8859_3 = 4,
+ AST_PARTY_CHAR_SET_ISO8859_4 = 5,
+ AST_PARTY_CHAR_SET_ISO8859_5 = 6,
+ AST_PARTY_CHAR_SET_ISO8859_7 = 7,
+ AST_PARTY_CHAR_SET_ISO10646_BMPSTRING = 8,
+ AST_PARTY_CHAR_SET_ISO10646_UTF_8STRING = 9,
+};
+
+/*!
+ * \since 1.8
+ * \brief Information needed to specify a name in a call.
+ * \note All string fields here are malloc'ed, so they need to be
+ * freed when the structure is deleted.
+ * \note NULL and "" must be considered equivalent.
+ */
+struct ast_party_name {
+ /*! \brief Subscriber name (Malloced) */
+ char *str;
+ /*!
+ * \brief Character set the name is using.
+ * \see enum AST_PARTY_CHAR_SET
+ * \note
+ * Set to AST_PARTY_CHAR_SET_ISO8859_1 if unsure what to use.
+ * \todo Start using the party name character set value. Not currently used.
+ */
+ int char_set;
+ /*!
+ * \brief Q.931 encoded presentation-indicator encoded field
+ * \note Must tolerate the Q.931 screening-indicator field values being present.
+ */
+ int presentation;
+ /*! \brief TRUE if the name information is valid/present */
+ unsigned char valid;
+};
+
+/*!
+ * \since 1.8
+ * \brief Information needed to specify a number in a call.
+ * \note All string fields here are malloc'ed, so they need to be
+ * freed when the structure is deleted.
+ * \note NULL and "" must be considered equivalent.
+ */
+struct ast_party_number {
+ /*! \brief Subscriber phone number (Malloced) */
+ char *str;
+ /*! \brief Q.931 Type-Of-Number and Numbering-Plan encoded fields */
+ int plan;
+ /*! \brief Q.931 presentation-indicator and screening-indicator encoded fields */
+ int presentation;
+ /*! \brief TRUE if the number information is valid/present */
+ unsigned char valid;
+};
+
/*!
* \since 1.8
* \brief Information needed to specify a subaddress in a call.
};
/*!
- * \brief Structure for all kinds of caller ID identifications.
+ * \since 1.8
+ * \brief Information needed to identify an endpoint in a call.
* \note All string fields here are malloc'ed, so they need to be
* freed when the structure is deleted.
- * Also, NULL and "" must be considered equivalent.
- *
- * \note SIP and IAX2 has utf8 encoded Unicode caller ID names.
- * In some cases, we also have an alternative (RPID) E.164 number that can be used
- * as caller ID on numeric E.164 phone networks (DAHDI or SIP/IAX2 to PSTN gateway).
- *
- * \todo Implement settings for transliteration between UTF8 caller ID names in
- * to Ascii Caller ID's (DAHDI). Östen Åsklund might be transliterated into
- * Osten Asklund or Oesten Aasklund depending upon language and person...
- * We need automatic routines for incoming calls and static settings for
- * our own accounts.
+ * \note NULL and "" must be considered equivalent.
*/
-struct ast_callerid {
- /*!
- * \brief Malloc'd Dialed Number Identifier
- * (Field will eventually move to struct ast_channel.dialed.number)
- */
- char *cid_dnid;
-
- /*!
- * \brief Malloc'd Caller Number
- * (Field will eventually move to struct ast_channel.caller.id.number)
- */
- char *cid_num;
-
- /*!
- * \brief Malloc'd Caller Name (ASCII)
- * (Field will eventually move to struct ast_channel.caller.id.name)
- */
- char *cid_name;
-
- /*!
- * \brief Malloc'd Automatic Number Identification (ANI)
- * (Field will eventually move to struct ast_channel.caller.ani)
- */
- char *cid_ani;
-
- /*!
- * \brief Callerid Q.931 encoded number presentation/screening fields
- * (Field will eventually move to struct ast_channel.caller.id.number_presentation)
- */
- int cid_pres;
-
- /*!
- * \brief Callerid ANI 2 (Info digits)
- * (Field will eventually move to struct ast_channel.caller.ani2)
- */
- int cid_ani2;
-
- /*!
- * \brief Callerid Q.931 encoded type-of-number/numbering-plan fields
- * \note Currently this value is mostly just passed around the system.
- * The H.323 interfaces set the value from received messages and uses the value for sent messages.
- * The DAHDI PRI interfaces set the value from received messages but does not use it for sent messages.
- * You can read it and set it but only H.323 uses it.
- * (Field will eventually move to struct ast_channel.caller.id.number_type)
- */
- int cid_ton;
-
- /*!
- * \brief Callerid Transit Network Select
- * \note Currently this value is just passed around the system.
- * You can read it and set it but it is never used for anything.
- * (Field will eventually move to struct ast_channel.dialed.transit_network_select)
- */
- int cid_tns;
+struct ast_party_id {
+ /*! \brief Subscriber name */
+ struct ast_party_name name;
+ /*! \brief Subscriber phone number */
+ struct ast_party_number number;
+ /*! \brief Subscriber subaddress. */
+ struct ast_party_subaddress subaddress;
/*!
- * \brief Callerid "Tag"
+ * \brief User-set "tag"
+ * \details
* A user-settable field used to help associate some extrinsic information
- * about the channel or user of the channel to the caller ID. This information
- * is not transmitted over the wire and so is only useful within an Asterisk
- * environment.
- * (Field will eventually move to struct ast_channel.caller.id.tag)
+ * about the channel or user of the channel to the party ID. This information
+ * is normally not transmitted over the wire and so is only useful within an
+ * Asterisk environment.
*/
- char *cid_tag;
+ char *tag;
+};
- /*!
- * \brief Caller id subaddress.
- * (Field will eventually move to struct ast_channel.caller.id.subaddress)
- */
- struct ast_party_subaddress subaddress;
- /*!
- * \brief Dialed/Called subaddress.
- * (Field will eventually move to struct ast_channel.dialed.subaddress)
- */
- struct ast_party_subaddress dialed_subaddress;
+/*!
+ * \since 1.8
+ * \brief Indicate what information in ast_party_id should be set.
+ */
+struct ast_set_party_id {
+ /*! TRUE if the ast_party_name information should be set. */
+ unsigned char name;
+ /*! TRUE if the ast_party_number information should be set. */
+ unsigned char number;
+ /*! TRUE if the ast_party_subaddress information should be set. */
+ unsigned char subaddress;
};
/*!
* \since 1.8
- * \brief Information needed to identify an endpoint in a call.
+ * \brief Dialed/Called Party information.
+ * \note Dialed Number Identifier (DNID)
* \note All string fields here are malloc'ed, so they need to be
* freed when the structure is deleted.
* \note NULL and "" must be considered equivalent.
*/
-struct ast_party_id {
- /*! \brief Subscriber phone number (Malloced) */
- char *number;
-
- /*! \brief Subscriber name (Malloced) */
- char *name;
-
- /*! \brief User-set "tag" */
- char *tag;
-
- /*! \brief Subscriber subaddress. */
+struct ast_party_dialed {
+ /*!
+ * \brief Dialed/Called number
+ * \note Done this way in case we ever really need to use ast_party_number.
+ * We currently do not need all of the ast_party_number fields.
+ */
+ struct {
+ /*! \brief Subscriber phone number (Malloced) */
+ char *str;
+ /*! \brief Q.931 Type-Of-Number and Numbering-Plan encoded fields */
+ int plan;
+ } number;
+ /*! \brief Dialed/Called subaddress */
struct ast_party_subaddress subaddress;
-
- /*! \brief Q.931 encoded type-of-number/numbering-plan fields */
- int number_type;
-
- /*! \brief Q.931 encoded number presentation/screening fields */
- int number_presentation;
+ /*!
+ * \brief Transit Network Select
+ * \note Currently this value is just passed around the system.
+ * You can read it and set it but it is never used for anything.
+ */
+ int transit_network_select;
};
/*!
* \note All string fields here are malloc'ed, so they need to be
* freed when the structure is deleted.
* \note NULL and "" must be considered equivalent.
+ *
+ * \note SIP and IAX2 has UTF8 encoded Unicode Caller ID names.
+ * In some cases, we also have an alternative (RPID) E.164 number that can
+ * be used as Caller ID on numeric E.164 phone networks (DAHDI or SIP/IAX2 to
+ * PSTN gateway).
+ *
+ * \todo Implement settings for transliteration between UTF8 Caller ID names in
+ * to ASCII Caller ID's (DAHDI). Östen Åsklund might be transliterated into
+ * Osten Asklund or Oesten Aasklund depending upon language and person...
+ * We need automatic routines for incoming calls and static settings for
+ * our own accounts.
*/
struct ast_party_caller {
- struct ast_party_id id; /*! \brief Caller party ID */
+ /*! \brief Caller party ID */
+ struct ast_party_id id;
- /*! \brief Automatic Number Identification (ANI) (Malloced) */
+ /*!
+ * \brief Automatic Number Identification (ANI) (Malloced)
+ * \todo BUGBUG This should be made an ast_party_id.
+ */
char *ani;
/*! \brief Automatic Number Identification 2 (Info Digits) */
int ani2;
};
+/*!
+ * \since 1.8
+ * \brief Indicate what information in ast_party_caller should be set.
+ */
+struct ast_set_party_caller {
+ /*! What caller id information to set. */
+ struct ast_set_party_id id;
+};
+
/*!
* \since 1.8
* \brief Connected Line/Party information.
* \note NULL and "" must be considered equivalent.
*/
struct ast_party_connected_line {
- struct ast_party_id id; /*! \brief Connected party ID */
+ /*! \brief Connected party ID */
+ struct ast_party_id id;
/*!
* \brief Automatic Number Identification (ANI) (Malloced)
* \note Not really part of connected line data but needed to
* save the corresponding caller id value.
+ * \todo BUGBUG This should be made an ast_party_id.
*/
char *ani;
int source;
};
+/*!
+ * \since 1.8
+ * \brief Indicate what information in ast_party_connected_line should be set.
+ */
+struct ast_set_party_connected_line {
+ /*! What connected line id information to set. */
+ struct ast_set_party_id id;
+};
+
/*!
* \since 1.8
* \brief Redirecting Line information.
int reason;
};
+/*!
+ * \since 1.8
+ * \brief Indicate what information in ast_party_redirecting should be set.
+ */
+struct ast_set_party_redirecting {
+ /*! What redirecting-from id information to set. */
+ struct ast_set_party_id from;
+ /*! What redirecting-to id information to set. */
+ struct ast_set_party_id to;
+};
+
/*!
* \brief
* Structure to describe a channel "technology", ie a channel driver
struct timeval whentohangup; /*!< Non-zero, set to actual time when channel is to be hung up */
pthread_t blocker; /*!< If anyone is blocking, this is them */
+ /*!
+ * \brief Dialed/Called information.
+ * \note Set on incoming channels to indicate the originally dialed party.
+ * \note Dialed Number Identifier (DNID)
+ */
+ struct ast_party_dialed dialed;
+
/*!
* \brief Channel Caller ID information.
* \note The caller id information is the caller id of this
* channel when it is used to initiate a call.
*/
- struct ast_callerid cid;
+ struct ast_party_caller caller;
/*!
* \brief Channel Connected Line ID information.
void ast_deactivate_generator(struct ast_channel *chan);
/*!
- * \brief Set caller ID number, name and ANI
+ * \brief Set caller ID number, name and ANI and generate AMI event.
*
+ * \note Use ast_channel_set_caller() and ast_channel_set_caller_event() instead.
* \note The channel does not need to be locked before calling this function.
*/
void ast_set_callerid(struct ast_channel *chan, const char *cid_num, const char *cid_name, const char *cid_ani);
+/*!
+ * \brief Set the caller id information in the Asterisk channel
+ * \since 1.8
+ *
+ * \param chan Asterisk channel to set caller id information
+ * \param caller Caller id information
+ * \param update What caller information to update. NULL if all.
+ *
+ * \return Nothing
+ *
+ * \note The channel does not need to be locked before calling this function.
+ */
+void ast_channel_set_caller(struct ast_channel *chan, const struct ast_party_caller *caller, const struct ast_set_party_caller *update);
+
+/*!
+ * \brief Set the caller id information in the Asterisk channel and generate an AMI event
+ * if the caller id name or number changed.
+ * \since 1.8
+ *
+ * \param chan Asterisk channel to set caller id information
+ * \param caller Caller id information
+ * \param update What caller information to update. NULL if all.
+ *
+ * \return Nothing
+ *
+ * \note The channel does not need to be locked before calling this function.
+ */
+void ast_channel_set_caller_event(struct ast_channel *chan, const struct ast_party_caller *caller, const struct ast_set_party_caller *update);
+
/*! Set the file descriptor on the channel */
void ast_channel_set_fd(struct ast_channel *chan, int which, int fd);
void ast_channel_set_linkgroup(struct ast_channel *chan, struct ast_channel *peer);
+/*!
+ * \brief Initialize the given name structure.
+ * \since 1.8
+ *
+ * \param init Name structure to initialize.
+ *
+ * \return Nothing
+ */
+void ast_party_name_init(struct ast_party_name *init);
+
+/*!
+ * \brief Copy the source party name information to the destination party name.
+ * \since 1.8
+ *
+ * \param dest Destination party name
+ * \param src Source party name
+ *
+ * \return Nothing
+ */
+void ast_party_name_copy(struct ast_party_name *dest, const struct ast_party_name *src);
+
+/*!
+ * \brief Initialize the given party name structure using the given guide
+ * for a set update operation.
+ * \since 1.8
+ *
+ * \details
+ * The initialization is needed to allow a set operation to know if a
+ * value needs to be updated. Simple integers need the guide's original
+ * value in case the set operation is not trying to set a new value.
+ * String values are simply set to NULL pointers if they are not going
+ * to be updated.
+ *
+ * \param init Party name structure to initialize.
+ * \param guide Source party name to use as a guide in initializing.
+ *
+ * \return Nothing
+ */
+void ast_party_name_set_init(struct ast_party_name *init, const struct ast_party_name *guide);
+
+/*!
+ * \brief Set the source party name information into the destination party name.
+ * \since 1.8
+ *
+ * \param dest The name one wishes to update
+ * \param src The new name values to update the dest
+ *
+ * \return Nothing
+ */
+void ast_party_name_set(struct ast_party_name *dest, const struct ast_party_name *src);
+
+/*!
+ * \brief Destroy the party name contents
+ * \since 1.8
+ *
+ * \param doomed The party name to destroy.
+ *
+ * \return Nothing
+ */
+void ast_party_name_free(struct ast_party_name *doomed);
+
+/*!
+ * \brief Initialize the given number structure.
+ * \since 1.8
+ *
+ * \param init Number structure to initialize.
+ *
+ * \return Nothing
+ */
+void ast_party_number_init(struct ast_party_number *init);
+
+/*!
+ * \brief Copy the source party number information to the destination party number.
+ * \since 1.8
+ *
+ * \param dest Destination party number
+ * \param src Source party number
+ *
+ * \return Nothing
+ */
+void ast_party_number_copy(struct ast_party_number *dest, const struct ast_party_number *src);
+
+/*!
+ * \brief Initialize the given party number structure using the given guide
+ * for a set update operation.
+ * \since 1.8
+ *
+ * \details
+ * The initialization is needed to allow a set operation to know if a
+ * value needs to be updated. Simple integers need the guide's original
+ * value in case the set operation is not trying to set a new value.
+ * String values are simply set to NULL pointers if they are not going
+ * to be updated.
+ *
+ * \param init Party number structure to initialize.
+ * \param guide Source party number to use as a guide in initializing.
+ *
+ * \return Nothing
+ */
+void ast_party_number_set_init(struct ast_party_number *init, const struct ast_party_number *guide);
+
+/*!
+ * \brief Set the source party number information into the destination party number.
+ * \since 1.8
+ *
+ * \param dest The number one wishes to update
+ * \param src The new number values to update the dest
+ *
+ * \return Nothing
+ */
+void ast_party_number_set(struct ast_party_number *dest, const struct ast_party_number *src);
+
+/*!
+ * \brief Destroy the party number contents
+ * \since 1.8
+ *
+ * \param doomed The party number to destroy.
+ *
+ * \return Nothing
+ */
+void ast_party_number_free(struct ast_party_number *doomed);
+
/*!
* \since 1.8
* \brief Initialize the given subaddress structure.
/*!
* \since 1.8
- * \brief Initialize the given party subadress structure using the given guide
+ * \brief Initialize the given party subaddress structure using the given guide
* for a set update operation.
*
* \details
* String values are simply set to NULL pointers if they are not going
* to be updated.
*
- * \param init Party Subaddress structure to initialize.
+ * \param init Party subaddress structure to initialize.
* \param guide Source party subaddress to use as a guide in initializing.
*
* \return Nothing
* \since 1.8
* \brief Set the source party subaddress information into the destination party subaddress.
*
- * \param dest Destination party subaddress
- * \param src Source party subaddress
+ * \param dest The subaddress one wishes to update
+ * \param src The new subaddress values to update the dest
*
* \return Nothing
*/
*/
void ast_party_id_init(struct ast_party_id *init);
+/*!
+ * \brief Copy the source party id information to the destination party id.
+ * \since 1.8
+ *
+ * \param dest Destination party id
+ * \param src Source party id
+ *
+ * \return Nothing
+ */
+void ast_party_id_copy(struct ast_party_id *dest, const struct ast_party_id *src);
+
+/*!
+ * \brief Initialize the given party id structure using the given guide
+ * for a set update operation.
+ * \since 1.8
+ *
+ * \details
+ * The initialization is needed to allow a set operation to know if a
+ * value needs to be updated. Simple integers need the guide's original
+ * value in case the set operation is not trying to set a new value.
+ * String values are simply set to NULL pointers if they are not going
+ * to be updated.
+ *
+ * \param init Party id structure to initialize.
+ * \param guide Source party id to use as a guide in initializing.
+ *
+ * \return Nothing
+ */
+void ast_party_id_set_init(struct ast_party_id *init, const struct ast_party_id *guide);
+
+/*!
+ * \brief Set the source party id information into the destination party id.
+ * \since 1.8
+ *
+ * \param dest The id one wishes to update
+ * \param src The new id values to update the dest
+ * \param update What id information to update. NULL if all.
+ *
+ * \return Nothing
+ */
+void ast_party_id_set(struct ast_party_id *dest, const struct ast_party_id *src, const struct ast_set_party_id *update);
+
/*!
* \brief Destroy the party id contents
* \since 1.8
*/
void ast_party_id_free(struct ast_party_id *doomed);
+/*!
+ * \brief Determine the overall presentation value for the given party.
+ * \since 1.8
+ *
+ * \param id Party to determine the overall presentation value.
+ *
+ * \return Overall presentation value for the given party.
+ */
+int ast_party_id_presentation(const struct ast_party_id *id);
+
+/*!
+ * \brief Initialize the given dialed structure.
+ * \since 1.8
+ *
+ * \param init Dialed structure to initialize.
+ *
+ * \return Nothing
+ */
+void ast_party_dialed_init(struct ast_party_dialed *init);
+
+/*!
+ * \brief Copy the source dialed party information to the destination dialed party.
+ * \since 1.8
+ *
+ * \param dest Destination dialed party
+ * \param src Source dialed party
+ *
+ * \return Nothing
+ */
+void ast_party_dialed_copy(struct ast_party_dialed *dest, const struct ast_party_dialed *src);
+
+/*!
+ * \brief Initialize the given dialed structure using the given
+ * guide for a set update operation.
+ * \since 1.8
+ *
+ * \details
+ * The initialization is needed to allow a set operation to know if a
+ * value needs to be updated. Simple integers need the guide's original
+ * value in case the set operation is not trying to set a new value.
+ * String values are simply set to NULL pointers if they are not going
+ * to be updated.
+ *
+ * \param init Caller structure to initialize.
+ * \param guide Source dialed to use as a guide in initializing.
+ *
+ * \return Nothing
+ */
+void ast_party_dialed_set_init(struct ast_party_dialed *init, const struct ast_party_dialed *guide);
+
+/*!
+ * \brief Set the dialed information based on another dialed source
+ * \since 1.8
+ *
+ * This is similar to ast_party_dialed_copy, except that NULL values for
+ * strings in the src parameter indicate not to update the corresponding dest values.
+ *
+ * \param dest The dialed one wishes to update
+ * \param src The new dialed values to update the dest
+ *
+ * \return Nada
+ */
+void ast_party_dialed_set(struct ast_party_dialed *dest, const struct ast_party_dialed *src);
+
+/*!
+ * \brief Destroy the dialed party contents
+ * \since 1.8
+ *
+ * \param doomed The dialed party to destroy.
+ *
+ * \return Nothing
+ */
+void ast_party_dialed_free(struct ast_party_dialed *doomed);
+
/*!
* \since 1.8
* \brief Initialize the given caller structure.
*
* \return Nothing
*/
-void ast_party_caller_copy(struct ast_callerid *dest, const struct ast_callerid *src);
+void ast_party_caller_copy(struct ast_party_caller *dest, const struct ast_party_caller *src);
+
+/*!
+ * \brief Initialize the given caller structure using the given
+ * guide for a set update operation.
+ * \since 1.8
+ *
+ * \details
+ * The initialization is needed to allow a set operation to know if a
+ * value needs to be updated. Simple integers need the guide's original
+ * value in case the set operation is not trying to set a new value.
+ * String values are simply set to NULL pointers if they are not going
+ * to be updated.
+ *
+ * \param init Caller structure to initialize.
+ * \param guide Source caller to use as a guide in initializing.
+ *
+ * \return Nothing
+ */
+void ast_party_caller_set_init(struct ast_party_caller *init, const struct ast_party_caller *guide);
+
+/*!
+ * \brief Set the caller information based on another caller source
+ * \since 1.8
+ *
+ * This is similar to ast_party_caller_copy, except that NULL values for
+ * strings in the src parameter indicate not to update the corresponding dest values.
+ *
+ * \param dest The caller one wishes to update
+ * \param src The new caller values to update the dest
+ * \param update What caller information to update. NULL if all.
+ *
+ * \return Nada
+ */
+void ast_party_caller_set(struct ast_party_caller *dest, const struct ast_party_caller *src, const struct ast_set_party_caller *update);
+
+/*!
+ * \brief Destroy the caller party contents
+ * \since 1.8
+ *
+ * \param doomed The caller party to destroy.
+ *
+ * \return Nothing
+ */
+void ast_party_caller_free(struct ast_party_caller *doomed);
/*!
* \since 1.8
* This is similar to ast_party_connected_line_copy, except that NULL values for
* strings in the src parameter indicate not to update the corresponding dest values.
*
- * \param src The source connected line to use as a guide to set the dest
* \param dest The connected line one wishes to update
+ * \param src The new connected line values to update the dest
+ * \param update What connected line information to update. NULL if all.
*
- * \return Nada
+ * \return Nothing
*/
-void ast_party_connected_line_set(struct ast_party_connected_line *dest, const struct ast_party_connected_line *src);
+void ast_party_connected_line_set(struct ast_party_connected_line *dest, const struct ast_party_connected_line *src, const struct ast_set_party_connected_line *update);
/*!
* \since 1.8
* \brief Collect the caller party information into a connected line structure.
*
* \param connected Collected caller information for the connected line
- * \param cid Caller information.
+ * \param caller Caller information.
*
* \return Nothing
*
* \warning DO NOT call ast_party_connected_line_free() on the filled in
* connected line structure!
*/
-void ast_party_connected_line_collect_caller(struct ast_party_connected_line *connected, struct ast_callerid *cid);
+void ast_party_connected_line_collect_caller(struct ast_party_connected_line *connected, struct ast_party_caller *caller);
/*!
* \since 1.8
*/
void ast_party_connected_line_free(struct ast_party_connected_line *doomed);
+/*!
+ * \brief Initialize the given redirecting structure.
+ * \since 1.8
+ *
+ * \param init Redirecting structure to initialize.
+ *
+ * \return Nothing
+ */
+void ast_party_redirecting_init(struct ast_party_redirecting *init);
+
/*!
* \since 1.8
* \brief Copy the source redirecting information to the destination redirecting.
*/
void ast_party_redirecting_set_init(struct ast_party_redirecting *init, const struct ast_party_redirecting *guide);
+/*!
+ * \brief Set the redirecting information based on another redirecting source
+ * \since 1.8
+ *
+ * This is similar to ast_party_redirecting_copy, except that NULL values for
+ * strings in the src parameter indicate not to update the corresponding dest values.
+ *
+ * \param dest The redirecting one wishes to update
+ * \param src The new redirecting values to update the dest
+ * \param update What redirecting information to update. NULL if all.
+ *
+ * \return Nothing
+ */
+void ast_party_redirecting_set(struct ast_party_redirecting *dest, const struct ast_party_redirecting *src, const struct ast_set_party_redirecting *update);
+
/*!
* \since 1.8
* \brief Destroy the redirecting information contents
*
* \note Assumes locks are already acquired
*/
-void ast_connected_line_copy_from_caller(struct ast_party_connected_line *dest, const struct ast_callerid *src);
+void ast_connected_line_copy_from_caller(struct ast_party_connected_line *dest, const struct ast_party_caller *src);
/*!
* \since 1.8
*
* \note Assumes locks are already acquired
*/
-void ast_connected_line_copy_to_caller(struct ast_callerid *dest, const struct ast_party_connected_line *src);
+void ast_connected_line_copy_to_caller(struct ast_party_caller *dest, const struct ast_party_connected_line *src);
/*!
* \since 1.8
*
* \param chan Asterisk channel to set connected line information
* \param connected Connected line information
+ * \param update What connected line information to update. NULL if all.
*
* \return Nothing
*
* \note The channel does not need to be locked before calling this function.
*/
-void ast_channel_set_connected_line(struct ast_channel *chan, const struct ast_party_connected_line *connected);
+void ast_channel_set_connected_line(struct ast_channel *chan, const struct ast_party_connected_line *connected, const struct ast_set_party_connected_line *update);
/*!
* \since 1.8
* \param data Buffer to fill with the frame data
* \param datalen Size of the buffer to fill
* \param connected Connected line information
+ * \param update What connected line information to build. NULL if all.
*
* \retval -1 if error
* \retval Amount of data buffer used
*/
-int ast_connected_line_build_data(unsigned char *data, size_t datalen, const struct ast_party_connected_line *connected);
+int ast_connected_line_build_data(unsigned char *data, size_t datalen, const struct ast_party_connected_line *connected, const struct ast_set_party_connected_line *update);
/*!
* \since 1.8
*
* \param chan Asterisk channel to indicate connected line information
* \param connected Connected line information
+ * \param update What connected line information to update. NULL if all.
*
* \return Nothing
*/
-void ast_channel_update_connected_line(struct ast_channel *chan, const struct ast_party_connected_line *connected);
+void ast_channel_update_connected_line(struct ast_channel *chan, const struct ast_party_connected_line *connected, const struct ast_set_party_connected_line *update);
/*!
* \since 1.8
*
* \param chan Asterisk channel to indicate connected line information
* \param connected Connected line information
+ * \param update What connected line information to update. NULL if all.
*
* \return Nothing
*/
-void ast_channel_queue_connected_line_update(struct ast_channel *chan, const struct ast_party_connected_line *connected);
+void ast_channel_queue_connected_line_update(struct ast_channel *chan, const struct ast_party_connected_line *connected, const struct ast_set_party_connected_line *update);
/*!
* \since 1.8
*
* \param chan Asterisk channel to set redirecting id information
* \param redirecting Redirecting id information
+ * \param update What redirecting information to update. NULL if all.
*
* \return Nothing
*
* \note The channel does not need to be locked before calling this function.
*/
-void ast_channel_set_redirecting(struct ast_channel *chan, const struct ast_party_redirecting *redirecting);
+void ast_channel_set_redirecting(struct ast_channel *chan, const struct ast_party_redirecting *redirecting, const struct ast_set_party_redirecting *update);
/*!
* \since 1.8
* \param data Buffer to fill with the frame data
* \param datalen Size of the buffer to fill
* \param redirecting Redirecting id information
+ * \param update What redirecting information to build. NULL if all.
*
* \retval -1 if error
* \retval Amount of data buffer used
*/
-int ast_redirecting_build_data(unsigned char *data, size_t datalen, const struct ast_party_redirecting *redirecting);
+int ast_redirecting_build_data(unsigned char *data, size_t datalen, const struct ast_party_redirecting *redirecting, const struct ast_set_party_redirecting *update);
/*!
* \since 1.8
*
* \param chan Asterisk channel to indicate redirecting id information
* \param redirecting Redirecting id information
+ * \param update What redirecting information to update. NULL if all.
*
* \return Nothing
*/
-void ast_channel_update_redirecting(struct ast_channel *chan, const struct ast_party_redirecting *redirecting);
+void ast_channel_update_redirecting(struct ast_channel *chan, const struct ast_party_redirecting *redirecting, const struct ast_set_party_redirecting *update);
/*!
* \since 1.8
*
* \param chan Asterisk channel to indicate redirecting id information
* \param redirecting Redirecting id information
+ * \param update What redirecting information to update. NULL if all.
*
* \return Nothing
*/
-void ast_channel_queue_redirecting_update(struct ast_channel *chan, const struct ast_party_redirecting *redirecting);
+void ast_channel_queue_redirecting_update(struct ast_channel *chan, const struct ast_party_redirecting *redirecting, const struct ast_set_party_redirecting *update);
/*!
* \since 1.8
break;
}
collect[x++] = res;
- if (!ast_matchmore_extension(chan, context, collect, 1, chan->cid.cid_num)) {
+ if (!ast_matchmore_extension(chan, context, collect, 1,
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) {
break;
}
}
if (res >= 0) {
- res = ast_exists_extension(chan, context, collect, 1, chan->cid.cid_num) ? 1 : 0;
+ res = ast_exists_extension(chan, context, collect, 1,
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL)) ? 1 : 0;
}
return res;
return "not-known";
}
+
+/*! \brief Translation table for ast_party_name char-set settings */
+static const struct ast_value_translation party_name_charset_tbl[] = {
+/* *INDENT-OFF* */
+ { AST_PARTY_CHAR_SET_UNKNOWN, "unknown", "Unknown" },
+ { AST_PARTY_CHAR_SET_ISO8859_1, "iso8859-1", "ISO8859-1" },
+ { AST_PARTY_CHAR_SET_WITHDRAWN, "withdrawn", "Withdrawn" },
+ { AST_PARTY_CHAR_SET_ISO8859_2, "iso8859-2", "ISO8859-2" },
+ { AST_PARTY_CHAR_SET_ISO8859_3, "iso8859-3", "ISO8859-3" },
+ { AST_PARTY_CHAR_SET_ISO8859_4, "iso8859-4", "ISO8859-4" },
+ { AST_PARTY_CHAR_SET_ISO8859_5, "iso8859-5", "ISO8859-5" },
+ { AST_PARTY_CHAR_SET_ISO8859_7, "iso8859-7", "ISO8859-7" },
+ { AST_PARTY_CHAR_SET_ISO10646_BMPSTRING, "bmp", "ISO10646 Bmp String" },
+ { AST_PARTY_CHAR_SET_ISO10646_UTF_8STRING, "utf8", "ISO10646 UTF-8 String" },
+/* *INDENT-ON* */
+};
+
+int ast_party_name_charset_parse(const char *data)
+{
+ int index;
+
+ for (index = 0; index < ARRAY_LEN(party_name_charset_tbl); ++index) {
+ if (!strcasecmp(party_name_charset_tbl[index].name, data)) {
+ return party_name_charset_tbl[index].value;
+ }
+ }
+
+ return -1;
+}
+
+const char *ast_party_name_charset_describe(int data)
+{
+ int index;
+
+ for (index = 0; index < ARRAY_LEN(party_name_charset_tbl); ++index) {
+ if (party_name_charset_tbl[index].value == data) {
+ return party_name_charset_tbl[index].description;
+ }
+ }
+
+ return "not-known";
+}
+
+const char *ast_party_name_charset_str(int data)
+{
+ int index;
+
+ for (index = 0; index < ARRAY_LEN(party_name_charset_tbl); ++index) {
+ if (party_name_charset_tbl[index].value == data) {
+ return party_name_charset_tbl[index].name;
+ }
+ }
+
+ return "not-known";
+}
}
generic_pvt->offer_timer_id = -1;
- if (chan->cid.cid_num) {
- ast_copy_string(generic_pvt->cid_num, chan->cid.cid_num, sizeof(generic_pvt->cid_num));
+ if (chan->caller.id.number.valid && chan->caller.id.number.str) {
+ ast_copy_string(generic_pvt->cid_num, chan->caller.id.number.str, sizeof(generic_pvt->cid_num));
}
- if (chan->cid.cid_name) {
- ast_copy_string(generic_pvt->cid_name, chan->cid.cid_name, sizeof(generic_pvt->cid_name));
+ if (chan->caller.id.name.valid && chan->caller.id.name.str) {
+ ast_copy_string(generic_pvt->cid_name, chan->caller.id.name.str, sizeof(generic_pvt->cid_name));
}
ast_copy_string(generic_pvt->exten, S_OR(chan->macroexten, chan->exten), sizeof(generic_pvt->exten));
ast_copy_string(generic_pvt->context, S_OR(chan->macrocontext, chan->context), sizeof(generic_pvt->context));
/* set cid info for one record */
static void set_one_cid(struct ast_cdr *cdr, struct ast_channel *c)
{
- /* Grab source from ANI or normal Caller*ID */
- const char *num = S_OR(c->cid.cid_ani, c->cid.cid_num);
- if (!cdr)
+ const char *num;
+
+ if (!cdr) {
return;
- if (!ast_strlen_zero(c->cid.cid_name)) {
- if (!ast_strlen_zero(num)) /* both name and number */
- snprintf(cdr->clid, sizeof(cdr->clid), "\"%s\" <%s>", c->cid.cid_name, num);
- else /* only name */
- ast_copy_string(cdr->clid, c->cid.cid_name, sizeof(cdr->clid));
- } else if (!ast_strlen_zero(num)) { /* only number */
- ast_copy_string(cdr->clid, num, sizeof(cdr->clid));
- } else { /* nothing known */
- cdr->clid[0] = '\0';
}
+
+ /* Grab source from ANI or normal Caller*ID */
+ num = S_OR(c->caller.ani,
+ S_COR(c->caller.id.number.valid, c->caller.id.number.str, NULL));
+ ast_callerid_merge(cdr->clid, sizeof(cdr->clid),
+ S_COR(c->caller.id.name.valid, c->caller.id.name.str, NULL), num, "");
ast_copy_string(cdr->src, S_OR(num, ""), sizeof(cdr->src));
- ast_cdr_setvar(cdr, "dnid", S_OR(c->cid.cid_dnid, ""), 0);
+ ast_cdr_setvar(cdr, "dnid", S_OR(c->dialed.number.str, ""), 0);
- if (c->cid.subaddress.valid) {
- ast_cdr_setvar(cdr, "callingsubaddr", S_OR(c->cid.subaddress.str, ""), 0);
+ if (c->caller.id.subaddress.valid) {
+ ast_cdr_setvar(cdr, "callingsubaddr", S_OR(c->caller.id.subaddress.str, ""), 0);
}
- if (c->cid.dialed_subaddress.valid) {
- ast_cdr_setvar(cdr, "calledsubaddr", S_OR(c->cid.dialed_subaddress.str, ""), 0);
+ if (c->dialed.subaddress.valid) {
+ ast_cdr_setvar(cdr, "calledsubaddr", S_OR(c->dialed.subaddress.str, ""), 0);
}
}
AST_LIST_INSERT_HEAD(headp, newvariable, entries);
}
- tchan->cid.cid_name = ast_strdup(record.caller_id_name);
- tchan->cid.cid_num = ast_strdup(record.caller_id_num);
- tchan->cid.cid_ani = ast_strdup(record.caller_id_ani);
- tchan->redirecting.from.number = ast_strdup(record.caller_id_rdnis);
- tchan->cid.cid_dnid = ast_strdup(record.caller_id_dnid);
+ 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 = 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_channel_lock(chan);
ev = ast_event_new(AST_EVENT_CEL,
- AST_EVENT_IE_CEL_EVENT_TYPE, AST_EVENT_IE_PLTYPE_UINT, event_type,
- AST_EVENT_IE_CEL_EVENT_TIME, AST_EVENT_IE_PLTYPE_UINT, eventtime.tv_sec,
- AST_EVENT_IE_CEL_EVENT_TIME_USEC, AST_EVENT_IE_PLTYPE_UINT, eventtime.tv_usec,
- AST_EVENT_IE_CEL_USEREVENT_NAME, AST_EVENT_IE_PLTYPE_STR, userdefevname,
- AST_EVENT_IE_CEL_CIDNAME, AST_EVENT_IE_PLTYPE_STR, S_OR(chan->cid.cid_name, ""),
- AST_EVENT_IE_CEL_CIDNUM, AST_EVENT_IE_PLTYPE_STR, S_OR(chan->cid.cid_num, ""),
- AST_EVENT_IE_CEL_CIDANI, AST_EVENT_IE_PLTYPE_STR, S_OR(chan->cid.cid_ani, ""),
- AST_EVENT_IE_CEL_CIDRDNIS, AST_EVENT_IE_PLTYPE_STR, S_OR(chan->redirecting.from.number, ""),
- AST_EVENT_IE_CEL_CIDDNID, AST_EVENT_IE_PLTYPE_STR, S_OR(chan->cid.cid_dnid, ""),
- AST_EVENT_IE_CEL_EXTEN, AST_EVENT_IE_PLTYPE_STR, chan->exten,
- AST_EVENT_IE_CEL_CONTEXT, AST_EVENT_IE_PLTYPE_STR, chan->context,
- AST_EVENT_IE_CEL_CHANNAME, AST_EVENT_IE_PLTYPE_STR, chan->name,
- AST_EVENT_IE_CEL_APPNAME, AST_EVENT_IE_PLTYPE_STR, S_OR(chan->appl, ""),
- AST_EVENT_IE_CEL_APPDATA, AST_EVENT_IE_PLTYPE_STR, S_OR(chan->data, ""),
- AST_EVENT_IE_CEL_AMAFLAGS, AST_EVENT_IE_PLTYPE_UINT, chan->amaflags,
- AST_EVENT_IE_CEL_ACCTCODE, AST_EVENT_IE_PLTYPE_STR, chan->accountcode,
- AST_EVENT_IE_CEL_PEERACCT, AST_EVENT_IE_PLTYPE_STR, chan->peeraccount,
- AST_EVENT_IE_CEL_UNIQUEID, AST_EVENT_IE_PLTYPE_STR, chan->uniqueid,
- AST_EVENT_IE_CEL_LINKEDID, AST_EVENT_IE_PLTYPE_STR, chan->linkedid,
- AST_EVENT_IE_CEL_USERFIELD, AST_EVENT_IE_PLTYPE_STR, chan->userfield,
- AST_EVENT_IE_CEL_EXTRA, AST_EVENT_IE_PLTYPE_STR, extra,
- AST_EVENT_IE_CEL_PEER, AST_EVENT_IE_PLTYPE_STR, peername,
- AST_EVENT_IE_END);
+ AST_EVENT_IE_CEL_EVENT_TYPE, AST_EVENT_IE_PLTYPE_UINT, event_type,
+ AST_EVENT_IE_CEL_EVENT_TIME, AST_EVENT_IE_PLTYPE_UINT, eventtime.tv_sec,
+ AST_EVENT_IE_CEL_EVENT_TIME_USEC, AST_EVENT_IE_PLTYPE_UINT, eventtime.tv_usec,
+ AST_EVENT_IE_CEL_USEREVENT_NAME, AST_EVENT_IE_PLTYPE_STR, userdefevname,
+ AST_EVENT_IE_CEL_CIDNAME, AST_EVENT_IE_PLTYPE_STR,
+ S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, ""),
+ AST_EVENT_IE_CEL_CIDNUM, AST_EVENT_IE_PLTYPE_STR,
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, ""),
+ AST_EVENT_IE_CEL_CIDANI, AST_EVENT_IE_PLTYPE_STR,
+ S_OR(chan->caller.ani, ""),
+ AST_EVENT_IE_CEL_CIDRDNIS, AST_EVENT_IE_PLTYPE_STR,
+ S_COR(chan->redirecting.from.number.valid, chan->redirecting.from.number.str, ""),
+ AST_EVENT_IE_CEL_CIDDNID, AST_EVENT_IE_PLTYPE_STR,
+ S_OR(chan->dialed.number.str, ""),
+ AST_EVENT_IE_CEL_EXTEN, AST_EVENT_IE_PLTYPE_STR, chan->exten,
+ AST_EVENT_IE_CEL_CONTEXT, AST_EVENT_IE_PLTYPE_STR, chan->context,
+ AST_EVENT_IE_CEL_CHANNAME, AST_EVENT_IE_PLTYPE_STR, chan->name,
+ AST_EVENT_IE_CEL_APPNAME, AST_EVENT_IE_PLTYPE_STR, S_OR(chan->appl, ""),
+ AST_EVENT_IE_CEL_APPDATA, AST_EVENT_IE_PLTYPE_STR, S_OR(chan->data, ""),
+ AST_EVENT_IE_CEL_AMAFLAGS, AST_EVENT_IE_PLTYPE_UINT, chan->amaflags,
+ AST_EVENT_IE_CEL_ACCTCODE, AST_EVENT_IE_PLTYPE_STR, chan->accountcode,
+ AST_EVENT_IE_CEL_PEERACCT, AST_EVENT_IE_PLTYPE_STR, chan->peeraccount,
+ AST_EVENT_IE_CEL_UNIQUEID, AST_EVENT_IE_PLTYPE_STR, chan->uniqueid,
+ AST_EVENT_IE_CEL_LINKEDID, AST_EVENT_IE_PLTYPE_STR, chan->linkedid,
+ AST_EVENT_IE_CEL_USERFIELD, AST_EVENT_IE_PLTYPE_STR, chan->userfield,
+ AST_EVENT_IE_CEL_EXTRA, AST_EVENT_IE_PLTYPE_STR, extra,
+ AST_EVENT_IE_CEL_PEER, AST_EVENT_IE_PLTYPE_STR, peername,
+ AST_EVENT_IE_END);
ast_channel_unlock(chan);
#include <sys/epoll.h>
#endif
+#if defined(KEEP_TILL_CHANNEL_PARTY_NUMBER_INFO_NEEDED)
#if defined(HAVE_PRI)
#include "libpri.h"
#endif /* defined(HAVE_PRI) */
+#endif /* defined(KEEP_TILL_CHANNEL_PARTY_NUMBER_INFO_NEEDED) */
struct ast_epoll_data {
struct ast_channel *chan;
#define NUM_CHANNEL_BUCKETS 1567
#endif
+#if 0 /* XXX AstData: ast_callerid no longer exists. (Equivalent code not readily apparent.) */
#define DATA_EXPORT_CALLERID(MEMBER) \
MEMBER(ast_callerid, cid_dnid, AST_DATA_STRING) \
MEMBER(ast_callerid, cid_num, AST_DATA_STRING) \
MEMBER(ast_callerid, cid_tag, AST_DATA_STRING)
AST_DATA_STRUCTURE(ast_callerid, DATA_EXPORT_CALLERID);
+#endif
#define DATA_EXPORT_CHANNEL(MEMBER) \
MEMBER(ast_channel, blockproc, AST_DATA_STRING) \
ast_data_add_bool(tree, "DISABLE_WORKAROUNDS", ast_test_flag(chan, AST_FLAG_DISABLE_WORKAROUNDS));
}
+#if defined(KEEP_TILL_CHANNEL_PARTY_NUMBER_INFO_NEEDED)
static const char *party_number_ton2str(int ton)
{
#if defined(HAVE_PRI)
#endif /* defined(HAVE_PRI) */
return "Unknown";
}
+#endif /* defined(KEEP_TILL_CHANNEL_PARTY_NUMBER_INFO_NEEDED) */
+#if defined(KEEP_TILL_CHANNEL_PARTY_NUMBER_INFO_NEEDED)
static const char *party_number_plan2str(int plan)
{
#if defined(HAVE_PRI)
#endif /* defined(HAVE_PRI) */
return "Unknown";
}
+#endif /* defined(KEEP_TILL_CHANNEL_PARTY_NUMBER_INFO_NEEDED) */
int ast_channel_data_add_structure(struct ast_data *tree,
struct ast_channel *chan, int add_bridged)
{
struct ast_channel *bc;
- struct ast_data *data_bridged, *data_cdr, *data_flags, *data_zones;
- struct ast_data *data_callerid, *enum_node, *data_softhangup;
+ struct ast_data *data_bridged;
+ struct ast_data *data_cdr;
+ struct ast_data *data_flags;
+ struct ast_data *data_zones;
+ struct ast_data *enum_node;
+ struct ast_data *data_softhangup;
+#if 0 /* XXX AstData: ast_callerid no longer exists. (Equivalent code not readily apparent.) */
+ struct ast_data *data_callerid;
char value_str[100];
+#endif
if (!tree) {
return -1;
ast_data_add_uint(tree, "timetohangup", chan->whentohangup.tv_sec);
+#if 0 /* XXX AstData: ast_callerid no longer exists. (Equivalent code not readily apparent.) */
/* callerid */
data_callerid = ast_data_add_node(tree, "callerid");
if (!data_callerid) {
party_number_ton2str(chan->cid.cid_ton),
party_number_plan2str(chan->cid.cid_ton));
ast_data_add_str(enum_node, "text", value_str);
+#endif
/* tone zone */
if (chan->zone) {
return ast_channel_unref(tmp);
}
+ ast_party_dialed_init(&tmp->dialed);
+ ast_party_caller_init(&tmp->caller);
+ ast_party_connected_line_init(&tmp->connected);
+ ast_party_redirecting_init(&tmp->redirecting);
+
if (cid_name) {
- if (!(tmp->cid.cid_name = ast_strdup(cid_name))) {
+ tmp->caller.id.name.valid = 1;
+ tmp->caller.id.name.str = ast_strdup(cid_name);
+ if (!tmp->caller.id.name.str) {
return ast_channel_unref(tmp);
}
}
if (cid_num) {
- if (!(tmp->cid.cid_num = ast_strdup(cid_num))) {
+ tmp->caller.id.number.valid = 1;
+ tmp->caller.id.number.str = ast_strdup(cid_num);
+ if (!tmp->caller.id.number.str) {
return ast_channel_unref(tmp);
}
}
return ast_safe_sleep_conditional(chan, ms, NULL, NULL);
}
-static void free_cid(struct ast_callerid *cid)
-{
- if (cid->cid_dnid)
- ast_free(cid->cid_dnid);
- if (cid->cid_num)
- ast_free(cid->cid_num);
- if (cid->cid_name)
- ast_free(cid->cid_name);
- if (cid->cid_ani)
- ast_free(cid->cid_ani);
- if (cid->cid_tag)
- ast_free(cid->cid_tag);
- cid->cid_dnid = cid->cid_num = cid->cid_name = cid->cid_ani = NULL;
- ast_party_subaddress_free(&cid->subaddress);
- ast_party_subaddress_free(&cid->dialed_subaddress);
-}
-
struct ast_channel *ast_channel_release(struct ast_channel *chan)
{
/* Safe, even if already unlinked. */
return ast_channel_unref(chan);
}
+void ast_party_name_init(struct ast_party_name *init)
+{
+ init->str = NULL;
+ init->char_set = AST_PARTY_CHAR_SET_ISO8859_1;
+ init->presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
+ init->valid = 0;
+}
+
+void ast_party_name_copy(struct ast_party_name *dest, const struct ast_party_name *src)
+{
+ if (dest == src) {
+ /* Don't copy to self */
+ return;
+ }
+
+ ast_free(dest->str);
+ dest->str = ast_strdup(src->str);
+ dest->char_set = src->char_set;
+ dest->presentation = src->presentation;
+ dest->valid = src->valid;
+}
+
+void ast_party_name_set_init(struct ast_party_name *init, const struct ast_party_name *guide)
+{
+ init->str = NULL;
+ init->char_set = guide->char_set;
+ init->presentation = guide->presentation;
+ init->valid = guide->valid;
+}
+
+void ast_party_name_set(struct ast_party_name *dest, const struct ast_party_name *src)
+{
+ if (dest == src) {
+ /* Don't set to self */
+ return;
+ }
+
+ if (src->str && src->str != dest->str) {
+ ast_free(dest->str);
+ dest->str = ast_strdup(src->str);
+ }
+
+ dest->char_set = src->char_set;
+ dest->presentation = src->presentation;
+ dest->valid = src->valid;
+}
+
+void ast_party_name_free(struct ast_party_name *doomed)
+{
+ ast_free(doomed->str);
+ doomed->str = NULL;
+}
+
+void ast_party_number_init(struct ast_party_number *init)
+{
+ init->str = NULL;
+ init->plan = 0;/* Unknown */
+ init->presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
+ init->valid = 0;
+}
+
+void ast_party_number_copy(struct ast_party_number *dest, const struct ast_party_number *src)
+{
+ if (dest == src) {
+ /* Don't copy to self */
+ return;
+ }
+
+ ast_free(dest->str);
+ dest->str = ast_strdup(src->str);
+ dest->plan = src->plan;
+ dest->presentation = src->presentation;
+ dest->valid = src->valid;
+}
+
+void ast_party_number_set_init(struct ast_party_number *init, const struct ast_party_number *guide)
+{
+ init->str = NULL;
+ init->plan = guide->plan;
+ init->presentation = guide->presentation;
+ init->valid = guide->valid;
+}
+
+void ast_party_number_set(struct ast_party_number *dest, const struct ast_party_number *src)
+{
+ if (dest == src) {
+ /* Don't set to self */
+ return;
+ }
+
+ if (src->str && src->str != dest->str) {
+ ast_free(dest->str);
+ dest->str = ast_strdup(src->str);
+ }
+
+ dest->plan = src->plan;
+ dest->presentation = src->presentation;
+ dest->valid = src->valid;
+}
+
+void ast_party_number_free(struct ast_party_number *doomed)
+{
+ ast_free(doomed->str);
+ doomed->str = NULL;
+}
+
void ast_party_subaddress_init(struct ast_party_subaddress *init)
{
init->str = NULL;
return;
}
- if (dest->str) {
- ast_free(dest->str);
- }
+ ast_free(dest->str);
dest->str = ast_strdup(src->str);
dest->type = src->type;
dest->odd_even_indicator = src->odd_even_indicator;
}
if (src->str && src->str != dest->str) {
- if (dest->str) {
- ast_free(dest->str);
- }
+ ast_free(dest->str);
dest->str = ast_strdup(src->str);
}
void ast_party_subaddress_free(struct ast_party_subaddress *doomed)
{
- if (doomed->str) {
- ast_free(doomed->str);
- doomed->str = NULL;
- }
+ ast_free(doomed->str);
+ doomed->str = NULL;
}
void ast_party_id_init(struct ast_party_id *init)
{
- init->number = NULL;
- init->name = NULL;
- init->tag = NULL;
- init->number_type = 0; /* Unknown */
- init->number_presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
+ ast_party_name_init(&init->name);
+ ast_party_number_init(&init->number);
ast_party_subaddress_init(&init->subaddress);
+ init->tag = NULL;
}
-/*!
- * \internal
- * \brief Copy the source party id information to the destination party id.
- *
- * \param dest Destination party id
- * \param src Source party id
- *
- * \return Nothing
- */
-static void ast_party_id_copy(struct ast_party_id *dest, const struct ast_party_id *src)
+void ast_party_id_copy(struct ast_party_id *dest, const struct ast_party_id *src)
{
if (dest == src) {
/* Don't copy to self */
return;
}
- if (dest->number) {
- ast_free(dest->number);
- }
- dest->number = ast_strdup(src->number);
-
- if (dest->name) {
- ast_free(dest->name);
- }
- dest->name = ast_strdup(src->name);
+ ast_party_name_copy(&dest->name, &src->name);
+ ast_party_number_copy(&dest->number, &src->number);
+ ast_party_subaddress_copy(&dest->subaddress, &src->subaddress);
- if (dest->tag) {
- ast_free(dest->tag);
- }
+ ast_free(dest->tag);
dest->tag = ast_strdup(src->tag);
-
- dest->number_type = src->number_type;
- dest->number_presentation = src->number_presentation;
- ast_party_subaddress_copy(&dest->subaddress, &src->subaddress);
}
-/*!
- * \internal
- * \brief Initialize the given party id structure using the given guide
- * for a set update operation.
- *
- * \details
- * The initialization is needed to allow a set operation to know if a
- * value needs to be updated. Simple integers need the guide's original
- * value in case the set operation is not trying to set a new value.
- * String values are simply set to NULL pointers if they are not going
- * to be updated.
- *
- * \param init Party id structure to initialize.
- * \param guide Source party id to use as a guide in initializing.
- *
- * \return Nothing
- */
-static void ast_party_id_set_init(struct ast_party_id *init, const struct ast_party_id *guide)
+void ast_party_id_set_init(struct ast_party_id *init, const struct ast_party_id *guide)
{
- init->number = NULL;
- init->name = NULL;
- init->tag = NULL;
- init->number_type = guide->number_type;
- init->number_presentation = guide->number_presentation;
+ ast_party_name_set_init(&init->name, &guide->name);
+ ast_party_number_set_init(&init->number, &guide->number);
ast_party_subaddress_set_init(&init->subaddress, &guide->subaddress);
+ init->tag = NULL;
}
-/*!
- * \internal
- * \brief Set the source party id information into the destination party id.
- *
- * \param dest Destination party id
- * \param src Source party id
- *
- * \return Nothing
- */
-static void ast_party_id_set(struct ast_party_id *dest, const struct ast_party_id *src)
+void ast_party_id_set(struct ast_party_id *dest, const struct ast_party_id *src, const struct ast_set_party_id *update)
{
if (dest == src) {
/* Don't set to self */
return;
}
- if (src->name && src->name != dest->name) {
- if (dest->name) {
- ast_free(dest->name);
- }
- dest->name = ast_strdup(src->name);
+ if (!update || update->name) {
+ ast_party_name_set(&dest->name, &src->name);
}
-
- if (src->number && src->number != dest->number) {
- if (dest->number) {
- ast_free(dest->number);
- }
- dest->number = ast_strdup(src->number);
+ if (!update || update->number) {
+ ast_party_number_set(&dest->number, &src->number);
+ }
+ if (!update || update->subaddress) {
+ ast_party_subaddress_set(&dest->subaddress, &src->subaddress);
}
if (src->tag && src->tag != dest->tag) {
- if (dest->tag) {
- ast_free(dest->tag);
- }
+ ast_free(dest->tag);
dest->tag = ast_strdup(src->tag);
}
-
- dest->number_type = src->number_type;
- dest->number_presentation = src->number_presentation;
- ast_party_subaddress_set(&dest->subaddress, &src->subaddress);
}
void ast_party_id_free(struct ast_party_id *doomed)
{
- if (doomed->number) {
- ast_free(doomed->number);
- doomed->number = NULL;
+ ast_party_name_free(&doomed->name);
+ ast_party_number_free(&doomed->number);
+ ast_party_subaddress_free(&doomed->subaddress);
+
+ ast_free(doomed->tag);
+ doomed->tag = NULL;
+}
+
+int ast_party_id_presentation(const struct ast_party_id *id)
+{
+ int number_priority;
+ int number_value;
+ int number_screening;
+ int name_priority;
+ int name_value;
+
+ /* Determine name presentation priority. */
+ if (!id->name.valid) {
+ name_value = AST_PRES_UNAVAILABLE;
+ name_priority = 3;
+ } else {
+ name_value = id->name.presentation & AST_PRES_RESTRICTION;
+ switch (name_value) {
+ case AST_PRES_RESTRICTED:
+ name_priority = 0;
+ break;
+ case AST_PRES_ALLOWED:
+ name_priority = 1;
+ break;
+ case AST_PRES_UNAVAILABLE:
+ name_priority = 2;
+ break;
+ default:
+ name_value = AST_PRES_UNAVAILABLE;
+ name_priority = 3;
+ break;
+ }
}
- if (doomed->name) {
- ast_free(doomed->name);
- doomed->name = NULL;
+ /* Determine number presentation priority. */
+ if (!id->number.valid) {
+ number_screening = AST_PRES_USER_NUMBER_UNSCREENED;
+ number_value = AST_PRES_UNAVAILABLE;
+ number_priority = 3;
+ } else {
+ number_screening = id->number.presentation & AST_PRES_NUMBER_TYPE;
+ number_value = id->number.presentation & AST_PRES_RESTRICTION;
+ switch (number_value) {
+ case AST_PRES_RESTRICTED:
+ number_priority = 0;
+ break;
+ case AST_PRES_ALLOWED:
+ number_priority = 1;
+ break;
+ case AST_PRES_UNAVAILABLE:
+ number_priority = 2;
+ break;
+ default:
+ number_screening = AST_PRES_USER_NUMBER_UNSCREENED;
+ number_value = AST_PRES_UNAVAILABLE;
+ number_priority = 3;
+ break;
+ }
}
- if (doomed->tag) {
- ast_free(doomed->tag);
- doomed->tag = NULL;
+ /* Select the wining presentation value. */
+ if (name_priority < number_priority) {
+ number_value = name_value;
}
- ast_party_subaddress_free(&doomed->subaddress);
+
+ return number_value | number_screening;
}
-void ast_party_caller_init(struct ast_party_caller *init)
+void ast_party_dialed_init(struct ast_party_dialed *init)
{
- ast_party_id_init(&init->id);
- init->ani = NULL;
- init->ani2 = 0;
+ init->number.str = NULL;
+ init->number.plan = 0;/* Unknown */
+ ast_party_subaddress_init(&init->subaddress);
+ init->transit_network_select = 0;
}
-void ast_party_caller_copy(struct ast_callerid *dest, const struct ast_callerid *src)
+void ast_party_dialed_copy(struct ast_party_dialed *dest, const struct ast_party_dialed *src)
{
if (dest == src) {
/* Don't copy to self */
return;
}
-#if 1
- /* Copy caller-id specific information ONLY from struct ast_callerid */
- if (dest->cid_num)
- {
- ast_free(dest->cid_num);
- }
- dest->cid_num = ast_strdup(src->cid_num);
+ ast_free(dest->number.str);
+ dest->number.str = ast_strdup(src->number.str);
+ dest->number.plan = src->number.plan;
+ ast_party_subaddress_copy(&dest->subaddress, &src->subaddress);
+ dest->transit_network_select = src->transit_network_select;
+}
- if (dest->cid_name)
- {
- ast_free(dest->cid_name);
- }
- dest->cid_name = ast_strdup(src->cid_name);
+void ast_party_dialed_set_init(struct ast_party_dialed *init, const struct ast_party_dialed *guide)
+{
+ init->number.str = NULL;
+ init->number.plan = guide->number.plan;
+ ast_party_subaddress_set_init(&init->subaddress, &guide->subaddress);
+ init->transit_network_select = guide->transit_network_select;
+}
- if (dest->cid_tag) {
- ast_free(dest->cid_tag);
+void ast_party_dialed_set(struct ast_party_dialed *dest, const struct ast_party_dialed *src)
+{
+ if (src->number.str && src->number.str != dest->number.str) {
+ ast_free(dest->number.str);
+ dest->number.str = ast_strdup(src->number.str);
}
- dest->cid_tag = ast_strdup(src->cid_tag);
+ dest->number.plan = src->number.plan;
+
+ ast_party_subaddress_set(&dest->subaddress, &src->subaddress);
- dest->cid_ton = src->cid_ton;
- dest->cid_pres = src->cid_pres;
+ dest->transit_network_select = src->transit_network_select;
+}
+void ast_party_dialed_free(struct ast_party_dialed *doomed)
+{
+ ast_free(doomed->number.str);
+ doomed->number.str = NULL;
+ ast_party_subaddress_free(&doomed->subaddress);
+}
- if (dest->cid_ani)
- {
- ast_free(dest->cid_ani);
+void ast_party_caller_init(struct ast_party_caller *init)
+{
+ ast_party_id_init(&init->id);
+ init->ani = NULL;
+ init->ani2 = 0;
+}
+
+void ast_party_caller_copy(struct ast_party_caller *dest, const struct ast_party_caller *src)
+{
+ if (dest == src) {
+ /* Don't copy to self */
+ return;
}
- dest->cid_ani = ast_strdup(src->cid_ani);
- dest->cid_ani2 = src->cid_ani2;
+ ast_party_id_copy(&dest->id, &src->id);
- ast_party_subaddress_copy(&dest->subaddress, &src->subaddress);
+ ast_free(dest->ani);
+ dest->ani = ast_strdup(src->ani);
-#else
+ dest->ani2 = src->ani2;
+}
- /* The src and dest parameter types will become struct ast_party_caller ptrs. */
- /* This is future code */
+void ast_party_caller_set_init(struct ast_party_caller *init, const struct ast_party_caller *guide)
+{
+ ast_party_id_set_init(&init->id, &guide->id);
+ init->ani = NULL;
+ init->ani2 = guide->ani2;
+}
- ast_party_id_copy(&dest->id, &src->id);
+void ast_party_caller_set(struct ast_party_caller *dest, const struct ast_party_caller *src, const struct ast_set_party_caller *update)
+{
+ ast_party_id_set(&dest->id, &src->id, update ? &update->id : NULL);
- if (dest->ani) {
+ if (src->ani && src->ani != dest->ani) {
ast_free(dest->ani);
+ dest->ani = ast_strdup(src->ani);
}
- dest->ani = ast_strdup(src->ani);
dest->ani2 = src->ani2;
-#endif
+}
+
+void ast_party_caller_free(struct ast_party_caller *doomed)
+{
+ ast_party_id_free(&doomed->id);
+
+ ast_free(doomed->ani);
+ doomed->ani = NULL;
}
void ast_party_connected_line_init(struct ast_party_connected_line *init)
ast_party_id_copy(&dest->id, &src->id);
- if (dest->ani) {
- ast_free(dest->ani);
- }
+ ast_free(dest->ani);
dest->ani = ast_strdup(src->ani);
dest->ani2 = src->ani2;
init->source = guide->source;
}
-void ast_party_connected_line_set(struct ast_party_connected_line *dest, const struct ast_party_connected_line *src)
+void ast_party_connected_line_set(struct ast_party_connected_line *dest, const struct ast_party_connected_line *src, const struct ast_set_party_connected_line *update)
{
- ast_party_id_set(&dest->id, &src->id);
+ ast_party_id_set(&dest->id, &src->id, update ? &update->id : NULL);
if (src->ani && src->ani != dest->ani) {
- if (dest->ani) {
- ast_free(dest->ani);
- }
+ ast_free(dest->ani);
dest->ani = ast_strdup(src->ani);
}
dest->source = src->source;
}
-void ast_party_connected_line_collect_caller(struct ast_party_connected_line *connected, struct ast_callerid *cid)
+void ast_party_connected_line_collect_caller(struct ast_party_connected_line *connected, struct ast_party_caller *caller)
{
- connected->id.number = cid->cid_num;
- connected->id.name = cid->cid_name;
- connected->id.number_type = cid->cid_ton;
- connected->id.number_presentation = cid->cid_pres;
- connected->id.tag = cid->cid_tag;
- connected->id.subaddress = cid->subaddress;
-
- connected->ani = cid->cid_ani;
- connected->ani2 = cid->cid_ani2;
+ connected->id = caller->id;
+ connected->ani = caller->ani;
+ connected->ani2 = caller->ani2;
connected->source = AST_CONNECTED_LINE_UPDATE_SOURCE_UNKNOWN;
}
{
ast_party_id_free(&doomed->id);
- if (doomed->ani) {
- ast_free(doomed->ani);
- doomed->ani = NULL;
- }
+ ast_free(doomed->ani);
+ doomed->ani = NULL;
+}
+
+void ast_party_redirecting_init(struct ast_party_redirecting *init)
+{
+ ast_party_id_init(&init->from);
+ ast_party_id_init(&init->to);
+ init->count = 0;
+ init->reason = AST_REDIRECTING_REASON_UNKNOWN;
}
void ast_party_redirecting_copy(struct ast_party_redirecting *dest, const struct ast_party_redirecting *src)
init->reason = guide->reason;
}
+void ast_party_redirecting_set(struct ast_party_redirecting *dest, const struct ast_party_redirecting *src, const struct ast_set_party_redirecting *update)
+{
+ ast_party_id_set(&dest->from, &src->from, update ? &update->from : NULL);
+ ast_party_id_set(&dest->to, &src->to, update ? &update->to : NULL);
+ dest->reason = src->reason;
+ dest->count = src->count;
+}
+
void ast_party_redirecting_free(struct ast_party_redirecting *doomed)
{
ast_party_id_free(&doomed->from);
if (chan->pbx)
ast_log(LOG_WARNING, "PBX may not have been terminated properly on '%s'\n", chan->name);
- free_cid(&chan->cid);
+ ast_party_dialed_free(&chan->dialed);
+ ast_party_caller_free(&chan->caller);
ast_party_connected_line_free(&chan->connected);
ast_party_redirecting_free(&chan->redirecting);
headp = &chan->varshead;
- free_cid(&chan->cid);
+ ast_party_dialed_free(&chan->dialed);
+ ast_party_caller_free(&chan->caller);
+ ast_party_connected_line_free(&chan->connected);
+ ast_party_redirecting_free(&chan->redirecting);
/* loop over the variables list, freeing all data and deleting list items */
/* no need to lock the list, as the channel is already locked */
ast_channel_unlock(chan);
ast_cc_offer(chan);
ast_manager_event(chan, EVENT_FLAG_CALL, "Hangup",
- "Channel: %s\r\n"
- "Uniqueid: %s\r\n"
- "CallerIDNum: %s\r\n"
- "CallerIDName: %s\r\n"
- "Cause: %d\r\n"
- "Cause-txt: %s\r\n",
- chan->name,
- chan->uniqueid,
- S_OR(chan->cid.cid_num, "<unknown>"),
- S_OR(chan->cid.cid_name, "<unknown>"),
- chan->hangupcause,
- ast_cause2str(chan->hangupcause)
- );
+ "Channel: %s\r\n"
+ "Uniqueid: %s\r\n"
+ "CallerIDNum: %s\r\n"
+ "CallerIDName: %s\r\n"
+ "Cause: %d\r\n"
+ "Cause-txt: %s\r\n",
+ chan->name,
+ chan->uniqueid,
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, "<unknown>"),
+ S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, "<unknown>"),
+ chan->hangupcause,
+ ast_cause2str(chan->hangupcause)
+ );
if (chan->cdr && !ast_test_flag(chan->cdr, AST_CDR_FLAG_BRIDGED) &&
!ast_test_flag(chan->cdr, AST_CDR_FLAG_POST_DISABLED) &&
ast_party_connected_line_set_init(&connected, &chan->connected);
res = ast_connected_line_parse_data(data, datalen, &connected);
if (!res) {
- ast_channel_set_connected_line(chan, &connected);
+ ast_channel_set_connected_line(chan, &connected, NULL);
}
ast_party_connected_line_free(&connected);
}
ast_party_redirecting_set_init(&redirecting, &chan->redirecting);
res = ast_redirecting_parse_data(data, datalen, &redirecting);
if (!res) {
- ast_channel_set_redirecting(chan, &redirecting);
+ ast_channel_set_redirecting(chan, &redirecting, NULL);
}
ast_party_redirecting_free(&redirecting);
}
return NULL;
}
- ast_channel_set_redirecting(new, apr);
+ ast_channel_set_redirecting(new, apr, NULL);
/* Copy/inherit important information into new channel */
if (oh) {
ast_set_callerid(new, oh->cid_num, oh->cid_name, oh->cid_num);
}
if (oh->parent_channel) {
- ast_channel_update_redirecting(oh->parent_channel, apr);
+ ast_channel_update_redirecting(oh->parent_channel, apr, NULL);
ast_channel_inherit_variables(oh->parent_channel, new);
ast_channel_datastore_inherit(oh->parent_channel, new);
}
ast_cdr_setaccount(new, oh->account);
}
} else if (caller) { /* no outgoing helper so use caller if avaliable */
- ast_channel_update_redirecting(caller, apr);
+ ast_channel_update_redirecting(caller, apr, NULL);
ast_channel_inherit_variables(caller, new);
ast_channel_datastore_inherit(caller, new);
}
}
ast_copy_flags(new->cdr, orig->cdr, AST_CDR_FLAG_ORIGINATED);
ast_string_field_set(new, accountcode, orig->accountcode);
- ast_party_caller_copy(&new->cid, &orig->cid);
+ ast_party_caller_copy(&new->caller, &orig->caller);
ast_party_connected_line_copy(&new->connected, &orig->connected);
ast_channel_unlock(new);
ast_channel_unlock(orig);
ast_set_callerid(chan, cid_num, cid_name, cid_num);
ast_set_flag(chan->cdr, AST_CDR_FLAG_ORIGINATED);
ast_party_connected_line_set_init(&connected, &chan->connected);
- connected.id.number = (char *) cid_num;
- connected.id.name = (char *) cid_name;
- connected.id.number_presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
- ast_channel_set_connected_line(chan, &connected);
+ if (cid_num) {
+ connected.id.number.valid = 1;
+ connected.id.number.str = (char *) cid_num;
+ connected.id.number.presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
+ }
+ if (cid_name) {
+ connected.id.name.valid = 1;
+ connected.id.name.str = (char *) cid_name;
+ connected.id.name.presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
+ }
+ ast_channel_set_connected_line(chan, &connected, NULL);
if (ast_call(chan, data, 0)) { /* ast_call failed... */
ast_log(LOG_NOTICE, "Unable to call channel %s/%s\n", type, (char *)data);
*/
static void report_new_callerid(struct ast_channel *chan)
{
+ int pres;
+
+ pres = ast_party_id_presentation(&chan->caller.id);
ast_manager_event(chan, EVENT_FLAG_CALL, "NewCallerid",
- "Channel: %s\r\n"
- "CallerIDNum: %s\r\n"
- "CallerIDName: %s\r\n"
- "Uniqueid: %s\r\n"
- "CID-CallingPres: %d (%s)\r\n",
- chan->name,
- S_OR(chan->cid.cid_num, ""),
- S_OR(chan->cid.cid_name, ""),
- chan->uniqueid,
- chan->cid.cid_pres,
- ast_describe_caller_presentation(chan->cid.cid_pres)
- );
+ "Channel: %s\r\n"
+ "CallerIDNum: %s\r\n"
+ "CallerIDName: %s\r\n"
+ "Uniqueid: %s\r\n"
+ "CID-CallingPres: %d (%s)\r\n",
+ chan->name,
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, ""),
+ S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, ""),
+ chan->uniqueid,
+ pres,
+ ast_describe_caller_presentation(pres)
+ );
}
/*!
const struct ast_channel_tech *t;
void *t_pvt;
union {
- struct ast_callerid cid;
+ struct ast_party_dialed dialed;
+ struct ast_party_caller caller;
struct ast_party_connected_line connected;
struct ast_party_redirecting redirecting;
} exchange;
* Just swap the whole structures, nevermind the allocations,
* they'll work themselves out.
*/
- exchange.cid = original->cid;
- original->cid = clonechan->cid;
- clonechan->cid = exchange.cid;
- report_new_callerid(original);
+ exchange.dialed = original->dialed;
+ original->dialed = clonechan->dialed;
+ clonechan->dialed = exchange.dialed;
+
+ exchange.caller = original->caller;
+ original->caller = clonechan->caller;
+ clonechan->caller = exchange.caller;
exchange.connected = original->connected;
original->connected = clonechan->connected;
clonechan->connected = exchange.connected;
+
exchange.redirecting = original->redirecting;
original->redirecting = clonechan->redirecting;
clonechan->redirecting = exchange.redirecting;
+ report_new_callerid(original);
+
/* Restore original timing file descriptor */
ast_channel_set_fd(original, AST_TIMING_FD, original->timingfd);
ast_channel_lock(chan);
if (cid_num) {
- if (chan->cid.cid_num)
- ast_free(chan->cid.cid_num);
- chan->cid.cid_num = ast_strdup(cid_num);
+ chan->caller.id.number.valid = 1;
+ ast_free(chan->caller.id.number.str);
+ chan->caller.id.number.str = ast_strdup(cid_num);
}
if (cid_name) {
- if (chan->cid.cid_name)
- ast_free(chan->cid.cid_name);
- chan->cid.cid_name = ast_strdup(cid_name);
+ chan->caller.id.name.valid = 1;
+ ast_free(chan->caller.id.name.str);
+ chan->caller.id.name.str = ast_strdup(cid_name);
}
if (cid_ani) {
- if (chan->cid.cid_ani)
- ast_free(chan->cid.cid_ani);
- chan->cid.cid_ani = ast_strdup(cid_ani);
+ ast_free(chan->caller.ani);
+ chan->caller.ani = ast_strdup(cid_ani);
}
report_new_callerid(chan);
ast_channel_unlock(chan);
}
+void ast_channel_set_caller(struct ast_channel *chan, const struct ast_party_caller *caller, const struct ast_set_party_caller *update)
+{
+ if (&chan->caller == caller) {
+ /* Don't set to self */
+ return;
+ }
+
+ ast_channel_lock(chan);
+ ast_party_caller_set(&chan->caller, caller, update);
+ ast_channel_unlock(chan);
+}
+
+void ast_channel_set_caller_event(struct ast_channel *chan, const struct ast_party_caller *caller, const struct ast_set_party_caller *update)
+{
+ struct ast_party_caller pre_set;
+
+ if (&chan->caller == caller) {
+ /* Don't set to self */
+ return;
+ }
+
+ ast_channel_lock(chan);
+ pre_set = chan->caller;
+ ast_party_caller_set(&chan->caller, caller, update);
+ if (S_COR(pre_set.id.number.valid, pre_set.id.number.str, NULL)
+ != S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL)
+ || S_COR(pre_set.id.name.valid, pre_set.id.name.str, NULL)
+ != S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL)) {
+ /* The caller id name or number changed. */
+ report_new_callerid(chan);
+ }
+ ast_channel_unlock(chan);
+}
+
int ast_setstate(struct ast_channel *chan, enum ast_channel_state state)
{
int oldstate = chan->_state;
/* setstate used to conditionally report Newchannel; this is no more */
ast_manager_event(chan, EVENT_FLAG_CALL, "Newstate",
- "Channel: %s\r\n"
- "ChannelState: %d\r\n"
- "ChannelStateDesc: %s\r\n"
- "CallerIDNum: %s\r\n"
- "CallerIDName: %s\r\n"
- "Uniqueid: %s\r\n",
- chan->name, chan->_state, ast_state2str(chan->_state),
- S_OR(chan->cid.cid_num, ""),
- S_OR(chan->cid.cid_name, ""),
- chan->uniqueid);
+ "Channel: %s\r\n"
+ "ChannelState: %d\r\n"
+ "ChannelStateDesc: %s\r\n"
+ "CallerIDNum: %s\r\n"
+ "CallerIDName: %s\r\n"
+ "Uniqueid: %s\r\n",
+ chan->name, chan->_state, ast_state2str(chan->_state),
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, ""),
+ S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, ""),
+ chan->uniqueid);
return 0;
}
{
struct ast_channel *chans[2] = { c0, c1 };
ast_manager_event_multichan(EVENT_FLAG_CALL, "Bridge", 2, chans,
- "Bridgestate: %s\r\n"
- "Bridgetype: %s\r\n"
- "Channel1: %s\r\n"
- "Channel2: %s\r\n"
- "Uniqueid1: %s\r\n"
- "Uniqueid2: %s\r\n"
- "CallerID1: %s\r\n"
- "CallerID2: %s\r\n",
- onoff ? "Link" : "Unlink",
- type == 1 ? "core" : "native",
- c0->name, c1->name, c0->uniqueid, c1->uniqueid,
- S_OR(c0->cid.cid_num, ""),
- S_OR(c1->cid.cid_num, ""));
+ "Bridgestate: %s\r\n"
+ "Bridgetype: %s\r\n"
+ "Channel1: %s\r\n"
+ "Channel2: %s\r\n"
+ "Uniqueid1: %s\r\n"
+ "Uniqueid2: %s\r\n"
+ "CallerID1: %s\r\n"
+ "CallerID2: %s\r\n",
+ onoff ? "Link" : "Unlink",
+ type == 1 ? "core" : "native",
+ c0->name, c1->name,
+ c0->uniqueid, c1->uniqueid,
+ S_COR(c0->caller.id.number.valid, c0->caller.id.number.str, ""),
+ S_COR(c1->caller.id.number.valid, c1->caller.id.number.str, ""));
}
static void update_bridge_vars(struct ast_channel *c0, struct ast_channel *c1)
ast_set_flag(c1, AST_FLAG_NBRIDGE);
if ((res = c0->tech->bridge(c0, c1, config->flags, fo, rc, timeoutms)) == AST_BRIDGE_COMPLETE) {
ast_manager_event_multichan(EVENT_FLAG_CALL, "Unlink", 2, chans,
- "Channel1: %s\r\n"
- "Channel2: %s\r\n"
- "Uniqueid1: %s\r\n"
- "Uniqueid2: %s\r\n"
- "CallerID1: %s\r\n"
- "CallerID2: %s\r\n",
- c0->name, c1->name, c0->uniqueid, c1->uniqueid, S_OR(c0->cid.cid_num, "<unknown>"), S_OR(c1->cid.cid_num, "<unknown>"));
+ "Channel1: %s\r\n"
+ "Channel2: %s\r\n"
+ "Uniqueid1: %s\r\n"
+ "Uniqueid2: %s\r\n"
+ "CallerID1: %s\r\n"
+ "CallerID2: %s\r\n",
+ c0->name, c1->name,
+ c0->uniqueid, c1->uniqueid,
+ S_COR(c0->caller.id.number.valid, c0->caller.id.number.str, "<unknown>"),
+ S_COR(c1->caller.id.number.valid, c1->caller.id.number.str, "<unknown>"));
ast_debug(1, "Returning from native bridge, channels: %s, %s\n", c0->name, c1->name);
c1->_bridge = NULL;
ast_manager_event_multichan(EVENT_FLAG_CALL, "Unlink", 2, chans,
- "Channel1: %s\r\n"
- "Channel2: %s\r\n"
- "Uniqueid1: %s\r\n"
- "Uniqueid2: %s\r\n"
- "CallerID1: %s\r\n"
- "CallerID2: %s\r\n",
- c0->name, c1->name, c0->uniqueid, c1->uniqueid, S_OR(c0->cid.cid_num, "<unknown>"), S_OR(c1->cid.cid_num, "<unknown>"));
+ "Channel1: %s\r\n"
+ "Channel2: %s\r\n"
+ "Uniqueid1: %s\r\n"
+ "Uniqueid2: %s\r\n"
+ "CallerID1: %s\r\n"
+ "CallerID2: %s\r\n",
+ c0->name, c1->name,
+ c0->uniqueid, c1->uniqueid,
+ S_COR(c0->caller.id.number.valid, c0->caller.id.number.str, "<unknown>"),
+ S_COR(c1->caller.id.number.valid, c1->caller.id.number.str, "<unknown>"));
ast_debug(1, "Bridge stops bridging channels %s and %s\n", c0->name, c1->name);
return res;
return ast_say_digit_str_full(chan, buf, ints, lang, audiofd, ctrlfd);
}
-void ast_connected_line_copy_from_caller(struct ast_party_connected_line *dest, const struct ast_callerid *src)
+void ast_connected_line_copy_from_caller(struct ast_party_connected_line *dest, const struct ast_party_caller *src)
{
-#if 1
- /* Must manually fill in struct ast_party_id until struct ast_callerid goes away */
- if (dest->id.number) {
- ast_free(dest->id.number);
- }
- dest->id.number = ast_strdup(src->cid_num);
+ ast_party_id_copy(&dest->id, &src->id);
- if (dest->id.name) {
- ast_free(dest->id.name);
- }
- dest->id.name = ast_strdup(src->cid_name);
-
- if (dest->id.tag) {
- ast_free(dest->id.tag);
- }
- dest->id.tag = ast_strdup(src->cid_tag);
-
- dest->id.number_type = src->cid_ton;
- dest->id.number_presentation = src->cid_pres;
-
-
- if (dest->ani) {
- ast_free(dest->ani);
- }
- dest->ani = ast_strdup(src->cid_ani);
-
- dest->ani2 = src->cid_ani2;
- ast_party_subaddress_copy(&dest->id.subaddress, &src->subaddress);
-
-#else
-
- /* The src parameter type will become a struct ast_party_caller ptr. */
- /* This is future code */
-
- ast_party_id_copy(&dest->id, &src->id);
-
- if (dest->ani) {
- ast_free(dest->ani);
- }
- dest->ani = ast_strdup(src->ani);
+ ast_free(dest->ani);
+ dest->ani = ast_strdup(src->ani);
dest->ani2 = src->ani2;
-#endif
}
-void ast_connected_line_copy_to_caller(struct ast_callerid *dest, const struct ast_party_connected_line *src)
+void ast_connected_line_copy_to_caller(struct ast_party_caller *dest, const struct ast_party_connected_line *src)
{
-#if 1
- /* Must manually extract from struct ast_party_id until struct ast_callerid goes away */
- if (dest->cid_num) {
- ast_free(dest->cid_num);
- }
- dest->cid_num = ast_strdup(src->id.number);
-
- if (dest->cid_name) {
- ast_free(dest->cid_name);
- }
- dest->cid_name = ast_strdup(src->id.name);
-
- if (dest->cid_tag) {
- ast_free(dest->cid_tag);
- }
- dest->cid_tag = ast_strdup(src->id.tag);
-
- dest->cid_ton = src->id.number_type;
- dest->cid_pres = src->id.number_presentation;
-
-
- if (dest->cid_ani) {
- ast_free(dest->cid_ani);
- }
- dest->cid_ani = ast_strdup(src->ani);
-
- dest->cid_ani2 = src->ani2;
- ast_party_subaddress_copy(&dest->subaddress, &src->id.subaddress);
-
-#else
-
- /* The dest parameter type will become a struct ast_party_caller ptr. */
- /* This is future code */
-
ast_party_id_copy(&dest->id, &src->id);
- if (dest->ani) {
- ast_free(dest->ani);
- }
+ ast_free(dest->ani);
dest->ani = ast_strdup(src->ani);
dest->ani2 = src->ani2;
-#endif
}
-void ast_channel_set_connected_line(struct ast_channel *chan, const struct ast_party_connected_line *connected)
+void ast_channel_set_connected_line(struct ast_channel *chan, const struct ast_party_connected_line *connected, const struct ast_set_party_connected_line *update)
{
if (&chan->connected == connected) {
/* Don't set to self */
}
ast_channel_lock(chan);
- ast_party_connected_line_set(&chan->connected, connected);
+ ast_party_connected_line_set(&chan->connected, connected, update);
ast_channel_unlock(chan);
}
-/*!
- * \brief Element identifiers for connected line indication frame data
- * \note Only add to the end of this enum.
- */
-enum {
- AST_CONNECTED_LINE_NUMBER,
- AST_CONNECTED_LINE_NAME,
- AST_CONNECTED_LINE_NUMBER_TYPE,
- AST_CONNECTED_LINE_NUMBER_PRESENTATION,
- AST_CONNECTED_LINE_SOURCE,
- AST_CONNECTED_LINE_SUBADDRESS,
- AST_CONNECTED_LINE_SUBADDRESS_TYPE,
- AST_CONNECTED_LINE_SUBADDRESS_ODD_EVEN,
- AST_CONNECTED_LINE_SUBADDRESS_VALID,
- AST_CONNECTED_LINE_TAG,
+/*! \note Should follow struct ast_party_name */
+struct ast_party_name_ies {
+ /*! \brief Subscriber name ie */
+ int str;
+ /*! \brief Character set ie. */
+ int char_set;
+ /*! \brief presentation-indicator ie */
+ int presentation;
+ /*! \brief valid/present ie */
+ int valid;
};
-int ast_connected_line_build_data(unsigned char *data, size_t datalen, const struct ast_party_connected_line *connected)
+/*!
+ * \internal
+ * \since 1.8
+ * \brief Build a party name information data frame component.
+ *
+ * \param data Buffer to fill with the frame data
+ * \param datalen Size of the buffer to fill
+ * \param name Party name information
+ * \param label Name of particular party name
+ * \param ies Data frame ie values for the party name components
+ *
+ * \retval -1 if error
+ * \retval Amount of data buffer used
+ */
+static int party_name_build_data(unsigned char *data, size_t datalen, const struct ast_party_name *name, const char *label, const struct ast_party_name_ies *ies)
{
- int32_t value;
size_t length;
size_t pos = 0;
* The size of integer values must be fixed in case the frame is
* shipped to another machine.
*/
-
- /* *************** Connected line party id *************** */
- if (connected->id.number) {
- length = strlen(connected->id.number);
+ if (name->str) {
+ length = strlen(name->str);
if (datalen < pos + (sizeof(data[0]) * 2) + length) {
- ast_log(LOG_WARNING, "No space left for connected line number\n");
+ ast_log(LOG_WARNING, "No space left for %s name\n", label);
return -1;
}
- data[pos++] = AST_CONNECTED_LINE_NUMBER;
+ data[pos++] = ies->str;
data[pos++] = length;
- memcpy(data + pos, connected->id.number, length);
+ memcpy(data + pos, name->str, length);
pos += length;
}
- if (connected->id.name) {
- length = strlen(connected->id.name);
- if (datalen < pos + (sizeof(data[0]) * 2) + length) {
- ast_log(LOG_WARNING, "No space left for connected line name\n");
- return -1;
- }
- data[pos++] = AST_CONNECTED_LINE_NAME;
- data[pos++] = length;
- memcpy(data + pos, connected->id.name, length);
- pos += length;
+ if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
+ ast_log(LOG_WARNING, "No space left for %s name char set\n", label);
+ return -1;
}
+ data[pos++] = ies->char_set;
+ data[pos++] = 1;
+ data[pos++] = name->char_set;
+
+ if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
+ ast_log(LOG_WARNING, "No space left for %s name presentation\n", label);
+ return -1;
+ }
+ data[pos++] = ies->presentation;
+ data[pos++] = 1;
+ data[pos++] = name->presentation;
+
+ if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
+ ast_log(LOG_WARNING, "No space left for %s name valid\n", label);
+ return -1;
+ }
+ data[pos++] = ies->valid;
+ data[pos++] = 1;
+ data[pos++] = name->valid;
+
+ return pos;
+}
+
+/*! \note Should follow struct ast_party_number */
+struct ast_party_number_ies {
+ /*! \brief Subscriber phone number ie */
+ int str;
+ /*! \brief Type-Of-Number and Numbering-Plan ie */
+ int plan;
+ /*! \brief presentation-indicator ie */
+ int presentation;
+ /*! \brief valid/present ie */
+ int valid;
+};
- if (connected->id.tag) {
- length = strlen(connected->id.tag);
+/*!
+ * \internal
+ * \since 1.8
+ * \brief Build a party number information data frame component.
+ *
+ * \param data Buffer to fill with the frame data
+ * \param datalen Size of the buffer to fill
+ * \param number Party number information
+ * \param label Name of particular party number
+ * \param ies Data frame ie values for the party number components
+ *
+ * \retval -1 if error
+ * \retval Amount of data buffer used
+ */
+static int party_number_build_data(unsigned char *data, size_t datalen, const struct ast_party_number *number, const char *label, const struct ast_party_number_ies *ies)
+{
+ size_t length;
+ size_t pos = 0;
+
+ /*
+ * The size of integer values must be fixed in case the frame is
+ * shipped to another machine.
+ */
+ if (number->str) {
+ length = strlen(number->str);
if (datalen < pos + (sizeof(data[0]) * 2) + length) {
- ast_log(LOG_WARNING, "No space left for connected line tag\n");
+ ast_log(LOG_WARNING, "No space left for %s number\n", label);
return -1;
}
- data[pos++] = AST_CONNECTED_LINE_TAG;
+ data[pos++] = ies->str;
data[pos++] = length;
- memcpy(data + pos, connected->id.tag, length);
+ memcpy(data + pos, number->str, length);
pos += length;
}
if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
- ast_log(LOG_WARNING, "No space left for connected line type of number\n");
+ ast_log(LOG_WARNING, "No space left for %s numbering plan\n", label);
return -1;
}
- data[pos++] = AST_CONNECTED_LINE_NUMBER_TYPE;
+ data[pos++] = ies->plan;
data[pos++] = 1;
- data[pos++] = connected->id.number_type;
+ data[pos++] = number->plan;
if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
- ast_log(LOG_WARNING, "No space left for connected line presentation\n");
+ ast_log(LOG_WARNING, "No space left for %s number presentation\n", label);
return -1;
}
- data[pos++] = AST_CONNECTED_LINE_NUMBER_PRESENTATION;
+ data[pos++] = ies->presentation;
data[pos++] = 1;
- data[pos++] = connected->id.number_presentation;
+ data[pos++] = number->presentation;
- /* Connected line source */
- if (datalen < pos + (sizeof(data[0]) * 2) + sizeof(value)) {
- ast_log(LOG_WARNING, "No space left for connected line source\n");
+ if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
+ ast_log(LOG_WARNING, "No space left for %s number valid\n", label);
return -1;
}
- data[pos++] = AST_CONNECTED_LINE_SOURCE;
- data[pos++] = sizeof(value);
- value = htonl(connected->source);
- memcpy(data + pos, &value, sizeof(value));
- pos += sizeof(value);
+ data[pos++] = ies->valid;
+ data[pos++] = 1;
+ data[pos++] = number->valid;
- /* Connected line Subaddress */
- if (connected->id.subaddress.str) {
- length = strlen(connected->id.subaddress.str);
+ return pos;
+}
+
+/*! \note Should follow struct ast_party_subaddress */
+struct ast_party_subaddress_ies {
+ /*! \brief subaddress ie. */
+ int str;
+ /*! \brief subaddress type ie */
+ int type;
+ /*! \brief odd/even indicator ie */
+ int odd_even_indicator;
+ /*! \brief valid/present ie */
+ int valid;
+};
+
+/*!
+ * \internal
+ * \since 1.8
+ * \brief Build a party subaddress information data frame component.
+ *
+ * \param data Buffer to fill with the frame data
+ * \param datalen Size of the buffer to fill
+ * \param subaddress Party subaddress information
+ * \param label Name of particular party subaddress
+ * \param ies Data frame ie values for the party subaddress components
+ *
+ * \retval -1 if error
+ * \retval Amount of data buffer used
+ */
+static int party_subaddress_build_data(unsigned char *data, size_t datalen, const struct ast_party_subaddress *subaddress, const char *label, const struct ast_party_subaddress_ies *ies)
+{
+ size_t length;
+ size_t pos = 0;
+
+ /*
+ * The size of integer values must be fixed in case the frame is
+ * shipped to another machine.
+ */
+ if (subaddress->str) {
+ length = strlen(subaddress->str);
if (datalen < pos + (sizeof(data[0]) * 2) + length) {
- ast_log(LOG_WARNING, "No space left for connected line subaddress\n");
+ ast_log(LOG_WARNING, "No space left for %s subaddress\n", label);
return -1;
}
- data[pos++] = AST_CONNECTED_LINE_SUBADDRESS;
+ data[pos++] = ies->str;
data[pos++] = length;
- memcpy(data + pos, connected->id.subaddress.str, length);
+ memcpy(data + pos, subaddress->str, length);
pos += length;
}
- /* Connected line Subaddress Type */
+
if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
- ast_log(LOG_WARNING, "No space left for connected line type of subaddress\n");
+ ast_log(LOG_WARNING, "No space left for %s type of subaddress\n", label);
return -1;
}
- data[pos++] = AST_CONNECTED_LINE_SUBADDRESS_TYPE;
+ data[pos++] = ies->type;
data[pos++] = 1;
- data[pos++] = connected->id.subaddress.type;
+ data[pos++] = subaddress->type;
- /* Connected line Subaddress Odd/Even indicator */
if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
ast_log(LOG_WARNING,
- "No space left for connected line subaddress odd-even indicator\n");
+ "No space left for %s subaddress odd-even indicator\n", label);
+ return -1;
+ }
+ data[pos++] = ies->odd_even_indicator;
+ data[pos++] = 1;
+ data[pos++] = subaddress->odd_even_indicator;
+
+ if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
+ ast_log(LOG_WARNING, "No space left for %s subaddress valid\n", label);
return -1;
}
- data[pos++] = AST_CONNECTED_LINE_SUBADDRESS_ODD_EVEN;
+ data[pos++] = ies->valid;
data[pos++] = 1;
- data[pos++] = connected->id.subaddress.odd_even_indicator;
+ data[pos++] = subaddress->valid;
+
+ return pos;
+}
+
+/*! \note Should follow struct ast_party_id */
+struct ast_party_id_ies {
+ /*! \brief Subscriber name ies */
+ struct ast_party_name_ies name;
+ /*! \brief Subscriber phone number ies */
+ struct ast_party_number_ies number;
+ /*! \brief Subscriber subaddress ies. */
+ struct ast_party_subaddress_ies subaddress;
+ /*! \brief User party id tag ie. */
+ int tag;
+ /*! \brief Combined name and number presentation ie. */
+ int combined_presentation;
+};
+
+/*!
+ * \internal
+ * \since 1.8
+ * \brief Build a party id information data frame component.
+ *
+ * \param data Buffer to fill with the frame data
+ * \param datalen Size of the buffer to fill
+ * \param id Party id information
+ * \param label Name of particular party id
+ * \param ies Data frame ie values for the party id components
+ * \param update What id information to build. NULL if all.
+ *
+ * \retval -1 if error
+ * \retval Amount of data buffer used
+ */
+static int party_id_build_data(unsigned char *data, size_t datalen,
+ const struct ast_party_id *id, const char *label, const struct ast_party_id_ies *ies,
+ const struct ast_set_party_id *update)
+{
+ size_t length;
+ size_t pos = 0;
+ int res;
- /* Connected line Subaddress Valid */
+ /*
+ * The size of integer values must be fixed in case the frame is
+ * shipped to another machine.
+ */
+
+ if (!update || update->name) {
+ res = party_name_build_data(data + pos, datalen - pos, &id->name, label,
+ &ies->name);
+ if (res < 0) {
+ return -1;
+ }
+ pos += res;
+ }
+
+ if (!update || update->number) {
+ res = party_number_build_data(data + pos, datalen - pos, &id->number, label,
+ &ies->number);
+ if (res < 0) {
+ return -1;
+ }
+ pos += res;
+ }
+
+ if (!update || update->subaddress) {
+ res = party_subaddress_build_data(data + pos, datalen - pos, &id->subaddress,
+ label, &ies->subaddress);
+ if (res < 0) {
+ return -1;
+ }
+ pos += res;
+ }
+
+ /* *************** Party id user tag **************************** */
+ if (id->tag) {
+ length = strlen(id->tag);
+ if (datalen < pos + (sizeof(data[0]) * 2) + length) {
+ ast_log(LOG_WARNING, "No space left for %s tag\n", label);
+ return -1;
+ }
+ data[pos++] = ies->tag;
+ data[pos++] = length;
+ memcpy(data + pos, id->tag, length);
+ pos += length;
+ }
+
+ /* *************** Party id combined presentation *************** */
+ if (!update || update->number) {
+ int presentation;
+
+ if (!update || update->name) {
+ presentation = ast_party_id_presentation(id);
+ } else {
+ /*
+ * We must compromise because not all the information is available
+ * to determine a combined presentation value.
+ * We will only send the number presentation instead.
+ */
+ presentation = id->number.presentation;
+ }
+
+ if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
+ ast_log(LOG_WARNING, "No space left for %s combined presentation\n", label);
+ return -1;
+ }
+ data[pos++] = ies->combined_presentation;
+ data[pos++] = 1;
+ data[pos++] = presentation;
+ }
+
+ return pos;
+}
+
+/*!
+ * \brief Element identifiers for connected line indication frame data
+ * \note Only add to the end of this enum.
+ */
+enum {
+ AST_CONNECTED_LINE_NUMBER,
+ AST_CONNECTED_LINE_NAME,
+ AST_CONNECTED_LINE_NUMBER_PLAN,
+ AST_CONNECTED_LINE_ID_PRESENTATION,/* Combined number and name presentation. */
+ AST_CONNECTED_LINE_SOURCE,
+ AST_CONNECTED_LINE_SUBADDRESS,
+ AST_CONNECTED_LINE_SUBADDRESS_TYPE,
+ AST_CONNECTED_LINE_SUBADDRESS_ODD_EVEN,
+ AST_CONNECTED_LINE_SUBADDRESS_VALID,
+ AST_CONNECTED_LINE_TAG,
+ AST_CONNECTED_LINE_VERSION,
+ AST_CONNECTED_LINE_NAME_VALID,
+ AST_CONNECTED_LINE_NAME_CHAR_SET,
+ AST_CONNECTED_LINE_NAME_PRESENTATION,
+ AST_CONNECTED_LINE_NUMBER_VALID,
+ AST_CONNECTED_LINE_NUMBER_PRESENTATION,
+};
+
+int ast_connected_line_build_data(unsigned char *data, size_t datalen, const struct ast_party_connected_line *connected, const struct ast_set_party_connected_line *update)
+{
+ int32_t value;
+ size_t pos = 0;
+ int res;
+
+ static const struct ast_party_id_ies ies = {
+ .name.str = AST_CONNECTED_LINE_NAME,
+ .name.char_set = AST_CONNECTED_LINE_NAME_CHAR_SET,
+ .name.presentation = AST_CONNECTED_LINE_NAME_PRESENTATION,
+ .name.valid = AST_CONNECTED_LINE_NAME_VALID,
+
+ .number.str = AST_CONNECTED_LINE_NUMBER,
+ .number.plan = AST_CONNECTED_LINE_NUMBER_PLAN,
+ .number.presentation = AST_CONNECTED_LINE_NUMBER_PRESENTATION,
+ .number.valid = AST_CONNECTED_LINE_NUMBER_VALID,
+
+ .subaddress.str = AST_CONNECTED_LINE_SUBADDRESS,
+ .subaddress.type = AST_CONNECTED_LINE_SUBADDRESS_TYPE,
+ .subaddress.odd_even_indicator = AST_CONNECTED_LINE_SUBADDRESS_ODD_EVEN,
+ .subaddress.valid = AST_CONNECTED_LINE_SUBADDRESS_VALID,
+
+ .tag = AST_CONNECTED_LINE_TAG,
+ .combined_presentation = AST_CONNECTED_LINE_ID_PRESENTATION,
+ };
+
+ /*
+ * The size of integer values must be fixed in case the frame is
+ * shipped to another machine.
+ */
+
+ /* Connected line frame version */
if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
- ast_log(LOG_WARNING, "No space left for connected line subaddress valid\n");
+ ast_log(LOG_WARNING, "No space left for connected line frame version\n");
return -1;
}
- data[pos++] = AST_CONNECTED_LINE_SUBADDRESS_VALID;
+ data[pos++] = AST_CONNECTED_LINE_VERSION;
data[pos++] = 1;
- data[pos++] = connected->id.subaddress.valid;
+ data[pos++] = 2;/* Version 1 did not have a version ie */
+
+ res = party_id_build_data(data + pos, datalen - pos, &connected->id,
+ "connected line", &ies, update ? &update->id : NULL);
+ if (res < 0) {
+ return -1;
+ }
+ pos += res;
+
+ /* Connected line source */
+ if (datalen < pos + (sizeof(data[0]) * 2) + sizeof(value)) {
+ ast_log(LOG_WARNING, "No space left for connected line source\n");
+ return -1;
+ }
+ data[pos++] = AST_CONNECTED_LINE_SOURCE;
+ data[pos++] = sizeof(value);
+ value = htonl(connected->source);
+ memcpy(data + pos, &value, sizeof(value));
+ pos += sizeof(value);
return pos;
}
unsigned char ie_len;
unsigned char ie_id;
int32_t value;
+ int frame_version = 1;
+ int combined_presentation = 0;
+ int got_combined_presentation = 0;/* TRUE if got a combined name and number presentation value. */
for (pos = 0; pos < datalen; pos += ie_len) {
if (datalen < pos + sizeof(ie_id) + sizeof(ie_len)) {
}
switch (ie_id) {
- case AST_CONNECTED_LINE_NUMBER:
- if (connected->id.number) {
- ast_free(connected->id.number);
- }
- connected->id.number = ast_malloc(ie_len + 1);
- if (connected->id.number) {
- memcpy(connected->id.number, data + pos, ie_len);
- connected->id.number[ie_len] = 0;
+/* Connected line party frame version */
+ case AST_CONNECTED_LINE_VERSION:
+ if (ie_len != 1) {
+ ast_log(LOG_WARNING, "Invalid connected line frame version (%u)\n",
+ (unsigned) ie_len);
+ break;
}
+ frame_version = data[pos];
break;
+/* Connected line party id name */
case AST_CONNECTED_LINE_NAME:
- if (connected->id.name) {
- ast_free(connected->id.name);
+ ast_free(connected->id.name.str);
+ connected->id.name.str = ast_malloc(ie_len + 1);
+ if (connected->id.name.str) {
+ memcpy(connected->id.name.str, data + pos, ie_len);
+ connected->id.name.str[ie_len] = 0;
}
- connected->id.name = ast_malloc(ie_len + 1);
- if (connected->id.name) {
- memcpy(connected->id.name, data + pos, ie_len);
- connected->id.name[ie_len] = 0;
+ break;
+ case AST_CONNECTED_LINE_NAME_CHAR_SET:
+ if (ie_len != 1) {
+ ast_log(LOG_WARNING, "Invalid connected line name char set (%u)\n",
+ (unsigned) ie_len);
+ break;
}
+ connected->id.name.char_set = data[pos];
break;
- case AST_CONNECTED_LINE_TAG:
- if (connected->id.tag) {
- ast_free(connected->id.tag);
+ case AST_CONNECTED_LINE_NAME_PRESENTATION:
+ if (ie_len != 1) {
+ ast_log(LOG_WARNING, "Invalid connected line name presentation (%u)\n",
+ (unsigned) ie_len);
+ break;
}
- connected->id.tag = ast_malloc(ie_len + 1);
- if (connected->id.tag) {
- memcpy(connected->id.tag, data + pos, ie_len);
- connected->id.tag[ie_len] = 0;
+ connected->id.name.presentation = data[pos];
+ break;
+ case AST_CONNECTED_LINE_NAME_VALID:
+ if (ie_len != 1) {
+ ast_log(LOG_WARNING, "Invalid connected line name valid (%u)\n",
+ (unsigned) ie_len);
+ break;
+ }
+ connected->id.name.valid = data[pos];
+ break;
+/* Connected line party id number */
+ case AST_CONNECTED_LINE_NUMBER:
+ ast_free(connected->id.number.str);
+ connected->id.number.str = ast_malloc(ie_len + 1);
+ if (connected->id.number.str) {
+ memcpy(connected->id.number.str, data + pos, ie_len);
+ connected->id.number.str[ie_len] = 0;
}
break;
- case AST_CONNECTED_LINE_NUMBER_TYPE:
+ case AST_CONNECTED_LINE_NUMBER_PLAN:
if (ie_len != 1) {
- ast_log(LOG_WARNING, "Invalid connected line type of number (%u)\n", (unsigned) ie_len);
+ ast_log(LOG_WARNING, "Invalid connected line numbering plan (%u)\n",
+ (unsigned) ie_len);
break;
}
- connected->id.number_type = data[pos];
+ connected->id.number.plan = data[pos];
break;
case AST_CONNECTED_LINE_NUMBER_PRESENTATION:
if (ie_len != 1) {
- ast_log(LOG_WARNING, "Invalid connected line presentation (%u)\n", (unsigned) ie_len);
+ ast_log(LOG_WARNING, "Invalid connected line number presentation (%u)\n",
+ (unsigned) ie_len);
break;
}
- connected->id.number_presentation = data[pos];
+ connected->id.number.presentation = data[pos];
break;
- case AST_CONNECTED_LINE_SOURCE:
- if (ie_len != sizeof(value)) {
- ast_log(LOG_WARNING, "Invalid connected line source (%u)\n", (unsigned) ie_len);
+ case AST_CONNECTED_LINE_NUMBER_VALID:
+ if (ie_len != 1) {
+ ast_log(LOG_WARNING, "Invalid connected line number valid (%u)\n",
+ (unsigned) ie_len);
break;
}
- memcpy(&value, data + pos, sizeof(value));
- connected->source = ntohl(value);
+ connected->id.number.valid = data[pos];
break;
- case AST_CONNECTED_LINE_SUBADDRESS:
- if (connected->id.subaddress.str) {
- ast_free(connected->id.subaddress.str);
+/* Connected line party id combined presentation */
+ case AST_CONNECTED_LINE_ID_PRESENTATION:
+ if (ie_len != 1) {
+ ast_log(LOG_WARNING, "Invalid connected line combined presentation (%u)\n",
+ (unsigned) ie_len);
+ break;
}
+ combined_presentation = data[pos];
+ got_combined_presentation = 1;
+ break;
+/* Connected line party id subaddress */
+ case AST_CONNECTED_LINE_SUBADDRESS:
+ ast_free(connected->id.subaddress.str);
connected->id.subaddress.str = ast_malloc(ie_len + 1);
if (connected->id.subaddress.str) {
memcpy(connected->id.subaddress.str, data + pos, ie_len);
}
connected->id.subaddress.valid = data[pos];
break;
+/* Connected line party tag */
+ case AST_CONNECTED_LINE_TAG:
+ ast_free(connected->id.tag);
+ connected->id.tag = ast_malloc(ie_len + 1);
+ if (connected->id.tag) {
+ memcpy(connected->id.tag, data + pos, ie_len);
+ connected->id.tag[ie_len] = 0;
+ }
+ break;
+/* Connected line party source */
+ case AST_CONNECTED_LINE_SOURCE:
+ if (ie_len != sizeof(value)) {
+ ast_log(LOG_WARNING, "Invalid connected line source (%u)\n",
+ (unsigned) ie_len);
+ break;
+ }
+ memcpy(&value, data + pos, sizeof(value));
+ connected->source = ntohl(value);
+ break;
+/* Connected line party unknown element */
default:
- ast_log(LOG_DEBUG, "Unknown connected line element: %u (%u)\n", (unsigned) ie_id, (unsigned) ie_len);
+ ast_log(LOG_DEBUG, "Unknown connected line element: %u (%u)\n",
+ (unsigned) ie_id, (unsigned) ie_len);
break;
}
}
+ switch (frame_version) {
+ case 1:
+ /*
+ * The other end is an earlier version that we need to adjust
+ * for compatibility.
+ */
+ connected->id.name.valid = 1;
+ connected->id.name.char_set = AST_PARTY_CHAR_SET_ISO8859_1;
+ connected->id.number.valid = 1;
+ if (got_combined_presentation) {
+ connected->id.name.presentation = combined_presentation;
+ connected->id.number.presentation = combined_presentation;
+ }
+ break;
+ case 2:
+ /* The other end is at the same level as we are. */
+ break;
+ default:
+ /*
+ * The other end is newer than we are.
+ * We need to assume that they are compatible with us.
+ */
+ ast_log(LOG_DEBUG, "Connected line frame has newer version: %u\n",
+ (unsigned) frame_version);
+ break;
+ }
+
return 0;
}
-void ast_channel_update_connected_line(struct ast_channel *chan, const struct ast_party_connected_line *connected)
+void ast_channel_update_connected_line(struct ast_channel *chan, const struct ast_party_connected_line *connected, const struct ast_set_party_connected_line *update)
{
unsigned char data[1024]; /* This should be large enough */
size_t datalen;
- datalen = ast_connected_line_build_data(data, sizeof(data), connected);
+ datalen = ast_connected_line_build_data(data, sizeof(data), connected, update);
if (datalen == (size_t) -1) {
return;
}
ast_indicate_data(chan, AST_CONTROL_CONNECTED_LINE, data, datalen);
}
-void ast_channel_queue_connected_line_update(struct ast_channel *chan, const struct ast_party_connected_line *connected)
+void ast_channel_queue_connected_line_update(struct ast_channel *chan, const struct ast_party_connected_line *connected, const struct ast_set_party_connected_line *update)
{
unsigned char data[1024]; /* This should be large enough */
size_t datalen;
- datalen = ast_connected_line_build_data(data, sizeof(data), connected);
+ datalen = ast_connected_line_build_data(data, sizeof(data), connected, update);
if (datalen == (size_t) -1) {
return;
}
ast_queue_control_data(chan, AST_CONTROL_CONNECTED_LINE, data, datalen);
}
-void ast_channel_set_redirecting(struct ast_channel *chan, const struct ast_party_redirecting *redirecting)
+void ast_channel_set_redirecting(struct ast_channel *chan, const struct ast_party_redirecting *redirecting, const struct ast_set_party_redirecting *update)
{
if (&chan->redirecting == redirecting) {
/* Don't set to self */
}
ast_channel_lock(chan);
-
- ast_party_id_set(&chan->redirecting.from, &redirecting->from);
- ast_party_id_set(&chan->redirecting.to, &redirecting->to);
- chan->redirecting.reason = redirecting->reason;
- chan->redirecting.count = redirecting->count;
-
+ ast_party_redirecting_set(&chan->redirecting, redirecting, update);
ast_channel_unlock(chan);
}
enum {
AST_REDIRECTING_FROM_NUMBER,
AST_REDIRECTING_FROM_NAME,
- AST_REDIRECTING_FROM_NUMBER_TYPE,
- AST_REDIRECTING_FROM_NUMBER_PRESENTATION,
+ AST_REDIRECTING_FROM_NUMBER_PLAN,
+ AST_REDIRECTING_FROM_ID_PRESENTATION,
AST_REDIRECTING_TO_NUMBER,
AST_REDIRECTING_TO_NAME,
- AST_REDIRECTING_TO_NUMBER_TYPE,
- AST_REDIRECTING_TO_NUMBER_PRESENTATION,
+ AST_REDIRECTING_TO_NUMBER_PLAN,
+ AST_REDIRECTING_TO_ID_PRESENTATION,
AST_REDIRECTING_REASON,
AST_REDIRECTING_COUNT,
AST_REDIRECTING_FROM_SUBADDRESS,
AST_REDIRECTING_TO_SUBADDRESS_VALID,
AST_REDIRECTING_FROM_TAG,
AST_REDIRECTING_TO_TAG,
+ AST_REDIRECTING_VERSION,
+ AST_REDIRECTING_FROM_NAME_VALID,
+ AST_REDIRECTING_FROM_NAME_CHAR_SET,
+ AST_REDIRECTING_FROM_NAME_PRESENTATION,
+ AST_REDIRECTING_FROM_NUMBER_VALID,
+ AST_REDIRECTING_FROM_NUMBER_PRESENTATION,
+ AST_REDIRECTING_TO_NAME_VALID,
+ AST_REDIRECTING_TO_NAME_CHAR_SET,
+ AST_REDIRECTING_TO_NAME_PRESENTATION,
+ AST_REDIRECTING_TO_NUMBER_VALID,
+ AST_REDIRECTING_TO_NUMBER_PRESENTATION,
};
-int ast_redirecting_build_data(unsigned char *data, size_t datalen, const struct ast_party_redirecting *redirecting)
+int ast_redirecting_build_data(unsigned char *data, size_t datalen, const struct ast_party_redirecting *redirecting, const struct ast_set_party_redirecting *update)
{
int32_t value;
- size_t length;
size_t pos = 0;
+ int res;
- /*
- * The size of integer values must be fixed in case the frame is
- * shipped to another machine.
- */
-
- /* *************** Redirecting from party id *************** */
- if (redirecting->from.number) {
- length = strlen(redirecting->from.number);
- if (datalen < pos + (sizeof(data[0]) * 2) + length) {
- ast_log(LOG_WARNING, "No space left for redirecting from number\n");
- return -1;
- }
- data[pos++] = AST_REDIRECTING_FROM_NUMBER;
- data[pos++] = length;
- memcpy(data + pos, redirecting->from.number, length);
- pos += length;
- }
-
- if (redirecting->from.name) {
- length = strlen(redirecting->from.name);
- if (datalen < pos + (sizeof(data[0]) * 2) + length) {
- ast_log(LOG_WARNING, "No space left for redirecting from name\n");
- return -1;
- }
- data[pos++] = AST_REDIRECTING_FROM_NAME;
- data[pos++] = length;
- memcpy(data + pos, redirecting->from.name, length);
- pos += length;
- }
-
- if (redirecting->from.tag) {
- length = strlen(redirecting->from.tag);
- if (datalen < pos + (sizeof(data[0]) * 2) + length) {
- ast_log(LOG_WARNING, "No space left for redirecting from name\n");
- return -1;
- }
- data[pos++] = AST_REDIRECTING_FROM_TAG;
- data[pos++] = length;
- memcpy(data + pos, redirecting->from.tag, length);
- pos += length;
- }
-
- if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
- ast_log(LOG_WARNING, "No space left for redirecting from type of number\n");
- return -1;
- }
- data[pos++] = AST_REDIRECTING_FROM_NUMBER_TYPE;
- data[pos++] = 1;
- data[pos++] = redirecting->from.number_type;
-
- if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
- ast_log(LOG_WARNING, "No space left for redirecting from presentation\n");
- return -1;
- }
- data[pos++] = AST_REDIRECTING_FROM_NUMBER_PRESENTATION;
- data[pos++] = 1;
- data[pos++] = redirecting->from.number_presentation;
-
- /* subaddress */
- if (redirecting->from.subaddress.str) {
- length = strlen(redirecting->from.subaddress.str);
- if (datalen < pos + (sizeof(data[0]) * 2) + length) {
- ast_log(LOG_WARNING, "No space left for redirecting-from subaddress\n");
- return -1;
- }
- data[pos++] = AST_REDIRECTING_FROM_SUBADDRESS;
- data[pos++] = length;
- memcpy(data + pos, redirecting->from.subaddress.str, length);
- pos += length;
- }
-
- if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
- ast_log(LOG_WARNING, "No space left for redirecting-from type of subaddress\n");
- return -1;
- }
- data[pos++] = AST_REDIRECTING_FROM_SUBADDRESS_TYPE;
- data[pos++] = 1;
- data[pos++] = redirecting->from.subaddress.type;
-
- if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
- ast_log(LOG_WARNING,
- "No space left for redirecting-from subaddress odd-even indicator\n");
- return -1;
- }
- data[pos++] = AST_REDIRECTING_FROM_SUBADDRESS_ODD_EVEN;
- data[pos++] = 1;
- data[pos++] = redirecting->from.subaddress.odd_even_indicator;
-
- if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
- ast_log(LOG_WARNING, "No space left for redirecting-from subaddress valid\n");
- return -1;
- }
- data[pos++] = AST_REDIRECTING_FROM_SUBADDRESS_VALID;
- data[pos++] = 1;
- data[pos++] = redirecting->from.subaddress.valid;
-
- /* *************** Redirecting to party id *************** */
- if (redirecting->to.number) {
- length = strlen(redirecting->to.number);
- if (datalen < pos + (sizeof(data[0]) * 2) + length) {
- ast_log(LOG_WARNING, "No space left for redirecting to number\n");
- return -1;
- }
- data[pos++] = AST_REDIRECTING_TO_NUMBER;
- data[pos++] = length;
- memcpy(data + pos, redirecting->to.number, length);
- pos += length;
- }
-
- if (redirecting->to.name) {
- length = strlen(redirecting->to.name);
- if (datalen < pos + (sizeof(data[0]) * 2) + length) {
- ast_log(LOG_WARNING, "No space left for redirecting to name\n");
- return -1;
- }
- data[pos++] = AST_REDIRECTING_TO_NAME;
- data[pos++] = length;
- memcpy(data + pos, redirecting->to.name, length);
- pos += length;
- }
-
- if (redirecting->to.tag) {
- length = strlen(redirecting->to.tag);
- if (datalen < pos + (sizeof(data[0]) * 2) + length) {
- ast_log(LOG_WARNING, "No space left for redirecting to name\n");
- return -1;
- }
- data[pos++] = AST_REDIRECTING_TO_TAG;
- data[pos++] = length;
- memcpy(data + pos, redirecting->to.tag, length);
- pos += length;
- }
+ static const struct ast_party_id_ies from_ies = {
+ .name.str = AST_REDIRECTING_FROM_NAME,
+ .name.char_set = AST_REDIRECTING_FROM_NAME_CHAR_SET,
+ .name.presentation = AST_REDIRECTING_FROM_NAME_PRESENTATION,
+ .name.valid = AST_REDIRECTING_FROM_NAME_VALID,
- if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
- ast_log(LOG_WARNING, "No space left for redirecting to type of number\n");
- return -1;
- }
- data[pos++] = AST_REDIRECTING_TO_NUMBER_TYPE;
- data[pos++] = 1;
- data[pos++] = redirecting->to.number_type;
+ .number.str = AST_REDIRECTING_FROM_NUMBER,
+ .number.plan = AST_REDIRECTING_FROM_NUMBER_PLAN,
+ .number.presentation = AST_REDIRECTING_FROM_NUMBER_PRESENTATION,
+ .number.valid = AST_REDIRECTING_FROM_NUMBER_VALID,
- if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
- ast_log(LOG_WARNING, "No space left for redirecting to presentation\n");
- return -1;
- }
- data[pos++] = AST_REDIRECTING_TO_NUMBER_PRESENTATION;
- data[pos++] = 1;
- data[pos++] = redirecting->to.number_presentation;
+ .subaddress.str = AST_REDIRECTING_FROM_SUBADDRESS,
+ .subaddress.type = AST_REDIRECTING_FROM_SUBADDRESS_TYPE,
+ .subaddress.odd_even_indicator = AST_REDIRECTING_FROM_SUBADDRESS_ODD_EVEN,
+ .subaddress.valid = AST_REDIRECTING_FROM_SUBADDRESS_VALID,
- /* subaddress */
- if (redirecting->to.subaddress.str) {
- length = strlen(redirecting->to.subaddress.str);
- if (datalen < pos + (sizeof(data[0]) * 2) + length) {
- ast_log(LOG_WARNING, "No space left for redirecting-to subaddress\n");
- return -1;
- }
- data[pos++] = AST_REDIRECTING_TO_SUBADDRESS;
- data[pos++] = length;
- memcpy(data + pos, redirecting->to.subaddress.str, length);
- pos += length;
- }
+ .tag = AST_REDIRECTING_FROM_TAG,
+ .combined_presentation = AST_REDIRECTING_FROM_ID_PRESENTATION,
+ };
+ static const struct ast_party_id_ies to_ies = {
+ .name.str = AST_REDIRECTING_TO_NAME,
+ .name.char_set = AST_REDIRECTING_TO_NAME_CHAR_SET,
+ .name.presentation = AST_REDIRECTING_TO_NAME_PRESENTATION,
+ .name.valid = AST_REDIRECTING_TO_NAME_VALID,
+
+ .number.str = AST_REDIRECTING_TO_NUMBER,
+ .number.plan = AST_REDIRECTING_TO_NUMBER_PLAN,
+ .number.presentation = AST_REDIRECTING_TO_NUMBER_PRESENTATION,
+ .number.valid = AST_REDIRECTING_TO_NUMBER_VALID,
+
+ .subaddress.str = AST_REDIRECTING_TO_SUBADDRESS,
+ .subaddress.type = AST_REDIRECTING_TO_SUBADDRESS_TYPE,
+ .subaddress.odd_even_indicator = AST_REDIRECTING_TO_SUBADDRESS_ODD_EVEN,
+ .subaddress.valid = AST_REDIRECTING_TO_SUBADDRESS_VALID,
+
+ .tag = AST_REDIRECTING_TO_TAG,
+ .combined_presentation = AST_REDIRECTING_TO_ID_PRESENTATION,
+ };
+ /* Redirecting frame version */
if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
- ast_log(LOG_WARNING, "No space left for redirecting-to type of subaddress\n");
+ ast_log(LOG_WARNING, "No space left for redirecting frame version\n");
return -1;
}
- data[pos++] = AST_REDIRECTING_TO_SUBADDRESS_TYPE;
+ data[pos++] = AST_REDIRECTING_VERSION;
data[pos++] = 1;
- data[pos++] = redirecting->to.subaddress.type;
+ data[pos++] = 2;/* Version 1 did not have a version ie */
- if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
- ast_log(LOG_WARNING,
- "No space left for redirecting-to subaddress odd-even indicator\n");
+ res = party_id_build_data(data + pos, datalen - pos, &redirecting->from,
+ "redirecting-from", &from_ies, update ? &update->from : NULL);
+ if (res < 0) {
return -1;
}
- data[pos++] = AST_REDIRECTING_TO_SUBADDRESS_ODD_EVEN;
- data[pos++] = 1;
- data[pos++] = redirecting->to.subaddress.odd_even_indicator;
+ pos += res;
- if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
- ast_log(LOG_WARNING, "No space left for redirecting-to subaddress valid\n");
+ res = party_id_build_data(data + pos, datalen - pos, &redirecting->to,
+ "redirecting-to", &to_ies, update ? &update->to : NULL);
+ if (res < 0) {
return -1;
}
- data[pos++] = AST_REDIRECTING_TO_SUBADDRESS_VALID;
- data[pos++] = 1;
- data[pos++] = redirecting->to.subaddress.valid;
+ pos += res;
/* Redirecting reason */
if (datalen < pos + (sizeof(data[0]) * 2) + sizeof(value)) {
unsigned char ie_len;
unsigned char ie_id;
int32_t value;
+ int frame_version = 1;
+ int from_combined_presentation = 0;
+ int got_from_combined_presentation = 0;/* TRUE if got a combined name and number presentation value. */
+ int to_combined_presentation = 0;
+ int got_to_combined_presentation = 0;/* TRUE if got a combined name and number presentation value. */
for (pos = 0; pos < datalen; pos += ie_len) {
if (datalen < pos + sizeof(ie_id) + sizeof(ie_len)) {
}
switch (ie_id) {
- case AST_REDIRECTING_FROM_NUMBER:
- if (redirecting->from.number) {
- ast_free(redirecting->from.number);
- }
- redirecting->from.number = ast_malloc(ie_len + 1);
- if (redirecting->from.number) {
- memcpy(redirecting->from.number, data + pos, ie_len);
- redirecting->from.number[ie_len] = 0;
+/* Redirecting frame version */
+ case AST_REDIRECTING_VERSION:
+ if (ie_len != 1) {
+ ast_log(LOG_WARNING, "Invalid redirecting frame version (%u)\n",
+ (unsigned) ie_len);
+ break;
}
+ frame_version = data[pos];
break;
+/* Redirecting-from party id name */
case AST_REDIRECTING_FROM_NAME:
- if (redirecting->from.name) {
- ast_free(redirecting->from.name);
+ ast_free(redirecting->from.name.str);
+ redirecting->from.name.str = ast_malloc(ie_len + 1);
+ if (redirecting->from.name.str) {
+ memcpy(redirecting->from.name.str, data + pos, ie_len);
+ redirecting->from.name.str[ie_len] = 0;
}
- redirecting->from.name = ast_malloc(ie_len + 1);
- if (redirecting->from.name) {
- memcpy(redirecting->from.name, data + pos, ie_len);
- redirecting->from.name[ie_len] = 0;
+ break;
+ case AST_REDIRECTING_FROM_NAME_CHAR_SET:
+ if (ie_len != 1) {
+ ast_log(LOG_WARNING, "Invalid redirecting-from name char set (%u)\n",
+ (unsigned) ie_len);
+ break;
}
+ redirecting->from.name.char_set = data[pos];
break;
- case AST_REDIRECTING_FROM_TAG:
- if (redirecting->from.tag) {
- ast_free(redirecting->from.tag);
+ case AST_REDIRECTING_FROM_NAME_PRESENTATION:
+ if (ie_len != 1) {
+ ast_log(LOG_WARNING, "Invalid redirecting-from name presentation (%u)\n",
+ (unsigned) ie_len);
+ break;
}
- redirecting->from.tag = ast_malloc(ie_len + 1);
- if (redirecting->from.tag) {
- memcpy(redirecting->from.tag, data + pos, ie_len);
- redirecting->from.tag[ie_len] = 0;
+ redirecting->from.name.presentation = data[pos];
+ break;
+ case AST_REDIRECTING_FROM_NAME_VALID:
+ if (ie_len != 1) {
+ ast_log(LOG_WARNING, "Invalid redirecting-from name valid (%u)\n",
+ (unsigned) ie_len);
+ break;
+ }
+ redirecting->from.name.valid = data[pos];
+ break;
+/* Redirecting-from party id number */
+ case AST_REDIRECTING_FROM_NUMBER:
+ ast_free(redirecting->from.number.str);
+ redirecting->from.number.str = ast_malloc(ie_len + 1);
+ if (redirecting->from.number.str) {
+ memcpy(redirecting->from.number.str, data + pos, ie_len);
+ redirecting->from.number.str[ie_len] = 0;
}
break;
- case AST_REDIRECTING_FROM_NUMBER_TYPE:
+ case AST_REDIRECTING_FROM_NUMBER_PLAN:
if (ie_len != 1) {
- ast_log(LOG_WARNING, "Invalid redirecting from type of number (%u)\n", (unsigned) ie_len);
+ ast_log(LOG_WARNING, "Invalid redirecting-from numbering plan (%u)\n",
+ (unsigned) ie_len);
break;
}
- redirecting->from.number_type = data[pos];
+ redirecting->from.number.plan = data[pos];
break;
case AST_REDIRECTING_FROM_NUMBER_PRESENTATION:
if (ie_len != 1) {
- ast_log(LOG_WARNING, "Invalid redirecting from presentation (%u)\n", (unsigned) ie_len);
+ ast_log(LOG_WARNING, "Invalid redirecting-from number presentation (%u)\n",
+ (unsigned) ie_len);
break;
}
- redirecting->from.number_presentation = data[pos];
+ redirecting->from.number.presentation = data[pos];
break;
- case AST_REDIRECTING_FROM_SUBADDRESS:
- if (redirecting->from.subaddress.str) {
- ast_free(redirecting->from.subaddress.str);
+ case AST_REDIRECTING_FROM_NUMBER_VALID:
+ if (ie_len != 1) {
+ ast_log(LOG_WARNING, "Invalid redirecting-from number valid (%u)\n",
+ (unsigned) ie_len);
+ break;
}
+ redirecting->from.number.valid = data[pos];
+ break;
+/* Redirecting-from party id combined presentation */
+ case AST_REDIRECTING_FROM_ID_PRESENTATION:
+ if (ie_len != 1) {
+ ast_log(LOG_WARNING, "Invalid redirecting-from combined presentation (%u)\n",
+ (unsigned) ie_len);
+ break;
+ }
+ from_combined_presentation = data[pos];
+ got_from_combined_presentation = 1;
+ break;
+/* Redirecting-from party id subaddress */
+ case AST_REDIRECTING_FROM_SUBADDRESS:
+ ast_free(redirecting->from.subaddress.str);
redirecting->from.subaddress.str = ast_malloc(ie_len + 1);
if (redirecting->from.subaddress.str) {
memcpy(redirecting->from.subaddress.str, data + pos, ie_len);
break;
case AST_REDIRECTING_FROM_SUBADDRESS_TYPE:
if (ie_len != 1) {
- ast_log(LOG_WARNING, "Invalid redirecting from type of subaddress (%u)\n",
+ ast_log(LOG_WARNING, "Invalid redirecting-from type of subaddress (%u)\n",
(unsigned) ie_len);
break;
}
case AST_REDIRECTING_FROM_SUBADDRESS_ODD_EVEN:
if (ie_len != 1) {
ast_log(LOG_WARNING,
- "Invalid redirecting from subaddress odd-even indicator (%u)\n",
+ "Invalid redirecting-from subaddress odd-even indicator (%u)\n",
(unsigned) ie_len);
break;
}
break;
case AST_REDIRECTING_FROM_SUBADDRESS_VALID:
if (ie_len != 1) {
- ast_log(LOG_WARNING, "Invalid redirecting from subaddress valid (%u)\n",
+ ast_log(LOG_WARNING, "Invalid redirecting-from subaddress valid (%u)\n",
(unsigned) ie_len);
break;
}
redirecting->from.subaddress.valid = data[pos];
break;
- case AST_REDIRECTING_TO_NUMBER:
- if (redirecting->to.number) {
- ast_free(redirecting->to.number);
- }
- redirecting->to.number = ast_malloc(ie_len + 1);
- if (redirecting->to.number) {
- memcpy(redirecting->to.number, data + pos, ie_len);
- redirecting->to.number[ie_len] = 0;
+/* Redirecting-from party id tag */
+ case AST_REDIRECTING_FROM_TAG:
+ ast_free(redirecting->from.tag);
+ redirecting->from.tag = ast_malloc(ie_len + 1);
+ if (redirecting->from.tag) {
+ memcpy(redirecting->from.tag, data + pos, ie_len);
+ redirecting->from.tag[ie_len] = 0;
}
break;
+/* Redirecting-to party id name */
case AST_REDIRECTING_TO_NAME:
- if (redirecting->to.name) {
- ast_free(redirecting->to.name);
+ ast_free(redirecting->to.name.str);
+ redirecting->to.name.str = ast_malloc(ie_len + 1);
+ if (redirecting->to.name.str) {
+ memcpy(redirecting->to.name.str, data + pos, ie_len);
+ redirecting->to.name.str[ie_len] = 0;
}
- redirecting->to.name = ast_malloc(ie_len + 1);
- if (redirecting->to.name) {
- memcpy(redirecting->to.name, data + pos, ie_len);
- redirecting->to.name[ie_len] = 0;
+ break;
+ case AST_REDIRECTING_TO_NAME_CHAR_SET:
+ if (ie_len != 1) {
+ ast_log(LOG_WARNING, "Invalid redirecting-to name char set (%u)\n",
+ (unsigned) ie_len);
+ break;
}
+ redirecting->to.name.char_set = data[pos];
break;
- case AST_REDIRECTING_TO_TAG:
- if (redirecting->to.tag) {
- ast_free(redirecting->to.tag);
+ case AST_REDIRECTING_TO_NAME_PRESENTATION:
+ if (ie_len != 1) {
+ ast_log(LOG_WARNING, "Invalid redirecting-to name presentation (%u)\n",
+ (unsigned) ie_len);
+ break;
}
- redirecting->to.tag = ast_malloc(ie_len + 1);
- if (redirecting->to.tag) {
- memcpy(redirecting->to.tag, data + pos, ie_len);
- redirecting->to.tag[ie_len] = 0;
+ redirecting->to.name.presentation = data[pos];
+ break;
+ case AST_REDIRECTING_TO_NAME_VALID:
+ if (ie_len != 1) {
+ ast_log(LOG_WARNING, "Invalid redirecting-to name valid (%u)\n",
+ (unsigned) ie_len);
+ break;
}
+ redirecting->to.name.valid = data[pos];
break;
- case AST_REDIRECTING_TO_NUMBER_TYPE:
+/* Redirecting-to party id number */
+ case AST_REDIRECTING_TO_NUMBER:
+ ast_free(redirecting->to.number.str);
+ redirecting->to.number.str = ast_malloc(ie_len + 1);
+ if (redirecting->to.number.str) {
+ memcpy(redirecting->to.number.str, data + pos, ie_len);
+ redirecting->to.number.str[ie_len] = 0;
+ }
+ break;
+ case AST_REDIRECTING_TO_NUMBER_PLAN:
if (ie_len != 1) {
- ast_log(LOG_WARNING, "Invalid redirecting to type of number (%u)\n", (unsigned) ie_len);
+ ast_log(LOG_WARNING, "Invalid redirecting-to numbering plan (%u)\n",
+ (unsigned) ie_len);
break;
}
- redirecting->to.number_type = data[pos];
+ redirecting->to.number.plan = data[pos];
break;
case AST_REDIRECTING_TO_NUMBER_PRESENTATION:
if (ie_len != 1) {
- ast_log(LOG_WARNING, "Invalid redirecting to presentation (%u)\n", (unsigned) ie_len);
+ ast_log(LOG_WARNING, "Invalid redirecting-to number presentation (%u)\n",
+ (unsigned) ie_len);
break;
}
- redirecting->to.number_presentation = data[pos];
+ redirecting->to.number.presentation = data[pos];
break;
- case AST_REDIRECTING_TO_SUBADDRESS:
- if (redirecting->to.subaddress.str) {
- ast_free(redirecting->to.subaddress.str);
+ case AST_REDIRECTING_TO_NUMBER_VALID:
+ if (ie_len != 1) {
+ ast_log(LOG_WARNING, "Invalid redirecting-to number valid (%u)\n",
+ (unsigned) ie_len);
+ break;
+ }
+ redirecting->to.number.valid = data[pos];
+ break;
+/* Redirecting-to party id combined presentation */
+ case AST_REDIRECTING_TO_ID_PRESENTATION:
+ if (ie_len != 1) {
+ ast_log(LOG_WARNING, "Invalid redirecting-to combined presentation (%u)\n",
+ (unsigned) ie_len);
+ break;
}
+ to_combined_presentation = data[pos];
+ got_to_combined_presentation = 1;
+ break;
+/* Redirecting-to party id subaddress */
+ case AST_REDIRECTING_TO_SUBADDRESS:
+ ast_free(redirecting->to.subaddress.str);
redirecting->to.subaddress.str = ast_malloc(ie_len + 1);
if (redirecting->to.subaddress.str) {
memcpy(redirecting->to.subaddress.str, data + pos, ie_len);
break;
case AST_REDIRECTING_TO_SUBADDRESS_TYPE:
if (ie_len != 1) {
- ast_log(LOG_WARNING, "Invalid redirecting to type of subaddress (%u)\n",
+ ast_log(LOG_WARNING, "Invalid redirecting-to type of subaddress (%u)\n",
(unsigned) ie_len);
break;
}
case AST_REDIRECTING_TO_SUBADDRESS_ODD_EVEN:
if (ie_len != 1) {
ast_log(LOG_WARNING,
- "Invalid redirecting to subaddress odd-even indicator (%u)\n",
+ "Invalid redirecting-to subaddress odd-even indicator (%u)\n",
(unsigned) ie_len);
break;
}
break;
case AST_REDIRECTING_TO_SUBADDRESS_VALID:
if (ie_len != 1) {
- ast_log(LOG_WARNING, "Invalid redirecting to subaddress valid (%u)\n",
+ ast_log(LOG_WARNING, "Invalid redirecting-to subaddress valid (%u)\n",
(unsigned) ie_len);
break;
}
redirecting->to.subaddress.valid = data[pos];
break;
+/* Redirecting-to party id tag */
+ case AST_REDIRECTING_TO_TAG:
+ ast_free(redirecting->to.tag);
+ redirecting->to.tag = ast_malloc(ie_len + 1);
+ if (redirecting->to.tag) {
+ memcpy(redirecting->to.tag, data + pos, ie_len);
+ redirecting->to.tag[ie_len] = 0;
+ }
+ break;
+/* Redirecting reason */
case AST_REDIRECTING_REASON:
if (ie_len != sizeof(value)) {
- ast_log(LOG_WARNING, "Invalid redirecting reason (%u)\n", (unsigned) ie_len);
+ ast_log(LOG_WARNING, "Invalid redirecting reason (%u)\n",
+ (unsigned) ie_len);
break;
}
memcpy(&value, data + pos, sizeof(value));
redirecting->reason = ntohl(value);
break;
+/* Redirecting count */
case AST_REDIRECTING_COUNT:
if (ie_len != sizeof(value)) {
- ast_log(LOG_WARNING, "Invalid redirecting count (%u)\n", (unsigned) ie_len);
+ ast_log(LOG_WARNING, "Invalid redirecting count (%u)\n",
+ (unsigned) ie_len);
break;
}
memcpy(&value, data + pos, sizeof(value));
redirecting->count = ntohl(value);
break;
+/* Redirecting unknown element */
default:
- ast_log(LOG_DEBUG, "Unknown redirecting element: %u (%u)\n", (unsigned) ie_id, (unsigned) ie_len);
+ ast_log(LOG_DEBUG, "Unknown redirecting element: %u (%u)\n",
+ (unsigned) ie_id, (unsigned) ie_len);
break;
}
}
+ switch (frame_version) {
+ case 1:
+ /*
+ * The other end is an earlier version that we need to adjust
+ * for compatibility.
+ */
+ redirecting->from.name.valid = 1;
+ redirecting->from.name.char_set = AST_PARTY_CHAR_SET_ISO8859_1;
+ redirecting->from.number.valid = 1;
+ if (got_from_combined_presentation) {
+ redirecting->from.name.presentation = from_combined_presentation;
+ redirecting->from.number.presentation = from_combined_presentation;
+ }
+
+ redirecting->to.name.valid = 1;
+ redirecting->to.name.char_set = AST_PARTY_CHAR_SET_ISO8859_1;
+ redirecting->to.number.valid = 1;
+ if (got_to_combined_presentation) {
+ redirecting->to.name.presentation = to_combined_presentation;
+ redirecting->to.number.presentation = to_combined_presentation;
+ }
+ break;
+ case 2:
+ /* The other end is at the same level as we are. */
+ break;
+ default:
+ /*
+ * The other end is newer than we are.
+ * We need to assume that they are compatible with us.
+ */
+ ast_log(LOG_DEBUG, "Redirecting frame has newer version: %u\n",
+ (unsigned) frame_version);
+ break;
+ }
+
return 0;
}
-void ast_channel_update_redirecting(struct ast_channel *chan, const struct ast_party_redirecting *redirecting)
+void ast_channel_update_redirecting(struct ast_channel *chan, const struct ast_party_redirecting *redirecting, const struct ast_set_party_redirecting *update)
{
unsigned char data[1024]; /* This should be large enough */
size_t datalen;
- datalen = ast_redirecting_build_data(data, sizeof(data), redirecting);
+ datalen = ast_redirecting_build_data(data, sizeof(data), redirecting, update);
if (datalen == (size_t) -1) {
return;
}
ast_indicate_data(chan, AST_CONTROL_REDIRECTING, data, datalen);
}
-void ast_channel_queue_redirecting_update(struct ast_channel *chan, const struct ast_party_redirecting *redirecting)
+void ast_channel_queue_redirecting_update(struct ast_channel *chan, const struct ast_party_redirecting *redirecting, const struct ast_set_party_redirecting *update)
{
unsigned char data[1024]; /* This should be large enough */
size_t datalen;
- datalen = ast_redirecting_build_data(data, sizeof(data), redirecting);
+ datalen = ast_redirecting_build_data(data, sizeof(data), redirecting, update);
if (datalen == (size_t) -1) {
return;
}
}
if (!(retval = ast_app_run_macro(autoservice_chan, macro_chan, macro, macro_args))) {
- ast_channel_update_connected_line(macro_chan, ¯o_chan->connected);
+ ast_channel_update_connected_line(macro_chan, ¯o_chan->connected, NULL);
}
return retval;
retval = ast_app_run_macro(autoservice_chan, macro_chan, macro, macro_args);
if (!retval) {
- ast_channel_update_redirecting(macro_chan, ¯o_chan->redirecting);
+ ast_channel_update_redirecting(macro_chan, ¯o_chan->redirecting, NULL);
}
return retval;
ast_cli(a->fd, CONCISE_FORMAT_STRING, c->name, c->context, c->exten, c->priority, ast_state2str(c->_state),
c->appl ? c->appl : "(None)",
S_OR(c->data, ""), /* XXX different from verbose ? */
- S_OR(c->cid.cid_num, ""),
+ S_COR(c->caller.id.number.valid, c->caller.id.number.str, ""),
S_OR(c->accountcode, ""),
S_OR(c->peeraccount, ""),
c->amaflags,
ast_cli(a->fd, VERBOSE_FORMAT_STRING, c->name, c->context, c->exten, c->priority, ast_state2str(c->_state),
c->appl ? c->appl : "(None)",
c->data ? S_OR(c->data, "(Empty)" ): "(None)",
- S_OR(c->cid.cid_num, ""),
+ S_COR(c->caller.id.number.valid, c->caller.id.number.str, ""),
durbuf,
S_OR(c->accountcode, ""),
S_OR(c->peeraccount, ""),
" Data: %s\n"
" Blocking in: %s\n",
c->name, c->tech->type, c->uniqueid, c->linkedid,
- S_OR(c->cid.cid_num, "(N/A)"),
- S_OR(c->cid.cid_name, "(N/A)"),
- S_OR(c->cid.cid_dnid, "(N/A)"),
+ S_COR(c->caller.id.number.valid, c->caller.id.number.str, "(N/A)"),
+ S_COR(c->caller.id.name.valid, c->caller.id.name.str, "(N/A)"),
+ S_OR(c->dialed.number.str, "(N/A)"),
c->language,
ast_state2str(c->_state), c->_state, c->rings,
ast_getformatname_multiple(nf, sizeof(nf), c->nativeformats),
/* Copy over callerid information */
ast_party_redirecting_copy(&channel->owner->redirecting, &chan->redirecting);
- channel->owner->cid.cid_tns = chan->cid.cid_tns;
+ channel->owner->dialed.transit_network_select = chan->dialed.transit_network_select;
- ast_connected_line_copy_from_caller(&channel->owner->connected, &chan->cid);
+ ast_connected_line_copy_from_caller(&channel->owner->connected, &chan->caller);
ast_string_field_set(channel->owner, language, chan->language);
ast_string_field_set(channel->owner, accountcode, chan->accountcode);
"Uniqueid: %s\r\n",
pu->parkingexten, pu->chan->name, pu->parkinglot->name, event_from ? event_from : "",
(long)pu->start.tv_sec + (long)(pu->parkingtime/1000) - (long)time(NULL),
- S_OR(pu->chan->cid.cid_num, "<unknown>"),
- S_OR(pu->chan->cid.cid_name, "<unknown>"),
+ S_COR(pu->chan->caller.id.number.valid, pu->chan->caller.id.number.str, "<unknown>"),
+ S_COR(pu->chan->caller.id.name.valid, pu->chan->caller.id.name.str, "<unknown>"),
pu->chan->uniqueid
);
snprintf(touch_filename, len, "%s-%ld-%s", S_OR(touch_monitor_prefix, "auto"), (long)time(NULL), touch_monitor);
snprintf(args, len, "%s,%s,m", S_OR(touch_format, "wav"), touch_filename);
} else {
- caller_chan_id = ast_strdupa(S_OR(caller_chan->cid.cid_num, caller_chan->name));
- callee_chan_id = ast_strdupa(S_OR(callee_chan->cid.cid_num, callee_chan->name));
+ caller_chan_id = ast_strdupa(S_COR(caller_chan->caller.id.number.valid,
+ caller_chan->caller.id.number.str, caller_chan->name));
+ callee_chan_id = ast_strdupa(S_COR(callee_chan->caller.id.number.valid,
+ callee_chan->caller.id.number.str, callee_chan->name));
len = strlen(caller_chan_id) + strlen(callee_chan_id) + 50;
args = alloca(len);
touch_filename = alloca(len);
snprintf(touch_filename, len, "auto-%ld-%s", (long)time(NULL), touch_monitor);
snprintf(args, len, "%s.%s,b", touch_filename, (touch_format) ? touch_format : "wav");
} else {
- caller_chan_id = ast_strdupa(S_OR(caller_chan->cid.cid_num, caller_chan->name));
- callee_chan_id = ast_strdupa(S_OR(callee_chan->cid.cid_num, callee_chan->name));
+ caller_chan_id = ast_strdupa(S_COR(caller_chan->caller.id.number.valid,
+ caller_chan->caller.id.number.str, caller_chan->name));
+ callee_chan_id = ast_strdupa(S_COR(callee_chan->caller.id.number.valid,
+ callee_chan->caller.id.number.str, callee_chan->name));
len = strlen(caller_chan_id) + strlen(callee_chan_id) + 50;
args = alloca(len);
touch_filename = alloca(len);
ast_log(LOG_WARNING, "Unable to park call %s, parkstatus = %d\n", transferee->name, parkstatus);
}
/*! \todo XXX Maybe we should have another message here instead of invalid extension XXX */
- } else if (ast_exists_extension(transferee, transferer_real_context, xferto, 1, transferer->cid.cid_num)) {
+ } else if (ast_exists_extension(transferee, transferer_real_context, xferto, 1,
+ S_COR(transferer->caller.id.number.valid, transferer->caller.id.number.str, NULL))) {
ast_cel_report_event(transferer, AST_CEL_BLINDTRANSFER, NULL, xferto, transferee);
pbx_builtin_setvar_helper(transferer, "BLINDTRANSFER", transferee->name);
pbx_builtin_setvar_helper(transferee, "BLINDTRANSFER", transferer->name);
ast_set_flag(transferee, AST_FLAG_BRIDGE_HANGUP_DONT); /* don't let the after-bridge code run the h-exten */
ast_log(LOG_DEBUG,"ABOUT TO AST_ASYNC_GOTO, have a pbx... set HANGUP_DONT on chan=%s\n", transferee->name);
if (ast_channel_connected_line_macro(transferee, transferer, &transferer->connected, 1, 0)) {
- ast_channel_update_connected_line(transferee, &transferer->connected);
+ ast_channel_update_connected_line(transferee, &transferer->connected, NULL);
}
set_c_e_p(transferee, transferer_real_context, xferto, 0);
}
}
/* valid extension, res == 1 */
- if (!ast_exists_extension(transferer, transferer_real_context, xferto, 1, transferer->cid.cid_num)) {
+ if (!ast_exists_extension(transferer, transferer_real_context, xferto, 1,
+ S_COR(transferer->caller.id.number.valid, transferer->caller.id.number.str, NULL))) {
ast_log(LOG_WARNING, "Extension %s does not exist in context %s\n",xferto,transferer_real_context);
finishup(transferee);
if (ast_stream_and_wait(transferer, "beeperr", ""))
}
}
- newchan = feature_request_and_dial(transferer, transferee, "Local", ast_best_codec(transferer->nativeformats),
- xferto, atxfernoanswertimeout, &outstate, transferer->cid.cid_num, transferer->cid.cid_name, 1, transferer->language);
+ newchan = feature_request_and_dial(transferer, transferee, "Local",
+ ast_best_codec(transferer->nativeformats),
+ xferto, atxfernoanswertimeout, &outstate,
+ transferer->caller.id.number.valid ? transferer->caller.id.number.str : NULL,
+ transferer->caller.id.name.valid ? transferer->caller.id.name.str : NULL,
+ 1, transferer->language);
ast_party_connected_line_init(&connected_line);
if (!ast_check_hangup(transferer)) {
*/
connected_line.source = AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER;
if (ast_channel_connected_line_macro(newchan, xferchan, &connected_line, 1, 0)) {
- ast_channel_update_connected_line(xferchan, &connected_line);
+ ast_channel_update_connected_line(xferchan, &connected_line, NULL);
}
ast_channel_lock(xferchan);
- ast_connected_line_copy_from_caller(&connected_line, &xferchan->cid);
+ ast_connected_line_copy_from_caller(&connected_line, &xferchan->caller);
ast_channel_unlock(xferchan);
connected_line.source = AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER;
if (ast_channel_connected_line_macro(xferchan, newchan, &connected_line, 0, 0)) {
- ast_channel_update_connected_line(newchan, &connected_line);
+ ast_channel_update_connected_line(newchan, &connected_line, NULL);
}
ast_party_connected_line_free(&connected_line);
}
ast_log(LOG_NOTICE, "We're trying to call %s/%s\n", transferer_tech, transferer_name);
- newchan = feature_request_and_dial(transferee, NULL, transferer_tech, ast_best_codec(transferee->nativeformats),
- transferer_name, atxfernoanswertimeout, &outstate, transferee->cid.cid_num, transferee->cid.cid_name, 0, transferer->language);
+ newchan = feature_request_and_dial(transferee, NULL, transferer_tech,
+ ast_best_codec(transferee->nativeformats),
+ transferer_name, atxfernoanswertimeout, &outstate,
+ transferee->caller.id.number.valid ? transferee->caller.id.number.str : NULL,
+ transferee->caller.id.name.valid ? transferee->caller.id.name.str : NULL,
+ 0, transferer->language);
while (!newchan && !atxferdropcall && tries < atxfercallbackretries) {
/* Trying to transfer again */
ast_autoservice_start(transferee);
ast_indicate(transferee, AST_CONTROL_HOLD);
- newchan = feature_request_and_dial(transferer, transferee, "Local", ast_best_codec(transferer->nativeformats),
- xferto, atxfernoanswertimeout, &outstate, transferer->cid.cid_num, transferer->cid.cid_name, 1, transferer->language);
+ newchan = feature_request_and_dial(transferer, transferee, "Local",
+ ast_best_codec(transferer->nativeformats),
+ xferto, atxfernoanswertimeout, &outstate,
+ transferer->caller.id.number.valid ? transferer->caller.id.number.str : NULL,
+ transferer->caller.id.name.valid ? transferer->caller.id.name.str : NULL,
+ 1, transferer->language);
if (ast_autoservice_stop(transferee) < 0) {
if (newchan)
ast_hangup(newchan);
ast_debug(1, "Sleeping for %d ms before callback.\n", atxferloopdelay);
ast_safe_sleep(transferee, atxferloopdelay);
ast_debug(1, "Trying to callback...\n");
- newchan = feature_request_and_dial(transferee, NULL, transferer_tech, ast_best_codec(transferee->nativeformats),
- transferer_name, atxfernoanswertimeout, &outstate, transferee->cid.cid_num, transferee->cid.cid_name, 0, transferer->language);
+ newchan = feature_request_and_dial(transferee, NULL, transferer_tech,
+ ast_best_codec(transferee->nativeformats),
+ transferer_name, atxfernoanswertimeout, &outstate,
+ transferee->caller.id.number.valid ? transferee->caller.id.number.str : NULL,
+ transferee->caller.id.name.valid ? transferee->caller.id.name.str : NULL,
+ 0, transferer->language);
}
tries++;
}
}
ast_channel_lock(newchan);
- ast_connected_line_copy_from_caller(&connected_line, &newchan->cid);
+ ast_connected_line_copy_from_caller(&connected_line, &newchan->caller);
ast_channel_unlock(newchan);
connected_line.source = AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER;
if (ast_channel_connected_line_macro(newchan, xferchan, &connected_line, 1, 0)) {
- ast_channel_update_connected_line(xferchan, &connected_line);
+ ast_channel_update_connected_line(xferchan, &connected_line, NULL);
}
ast_channel_lock(xferchan);
- ast_connected_line_copy_from_caller(&connected_line, &xferchan->cid);
+ ast_connected_line_copy_from_caller(&connected_line, &xferchan->caller);
ast_channel_unlock(xferchan);
connected_line.source = AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER;
if (ast_channel_connected_line_macro(xferchan, newchan, &connected_line, 0, 0)) {
- ast_channel_update_connected_line(newchan, &connected_line);
+ ast_channel_update_connected_line(newchan, &connected_line, NULL);
}
ast_party_connected_line_free(&connected_line);
pbx_builtin_setvar_helper(chan, "TRANSFERERNAME", caller->name);
ast_channel_lock(chan);
- ast_connected_line_copy_from_caller(&chan->connected, &caller->cid);
+ ast_connected_line_copy_from_caller(&chan->connected, &caller->caller);
ast_channel_unlock(chan);
if (ast_call(chan, data, timeout)) {
* if it were, then chan belongs to a different thread now, and might have been hung up long
* ago.
*/
- if (!ast_test_flag(&(config->features_caller),AST_FEATURE_NO_H_EXTEN) &&
- ast_exists_extension(chan, chan->context, "h", 1, chan->cid.cid_num)) {
+ if (!ast_test_flag(&(config->features_caller),AST_FEATURE_NO_H_EXTEN)
+ && ast_exists_extension(chan, chan->context, "h", 1,
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) {
struct ast_cdr *swapper = NULL;
char savelastapp[AST_MAX_EXTENSION];
char savelastdata[AST_MAX_EXTENSION];
ast_copy_string(chan->exten, "h", sizeof(chan->exten));
chan->priority = 1;
ast_channel_unlock(chan);
- while ((spawn_error = ast_spawn_extension(chan, chan->context, chan->exten, chan->priority, chan->cid.cid_num, &found, 1)) == 0) {
+ while ((spawn_error = ast_spawn_extension(chan, chan->context, chan->exten,
+ chan->priority,
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL),
+ &found, 1)) == 0) {
chan->priority++;
}
- if (spawn_error && (!ast_exists_extension(chan, chan->context, chan->exten, chan->priority, chan->cid.cid_num) || ast_check_hangup(chan))) {
+ if (spawn_error
+ && (!ast_exists_extension(chan, chan->context, chan->exten, chan->priority,
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))
+ || ast_check_hangup(chan))) {
/* if the extension doesn't exist or a hangup occurred, this isn't really a spawn error */
spawn_error = 0;
}
pu->parkingexten,
pu->chan->name,
pu->parkinglot->name,
- S_OR(pu->chan->cid.cid_num, "<unknown>"),
- S_OR(pu->chan->cid.cid_name, "<unknown>"),
+ S_COR(pu->chan->caller.id.number.valid, pu->chan->caller.id.number.str, "<unknown>"),
+ S_COR(pu->chan->caller.id.name.valid, pu->chan->caller.id.name.str, "<unknown>"),
pu->chan->uniqueid
);
}
"CallerIDNum: %s\r\n"
"CallerIDName: %s\r\n",
pu->parkingexten, pu->chan->name, chan->name,
- S_OR(pu->chan->cid.cid_num, "<unknown>"),
- S_OR(pu->chan->cid.cid_name, "<unknown>")
+ S_COR(pu->chan->caller.id.number.valid, pu->chan->caller.id.number.str, "<unknown>"),
+ S_COR(pu->chan->caller.id.name.valid, pu->chan->caller.id.name.str, "<unknown>")
);
ast_free(pu);
"\r\n",
cur->parkingnum, cur->chan->name, cur->peername,
(long) cur->start.tv_sec + (long) (cur->parkingtime / 1000) - (long) time(NULL),
- S_OR(cur->chan->cid.cid_num, ""), /* XXX in other places it is <unknown> */
- S_OR(cur->chan->cid.cid_name, ""),
+ S_COR(cur->chan->caller.id.number.valid, cur->chan->caller.id.number.str, ""), /* XXX in other places it is <unknown> */
+ S_COR(cur->chan->caller.id.name.valid, cur->chan->caller.id.name.str, ""),
idText);
}
AST_LIST_UNLOCK(&curlot->parkings);
connected_caller = cur->connected;
connected_caller.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
if (ast_channel_connected_line_macro(NULL, chan, &connected_caller, 0, 0)) {
- ast_channel_update_connected_line(chan, &connected_caller);
+ ast_channel_update_connected_line(chan, &connected_caller, NULL);
}
- ast_party_connected_line_collect_caller(&connected_caller, &chan->cid);
+ ast_party_connected_line_collect_caller(&connected_caller, &chan->caller);
connected_caller.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
- ast_channel_queue_connected_line_update(chan, &connected_caller);
+ ast_channel_queue_connected_line_update(chan, &connected_caller, NULL);
ast_channel_unlock(cur);
ast_channel_unlock(chan);
case AST_FRAME_DTMF_END:
if (context) {
const char exten[2] = { fr->subclass.integer, '\0' };
- if (ast_exists_extension(c, context, exten, 1, c->cid.cid_num)) {
+ if (ast_exists_extension(c, context, exten, 1,
+ S_COR(c->caller.id.number.valid, c->caller.id.number.str, NULL))) {
res = fr->subclass.integer;
ast_frfree(fr);
ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
"%s"
"\r\n",
c->name,
- S_OR(c->cid.cid_num, ""),
- S_OR(c->cid.cid_name, ""),
+ S_COR(c->caller.id.number.valid, c->caller.id.number.str, ""),
+ S_COR(c->caller.id.name.valid, c->caller.id.name.str, ""),
c->accountcode,
c->_state,
ast_state2str(c->_state), c->context,
"%s"
"\r\n",
c->name,
- S_OR(c->cid.cid_num, "<unknown>"),
- S_OR(c->cid.cid_name, "<unknown>"),
+ S_COR(c->caller.id.number.valid, c->caller.id.number.str, "<unknown>"),
+ S_COR(c->caller.id.name.valid, c->caller.id.name.str, "<unknown>"),
c->accountcode,
ast_state2str(c->_state), bridge, c->uniqueid,
ast_str_buffer(str), idText);
"BridgedUniqueID: %s\r\n"
"\r\n", idText, c->name, c->uniqueid, c->context, c->exten, c->priority, c->_state,
ast_state2str(c->_state), c->appl ? c->appl : "", c->data ? S_OR(c->data, "") : "",
- S_OR(c->cid.cid_num, ""), durbuf, S_OR(c->accountcode, ""), bc ? bc->name : "", bc ? bc->uniqueid : "");
+ S_COR(c->caller.id.number.valid, c->caller.id.number.str, ""),
+ durbuf, S_OR(c->accountcode, ""), bc ? bc->name : "", bc ? bc->uniqueid : "");
ast_channel_unlock(c);
if (!strncmp(var, "CALL", 4)) {
if (!strncmp(var + 4, "ING", 3)) {
if (!strcmp(var + 7, "PRES")) { /* CALLINGPRES */
- ast_str_set(str, maxlen, "%d", c->cid.cid_pres);
+ ast_str_set(str, maxlen, "%d",
+ ast_party_id_presentation(&c->caller.id));
s = ast_str_buffer(*str);
} else if (!strcmp(var + 7, "ANI2")) { /* CALLINGANI2 */
- ast_str_set(str, maxlen, "%d", c->cid.cid_ani2);
+ ast_str_set(str, maxlen, "%d", c->caller.ani2);
s = ast_str_buffer(*str);
} else if (!strcmp(var + 7, "TON")) { /* CALLINGTON */
- ast_str_set(str, maxlen, "%d", c->cid.cid_ton);
+ ast_str_set(str, maxlen, "%d", c->caller.id.number.plan);
s = ast_str_buffer(*str);
} else if (!strcmp(var + 7, "TNS")) { /* CALLINGTNS */
- ast_str_set(str, maxlen, "%d", c->cid.cid_tns);
+ ast_str_set(str, maxlen, "%d", c->dialed.transit_network_select);
s = ast_str_buffer(*str);
}
}
int digit;
buf[pos] = '\0'; /* make sure it is properly terminated */
- while (ast_matchmore_extension(c, c->context, buf, 1, c->cid.cid_num)) {
+ while (ast_matchmore_extension(c, c->context, buf, 1,
+ S_COR(c->caller.id.number.valid, c->caller.id.number.str, NULL))) {
/* As long as we're willing to wait, and as long as it's not defined,
keep reading digits until we can't possibly get a right answer anymore. */
digit = ast_waitfordigit(c, waittime);
ast_set_flag(c, AST_FLAG_IN_AUTOLOOP);
/* Start by trying whatever the channel is set to */
- if (!ast_exists_extension(c, c->context, c->exten, c->priority, c->cid.cid_num)) {
+ if (!ast_exists_extension(c, c->context, c->exten, c->priority,
+ S_COR(c->caller.id.number.valid, c->caller.id.number.str, NULL))) {
/* If not successful fall back to 's' */
ast_verb(2, "Starting %s at %s,%s,%d failed so falling back to exten 's'\n", c->name, c->context, c->exten, c->priority);
/* XXX the original code used the existing priority in the call to
* I believe the correct thing is to set it to 1 immediately.
*/
set_ext_pri(c, "s", 1);
- if (!ast_exists_extension(c, c->context, c->exten, c->priority, c->cid.cid_num)) {
+ if (!ast_exists_extension(c, c->context, c->exten, c->priority,
+ S_COR(c->caller.id.number.valid, c->caller.id.number.str, NULL))) {
/* JK02: And finally back to default if everything else failed */
ast_verb(2, "Starting %s at %s,%s,%d still failed so falling back to context 'default'\n", c->name, c->context, c->exten, c->priority);
ast_copy_string(c->context, "default", sizeof(c->context));
int timeout = 0;
/* loop on priorities in this context/exten */
- while ( !(res = ast_spawn_extension(c, c->context, c->exten, c->priority, c->cid.cid_num, &found,1))) {
- if (c->_softhangup == AST_SOFTHANGUP_TIMEOUT && ast_exists_extension(c, c->context, "T", 1, c->cid.cid_num)) {
+ while (!(res = ast_spawn_extension(c, c->context, c->exten, c->priority,
+ S_COR(c->caller.id.number.valid, c->caller.id.number.str, NULL),
+ &found, 1))) {
+ if (c->_softhangup == AST_SOFTHANGUP_TIMEOUT
+ && ast_exists_extension(c, c->context, "T", 1,
+ S_COR(c->caller.id.number.valid, c->caller.id.number.str, NULL))) {
set_ext_pri(c, "T", 0); /* 0 will become 1 with the c->priority++; at the end */
/* If the AbsoluteTimeout is not reset to 0, we'll get an infinite loop */
memset(&c->whentohangup, 0, sizeof(c->whentohangup));
c->_softhangup &= ~AST_SOFTHANGUP_TIMEOUT;
- } else if (c->_softhangup == AST_SOFTHANGUP_TIMEOUT && ast_exists_extension(c, c->context, "e", 1, c->cid.cid_num)) {
+ } else if (c->_softhangup == AST_SOFTHANGUP_TIMEOUT
+ && ast_exists_extension(c, c->context, "e", 1,
+ S_COR(c->caller.id.number.valid, c->caller.id.number.str, NULL))) {
pbx_builtin_raise_exception(c, "ABSOLUTETIMEOUT");
/* If the AbsoluteTimeout is not reset to 0, we'll get an infinite loop */
memset(&c->whentohangup, 0, sizeof(c->whentohangup));
ast_verb(2, "Spawn extension (%s, %s, %d) exited INCOMPLETE on '%s'\n", c->context, c->exten, c->priority, c->name);
/* Don't cycle on incomplete - this will happen if the only extension that matches is our "incomplete" extension */
- if (!ast_matchmore_extension(c, c->context, c->exten, 1, c->cid.cid_num)) {
+ if (!ast_matchmore_extension(c, c->context, c->exten, 1,
+ S_COR(c->caller.id.number.valid, c->caller.id.number.str, NULL))) {
invalid = 1;
} else {
ast_copy_string(dst_exten, c->exten, sizeof(dst_exten));
ast_debug(1, "Spawn extension (%s,%s,%d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name);
ast_verb(2, "Spawn extension (%s, %s, %d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name);
- if ((res == AST_PBX_ERROR) && ast_exists_extension(c, c->context, "e", 1, c->cid.cid_num)) {
+ if ((res == AST_PBX_ERROR)
+ && ast_exists_extension(c, c->context, "e", 1,
+ S_COR(c->caller.id.number.valid, c->caller.id.number.str, NULL))) {
/* if we are already on the 'e' exten, don't jump to it again */
if (!strcmp(c->exten, "e")) {
ast_verb(2, "Spawn extension (%s, %s, %d) exited ERROR while already on 'e' exten on '%s'\n", c->context, c->exten, c->priority, c->name);
if (c->_softhangup == AST_SOFTHANGUP_ASYNCGOTO) {
c->_softhangup = 0;
continue;
- } else if (c->_softhangup == AST_SOFTHANGUP_TIMEOUT && ast_exists_extension(c, c->context, "T", 1, c->cid.cid_num)) {
+ } else if (c->_softhangup == AST_SOFTHANGUP_TIMEOUT
+ && ast_exists_extension(c, c->context, "T", 1,
+ S_COR(c->caller.id.number.valid, c->caller.id.number.str, NULL))) {
set_ext_pri(c, "T", 1);
/* If the AbsoluteTimeout is not reset to 0, we'll get an infinite loop */
memset(&c->whentohangup, 0, sizeof(c->whentohangup));
* hangup. We have options, here. We can either catch the failure
* and continue, or we can drop out entirely. */
- if (invalid || !ast_exists_extension(c, c->context, c->exten, 1, c->cid.cid_num)) {
+ if (invalid
+ || !ast_exists_extension(c, c->context, c->exten, 1,
+ S_COR(c->caller.id.number.valid, c->caller.id.number.str, NULL))) {
/*!\note
* If there is no match at priority 1, it is not a valid extension anymore.
* Try to continue at "i" (for invalid) or "e" (for exception) or exit if
* neither exist.
*/
- if (ast_exists_extension(c, c->context, "i", 1, c->cid.cid_num)) {
+ if (ast_exists_extension(c, c->context, "i", 1,
+ S_COR(c->caller.id.number.valid, c->caller.id.number.str, NULL))) {
ast_verb(3, "Sent into invalid extension '%s' in context '%s' on %s\n", c->exten, c->context, c->name);
pbx_builtin_setvar_helper(c, "INVALID_EXTEN", c->exten);
set_ext_pri(c, "i", 1);
- } else if (ast_exists_extension(c, c->context, "e", 1, c->cid.cid_num)) {
+ } else if (ast_exists_extension(c, c->context, "e", 1,
+ S_COR(c->caller.id.number.valid, c->caller.id.number.str, NULL))) {
pbx_builtin_raise_exception(c, "INVALID");
} else {
ast_log(LOG_WARNING, "Channel '%s' sent into invalid extension '%s' in context '%s', but no invalid handler\n",
break;
if (res == AST_PBX_INCOMPLETE && ast_strlen_zero(&dst_exten[pos]))
timeout = 1;
- if (!timeout && ast_exists_extension(c, c->context, dst_exten, 1, c->cid.cid_num)) /* Prepare the next cycle */
+ if (!timeout
+ && ast_exists_extension(c, c->context, dst_exten, 1,
+ S_COR(c->caller.id.number.valid, c->caller.id.number.str, NULL))) { /* Prepare the next cycle */
set_ext_pri(c, dst_exten, 1);
- else {
+ } else {
/* No such extension */
if (!timeout && !ast_strlen_zero(dst_exten)) {
/* An invalid extension */
- if (ast_exists_extension(c, c->context, "i", 1, c->cid.cid_num)) {
+ if (ast_exists_extension(c, c->context, "i", 1,
+ S_COR(c->caller.id.number.valid, c->caller.id.number.str, NULL))) {
ast_verb(3, "Invalid extension '%s' in context '%s' on %s\n", dst_exten, c->context, c->name);
pbx_builtin_setvar_helper(c, "INVALID_EXTEN", dst_exten);
set_ext_pri(c, "i", 1);
- } else if (ast_exists_extension(c, c->context, "e", 1, c->cid.cid_num)) {
+ } else if (ast_exists_extension(c, c->context, "e", 1,
+ S_COR(c->caller.id.number.valid, c->caller.id.number.str, NULL))) {
pbx_builtin_raise_exception(c, "INVALID");
} else {
ast_log(LOG_WARNING, "Invalid extension '%s', but no rule 'i' in context '%s'\n", dst_exten, c->context);
}
} else {
/* A simple timeout */
- if (ast_exists_extension(c, c->context, "t", 1, c->cid.cid_num)) {
+ if (ast_exists_extension(c, c->context, "t", 1,
+ S_COR(c->caller.id.number.valid, c->caller.id.number.str, NULL))) {
ast_verb(3, "Timeout on %s\n", c->name);
set_ext_pri(c, "t", 1);
- } else if (ast_exists_extension(c, c->context, "e", 1, c->cid.cid_num)) {
+ } else if (ast_exists_extension(c, c->context, "e", 1,
+ S_COR(c->caller.id.number.valid, c->caller.id.number.str, NULL))) {
pbx_builtin_raise_exception(c, "RESPONSETIMEOUT");
} else {
ast_log(LOG_WARNING, "Timeout, but no rule 't' in context '%s'\n", c->context);
ast_softhangup(c, AST_SOFTHANGUP_APPUNLOAD);
}
- if ((!args || !args->no_hangup_chan) &&
- !ast_test_flag(c, AST_FLAG_BRIDGE_HANGUP_RUN) &&
- ast_exists_extension(c, c->context, "h", 1, c->cid.cid_num)) {
+ if ((!args || !args->no_hangup_chan)
+ && !ast_test_flag(c, AST_FLAG_BRIDGE_HANGUP_RUN)
+ && ast_exists_extension(c, c->context, "h", 1,
+ S_COR(c->caller.id.number.valid, c->caller.id.number.str, NULL))) {
set_ext_pri(c, "h", 1);
if (c->cdr && ast_opt_end_cdr_before_h_exten) {
ast_cdr_end(c->cdr);
}
- while ((res = ast_spawn_extension(c, c->context, c->exten, c->priority, c->cid.cid_num, &found, 1)) == 0) {
+ while ((res = ast_spawn_extension(c, c->context, c->exten, c->priority,
+ S_COR(c->caller.id.number.valid, c->caller.id.number.str, NULL),
+ &found, 1)) == 0) {
c->priority++;
}
if (found && res) {
res = ast_waitfordigit(chan, ms);
if (!res) {
- if (ast_exists_extension(chan, chan->context, chan->exten, chan->priority + 1, chan->cid.cid_num)) {
+ if (ast_exists_extension(chan, chan->context, chan->exten, chan->priority + 1,
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) {
ast_verb(3, "Timeout on %s, continuing...\n", chan->name);
} else if (chan->_softhangup == AST_SOFTHANGUP_TIMEOUT) {
ast_verb(3, "Call timeout on %s, checking for 'T'\n", chan->name);
res = -1;
- } else if (ast_exists_extension(chan, chan->context, "t", 1, chan->cid.cid_num)) {
+ } else if (ast_exists_extension(chan, chan->context, "t", 1,
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) {
ast_verb(3, "Timeout on %s, going to 't'\n", chan->name);
set_ext_pri(chan, "t", 0); /* 0 will become 1, next time through the loop */
} else {
* users can EXEC Background and reasonably expect that the DTMF code will
* be returned (see #16434).
*/
- if (!ast_test_flag(chan, AST_FLAG_DISABLE_WORKAROUNDS) &&
- (exten[0] = res) &&
- ast_canmatch_extension(chan, args.context, exten, 1, chan->cid.cid_num) &&
- !ast_matchmore_extension(chan, args.context, exten, 1, chan->cid.cid_num)) {
+ if (!ast_test_flag(chan, AST_FLAG_DISABLE_WORKAROUNDS)
+ && (exten[0] = res)
+ && ast_canmatch_extension(chan, args.context, exten, 1,
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))
+ && !ast_matchmore_extension(chan, args.context, exten, 1,
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) {
snprintf(chan->exten, sizeof(chan->exten), "%c", res);
ast_copy_string(chan->context, args.context, sizeof(chan->context));
chan->priority = 0;
exten = chan->exten;
goto_func = (async) ? ast_async_goto : ast_explicit_goto;
- if (ast_exists_extension(chan, context, exten, priority, chan->cid.cid_num))
+ if (ast_exists_extension(chan, context, exten, priority,
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL)))
return goto_func(chan, context, exten, priority);
else {
return AST_PBX_GOTO_FAILED;
pri++;
}
if (sscanf(pri, "%30d", &ipri) != 1) {
- if ((ipri = ast_findlabel_extension(chan, context ? context : chan->context, exten ? exten : chan->exten,
- pri, chan->cid.cid_num)) < 1) {
+ ipri = ast_findlabel_extension(chan, context ? context : chan->context,
+ exten ? exten : chan->exten, pri,
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL));
+ if (ipri < 1) {
ast_log(LOG_WARNING, "Priority '%s' must be a number > 0, or valid label\n", pri);
return -1;
} else
ast_agi_send(fd, chan, "agi_version: %s\n", ast_get_version());
/* ANI/DNIS */
- ast_agi_send(fd, chan, "agi_callerid: %s\n", S_OR(chan->cid.cid_num, "unknown"));
- ast_agi_send(fd, chan, "agi_calleridname: %s\n", S_OR(chan->cid.cid_name, "unknown"));
- ast_agi_send(fd, chan, "agi_callingpres: %d\n", chan->cid.cid_pres);
- ast_agi_send(fd, chan, "agi_callingani2: %d\n", chan->cid.cid_ani2);
- ast_agi_send(fd, chan, "agi_callington: %d\n", chan->cid.cid_ton);
- ast_agi_send(fd, chan, "agi_callingtns: %d\n", chan->cid.cid_tns);
- ast_agi_send(fd, chan, "agi_dnid: %s\n", S_OR(chan->cid.cid_dnid, "unknown"));
- ast_agi_send(fd, chan, "agi_rdnis: %s\n", S_OR(chan->redirecting.from.number, "unknown"));
+ ast_agi_send(fd, chan, "agi_callerid: %s\n",
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, "unknown"));
+ ast_agi_send(fd, chan, "agi_calleridname: %s\n",
+ S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, "unknown"));
+ ast_agi_send(fd, chan, "agi_callingpres: %d\n",
+ ast_party_id_presentation(&chan->caller.id));
+ ast_agi_send(fd, chan, "agi_callingani2: %d\n", chan->caller.ani2);
+ ast_agi_send(fd, chan, "agi_callington: %d\n", chan->caller.id.number.plan);
+ ast_agi_send(fd, chan, "agi_callingtns: %d\n", chan->dialed.transit_network_select);
+ ast_agi_send(fd, chan, "agi_dnid: %s\n", S_OR(chan->dialed.number.str, "unknown"));
+ ast_agi_send(fd, chan, "agi_rdnis: %s\n",
+ S_COR(chan->redirecting.from.number.valid, chan->redirecting.from.number.str, "unknown"));
/* Context information */
ast_agi_send(fd, chan, "agi_context: %s\n", chan->context);
return RESULT_SHOWUSAGE;
if (sscanf(argv[2], "%30d", &pri) != 1) {
- if ((pri = ast_findlabel_extension(chan, chan->context, chan->exten, argv[2], chan->cid.cid_num)) < 1)
+ pri = ast_findlabel_extension(chan, chan->context, chan->exten, argv[2],
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL));
+ if (pri < 1)
return RESULT_SHOWUSAGE;
}
ret = (u_char *)&long_ret;
break;
case ASTCHANCIDDNID:
- if (chan->cid.cid_dnid) {
- strncpy(string_ret, chan->cid.cid_dnid, sizeof(string_ret));
+ if (chan->dialed.number.str) {
+ strncpy(string_ret, chan->dialed.number.str, sizeof(string_ret));
string_ret[sizeof(string_ret) - 1] = '\0';
*var_len = strlen(string_ret);
ret = (u_char *)string_ret;
}
break;
case ASTCHANCIDNUM:
- if (chan->cid.cid_num) {
- strncpy(string_ret, chan->cid.cid_num, sizeof(string_ret));
+ if (chan->caller.id.number.valid && chan->caller.id.number.str) {
+ strncpy(string_ret, chan->caller.id.number.str, sizeof(string_ret));
string_ret[sizeof(string_ret) - 1] = '\0';
*var_len = strlen(string_ret);
ret = (u_char *)string_ret;
}
break;
case ASTCHANCIDNAME:
- if (chan->cid.cid_name) {
- strncpy(string_ret, chan->cid.cid_name, sizeof(string_ret));
+ if (chan->caller.id.name.valid && chan->caller.id.name.str) {
+ strncpy(string_ret, chan->caller.id.name.str, sizeof(string_ret));
string_ret[sizeof(string_ret) - 1] = '\0';
*var_len = strlen(string_ret);
ret = (u_char *)string_ret;
}
break;
case ASTCHANCIDANI:
- if (chan->cid.cid_ani) {
- strncpy(string_ret, chan->cid.cid_ani, sizeof(string_ret));
+ if (chan->caller.ani) {
+ strncpy(string_ret, chan->caller.ani, sizeof(string_ret));
string_ret[sizeof(string_ret) - 1] = '\0';
*var_len = strlen(string_ret);
ret = (u_char *)string_ret;
}
break;
case ASTCHANCIDRDNIS:
- if (chan->redirecting.from.number) {
- strncpy(string_ret, chan->redirecting.from.number, sizeof(string_ret));
+ if (chan->redirecting.from.number.valid && chan->redirecting.from.number.str) {
+ strncpy(string_ret, chan->redirecting.from.number.str, sizeof(string_ret));
string_ret[sizeof(string_ret) - 1] = '\0';
*var_len = strlen(string_ret);
ret = (u_char *)string_ret;
}
break;
case ASTCHANCIDPRES:
- long_ret = chan->cid.cid_pres;
+ long_ret = ast_party_id_presentation(chan->caller.id);
ret = (u_char *)&long_ret;
break;
case ASTCHANCIDANI2:
- long_ret = chan->cid.cid_ani2;
+ long_ret = chan->caller.ani2;
ret = (u_char *)&long_ret;
break;
case ASTCHANCIDTON:
- long_ret = chan->cid.cid_ton;
+ long_ret = chan->caller.id.number.plan;
ret = (u_char *)&long_ret;
break;
case ASTCHANCIDTNS:
- long_ret = chan->cid.cid_tns;
+ long_ret = chan->dialed.transit_network_select;
ret = (u_char *)&long_ret;
break;
case ASTCHANAMAFLAGS:
c = ast_channel_alloc(0, 0, "", "", "", "", "", "", 0, "Test/substitution");
#define TEST(t) if (t == AST_TEST_FAIL) { res = AST_TEST_FAIL; }
- TEST(test_chan_integer(test, c, &c->cid.cid_pres, "${CALLINGPRES}"));
- TEST(test_chan_integer(test, c, &c->cid.cid_ani2, "${CALLINGANI2}"));
- TEST(test_chan_integer(test, c, &c->cid.cid_ton, "${CALLINGTON}"));
- TEST(test_chan_integer(test, c, &c->cid.cid_tns, "${CALLINGTNS}"));
+#if 0
+ /*
+ * We can no longer test the CALLINGPRES value this way because it is now
+ * a calculated value from the name and number presentation information to
+ * get a combined presentation value.
+ */
+ TEST(test_chan_integer(test, c, &c->caller.id.number.presentation, "${CALLINGPRES}"));
+#endif
+ TEST(test_chan_integer(test, c, &c->caller.ani2, "${CALLINGANI2}"));
+ TEST(test_chan_integer(test, c, &c->caller.id.number.plan, "${CALLINGTON}"));
+ TEST(test_chan_integer(test, c, &c->dialed.transit_network_select, "${CALLINGTNS}"));
TEST(test_chan_integer(test, c, &c->hangupcause, "${HANGUPCAUSE}"));
TEST(test_chan_integer(test, c, &c->priority, "${PRIORITY}"));
TEST(test_chan_string(test, c, c->context, sizeof(c->context), "${CONTEXT}"));