Index: channels/chan_zap.c =================================================================== --- channels/chan_zap.c (revision 49783) +++ channels/chan_zap.c (working copy) @@ -954,6 +954,13 @@ return 0; } +static int zt_get_history(int fd, void *buf, int buf_size) +{ + struct zt_history hist; + hist.buf=buf; + hist.len=buf_size; + return ioctl(fd, ZT_GET_HISTORY, &hist); +} static int alloc_sub(struct zt_pvt *p, int x) { @@ -6082,6 +6089,118 @@ if (p->use_callerid && (p->cid_signalling == CID_SIG_SMDI && smdi_msg)) { number = smdi_msg->calling_st; + /* Check to see if caller ID needs to be extracted from + * the history buffer */ + } else if (p->use_callerid && p->cid_start == CID_START_USEHIST) { + ast_log(LOG_DEBUG,"Using history buffer to extract caller ID\n"); + cs = callerid_new(p->cid_signalling); + if (cs) { + unsigned char cidbuf[32768]; + res=0; + + res = zt_get_history(p->subs[index].zfd,cidbuf,sizeof(cidbuf)); + if(res<0) { + ast_log(LOG_ERROR,"zt_get_history failed: %s\n", strerror(errno)); + } else { + res=callerid_feed(cs,cidbuf,sizeof(cidbuf),AST_LAW(p)); + if (res < 0) { + ast_log(LOG_WARNING, "CallerID feed failed: %s\n", strerror(errno)); + } + } + + if(res==1) { + callerid_get(cs, &name, &number, &flags); + if (option_debug) + ast_log(LOG_DEBUG, "CallerID number: %s, name: %s, flags=%d\n", number, name, flags); + } + } + if (p->usedistinctiveringdetection == 1) { +#if 1 + bump_gains(p); +#endif + len = 0; + distMatches = 0; + /* Clear the current ring data array so we dont have old data in it. */ + for (receivedRingT=0; receivedRingT < 3; receivedRingT++) { + curRingData[receivedRingT] = 0; + } + receivedRingT = 0; + counter = 0; + counter1 = 0; + /* Check to see if context is what it should be, if not set to be. */ + if (strcmp(p->context,p->defcontext) != 0) { + strncpy(p->context, p->defcontext, sizeof(p->context)-1); + strncpy(chan->context,p->defcontext,sizeof(chan->context)-1); + } + + for(;;) { + i = ZT_IOMUX_READ | ZT_IOMUX_SIGEVENT; + if ((res = ioctl(p->subs[index].zfd, ZT_IOMUX, &i))) { + ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno)); + callerid_free(cs); + ast_hangup(chan); + return NULL; + } + if (i & ZT_IOMUX_SIGEVENT) { + res = zt_get_event(p->subs[index].zfd); + ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res)); + res = 0; + /* Let us detect distinctive ring */ + + curRingData[receivedRingT] = p->ringt; + + if (p->ringt < ringt_base/2) + break; + ++receivedRingT; /* Increment the ringT counter so we can match it against + values in zapata.conf for distinctive ring */ + } else if (i & ZT_IOMUX_READ) { + res = read(p->subs[index].zfd, buf, sizeof(buf)); + if (res < 0) { + if (errno != ELAST) { + ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno)); + callerid_free(cs); + ast_hangup(chan); + return NULL; + } + break; + } + if (p->ringt) + p->ringt--; + if (p->ringt == 1) { + res = -1; + break; + } + } + } + if(option_verbose > 2) + /* this only shows up if you have n of the dring patterns filled in */ + ast_verbose( VERBOSE_PREFIX_3 "Detected ring pattern: %d,%d,%d\n",curRingData[0],curRingData[1],curRingData[2]); + + for (counter=0; counter < 3; counter++) { + /* Check to see if the rings we received match any of the ones in zapata.conf for this + channel */ + distMatches = 0; + for (counter1=0; counter1 < 3; counter1++) { + if (curRingData[counter1] <= (p->drings.ringnum[counter].ring[counter1]+10) && curRingData[counter1] >= + (p->drings.ringnum[counter].ring[counter1]-10)) { + distMatches++; + } + } + if (distMatches == 3) { + /* The ring matches, set the context to whatever is for distinctive ring.. */ + strncpy(p->context, p->drings.ringContext[counter].contextData, sizeof(p->context)-1); + strncpy(chan->context, p->drings.ringContext[counter].contextData, sizeof(chan->context)-1); + if(option_verbose > 2) + ast_verbose( VERBOSE_PREFIX_3 "Distinctive Ring matched context %s\n",p->context); + break; + } + } + } + /* Restore linear mode (if appropriate) for Caller*ID processing */ + zt_setlinear(p->subs[index].zfd, p->subs[index].linear); +#if 1 + restore_gains(p); +#endif /* If we want caller id, we're in a prering state due to a polarity reversal * and we're set to use a polarity reversal to trigger the start of caller id, * grab the caller id and wait for ringing to start... */ @@ -10501,6 +10620,8 @@ confp->chan.cid_start = CID_START_RING; else if (!strcasecmp(v->value, "polarity")) confp->chan.cid_start = CID_START_POLARITY; + else if (!strcasecmp(v->value, "usehist")) + confp->chan.cid_start = CID_START_USEHIST; else if (ast_true(v->value)) confp->chan.cid_start = CID_START_RING; } else if (!strcasecmp(v->name, "threewaycalling")) { Index: include/asterisk/callerid.h =================================================================== --- include/asterisk/callerid.h (revision 49783) +++ include/asterisk/callerid.h (working copy) @@ -58,6 +58,7 @@ #define CID_START_RING 1 #define CID_START_POLARITY 2 +#define CID_START_USEHIST 3 #define AST_LIN2X(a) ((codec == AST_FORMAT_ALAW) ? (AST_LIN2A(a)) : (AST_LIN2MU(a)))