Index: main/callerid.c =================================================================== --- main/callerid.c (revision 48456) +++ main/callerid.c (working copy) @@ -171,6 +171,13 @@ *number = cid->number; } +void callerid_get_rawdata(struct callerid_state *cid, char **data, int *len, int *type) { + *data = cid->rawdata; + *len = cid->pos; + *type = cid->type; +} + + void callerid_get_dtmf(char *cidstring, char *number, int *flags) { int i; @@ -558,7 +565,7 @@ cid->sawflag = 2; break; case 2: /* Get lead-in */ - if ((b == 0x04) || (b == 0x80)) { + if ((b == CID_TYPE_SDMF_CLI) || (b == CID_TYPE_MDMF_CLI) || (b == CID_TYPE_MDMF_CLI_VM) || (b == CID_TYPE_SDMF_VM)) { cid->type = b; cid->sawflag = 3; cid->cksum = b; @@ -594,8 +601,12 @@ cid->number[0] = '\0'; cid->name[0] = '\0'; + + /* Init flags */ + cid->flags = 0; + /* If we get this far we're fine. */ - if (cid->type == 0x80) { + if ((cid->type == CID_TYPE_MDMF_CLI) || (cid->type == CID_TYPE_MDMF_CLI_VM)) { /* MDMF */ /* Go through each element and process */ for (x = 0; x < cid->pos;) { @@ -618,6 +629,7 @@ } break; case 6: /* Stentor Call Qualifier (ie. Long Distance call) */ + cid->flags |= CID_UNKNOWN_DATA; break; case 7: /* Name */ case 8: /* Name */ @@ -632,19 +644,22 @@ case 17: /* UK: Call type, 1=Voice Call, 2=Ringback when free, 129=Message waiting */ case 19: /* UK: Network message system status (Number of messages waiting) */ case 22: /* Something French */ + cid->flags |= CID_UNKNOWN_DATA; break; default: + cid->flags |= CID_UNKNOWN_DATA; ast_log(LOG_NOTICE, "Unknown IE %d\n", cid->rawdata[x - 1]); } x += cid->rawdata[x]; x++; } - } else { + } else if(cid->type == CID_TYPE_SDMF_CLI){ /* SDMF */ ast_copy_string(cid->number, cid->rawdata + 8, sizeof(cid->number)); + } else if(cid->type == CID_TYPE_SDMF_VM) { + cid->flags |= CID_UNKNOWN_DATA; } - /* Update flags */ - cid->flags = 0; + if (!strcmp(cid->number, "P")) { strcpy(cid->number, ""); cid->flags |= CID_PRIVATE_NUMBER; @@ -752,8 +767,68 @@ } -int vmwi_generate(unsigned char *buf, int active, int mdmf, int codec) +/*! \internal +* \brief Generate standard message info for mwi + +* Here we only put time and caller info +* (if number, name not known we don't put anything as they are optional fields and some fields 0x04, 0x10 are typically not allowed in MWI) +* Depending on telco there could be more fields (number of messages waiting...) but here we put the minimal so as to maximize compatibility +*/ +static int vmwi_genstdmsg(char *msg, int size, const char *number, const char *name, int flags) { + time_t t; + struct tm tm; + char *ptr; + int res; + int i, x; + + /* Get the time */ + time(&t); + localtime_r(&t,&tm); + + ptr = msg; + + /* Format time and message header */ + res = snprintf(ptr, size, "\001\010%02d%02d%02d%02d", tm.tm_mon + 1, + tm.tm_mday, tm.tm_hour, tm.tm_min); + size -= res; + ptr += res; + if (!ast_strlen_zero(number) && !(flags & CID_UNKNOWN_NUMBER) && !(flags & CID_PRIVATE_NUMBER)) { + /* Send up to 16 digits of number MAX */ + i = strlen(number); + if (i > 16) + i = 16; + res = snprintf(ptr, size, "\002%c", i); + size -= res; + ptr += res; + for (x = 0; x < i; x++) + ptr[x] = number[x]; + ptr[i] = '\0'; + ptr += i; + size -= i; + } + + if (!ast_strlen_zero(name) && !(flags & CID_UNKNOWN_NAME) && !(flags & CID_PRIVATE_NAME)) { + /* Send up to 16 digits of name MAX */ + i = strlen(name); + if (i > 16) + i = 16; + res = snprintf(ptr, size, "\007%c", i); + size -= res; + ptr += res; + for (x = 0; x < i; x++) + ptr[x] = name[x]; + ptr[i] = '\0'; + ptr += i; + size -= i; + } + + return (ptr - msg); + +} + +int vmwi_generate(unsigned char *buf, int active, int type, int codec, const char* number, const char* name, int flags) +{ unsigned char msg[256]; int len=0; int sum; @@ -762,14 +837,40 @@ float cr = 1.0; float ci = 0.0; float scont = 0.0; - - if (mdmf) { - /* MDMF Message waiting */ - msg[len++] = 0x82; + + if (type == 2) { + + /* MDMF Message waiting with date, number, name and MWI parameter */ + msg[0] = CID_TYPE_MDMF_CLI_VM; + + /* put date, number info at the right place */ + len = vmwi_genstdmsg(msg+2, sizeof(msg)-2, number, name, flags); + + /* length of MDMF CLI plus Message Waiting Structure */ + msg[1] = len+3; + + /* Got to the position to write to */ + len = len+2; + + /* "Message Waiting Parameter" */ + msg[len++] = 0x0b; + /* Length of IE is one */ + msg[len++] = 1; + /* Active or not */ + if (active) + msg[len++] = 0xff; + else + msg[len++] = 0x00; + + } else if (type == 1) { + + /* MDMF Message waiting only */ + /* same as above except that the only field is message waiting indicator */ + msg[len++] = CID_TYPE_MDMF_CLI_VM; /* Length is 3 */ msg[len++] = 3; /* IE is "Message Waiting Parameter" */ - msg[len++] = 0xb; + msg[len++] = 0x0b; /* Length of IE is one */ msg[len++] = 1; /* Active or not */ @@ -777,9 +878,10 @@ msg[len++] = 0xff; else msg[len++] = 0x00; - } else { + } else if (type == 0) { + /* SDMF Message waiting */ - msg[len++] = 0x6; + msg[len++] = CID_TYPE_SDMF_VM; /* Length is 3 */ msg[len++] = 3; if (active) { @@ -991,6 +1093,17 @@ return __ast_callerid_generate(buf, name, number, 0, codec); } +int ast_vmwi_generate(unsigned char *buf, int active, const char *name, const char *number, int codec) +{ + if(ast_strlen_zero(name)) + name = NULL; + if(ast_strlen_zero(number)) + number = NULL; + + /* as a default we will use full MDMF format ie type 2 */ + return vmwi_generate(buf, active, 2, codec, number, name, 0); +} + int ast_callerid_callwaiting_generate(unsigned char *buf, const char *name, const char *number, int codec) { return __ast_callerid_generate(buf, name, number, 1, codec);