Index: main/callerid.c =================================================================== --- main/callerid.c (.../trunk/main/callerid.c) (révision 38) +++ main/callerid.c (.../branches/newmwi/main/callerid.c) (révision 40) @@ -45,6 +45,20 @@ #include "asterisk/options.h" #include "asterisk/utils.h" + +/* defines dealing with different callerid raw data format */ +/*! Not a valid caller id */ +#define CID_TYPE_NONE 0x00 +/*! SDMF Caller ID */ +#define CID_TYPE_SDMF_CLI 0x04 +/*! SMDF Message Waiting Indication */ +#define CID_TYPE_SDMF_VM 0x06 +/*! MDMF Caller ID */ +#define CID_TYPE_MDMF_CLI 0x80 +/*! MDMF Message Waiting Indication (contains Caller ID info too) */ +#define CID_TYPE_MDMF_CLI_VM 0x82 + + struct callerid_state { fsk_data fskd; char rawdata[256]; @@ -61,6 +75,7 @@ int skipflag; unsigned short crc; + int mwi_is_on; }; @@ -161,6 +176,7 @@ /* cid->pos = 0; */ fskmodem_init(&cid->fskd); + cid->mwi_is_on = -1; } return cid; @@ -179,6 +195,16 @@ *number = cid->number; } +int callerid_is_mwi(struct callerid_state *cid) +{ + return (cid->type == CID_TYPE_SDMF_VM) || (cid->type == CID_TYPE_MDMF_CLI_VM); +} + +int callerid_is_mwi_on(struct callerid_state *cid) +{ + return cid->mwi_is_on; +} + void callerid_get_dtmf(char *cidstring, char *number, int *flags) { int i; @@ -561,7 +587,8 @@ 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; @@ -598,7 +625,8 @@ cid->number[0] = '\0'; cid->name[0] = '\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;) { @@ -632,6 +660,11 @@ memcpy(cid->name, cid->rawdata + x + 1, res); cid->name[res] = '\0'; break; + case 11: /* 0x0b Message waiting indicator */ + res = cid->rawdata[x]; + if (res == 1) + cid->mwi_is_on = (cid->rawdata[x+1] == (char)0xFF)? 1 : 0; + break; 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 */ @@ -649,9 +682,13 @@ 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) { + /* SDMF message waiting indication */ + if (cid->len == 3) + cid->mwi_is_on = (cid->rawdata[0] == 0x6F)? 1 : 0; } /* Update flags */ cid->flags = 0; @@ -761,9 +798,75 @@ } -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, 0x08 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) { - unsigned char msg[256]; + struct timeval tv = ast_tvnow(); + struct ast_tm tm; + char *ptr; + int res; + int i, x; + + /* Get the time */ + ast_localtime(&tv, &tm, NULL); + + 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 on, int type, int codec, + const char* number, const char* name, int flags) +{ + char msg[256]; int len=0; int sum; int x; @@ -771,27 +874,54 @@ float cr = 1.0; float ci = 0.0; float scont = 0.0; - - if (mdmf) { - /* MDMF Message waiting */ - msg[len++] = 0x82; + + if (type == CID_MWI_TYPE_MDMF_FULL) { + + /* 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; + + /* Go 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 (on) + msg[len++] = 0xff; + else + msg[len++] = 0x00; + + } else if (type == CID_MWI_TYPE_MDMF) { + + /* MDMF Message waiting only */ + /* same as above except that the we only put MWI parameter */ + 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 */ - if (active) + if (on) msg[len++] = 0xff; else msg[len++] = 0x00; - } else { + } else if (type == CID_MWI_TYPE_SDMF) { + /* SDMF Message waiting */ - msg[len++] = 0x6; + msg[len++] = CID_TYPE_SDMF_VM; /* Length is 3 */ msg[len++] = 3; - if (active) { + if (on) { msg[len++] = 0x42; msg[len++] = 0x42; msg[len++] = 0x42; @@ -848,10 +978,10 @@ for (x = 0; x < 150; x++) PUT_CLID_MARKMS; /* Send 0x80 indicating MDMF format */ - PUT_CLID(0x80); + PUT_CLID(CID_TYPE_MDMF_CLI); /* Put length of whole message */ PUT_CLID(len); - sum = 0x80 + strlen(msg); + sum = CID_TYPE_MDMF_CLI + strlen(msg); /* Put each character of message and update checksum */ for (x = 0; x < len; x++) { PUT_CLID(msg[x]); @@ -1001,6 +1131,16 @@ return __ast_callerid_generate(buf, name, number, 0, codec); } +int ast_vmwi_generate(unsigned char *buf, int on, int type, const char *name, + const char *number, int codec) +{ + if(ast_strlen_zero(name)) + name = NULL; + if(ast_strlen_zero(number)) + number = NULL; + return vmwi_generate(buf, on, type, 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);