Merge "chan_mobile: support handling of caller-id names ("cnam")." into 13

13.23
Jenkins2 7 years ago committed by Gerrit Code Review
commit aa37dad11a

@ -58,6 +58,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/compat.h"
#include "asterisk/lock.h"
#include "asterisk/callerid.h"
#include "asterisk/channel.h"
#include "asterisk/config.h"
#include "asterisk/logger.h"
@ -163,6 +164,12 @@ struct mbl_pvt {
AST_LIST_ENTRY(mbl_pvt) entry;
};
/*! Structure used by hfp_parse_clip to return two items */
struct cidinfo {
char *cnum;
char *cnam;
};
static AST_RWLIST_HEAD_STATIC(devices, mbl_pvt);
static int handle_response_ok(struct mbl_pvt *pvt, char *buf);
@ -208,7 +215,7 @@ static char *mblsendsms_desc =
" Dest - destination\n"
" Message - text of the message\n";
static struct ast_channel *mbl_new(int state, struct mbl_pvt *pvt, char *cid_num,
static struct ast_channel *mbl_new(int state, struct mbl_pvt *pvt, struct cidinfo *cidinfo,
const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor);
static struct ast_channel *mbl_request(const char *type, struct ast_format_cap *cap,
const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, int *cause);
@ -364,7 +371,8 @@ static struct hfp_hf hfp_our_brsf = {
static int hfp_parse_ciev(struct hfp_pvt *hfp, char *buf, int *value);
static char *hfp_parse_clip(struct hfp_pvt *hfp, char *buf);
static struct cidinfo hfp_parse_clip(struct hfp_pvt *hfp, char *buf);
static int parse_next_token(char string[], const int start, const char delim);
static int hfp_parse_cmti(struct hfp_pvt *hfp, char *buf);
static int hfp_parse_cmgr(struct hfp_pvt *hfp, char *buf, char **from_number, char **text);
static int hfp_parse_brsf(struct hfp_pvt *hfp, const char *buf);
@ -837,7 +845,7 @@ e_return:
*/
static struct ast_channel *mbl_new(int state, struct mbl_pvt *pvt, char *cid_num,
static struct ast_channel *mbl_new(int state, struct mbl_pvt *pvt, struct cidinfo *cidinfo,
const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor)
{
struct ast_channel *chn;
@ -853,9 +861,11 @@ static struct ast_channel *mbl_new(int state, struct mbl_pvt *pvt, char *cid_num
ast_smoother_reset(pvt->smoother, DEVICE_FRAME_SIZE);
ast_dsp_digitreset(pvt->dsp);
chn = ast_channel_alloc(1, state, cid_num, pvt->id, 0, 0, pvt->context,
assignedids, requestor, 0,
"Mobile/%s-%04lx", pvt->id, ast_random() & 0xffff);
chn = ast_channel_alloc(1, state,
cidinfo ? cidinfo->cnum : NULL,
cidinfo ? cidinfo->cnam : NULL,
0, 0, pvt->context, assignedids, requestor, 0,
"Mobile/%s-%04lx", pvt->id, ast_random() & 0xffff);
if (!chn) {
goto e_return;
}
@ -2203,45 +2213,103 @@ static int hfp_parse_ciev(struct hfp_pvt *hfp, char *buf, int *value)
* \param hfp an hfp_pvt struct
* \param buf the buffer to parse (null terminated)
* \note buf will be modified when the CID string is parsed
* \return NULL on error (parse error) or a pointer to the caller id
* information in buf
* \return a cidinfo structure pointing to the cnam and cnum
* data in buf. On parse errors, either or both pointers
* will point to null strings
*/
static char *hfp_parse_clip(struct hfp_pvt *hfp, char *buf)
static struct cidinfo hfp_parse_clip(struct hfp_pvt *hfp, char *buf)
{
int i, state;
char *clip = NULL;
size_t s;
int i;
int tokens[6];
char *cnamtmp;
char delim = ' '; /* First token terminates with space */
int invalid = 0; /* Number of invalid chars in cnam */
struct cidinfo cidinfo = { NULL, NULL };
/* parse clip info in the following format:
* +CLIP: "123456789",128,...
*/
state = 0;
s = strlen(buf);
for (i = 0; i < s && state != 3; i++) {
switch (state) {
case 0: /* search for start of the number (") */
if (buf[i] == '"') {
state++;
}
break;
case 1: /* mark the number */
clip = &buf[i];
state++;
/* fall through */
case 2: /* search for the end of the number (") */
if (buf[i] == '"') {
buf[i] = '\0';
state++;
}
break;
ast_debug(3, "[%s] hfp_parse_clip is processing \"%s\"\n", hfp->owner->id, buf);
tokens[0] = 0; /* First token starts in position 0 */
for (i = 1; i < ARRAY_LEN(tokens); i++) {
tokens[i] = parse_next_token(buf, tokens[i - 1], delim);
delim = ','; /* Subsequent tokens terminate with comma */
}
ast_debug(3, "[%s] hfp_parse_clip found tokens: 0=%s, 1=%s, 2=%s, 3=%s, 4=%s, 5=%s\n",
hfp->owner->id, &buf[tokens[0]], &buf[tokens[1]], &buf[tokens[2]],
&buf[tokens[3]], &buf[tokens[4]], &buf[tokens[5]]);
/* Clean up cnum, and make sure it is legitimate since it is untrusted. */
cidinfo.cnum = ast_strip_quoted(&buf[tokens[1]], "\"", "\"");
if (!ast_isphonenumber(cidinfo.cnum)) {
ast_debug(1, "[%s] hfp_parse_clip invalid cidinfo.cnum data \"%s\" - deleting\n",
hfp->owner->id, cidinfo.cnum);
cidinfo.cnum = "";
}
/*
* Some docs say tokens 2 and 3 including the commas are optional.
* If absent, that would move CNAM back to token 3.
*/
cidinfo.cnam = &buf[tokens[5]]; /* Assume it's in token 5 */
if (buf[tokens[5]] == '\0' && buf[tokens[4]] == '\0') {
/* Tokens 4 and 5 are empty. See if token 3 looks like CNAM (starts with ") */
i = tokens[3];
while (buf[i] == ' ') { /* Find the first non-blank */
i++;
}
if (buf[i] == '"') {
/* Starts with quote. Use this for CNAM. */
cidinfo.cnam = &buf[i];
}
}
if (state != 3) {
return NULL;
/* Clean up CNAM. */
cidinfo.cnam = ast_strip_quoted(cidinfo.cnam, "\"", "\"");
for (cnamtmp = cidinfo.cnam; *cnamtmp != '\0'; cnamtmp++) {
if (!strchr("ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789-,abcdefghijklmnopqrstuvwxyz_", *cnamtmp)) {
*cnamtmp = '_'; /* Invalid. Replace with underscore. */
invalid++;
}
}
if (invalid) {
ast_debug(2, "[%s] hfp_parse_clip replaced %d invalid byte(s) in cnam data\n",
hfp->owner->id, invalid);
}
ast_debug(2, "[%s] hfp_parse_clip returns cnum=%s and cnam=%s\n",
hfp->owner->id, cidinfo.cnum, cidinfo.cnam);
return cidinfo;
}
return clip;
/*!
* \brief Terminate current token and return an index to start of the next token.
* \param string the null-terminated string being parsed (will be altered!)
* \param start where the current token starts
* \param delim the token termination delimiter. \0 is also considered a terminator.
* \return index of the next token. May be the same as this token if the string is
* exhausted.
*/
static int parse_next_token(char string[], const int start, const char delim)
{
int index;
int quoting = 0;
for (index = start; string[index] != 0; index++) {
if ((string[index] == delim) && !quoting ) {
/* Found the delimiter, outside of quotes. This is the end of the token. */
string[index] = '\0'; /* Terminate this token. */
index++; /* Point the index to the start of the next token. */
break; /* We're done. */
} else if (string[index] == '"' && !quoting) {
/* Found a beginning quote mark. Remember it. */
quoting = 1;
} else if (string[index] == '"' ) {
/* Found the end quote mark. */
quoting = 0;
}
}
return index;
}
/*!
@ -3578,19 +3646,17 @@ static int handle_response_ciev(struct mbl_pvt *pvt, char *buf)
*/
static int handle_response_clip(struct mbl_pvt *pvt, char *buf)
{
char *clip;
struct msg_queue_entry *msg;
struct ast_channel *chan;
struct cidinfo cidinfo;
if ((msg = msg_queue_head(pvt)) && msg->expected == AT_CLIP) {
msg_queue_free_and_pop(pvt);
pvt->needcallerid = 0;
if (!(clip = hfp_parse_clip(pvt->hfp, buf))) {
ast_debug(1, "[%s] error parsing CLIP: %s\n", pvt->id, buf);
}
cidinfo = hfp_parse_clip(pvt->hfp, buf);
if (!(chan = mbl_new(AST_STATE_RING, pvt, clip, NULL, NULL))) {
if (!(chan = mbl_new(AST_STATE_RING, pvt, &cidinfo, NULL, NULL))) {
ast_log(LOG_ERROR, "[%s] unable to allocate channel for incoming call\n", pvt->id);
hfp_send_chup(pvt->hfp);
msg_queue_push(pvt, AT_OK, AT_CHUP);
@ -3859,7 +3925,7 @@ static void *do_monitor_phone(void *data)
break;
}
ast_debug(1, "[%s] %s\n", pvt->id, buf);
ast_debug(1, "[%s] read %s\n", pvt->id, buf);
switch (at_msg) {
case AT_BRSF:

Loading…
Cancel
Save