--- /usr/src/asterisk-16012006-svn/rtp.c 2006-01-16 19:31:59.000000000 +0000 +++ /usr/src/asterisk/rtp.c 2006-01-20 10:46:36.000000000 +0000 @@ -81,6 +81,15 @@ #define MAX_RTP_PT 256 +//MSG +#define MSG_RFC2833_CACHE_SIZE 10 +#define MSG_RFC2833_CACHE_TIMEOUT 1000 //should be plenty of time +#define MSG_RFC2833_CACHE_RESP 0 +#define MSG_RFC2833_CACHE_RXTS 1 +#define MSG_RFC2833_CACHE_STATUS 2 +#define MSG_RFC2833_CACHE_SEQNO 3 +//MSG + #define FLAG_3389_WARNING (1 << 0) #define FLAG_NAT_ACTIVE (3 << 1) #define FLAG_NAT_INACTIVE (0 << 1) @@ -124,6 +133,13 @@ int rtp_lookup_code_cache_code; int rtp_lookup_code_cache_result; struct ast_rtcp *rtcp; + +//MSG: + //resp (digit), rxts, firstts, seqno, status + unsigned int dtmf_array[MSG_RFC2833_CACHE_SIZE][4]; + struct timeval dtmf_time_array[MSG_RFC2833_CACHE_SIZE]; +//MSG: + }; /*! @@ -283,26 +299,106 @@ } else if (event < 17) { /* Event 16: Hook flash */ resp = 'X'; } - if (rtp->resp && (rtp->resp != resp)) { - f = send_dtmf(rtp); - } else if(event_end & 0x80) { - if (rtp->resp) { - if(rtp->lasteventendseqn != seqno) { - f = send_dtmf(rtp); - rtp->lasteventendseqn = seqno; +//MSG: +int i=0; +int j=0; +int dtmf_array=-1; +struct timeval now = ast_tvnow(); +struct timeval zip = ast_tvnow(); + +//ast_verbose("%c - rxcore: %d - txcore: %d - dtmfmute: %d\n",resp,ast_tvdiff_ms(rtp->rxcore,zip),ast_tvdiff_ms(rtp->txcore,zip),ast_tvdiff_ms(rtp->dtmfmute,zip)); + + +ast_verbose("%c %d %d",resp,rtp->lastrxts,seqno); + +for (i=0;idtmf_time_array[i])>MSG_RFC2833_CACHE_TIMEOUT) && rtp->dtmf_array[j][MSG_RFC2833_CACHE_STATUS]!=2) + { + //ast_verbose("old DTMF lost %c\n",rtp->dtmf_array[i][MSG_RFC2833_CACHE_RESP]); + ast_verbose(" old"); + continue; + } + else if (rtp->dtmf_array[i][MSG_RFC2833_CACHE_RESP]==resp && rtp->dtmf_array[i][MSG_RFC2833_CACHE_RXTS]==rtp->lastrxts) + { + ast_verbose(" found %d",i); + + //if this new packet is not an end but the last one was an end then assume its a new DTMF + if ( (rtp->dtmf_array[i][MSG_RFC2833_CACHE_SEQNO] < seqno) && (!(event_end & 0x80)) && (rtp->dtmf_array[i][MSG_RFC2833_CACHE_STATUS]==2)) + { + //'clear' this dtmf + ast_verbose(" multi"); + rtp->dtmf_array[i][MSG_RFC2833_CACHE_STATUS]=0; + i=MSG_RFC2833_CACHE_SIZE; + break; } - rtp->resp = 0; - } - resp = 0; - duration = 0; - } else if (rtp->resp && rtp->dtmfduration && (duration < rtp->dtmfduration)) { - f = send_dtmf(rtp); - } - if (!(event_end & 0x80)) - rtp->resp = resp; + + dtmf_array=i; + if (rtp->dtmf_array[i][MSG_RFC2833_CACHE_SEQNO] && (rtp->dtmf_array[i][MSG_RFC2833_CACHE_SEQNO]dtmf_array[i][MSG_RFC2833_CACHE_SEQNO]); + rtp->dtmf_array[i][MSG_RFC2833_CACHE_SEQNO]=seqno; + } + //update last recive timestamp + rtp->dtmf_time_array[i]=now; + f=NULL; + break; + } + } + +if (i==MSG_RFC2833_CACHE_SIZE) + { + for (j=0;jdtmf_array[j][MSG_RFC2833_CACHE_STATUS]==0 || (ast_tvdiff_ms(now, rtp->dtmf_time_array[j])>MSG_RFC2833_CACHE_TIMEOUT)) + { + ast_verbose(" NEW %d",j); + rtp->dtmf_array[j][MSG_RFC2833_CACHE_RESP]=resp; + rtp->dtmf_array[j][MSG_RFC2833_CACHE_RXTS]=rtp->lastrxts; + rtp->dtmf_array[j][MSG_RFC2833_CACHE_STATUS]=1; + rtp->dtmf_array[j][MSG_RFC2833_CACHE_SEQNO]=seqno; + rtp->dtmf_time_array[j]=now; + dtmf_array=j; + break; + } + } + if (j==MSG_RFC2833_CACHE_SIZE) + { + dtmf_array=-1; + } + } + +//this should not happen... ever +if (dtmf_array==-1) + { + ast_verbose("\nNew DTMF and can not find a free spot in dtmf array\n"); + return f; + } + +if ( (event_end & 0x80) && rtp->dtmf_array[dtmf_array][MSG_RFC2833_CACHE_STATUS]==1) + { rtp->dtmfcount = dtmftimeout; - rtp->dtmfduration = duration; - return f; + rtp->dtmfduration = duration; + ast_verbose(" end"); + } +else + { + ast_verbose(" ignored ------\n"); + return f; + } + +if(rtp->lasteventendseqn != seqno) + { + ast_verbose(" send ++++++"); + rtp->resp = resp; + rtp->dtmf_array[dtmf_array][MSG_RFC2833_CACHE_STATUS]=2; + f = send_dtmf(rtp); + rtp->lasteventendseqn = seqno; + } +ast_verbose("\n"); +return f; +//MSG: } /*!