Skip to content

Commit f2f397c

Browse files
InterLinked1gtjoseph
authored andcommitted
chan_dahdi: Fix buggy and missing Caller ID parameters
There are several things wrong with analog Caller ID handling that are fixed by this commit: callerid.c's Caller ID generation function contains the logic to use the presentation to properly send the proper Caller ID. However, currently, DAHDI does not pass any presentation information to the Caller ID module, which means that presentation is completely ignored on all calls. This means that lines could be getting Caller ID information they aren't supposed to. Part of the reason this has been obscured is because the simple switch logic for handling the built in *67 and *82 is completely wrong. Rather than modifying the presentation for the call accordingly (which is what it's supposed to do), it simply blanks out the Caller ID or fills it in. This is wrong, so wrong that it makes a mockery of the specification. Additionally, it would leave to the "UNAVAILABLE" disposition being used for Caller ID generation as opposed to the "PRIVATE" disposition that it should have been using. This is now fixed to only update the presentation and not modify the number and name, so that the simple switch *67/*82 work correctly. Next, sig_analog currently only copies over the name and number, nothing else, when it is filling in a duplicated caller id structure. Thus, we also now copy over the presentation information so that is available for the Caller ID spill. Additionally, this meant that "valid" was implicitly 0, and as such presentation would always fail to "Unavailable". The validity is therefore also copied over so it can be used by ast_party_id_presentation. As part of this fix, new API is added so that all the relevant Caller ID information can be passed in to the Caller ID generation functions. Parameters that are also completely missing from the Caller ID spill have also been added, to enhance the compatibility, correctness, and completeness of the Asterisk Caller ID implementation. ASTERISK-29991 #close Change-Id: Icc44a5e09979916f4c18a440f96e10dc1c76ae15
1 parent be6a03f commit f2f397c

File tree

4 files changed

+160
-16
lines changed

4 files changed

+160
-16
lines changed

channels/chan_dahdi.c

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1642,19 +1642,29 @@ static int my_send_callerid(void *pvt, int cwcid, struct ast_party_caller *calle
16421642
}
16431643

16441644
if ((p->cidspill = ast_malloc(MAX_CALLERID_SIZE))) {
1645+
int pres = ast_party_id_presentation(&caller->id);
16451646
if (cwcid == 0) {
1646-
p->cidlen = ast_callerid_generate(p->cidspill,
1647+
p->cidlen = ast_callerid_full_generate(p->cidspill,
16471648
caller->id.name.str,
16481649
caller->id.number.str,
1650+
NULL,
1651+
-1,
1652+
pres,
1653+
0,
1654+
CID_TYPE_MDMF,
16491655
AST_LAW(p));
16501656
} else {
16511657
ast_verb(3, "CPE supports Call Waiting Caller*ID. Sending '%s/%s'\n",
16521658
caller->id.name.str, caller->id.number.str);
16531659
p->callwaitcas = 0;
16541660
p->cidcwexpire = 0;
1655-
p->cidlen = ast_callerid_callwaiting_generate(p->cidspill,
1661+
p->cidlen = ast_callerid_callwaiting_full_generate(p->cidspill,
16561662
caller->id.name.str,
16571663
caller->id.number.str,
1664+
NULL,
1665+
-1,
1666+
pres,
1667+
0,
16581668
AST_LAW(p));
16591669
p->cidlen += READ_SIZE * 4;
16601670
}

channels/sig_analog.c

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1089,6 +1089,10 @@ int analog_call(struct analog_pvt *p, struct ast_channel *ast, const char *rdest
10891089
if (p->use_callerid) {
10901090
p->caller.id.name.str = p->lastcid_name;
10911091
p->caller.id.number.str = p->lastcid_num;
1092+
p->caller.id.name.valid = ast_channel_connected(ast)->id.name.valid;
1093+
p->caller.id.number.valid = ast_channel_connected(ast)->id.number.valid;
1094+
p->caller.id.name.presentation = ast_channel_connected(ast)->id.name.presentation;
1095+
p->caller.id.number.presentation = ast_channel_connected(ast)->id.number.presentation;
10921096
}
10931097

10941098
ast_setstate(ast, AST_STATE_RINGING);
@@ -2264,10 +2268,8 @@ static void *__analog_ss_thread(void *data)
22642268
ast_verb(3, "Disabling Caller*ID on %s\n", ast_channel_name(chan));
22652269
/* Disable Caller*ID if enabled */
22662270
p->hidecallerid = 1;
2267-
ast_party_number_free(&ast_channel_caller(chan)->id.number);
2268-
ast_party_number_init(&ast_channel_caller(chan)->id.number);
2269-
ast_party_name_free(&ast_channel_caller(chan)->id.name);
2270-
ast_party_name_init(&ast_channel_caller(chan)->id.name);
2271+
ast_channel_caller(chan)->id.number.presentation = AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED;
2272+
ast_channel_caller(chan)->id.name.presentation = AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED;
22712273
res = analog_play_tone(p, idx, ANALOG_TONE_DIALRECALL);
22722274
if (res) {
22732275
ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n",
@@ -2353,7 +2355,8 @@ static void *__analog_ss_thread(void *data)
23532355
ast_verb(3, "Enabling Caller*ID on %s\n", ast_channel_name(chan));
23542356
/* Enable Caller*ID if enabled */
23552357
p->hidecallerid = 0;
2356-
ast_set_callerid(chan, p->cid_num, p->cid_name, NULL);
2358+
ast_channel_caller(chan)->id.number.presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
2359+
ast_channel_caller(chan)->id.name.presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
23572360
res = analog_play_tone(p, idx, ANALOG_TONE_DIALRECALL);
23582361
if (res) {
23592362
ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n",

include/asterisk/callerid.h

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
#define CID_UNKNOWN_NUMBER (1 << 3)
5656
#define CID_MSGWAITING (1 << 4)
5757
#define CID_NOMSGWAITING (1 << 5)
58+
#define CID_QUALIFIER (1 << 6)
5859

5960
#define CID_SIG_BELL 1
6061
#define CID_SIG_V23 2
@@ -67,6 +68,12 @@
6768
#define CID_START_POLARITY_IN 3
6869
#define CID_START_DTMF_NOALERT 4
6970

71+
/* Caller ID message formats */
72+
/*! SDMF - number only */
73+
#define CID_TYPE_SDMF 0x00
74+
/*! MDMF - name, number, etc. */
75+
#define CID_TYPE_MDMF 0x01
76+
7077
/* defines dealing with message waiting indication generation */
7178
/*! MWI SDMF format */
7279
#define CID_MWI_TYPE_SDMF 0x00
@@ -101,7 +108,26 @@ void callerid_init(void);
101108
* \return It returns the size
102109
* (in bytes) of the data (if it returns a size of 0, there is probably an error)
103110
*/
104-
int callerid_generate(unsigned char *buf, const char *number, const char *name, int flags, int callwaiting, struct ast_format *codec);
111+
int callerid_generate(unsigned char *buf, const char *number, const char *name, int flags, int callwaiting, struct ast_format *codec);
112+
113+
/*! \brief Generates a CallerID FSK stream in ulaw format suitable for transmission.
114+
* \param buf Buffer to use. If "buf" is supplied, it will use that buffer instead of allocating its own.
115+
* "buf" must be at least 32000 bytes in size of you want to be sure you don't have an overrun.
116+
* \param number Use NULL for no number or "P" for "private"
117+
* \param name name to be used
118+
* \param ddn Dialable Directory Number (or NULL)
119+
* \param redirecting Redirecting reason
120+
* \param flags passed flags
121+
* \param format Message format
122+
* \param callwaiting callwaiting flag
123+
* \param codec -- either AST_FORMAT_ULAW or AST_FORMAT_ALAW
124+
* \details
125+
* This function creates a stream of callerid (a callerid spill) data in ulaw format.
126+
* \return It returns the size
127+
* (in bytes) of the data (if it returns a size of 0, there is probably an error)
128+
*/
129+
int callerid_full_generate(unsigned char *buf, const char *number, const char *name, const char *ddn, int redirecting,
130+
int flags, int format, int callwaiting, struct ast_format *codec);
105131

106132
/*! \brief Create a callerID state machine
107133
* \param cid_signalling Type of signalling in use
@@ -177,6 +203,23 @@ void callerid_free(struct callerid_state *cid);
177203
*/
178204
int ast_callerid_generate(unsigned char *buf, const char *name, const char *number, struct ast_format *codec);
179205

206+
/*! \brief Generate Caller-ID spill from the "callerid" field of asterisk (in e-mail address like format)
207+
* \param buf buffer for output samples. See callerid_generate() for details regarding buffer.
208+
* \param name Caller-ID Name
209+
* \param number Caller-ID Number
210+
* \param ddn Dialable Directory Number (or NULL)
211+
* \param redirecting Redirecting Reason (-1 if N/A)
212+
* \param pres Presentation (0 for default)
213+
* \param qualifier Call Qualifier (0 for no, 1 for yes)
214+
* \param format Message Format
215+
* \param codec Asterisk codec (either AST_FORMAT_ALAW or AST_FORMAT_ULAW)
216+
*
217+
* \details
218+
* Like ast_callerid_generate but with additional parameters.
219+
*/
220+
int ast_callerid_full_generate(unsigned char *buf, const char *name, const char *number,
221+
const char *ddn, int redirecting, int pres, int qualifier, int format, struct ast_format *codec);
222+
180223
/*!
181224
* \brief Generate message waiting indicator
182225
* \param buf
@@ -198,6 +241,12 @@ int ast_callerid_vmwi_generate(unsigned char *buf, int active, int type, struct
198241
*/
199242
int ast_callerid_callwaiting_generate(unsigned char *buf, const char *name, const char *number, struct ast_format *codec);
200243

244+
/*! \brief Generate Caller-ID spill but in a format suitable for Call Waiting(tm)'s Caller*ID(tm)
245+
* \see ast_callerid_generate() for other details
246+
*/
247+
int ast_callerid_callwaiting_full_generate(unsigned char *buf, const char *name, const char *number,
248+
const char *ddn, int redirecting, int pres, int qualifier, struct ast_format *codec);
249+
201250
/*! \brief Destructively parse inbuf into name and location (or number)
202251
* \details
203252
* Parses callerid stream from inbuf and changes into useable form, outputted in name and location.

main/callerid.c

Lines changed: 90 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -736,7 +736,8 @@ void callerid_free(struct callerid_state *cid)
736736
ast_free(cid);
737737
}
738738

739-
static int callerid_genmsg(char *msg, int size, const char *number, const char *name, int flags)
739+
static int callerid_genmsg(char *msg, int size, const char *number, const char *name, int flags, int format,
740+
const char *ddn, int redirecting)
740741
{
741742
struct timeval now = ast_tvnow();
742743
struct ast_tm tm;
@@ -754,6 +755,7 @@ static int callerid_genmsg(char *msg, int size, const char *number, const char *
754755
tm.tm_mday, tm.tm_hour, tm.tm_min);
755756
size -= res;
756757
ptr += res;
758+
757759
if (ast_strlen_zero(number) || (flags & CID_UNKNOWN_NUMBER)) {
758760
/* Indicate number not known */
759761
res = snprintf(ptr, size, "\004\001O");
@@ -779,6 +781,11 @@ static int callerid_genmsg(char *msg, int size, const char *number, const char *
779781
size -= i;
780782
}
781783

784+
if (format == CID_TYPE_SDMF) { /* If Simple Data Message Format, we're done. */
785+
/* (some older Caller ID units only support SDMF. If they get an MDMF spill, it's useless.) */
786+
return (ptr - msg);
787+
}
788+
782789
if (ast_strlen_zero(name) || (flags & CID_UNKNOWN_NAME)) {
783790
/* Indicate name not known */
784791
res = snprintf(ptr, size, "\010\001O");
@@ -803,8 +810,44 @@ static int callerid_genmsg(char *msg, int size, const char *number, const char *
803810
ptr += i;
804811
size -= i;
805812
}
806-
return (ptr - msg);
807813

814+
/* Call Qualifier */
815+
if (flags & CID_QUALIFIER) {
816+
res = snprintf(ptr, size, "\006\001L"); /* LDC (Long Distance Call) is the only valid option */
817+
size -= res;
818+
ptr += res;
819+
}
820+
821+
/* DDN (Dialable Directory Number) - 11 digits MAX, parameter 003 */
822+
/* some CPE seem to display the DDN instead of the CLID, if sent */
823+
824+
/* Redirecting Reason */
825+
if (redirecting >= 0) {
826+
res = 0;
827+
switch (redirecting) {
828+
case AST_REDIRECTING_REASON_USER_BUSY:
829+
res = snprintf(ptr, size, "\005\001\001");
830+
break;
831+
case AST_REDIRECTING_REASON_NO_ANSWER:
832+
res = snprintf(ptr, size, "\005\001\002");
833+
break;
834+
case AST_REDIRECTING_REASON_UNCONDITIONAL:
835+
res = snprintf(ptr, size, "\005\001\003");
836+
break;
837+
case AST_REDIRECTING_REASON_CALL_FWD_DTE:
838+
res = snprintf(ptr, size, "\005\001\004");
839+
break;
840+
case AST_REDIRECTING_REASON_DEFLECTION:
841+
res = snprintf(ptr, size, "\005\001\005");
842+
break;
843+
default:
844+
break;
845+
}
846+
ptr += res;
847+
size -= res;
848+
}
849+
850+
return (ptr - msg);
808851
}
809852

810853
int ast_callerid_vmwi_generate(unsigned char *buf, int active, int type, struct ast_format *codec,
@@ -824,7 +867,7 @@ int ast_callerid_vmwi_generate(unsigned char *buf, int active, int type, struct
824867
msg[0] = 0x82;
825868

826869
/* put date, number info at the right place */
827-
len = callerid_genmsg(msg+2, sizeof(msg)-2, number, name, flags);
870+
len = callerid_genmsg(msg+2, sizeof(msg)-2, number, name, flags, CID_TYPE_MDMF, "", -1);
828871

829872
/* length of MDMF CLI plus Message Waiting Structure */
830873
msg[1] = len+3;
@@ -896,6 +939,12 @@ int ast_callerid_vmwi_generate(unsigned char *buf, int active, int type, struct
896939
}
897940

898941
int callerid_generate(unsigned char *buf, const char *number, const char *name, int flags, int callwaiting, struct ast_format *codec)
942+
{
943+
return callerid_full_generate(buf, number, name, NULL, -1, flags, CID_TYPE_MDMF, callwaiting, codec);
944+
}
945+
946+
int callerid_full_generate(unsigned char *buf, const char *number, const char *name, const char *ddn, int redirecting,
947+
int flags, int format, int callwaiting, struct ast_format *codec)
899948
{
900949
int bytes = 0;
901950
int x, sum;
@@ -906,7 +955,7 @@ int callerid_generate(unsigned char *buf, const char *number, const char *name,
906955
float ci = 0.0;
907956
float scont = 0.0;
908957
char msg[256];
909-
len = callerid_genmsg(msg, sizeof(msg), number, name, flags);
958+
len = callerid_genmsg(msg, sizeof(msg), number, name, flags, format, ddn, redirecting);
910959
if (!callwaiting) {
911960
/* Wait a half a second */
912961
for (x = 0; x < 4000; x++)
@@ -1051,23 +1100,56 @@ int ast_callerid_parse(char *input_str, char **name, char **location)
10511100
return 0;
10521101
}
10531102

1054-
static int __ast_callerid_generate(unsigned char *buf, const char *name, const char *number, int callwaiting, struct ast_format *codec)
1103+
static int __ast_callerid_generate(unsigned char *buf, const char *name, const char *number,
1104+
const char *ddn, int redirecting, int pres, int qualifier, int format, int callwaiting, struct ast_format *codec)
10551105
{
1106+
int flags = 0;
1107+
1108+
ast_debug(1, "Caller ID Type %s: Number: %s, Name: %s, Redirecting No: %s, Redirecting Reason: %s, Pres: %s, Qualifier: %s, Format: %s\n",
1109+
callwaiting ? "II" : "I", number, name, ddn, ast_redirecting_reason_describe(redirecting),
1110+
ast_named_caller_presentation(pres), qualifier ? "LDC" : "None", format == CID_TYPE_MDMF ? "MDMF" : "SDMF");
1111+
10561112
if (ast_strlen_zero(name))
10571113
name = NULL;
10581114
if (ast_strlen_zero(number))
10591115
number = NULL;
1060-
return callerid_generate(buf, number, name, 0, callwaiting, codec);
1116+
1117+
if (pres & AST_PRES_RESTRICTED) {
1118+
flags |= CID_PRIVATE_NUMBER;
1119+
flags |= CID_PRIVATE_NAME;
1120+
} else if (pres & AST_PRES_UNAVAILABLE) {
1121+
flags |= CID_UNKNOWN_NUMBER;
1122+
flags |= CID_UNKNOWN_NAME;
1123+
}
1124+
1125+
if (qualifier) {
1126+
flags |= CID_QUALIFIER;
1127+
}
1128+
1129+
return callerid_full_generate(buf, number, name, ddn, redirecting, flags, format, callwaiting, codec);
10611130
}
10621131

10631132
int ast_callerid_generate(unsigned char *buf, const char *name, const char *number, struct ast_format *codec)
10641133
{
1065-
return __ast_callerid_generate(buf, name, number, 0, codec);
1134+
return __ast_callerid_generate(buf, name, number, "", -1, 0, 0, CID_TYPE_MDMF, 0, codec);
10661135
}
10671136

10681137
int ast_callerid_callwaiting_generate(unsigned char *buf, const char *name, const char *number, struct ast_format *codec)
10691138
{
1070-
return __ast_callerid_generate(buf, name, number, 1, codec);
1139+
return __ast_callerid_generate(buf, name, number, "", -1, 0, 0, CID_TYPE_MDMF, 1, codec);
1140+
}
1141+
1142+
int ast_callerid_full_generate(unsigned char *buf, const char *name, const char *number,
1143+
const char *ddn, int redirecting, int pres, int qualifier, int format, struct ast_format *codec)
1144+
{
1145+
return __ast_callerid_generate(buf, name, number, ddn, redirecting, pres, qualifier, format, 0, codec);
1146+
}
1147+
1148+
int ast_callerid_callwaiting_full_generate(unsigned char *buf, const char *name, const char *number,
1149+
const char *ddn, int redirecting, int pres, int qualifier, struct ast_format *codec)
1150+
{
1151+
/* Type II Caller ID (CWCID) only uses MDMF, so format isn't an argument */
1152+
return __ast_callerid_generate(buf, name, number, ddn, redirecting, pres, qualifier, CID_TYPE_MDMF, 1, codec);
10711153
}
10721154

10731155
char *ast_callerid_merge(char *buf, int bufsiz, const char *name, const char *num, const char *unknown)

0 commit comments

Comments
 (0)