[asterisk-commits] oej: branch oej/realtimetext-t140 r48260 - in
/team/oej/realtimetext-t140: ./...
asterisk-commits at lists.digium.com
asterisk-commits at lists.digium.com
Tue Dec 5 04:20:22 MST 2006
Author: oej
Date: Tue Dec 5 05:20:22 2006
New Revision: 48260
URL: http://svn.digium.com/view/asterisk?view=rev&rev=48260
Log:
Update to trunk, add line to CHANGES
Removed:
team/oej/realtimetext-t140/main/coef_in.h
team/oej/realtimetext-t140/main/coef_out.h
Modified:
team/oej/realtimetext-t140/ (props changed)
team/oej/realtimetext-t140/.cleancount
team/oej/realtimetext-t140/CHANGES
team/oej/realtimetext-t140/Makefile
team/oej/realtimetext-t140/agi/Makefile
team/oej/realtimetext-t140/apps/app_dial.c
team/oej/realtimetext-t140/apps/app_sms.c
team/oej/realtimetext-t140/apps/app_voicemail.c
team/oej/realtimetext-t140/channels/chan_sip.c
team/oej/realtimetext-t140/configs/extensions.conf.sample
team/oej/realtimetext-t140/configs/sip.conf.sample
team/oej/realtimetext-t140/configs/voicemail.conf.sample
team/oej/realtimetext-t140/configure
team/oej/realtimetext-t140/configure.ac
team/oej/realtimetext-t140/doc/snmp.txt
team/oej/realtimetext-t140/include/asterisk/frame.h
team/oej/realtimetext-t140/include/asterisk/rtp.h
team/oej/realtimetext-t140/include/asterisk/threadstorage.h
team/oej/realtimetext-t140/main/callerid.c
team/oej/realtimetext-t140/main/channel.c
team/oej/realtimetext-t140/main/cli.c
team/oej/realtimetext-t140/main/frame.c
team/oej/realtimetext-t140/main/fskmodem.c
team/oej/realtimetext-t140/main/rtp.c
team/oej/realtimetext-t140/main/tdd.c
team/oej/realtimetext-t140/makeopts.in
team/oej/realtimetext-t140/sounds/Makefile
Propchange: team/oej/realtimetext-t140/
------------------------------------------------------------------------------
Binary property 'branch-1.4-blocked' - no diff available.
Propchange: team/oej/realtimetext-t140/
------------------------------------------------------------------------------
Binary property 'branch-1.4-merged' - no diff available.
Propchange: team/oej/realtimetext-t140/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Tue Dec 5 05:20:22 2006
@@ -1,1 +1,1 @@
-/trunk:1-48172
+/trunk:1-48259
Modified: team/oej/realtimetext-t140/.cleancount
URL: http://svn.digium.com/view/asterisk/team/oej/realtimetext-t140/.cleancount?view=diff&rev=48260&r1=48259&r2=48260
==============================================================================
--- team/oej/realtimetext-t140/.cleancount (original)
+++ team/oej/realtimetext-t140/.cleancount Tue Dec 5 05:20:22 2006
@@ -1,1 +1,1 @@
-26
+27
Modified: team/oej/realtimetext-t140/CHANGES
URL: http://svn.digium.com/view/asterisk/team/oej/realtimetext-t140/CHANGES?view=diff&rev=48260&r1=48259&r2=48260
==============================================================================
--- team/oej/realtimetext-t140/CHANGES (original)
+++ team/oej/realtimetext-t140/CHANGES Tue Dec 5 05:20:22 2006
@@ -63,3 +63,4 @@
does not count paused queue members as unavailable.
* Added maxfiles option to options section of asterisk.conf which allows you to specify
what Asterisk should set as the maximum number of open files when it loads.
+ * Added support for T.140 realtime text in SIP/RTP
Modified: team/oej/realtimetext-t140/Makefile
URL: http://svn.digium.com/view/asterisk/team/oej/realtimetext-t140/Makefile?view=diff&rev=48260&r1=48259&r2=48260
==============================================================================
--- team/oej/realtimetext-t140/Makefile (original)
+++ team/oej/realtimetext-t140/Makefile Tue Dec 5 05:20:22 2006
@@ -57,6 +57,7 @@
export PROC
export SOLINK
export STRIP
+export DOWNLOAD
# even though we could use '-include makeopts' here, use a wildcard
# lookup anyway, so that make won't try to build makeopts if it doesn't
@@ -273,14 +274,14 @@
@echo " + Asterisk has successfully been built, and +"
@echo " + can be installed by running: +"
@echo " + +"
- @echo " + make install +"
+ @echo " + $(MAKE) install +"
@echo " +-------------------------------------------+"
_all: cleantest $(SUBDIRS)
makeopts: configure
@echo "****"
- @echo "**** The configure script must be executed before running 'make'."
+ @echo "**** The configure script must be executed before running '$(MAKE)'."
@echo "****"
@exit 1
Modified: team/oej/realtimetext-t140/agi/Makefile
URL: http://svn.digium.com/view/asterisk/team/oej/realtimetext-t140/agi/Makefile?view=diff&rev=48260&r1=48259&r2=48260
==============================================================================
--- team/oej/realtimetext-t140/agi/Makefile (original)
+++ team/oej/realtimetext-t140/agi/Makefile Tue Dec 5 05:20:22 2006
@@ -21,7 +21,7 @@
include $(ASTTOPDIR)/Makefile.rules
-all: #$(AGIS)
+all: $(AGIS)
strcompat.c: ../main/strcompat.c
@cp $< $@
Modified: team/oej/realtimetext-t140/apps/app_dial.c
URL: http://svn.digium.com/view/asterisk/team/oej/realtimetext-t140/apps/app_dial.c?view=diff&rev=48260&r1=48259&r2=48260
==============================================================================
--- team/oej/realtimetext-t140/apps/app_dial.c (original)
+++ team/oej/realtimetext-t140/apps/app_dial.c Tue Dec 5 05:20:22 2006
@@ -1430,6 +1430,7 @@
if (ast_test_flag(outgoing, OPT_MUSICBACK)) {
moh = 1;
ast_moh_start(chan, opt_args[OPT_ARG_MUSICBACK], NULL);
+ ast_indicate(chan, AST_CONTROL_PROGRESS);
} else if (ast_test_flag(outgoing, OPT_RINGBACK)) {
ast_indicate(chan, AST_CONTROL_RINGING);
sentringing++;
Modified: team/oej/realtimetext-t140/apps/app_sms.c
URL: http://svn.digium.com/view/asterisk/team/oej/realtimetext-t140/apps/app_sms.c?view=diff&rev=48260&r1=48259&r2=48260
==============================================================================
--- team/oej/realtimetext-t140/apps/app_sms.c (original)
+++ team/oej/realtimetext-t140/apps/app_sms.c Tue Dec 5 05:20:22 2006
@@ -119,59 +119,59 @@
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
-#define SMSLEN 160 /* max SMS length */
+#define SMSLEN 160 /*!< max SMS length */
typedef struct sms_s
{
- unsigned char hangup; /* we are done... */
- unsigned char err; /* set for any errors */
- unsigned char smsc:1; /* we are SMSC */
- unsigned char rx:1; /* this is a received message */
- char queue[30]; /* queue name */
- char oa[20]; /* originating address */
- char da[20]; /* destination address */
- time_t scts; /* time stamp, UTC */
- unsigned char pid; /* protocol ID */
- unsigned char dcs; /* data coding scheme */
- short mr; /* message reference - actually a byte, but usde -1 for not set */
- int udl; /* user data length */
- int udhl; /* user data header length */
- unsigned char srr:1; /* Status Report request */
- unsigned char udhi:1; /* User Data Header required, even if length 0 */
- unsigned char rp:1; /* Reply Path */
- unsigned int vp; /* validity period in minutes, 0 for not set */
- unsigned short ud[SMSLEN]; /* user data (message), UCS-2 coded */
- unsigned char udh[SMSLEN]; /* user data header */
- char cli[20]; /* caller ID */
- unsigned char ophase; /* phase (0-79) for 0 and 1 frequencies (1300Hz and 2100Hz) */
- unsigned char ophasep; /* phase (0-79) for 1200 bps */
- unsigned char obyte; /* byte being sent */
- unsigned int opause; /* silent pause before sending (in sample periods) */
- unsigned char obitp; /* bit in byte */
- unsigned char osync; /* sync bits to send */
- unsigned char obytep; /* byte in data */
- unsigned char obyten; /* bytes in data */
- unsigned char omsg[256]; /* data buffer (out) */
- unsigned char imsg[200]; /* data buffer (in) */
+ unsigned char hangup; /*!< we are done... */
+ unsigned char err; /*!< set for any errors */
+ unsigned char smsc:1; /*!< we are SMSC */
+ unsigned char rx:1; /*!< this is a received message */
+ char queue[30]; /*!< queue name */
+ char oa[20]; /*!< originating address */
+ char da[20]; /*!< destination address */
+ time_t scts; /*!< time stamp, UTC */
+ unsigned char pid; /*!< protocol ID */
+ unsigned char dcs; /*!< data coding scheme */
+ short mr; /*!< message reference - actually a byte, but usde -1 for not set */
+ int udl; /*!< user data length */
+ int udhl; /*!< user data header length */
+ unsigned char srr:1; /*!< Status Report request */
+ unsigned char udhi:1; /*!< User Data Header required, even if length 0 */
+ unsigned char rp:1; /*!< Reply Path */
+ unsigned int vp; /*!< validity period in minutes, 0 for not set */
+ unsigned short ud[SMSLEN]; /*!< user data (message), UCS-2 coded */
+ unsigned char udh[SMSLEN]; /*!< user data header */
+ char cli[20]; /*!< caller ID */
+ unsigned char ophase; /*!< phase (0-79) for 0 and 1 frequencies (1300Hz and 2100Hz) */
+ unsigned char ophasep; /*!< phase (0-79) for 1200 bps */
+ unsigned char obyte; /*!< byte being sent */
+ unsigned int opause; /*!< silent pause before sending (in sample periods) */
+ unsigned char obitp; /*!< bit in byte */
+ unsigned char osync; /*!< sync bits to send */
+ unsigned char obytep; /*!< byte in data */
+ unsigned char obyten; /*!< bytes in data */
+ unsigned char omsg[256]; /*!< data buffer (out) */
+ unsigned char imsg[200]; /*!< data buffer (in) */
signed long long ims0,
imc0,
ims1,
- imc1; /* magnitude averages sin/cos 0/1 */
+ imc1; /*!< magnitude averages sin/cos 0/1 */
unsigned int idle;
- unsigned short imag; /* signal level */
+ unsigned short imag; /*!< signal level */
unsigned char ips0,
ips1,
ipc0,
- ipc1; /* phase sin/cos 0/1 */
- unsigned char ibitl; /* last bit */
- unsigned char ibitc; /* bit run length count */
- unsigned char iphasep; /* bit phase (0-79) for 1200 bps */
- unsigned char ibitn; /* bit number in byte being received */
- unsigned char ibytev; /* byte value being received */
- unsigned char ibytep; /* byte pointer in messafe */
- unsigned char ibytec; /* byte checksum for message */
- unsigned char ierr; /* error flag */
- unsigned char ibith; /* history of last bits */
+ ipc1; /*!< phase sin/cos 0/1 */
+ unsigned char ibitl; /*!< last bit */
+ unsigned char ibitc; /*!< bit run length count */
+ unsigned char iphasep; /*!< bit phase (0-79) for 1200 bps */
+ unsigned char ibitn; /*!< bit number in byte being received */
+ unsigned char ibytev; /*!< byte value being received */
+ unsigned char ibytep; /*!< byte pointer in messafe */
+ unsigned char ibytec; /*!< byte checksum for message */
+ unsigned char ierr; /*!< error flag */
+ unsigned char ibith; /*!< history of last bits */
unsigned char ibitt; /* total of 1's in last 3 bites */
/* more to go here */
} sms_t;
Modified: team/oej/realtimetext-t140/apps/app_voicemail.c
URL: http://svn.digium.com/view/asterisk/team/oej/realtimetext-t140/apps/app_voicemail.c?view=diff&rev=48260&r1=48259&r2=48260
==============================================================================
--- team/oej/realtimetext-t140/apps/app_voicemail.c (original)
+++ team/oej/realtimetext-t140/apps/app_voicemail.c Tue Dec 5 05:20:22 2006
@@ -142,6 +142,7 @@
/* Don't modify these here; set your umask at runtime instead */
#define VOICEMAIL_DIR_MODE 0777
#define VOICEMAIL_FILE_MODE 0666
+#define CHUNKSIZE 65536
#define VOICEMAIL_CONFIG "voicemail.conf"
#define ASTERISK_USERNAME "asterisk"
@@ -1099,6 +1100,7 @@
goto yuck;
}
if (!strcasecmp(coltitle, "recording")) {
+ off_t offset;
res = SQLGetData(stmt, x + 1, SQL_BINARY, NULL, 0, &colsize2);
fdlen = colsize2;
if (fd > -1) {
@@ -1109,24 +1111,27 @@
fd = -1;
continue;
}
- if (fd > -1) {
- if ((fdm = mmap(NULL, fdlen, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)) == -1) {
+ /* Read out in small chunks */
+ for (offset = 0; offset < colsize2; offset += CHUNKSIZE) {
+ /* +1 because SQLGetData likes null-terminating binary data */
+ if ((fdm = mmap(NULL, CHUNKSIZE + 1, PROT_READ | PROT_WRITE, MAP_SHARED, fd, offset)) == (void *)-1) {
ast_log(LOG_WARNING, "Could not mmap the output file: %s (%d)\n", strerror(errno), errno);
SQLFreeHandle(SQL_HANDLE_STMT, stmt);
ast_odbc_release_obj(obj);
goto yuck;
+ } else {
+ res = SQLGetData(stmt, x + 1, SQL_BINARY, fdm, CHUNKSIZE + 1, NULL);
+ munmap(fdm, 0);
+ if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
+ ast_log(LOG_WARNING, "SQL Get Data error!\n[%s]\n\n", sql);
+ unlink(full_fn);
+ SQLFreeHandle(SQL_HANDLE_STMT, stmt);
+ ast_odbc_release_obj(obj);
+ goto yuck;
+ }
}
}
- }
- if (fdm) {
- memset(fdm, 0, fdlen);
- res = SQLGetData(stmt, x + 1, SQL_BINARY, fdm, fdlen, &colsize2);
- if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
- ast_log(LOG_WARNING, "SQL Get Data error!\n[%s]\n\n", sql);
- SQLFreeHandle (SQL_HANDLE_STMT, stmt);
- ast_odbc_release_obj(obj);
- goto yuck;
- }
+ truncate(full_fn, fdlen);
}
} else {
res = SQLGetData(stmt, x + 1, SQL_CHAR, rowdata, sizeof(rowdata), NULL);
@@ -1147,8 +1152,6 @@
yuck:
if (f)
fclose(f);
- if (fdm)
- munmap(fdm, fdlen);
if (fd > -1)
close(fd);
return x - 1;
@@ -8003,6 +8006,8 @@
if (option_verbose > 2)
ast_verbose(VERBOSE_PREFIX_3 "Saving message as is\n");
ast_stream_and_wait(chan, "vm-msgsaved", "");
+ STORE(recordfile, vmu->mailbox, vmu->context, -1, chan, vmu, fmt, duration, vms);
+ DISPOSE(recordfile, -1);
cmd = 't';
return res;
}
Modified: team/oej/realtimetext-t140/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/team/oej/realtimetext-t140/channels/chan_sip.c?view=diff&rev=48260&r1=48259&r2=48260
==============================================================================
--- team/oej/realtimetext-t140/channels/chan_sip.c (original)
+++ team/oej/realtimetext-t140/channels/chan_sip.c Tue Dec 5 05:20:22 2006
@@ -242,15 +242,15 @@
\note this is for the INVITE that sets up the dialog
*/
enum invitestates {
- INV_NONE = 0, /*!< No state at all, maybe not an INVITE dialog */
- INV_CALLING, /*!< Invite sent, no answer */
- INV_PROCEEDING, /*!< We got 1xx message */
- INV_EARLY_MEDIA, /*!< We got 18x message with to-tag back */
- INV_COMPLETED, /*!< Got final response with error. Wait for ACK, then CONFIRMED */
- INV_CONFIRMED, /*!< Confirmed response - we've got an ack (Incoming calls only) */
- INV_TERMINATED, /*!< Transaction done - either successful (AST_STATE_UP) or failed, but done
- The only way out of this is a BYE from one side */
- INV_CANCELLED /*!< Transaction cancelled by client or server in non-terminated state */
+ INV_NONE = 0, /*!< No state at all, maybe not an INVITE dialog */
+ INV_CALLING = 1, /*!< Invite sent, no answer */
+ INV_PROCEEDING = 2, /*!< We got/sent 1xx message */
+ INV_EARLY_MEDIA = 3, /*!< We got 18x message with to-tag back */
+ INV_COMPLETED = 4, /*!< Got final response with error. Wait for ACK, then CONFIRMED */
+ INV_CONFIRMED = 5, /*!< Confirmed response - we've got an ack (Incoming calls only) */
+ INV_TERMINATED = 6, /*!< Transaction done - either successful (AST_STATE_UP) or failed, but done
+ The only way out of this is a BYE from one side */
+ INV_CANCELLED = 7, /*!< Transaction cancelled by client or server in non-terminated state */
};
/* Do _NOT_ make any changes to this enum, or the array following it;
@@ -961,8 +961,6 @@
time_t lastrtprx; /*!< Last RTP received */
time_t lastrtptx; /*!< Last RTP sent */
int rtptimeout; /*!< RTP timeout time */
- int rtpholdtimeout; /*!< RTP timeout when on hold */
- int rtpkeepalive; /*!< Send RTP packets for keepalive */
struct sockaddr_in recv; /*!< Received as */
struct in_addr ourip; /*!< Our IP */
struct ast_channel *owner; /*!< Who owns us (if we have an owner) */
@@ -1661,6 +1659,14 @@
ast_verbose("Initreq: %d headers, %d lines\n", p->initreq.headers, p->initreq.lines);
}
+/*! \brief Encapsulate setting of SIP_ALREADYGONE to be able to trace it with debugging */
+static void sip_alreadygone(struct sip_pvt *dialog)
+{
+ if (option_debug > 2)
+ ast_log(LOG_DEBUG, "Setting SIP_ALREADYGONE on dialog %s\n", dialog->callid);
+ ast_set_flag(&dialog->flags[0], SIP_ALREADYGONE);
+}
+
/*! \brief returns true if 'name' (with optional trailing whitespace)
* matches the sip method 'id'.
@@ -1939,7 +1945,7 @@
sip_pvt_lock(pkt->owner);
}
if (pkt->owner->owner) {
- ast_set_flag(&pkt->owner->flags[0], SIP_ALREADYGONE);
+ sip_alreadygone(pkt->owner);
ast_log(LOG_WARNING, "Hanging up call %s - no reply to our critical packet.\n", pkt->owner->callid);
ast_queue_hangup(pkt->owner->owner);
ast_channel_unlock(pkt->owner->owner);
@@ -2726,17 +2732,21 @@
if (dialog->rtp) {
ast_rtp_setdtmf(dialog->rtp, ast_test_flag(&dialog->flags[0], SIP_DTMF) != SIP_DTMF_INFO);
ast_rtp_setdtmfcompensate(dialog->rtp, ast_test_flag(&dialog->flags[1], SIP_PAGE2_RFC2833_COMPENSATE));
+ ast_rtp_set_rtptimeout(dialog->rtp, peer->rtptimeout);
+ ast_rtp_set_rtpholdtimeout(dialog->rtp, peer->rtpholdtimeout);
+ ast_rtp_set_rtpkeepalive(dialog->rtp, peer->rtpkeepalive);
+ /* Set Frame packetization */
+ ast_rtp_codec_setpref(dialog->rtp, &dialog->prefs);
+ dialog->autoframing = peer->autoframing;
}
if (dialog->vrtp) {
ast_rtp_setdtmf(dialog->vrtp, 0);
ast_rtp_setdtmfcompensate(dialog->vrtp, 0);
- }
-
- /* Set Frame packetization */
- if (dialog->rtp) {
- ast_rtp_codec_setpref(dialog->rtp, &dialog->prefs);
- dialog->autoframing = peer->autoframing;
- }
+ ast_rtp_set_rtptimeout(dialog->vrtp, peer->rtptimeout);
+ ast_rtp_set_rtpholdtimeout(dialog->vrtp, peer->rtpholdtimeout);
+ ast_rtp_set_rtpkeepalive(dialog->vrtp, peer->rtpkeepalive);
+ }
+
ast_string_field_set(dialog, peername, peer->username);
ast_string_field_set(dialog, authname, peer->username);
ast_string_field_set(dialog, username, peer->username);
@@ -2774,8 +2784,6 @@
dialog->noncodeccapability &= ~AST_RTP_DTMF;
ast_string_field_set(dialog, context, peer->context);
dialog->rtptimeout = peer->rtptimeout;
- dialog->rtpholdtimeout = peer->rtpholdtimeout;
- dialog->rtpkeepalive = peer->rtpkeepalive;
if (peer->call_limit)
ast_set_flag(&dialog->flags[0], SIP_CALL_LIMIT);
dialog->maxcallbitrate = peer->maxcallbitrate;
@@ -3099,9 +3107,9 @@
/* Check the list of users only for incoming calls */
if (global_limitonpeers == FALSE && !outgoing && (u = find_user(name, 1))) {
- inuse = &u->inUse;
- call_limit = &u->call_limit;
- inringing = NULL;
+ inuse = &u->inUse;
+ call_limit = &u->call_limit;
+ inringing = NULL;
} else if ( (p = find_peer(ast_strlen_zero(fup->peername) ? name : fup->peername, NULL, 1) ) ) { /* Try to find peer */
inuse = &p->inUse;
call_limit = &p->call_limit;
@@ -3405,7 +3413,7 @@
return 0;
}
/* If the call is not UP, we need to send CANCEL instead of BYE */
- if (ast->_state == AST_STATE_RING || ast->_state == AST_STATE_RINGING) {
+ if (p->invitestate < INV_COMPLETED) {
needcancel = TRUE;
if (option_debug > 3)
ast_log(LOG_DEBUG, "Hanging up channel in state %s (not UP)\n", ast_state2str(ast->_state));
@@ -3426,7 +3434,7 @@
*/
if (ast_test_flag(&p->flags[0], SIP_ALREADYGONE))
needdestroy = 1; /* Set destroy flag at end of this function */
- else
+ else if (p->invitestate != INV_CALLING)
sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
/* Start the process if it's not already started */
@@ -3488,6 +3496,7 @@
but we can't send one while we have "INVITE" outstanding. */
ast_set_flag(&p->flags[0], SIP_PENDINGBYE);
ast_clear_flag(&p->flags[0], SIP_NEEDREINVITE);
+ sip_cancel_destroy(p);
}
}
}
@@ -3605,15 +3614,12 @@
case AST_FRAME_MODEM:
if (p) {
sip_pvt_lock(p);
- if (p->udptl) {
- if ((ast->_state != AST_STATE_UP) &&
- !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) &&
- !ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
- transmit_response_with_t38_sdp(p, "183 Session Progress", &p->initreq, XMIT_UNRELIABLE);
- ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT);
- }
+ /* UDPTL requires two-way communication, so early media is not needed here.
+ we simply forget the frames if we get modem frames before the bridge is up.
+ Fax will re-transmit.
+ */
+ if (p->udptl && ast->_state != AST_STATE_UP)
res = ast_udptl_write(p->udptl, frame);
- }
sip_pvt_unlock(p);
}
break;
@@ -3740,6 +3746,7 @@
switch(condition) {
case AST_CONTROL_RINGING:
if (ast->_state == AST_STATE_RING) {
+ p->invitestate = INV_EARLY_MEDIA;
if (!ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) ||
(ast_test_flag(&p->flags[0], SIP_PROG_INBAND) == SIP_PROG_INBAND_NEVER)) {
/* Send 180 ringing if out-of-band seems reasonable */
@@ -3756,7 +3763,8 @@
case AST_CONTROL_BUSY:
if (ast->_state != AST_STATE_UP) {
transmit_response(p, "486 Busy Here", &p->initreq);
- ast_set_flag(&p->flags[0], SIP_ALREADYGONE);
+ p->invitestate = INV_TERMINATED;
+ sip_alreadygone(p);
ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV);
break;
}
@@ -3765,7 +3773,8 @@
case AST_CONTROL_CONGESTION:
if (ast->_state != AST_STATE_UP) {
transmit_response(p, "503 Service Unavailable", &p->initreq);
- ast_set_flag(&p->flags[0], SIP_ALREADYGONE);
+ p->invitestate = INV_TERMINATED;
+ sip_alreadygone(p);
ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV);
break;
}
@@ -3776,6 +3785,7 @@
!ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) &&
!ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
transmit_response(p, "100 Trying", &p->initreq);
+ p->invitestate = INV_PROCEEDING;
break;
}
res = -1;
@@ -3784,6 +3794,7 @@
if ((ast->_state != AST_STATE_UP) &&
!ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) &&
!ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
+ p->invitestate = INV_EARLY_MEDIA;
transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, XMIT_UNRELIABLE);
ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT);
break;
@@ -4302,16 +4313,19 @@
ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) != SIP_DTMF_INFO);
ast_rtp_setdtmfcompensate(p->rtp, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE));
ast_rtp_settos(p->rtp, global_tos_audio);
+ ast_rtp_set_rtptimeout(p->rtp, global_rtptimeout);
+ ast_rtp_set_rtpholdtimeout(p->rtp, global_rtpholdtimeout);
+ ast_rtp_set_rtpkeepalive(p->rtp, global_rtpkeepalive);
if (p->vrtp) {
ast_rtp_settos(p->vrtp, global_tos_video);
ast_rtp_setdtmf(p->vrtp, 0);
ast_rtp_setdtmfcompensate(p->vrtp, 0);
+ ast_rtp_set_rtptimeout(p->vrtp, global_rtptimeout);
+ ast_rtp_set_rtpholdtimeout(p->vrtp, global_rtpholdtimeout);
+ ast_rtp_set_rtpkeepalive(p->vrtp, global_rtpkeepalive);
}
if (p->udptl)
ast_udptl_settos(p->udptl, global_tos_audio);
- p->rtptimeout = global_rtptimeout;
- p->rtpholdtimeout = global_rtpholdtimeout;
- p->rtpkeepalive = global_rtpkeepalive;
p->maxcallbitrate = default_maxcallbitrate;
}
@@ -10430,6 +10444,7 @@
ast_cli(fd, " T1 minimum: %d\n", global_t1min);
ast_cli(fd, " Relax DTMF: %s\n", global_relaxdtmf ? "Yes" : "No");
ast_cli(fd, " Compact SIP headers: %s\n", compactheaders ? "Yes" : "No");
+ ast_cli(fd, " RTP Keepalive: %d %s\n", global_rtpkeepalive, global_rtpkeepalive ? "" : "(Disabled)" );
ast_cli(fd, " RTP Timeout: %d %s\n", global_rtptimeout, global_rtptimeout ? "" : "(Disabled)" );
ast_cli(fd, " RTP Hold Timeout: %d %s\n", global_rtpholdtimeout, global_rtpholdtimeout ? "" : "(Disabled)");
ast_cli(fd, " MWI NOTIFY mime type: %s\n", default_notifymime);
@@ -11826,6 +11841,9 @@
if (bridgepvt->udptl) {
if (p->t38.state == T38_PEER_REINVITE) {
sip_handle_t38_reinvite(bridgepeer, p, 0);
+ ast_rtp_set_rtptimers_onhold(p->rtp);
+ if (p->vrtp)
+ ast_rtp_set_rtptimers_onhold(p->vrtp); /* Turn off RTP timers while we send fax */
} else if (p->t38.state == T38_DISABLED && bridgepeer && (bridgepvt->t38.state == T38_ENABLED)) {
ast_log(LOG_WARNING, "RTP re-inivte after T38 session not handled yet !\n");
/* Insted of this we should somehow re-invite the other side of the bridge to RTP */
@@ -11892,7 +11910,7 @@
if (p->authtries == MAX_AUTHTRIES || do_proxy_auth(p, req, resp, SIP_INVITE, 1)) {
ast_log(LOG_NOTICE, "Failed to authenticate on INVITE to '%s'\n", get_header(&p->initreq, "From"));
ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
- ast_set_flag(&p->flags[0], SIP_ALREADYGONE);
+ sip_alreadygone(p);
if (p->owner)
ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
}
@@ -11906,20 +11924,23 @@
if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner)
ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
- ast_set_flag(&p->flags[0], SIP_ALREADYGONE);
+ sip_alreadygone(p);
break;
case 404: /* Not found */
transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE))
ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
- ast_set_flag(&p->flags[0], SIP_ALREADYGONE);
+ sip_alreadygone(p);
break;
case 481: /* Call leg does not exist */
- /* Could be REFER or INVITE */
+ /* Could be REFER caused INVITE with replaces */
ast_log(LOG_WARNING, "Re-invite to non-existing call leg on other UA. SIP dialog '%s'. Giving up.\n", p->callid);
transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
+ if (p->owner)
+ ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
+ sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
break;
case 491: /* Pending */
@@ -11972,7 +11993,16 @@
ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
}
break;
-
+ case 481: /* Call leg does not exist */
+
+ /* A transfer with Replaces did not work */
+ /* OEJ: We should Set flag, cancel the REFER, go back
+ to original call - but right now we can't */
+ ast_log(LOG_WARNING, "Remote host can't match REFER request to call '%s'. Giving up.\n", p->callid);
+ if (p->owner)
+ ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
+ ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
+ break;
case 500: /* Server error */
case 501: /* Method not implemented */
@@ -12330,21 +12360,9 @@
break;
case 481: /* Call leg does not exist */
if (sipmethod == SIP_INVITE) {
- /* First we ACK */
- transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
- if (option_debug)
- ast_log(LOG_DEBUG, "Got 481 on Invite. Assuming INVITE with REPLACEs failed to '%s'\n", get_header(&p->initreq, "From"));
- if (owner)
- ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
- sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
+ handle_response_invite(p, resp, rest, req, seqno);
} else if (sipmethod == SIP_REFER) {
- /* A transfer with Replaces did not work */
- /* OEJ: We should Set flag, cancel the REFER, go back
- to original call - but right now we can't */
- ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid);
- if (owner)
- ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
- ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
+ handle_response_refer(p, resp, rest, req, seqno);
} else if (sipmethod == SIP_BYE) {
/* The other side has no transaction to bye,
just assume it's all right then */
@@ -12386,7 +12404,6 @@
/* Fatal response */
if ((option_verbose > 2) && (resp != 487))
ast_verbose(VERBOSE_PREFIX_3 "Got SIP response %d \"%s\" back from %s\n", resp, rest, ast_inet_ntoa(p->sa.sin_addr));
- ast_set_flag(&p->flags[0], SIP_ALREADYGONE);
stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */
@@ -12445,7 +12462,7 @@
/* ACK on invite */
if (sipmethod == SIP_INVITE)
transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
- ast_set_flag(&p->flags[0], SIP_ALREADYGONE);
+ sip_alreadygone(p);
if (!p->owner)
ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
} else if ((resp >= 100) && (resp < 200)) {
@@ -13534,7 +13551,7 @@
transmit_response(p, "503 Unavailable", req); /* OEJ - Right answer? */
else
transmit_response_reliable(p, "503 Unavailable", req);
- ast_set_flag(&p->flags[0], SIP_ALREADYGONE);
+ sip_alreadygone(p);
/* Unlock locks so ast_hangup can do its magic */
sip_pvt_unlock(p);
c->hangupcause = AST_CAUSE_CALL_REJECTED;
@@ -13858,7 +13875,7 @@
transmit_response(p, "603 Declined (No dialog)", req);
if (!ast_test_flag(req, SIP_PKT_IGNORE)) {
append_history(p, "Xfer", "Refer failed. Outside of dialog.");
- ast_set_flag(&p->flags[0], SIP_ALREADYGONE);
+ sip_alreadygone(p);
ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
}
return 0;
@@ -14117,7 +14134,7 @@
{
check_via(p, req);
- ast_set_flag(&p->flags[0], SIP_ALREADYGONE);
+ sip_alreadygone(p);
p->invitestate = INV_CANCELLED;
if (p->owner && p->owner->_state == AST_STATE_UP) {
@@ -14160,7 +14177,7 @@
if (sipdebug && option_debug)
ast_log(LOG_DEBUG, "Initializing initreq for method %s - callid %s\n", sip_methods[req->method].text, p->callid);
check_via(p, req);
- ast_set_flag(&p->flags[0], SIP_ALREADYGONE);
+ sip_alreadygone(p);
/* Get RTCP quality before end of call */
if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY) || p->owner) {
@@ -14915,52 +14932,66 @@
/*! \brief helper function for the monitoring thread */
-static void check_rtp_timeout(struct sip_pvt *sip, time_t t)
-{
- if (sip->rtp && sip->owner &&
- (sip->owner->_state == AST_STATE_UP) &&
- !sip->redirip.sin_addr.s_addr) {
- if (sip->lastrtptx &&
- sip->rtpkeepalive &&
- (t > sip->lastrtptx + sip->rtpkeepalive)) {
- /* Need to send an empty RTP packet */
- sip->lastrtptx = time(NULL);
- ast_rtp_sendcng(sip->rtp, 0);
- }
- if (sip->lastrtprx &&
- (sip->rtptimeout || sip->rtpholdtimeout) &&
- (t > sip->lastrtprx + sip->rtptimeout)) {
- /* Might be a timeout now -- see if we're on hold */
- struct sockaddr_in sin;
- ast_rtp_get_peer(sip->rtp, &sin);
- if (sin.sin_addr.s_addr ||
- (sip->rtpholdtimeout &&
- (t > sip->lastrtprx + sip->rtpholdtimeout))) {
- /* Needs a hangup */
- if (sip->rtptimeout) {
- while (sip->owner && ast_channel_trylock(sip->owner)) {
- sip_pvt_unlock(sip);
- usleep(1);
- sip_pvt_lock(sip);
- }
- if (sip->owner) {
- if (!(ast_rtp_get_bridged(sip->rtp))) {
- ast_log(LOG_NOTICE,
- "Disconnecting call '%s' for lack of RTP activity in %ld seconds\n",
- sip->owner->name,
- (long) (t - sip->lastrtprx));
- /* Issue a softhangup */
- ast_softhangup_nolock(sip->owner, AST_SOFTHANGUP_DEV);
- } else
- ast_log(LOG_NOTICE, "'%s' will not be disconnected in %ld seconds because it is directly bridged to another RTP stream\n", sip->owner->name, (long) (t - sip->lastrtprx));
- ast_channel_unlock(sip->owner);
- /* forget the timeouts for this call, since a hangup
- has already been requested and we don't want to
- repeatedly request hangups
- */
- sip->rtptimeout = 0;
- sip->rtpholdtimeout = 0;
- }
+static void check_rtp_timeout(struct sip_pvt *dialog, time_t t)
+{
+ /* If we have no RTP or no active owner, no need to check timers */
+ if (!dialog->rtp || !dialog->owner)
+ return;
+ /* If the call is not in UP state or redirected outside Asterisk, no need to check timers */
+ if (dialog->owner->_state != AST_STATE_UP || dialog->redirip.sin_addr.s_addr)
+ return;
+
+ /* If we have no timers set, return now */
+ if (ast_rtp_get_rtpkeepalive(dialog->rtp) == 0 || (ast_rtp_get_rtptimeout(dialog->rtp) == 0 && ast_rtp_get_rtpholdtimeout(dialog->rtp) == 0))
+ return;
+
+ /* Check AUDIO RTP keepalives */
+ if (dialog->lastrtptx && ast_rtp_get_rtpkeepalive(dialog->rtp) &&
+ (t > dialog->lastrtptx + ast_rtp_get_rtpkeepalive(dialog->rtp))) {
+ /* Need to send an empty RTP packet */
+ dialog->lastrtptx = time(NULL);
+ ast_rtp_sendcng(dialog->rtp, 0);
+ }
+
+ /*! \todo Check video RTP keepalives
+
+ Do we need to move the lastrtptx to the RTP structure to have one for audio and one
+ for video? It really does belong to the RTP structure.
+ */
+
+ /* Check AUDIO RTP timers */
+ if (dialog->lastrtprx && (ast_rtp_get_rtptimeout(dialog->rtp) || ast_rtp_get_rtpholdtimeout(dialog->rtp)) &&
+ (t > dialog->lastrtprx + ast_rtp_get_rtptimeout(dialog->rtp))) {
+
+ /* Might be a timeout now -- see if we're on hold */
+ struct sockaddr_in sin;
+ ast_rtp_get_peer(dialog->rtp, &sin);
+ if (sin.sin_addr.s_addr || (ast_rtp_get_rtpholdtimeout(dialog->rtp) &&
+ (t > dialog->lastrtprx + ast_rtp_get_rtpholdtimeout(dialog->rtp)))) {
+ /* Needs a hangup */
+ if (dialog->rtptimeout) {
+ while (dialog->owner && ast_channel_trylock(dialog->owner)) {
+ sip_pvt_unlock(dialog);
+ usleep(1);
+ sip_pvt_lock(dialog);
+ }
+ if (!(ast_rtp_get_bridged(dialog->rtp))) {
+ ast_log(LOG_NOTICE, "Disconnecting call '%s' for lack of RTP activity in %ld seconds\n",
+ dialog->owner->name, (long) (t - dialog->lastrtprx));
+ /* Issue a softhangup */
+ ast_softhangup_nolock(dialog->owner, AST_SOFTHANGUP_DEV);
+ } else
+ ast_log(LOG_NOTICE, "'%s' will not be disconnected in %ld seconds because it is directly bridged to another RTP stream\n", dialog->owner->name, (long) (t - dialog->lastrtprx));
+ ast_channel_unlock(dialog->owner);
+ /* forget the timeouts for this call, since a hangup
+ has already been requested and we don't want to
+ repeatedly request hangups
+ */
+ ast_rtp_set_rtptimeout(dialog->rtp, 0);
+ ast_rtp_set_rtpholdtimeout(dialog->rtp, 0);
+ if (dialog->vrtp) {
+ ast_rtp_set_rtptimeout(dialog->vrtp, 0);
+ ast_rtp_set_rtpholdtimeout(dialog->vrtp, 0);
}
}
}
@@ -14974,7 +15005,7 @@
static void *do_monitor(void *data)
{
int res;
- struct sip_pvt *sip;
+ struct sip_pvt *dialog;
struct sip_peer *peer = NULL;
time_t t;
int fastrestart = FALSE;
@@ -15002,6 +15033,7 @@
if (sipsock > -1)
sipsock_read_id = ast_io_change(io, sipsock_read_id, sipsock, NULL, 0, NULL);
}
+
/* Check for dialogs needing to be killed */
dialoglist_lock();
restartsearch:
@@ -15010,18 +15042,20 @@
of time since the last time we did it (when MWI is being sent, we can
get back to this point every millisecond or less)
*/
- for (sip = dialoglist; !fastrestart && sip; sip = sip->next) {
- sip_pvt_lock(sip);
+ for (dialog = dialoglist; !fastrestart && dialog; dialog = dialog->next) {
+ sip_pvt_lock(dialog);
/* Check RTP timeouts and kill calls if we have a timeout set and do not get RTP */
- check_rtp_timeout(sip, t);
+ check_rtp_timeout(dialog, t);
/* If we have sessions that needs to be destroyed, do it now */
- if (ast_test_flag(&sip->flags[0], SIP_NEEDDESTROY) && !sip->packets &&
- !sip->owner) {
- sip_pvt_unlock(sip);
- __sip_destroy(sip, TRUE, FALSE);
+ /* Check if we have outstanding requests not responsed to or an active call
+ - if that's the case, wait with destruction */
+ if (ast_test_flag(&dialog->flags[0], SIP_NEEDDESTROY) && !dialog->packets &&
+ !dialog->owner) {
+ sip_pvt_unlock(dialog);
+ __sip_destroy(dialog, TRUE, FALSE);
goto restartsearch;
}
- sip_pvt_unlock(sip);
+ sip_pvt_unlock(dialog);
}
dialoglist_unlock();
@@ -15030,7 +15064,8 @@
res = ast_sched_wait(sched);
if ((res < 0) || (res > 1000))
res = 1000;
- /* If we might need to send more mailboxes, don't wait long at all.*/
+
+ /* If we might need to send more mailbox notifications, don't wait long at all.*/
if (fastrestart)
res = 1;
res = ast_io_wait(io, res);
@@ -16268,10 +16303,10 @@
compactheaders = ast_true(v->value);
} else if (!strcasecmp(v->name, "notifymimetype")) {
ast_copy_string(default_notifymime, v->value, sizeof(default_notifymime));
+ } else if (!strcasecmp(v->name, "limitonpeers")) {
+ global_limitonpeers = ast_true(v->value);
} else if (!strcasecmp(v->name, "notifyringing")) {
global_notifyringing = ast_true(v->value);
- } else if (!strcasecmp(v->name, "limitpeersonly")) {
- global_limitonpeers = ast_true(v->value);
} else if (!strcasecmp(v->name, "notifyhold")) {
global_notifyhold = ast_true(v->value);
} else if (!strcasecmp(v->name, "alwaysauthreject")) {
Modified: team/oej/realtimetext-t140/configs/extensions.conf.sample
URL: http://svn.digium.com/view/asterisk/team/oej/realtimetext-t140/configs/extensions.conf.sample?view=diff&rev=48260&r1=48259&r2=48260
==============================================================================
--- team/oej/realtimetext-t140/configs/extensions.conf.sample (original)
+++ team/oej/realtimetext-t140/configs/extensions.conf.sample Tue Dec 5 05:20:22 2006
@@ -167,7 +167,7 @@
;
; List canonical entries here
;
-;exten => 12564286000,1,Macro(std-exten,6000,IAX2/foo)
+;exten => 12564286000,1,Macro(stdexten,6000,IAX2/foo)
;exten => _125642860XX,1,Dial(IAX2/otherbox/${EXTEN:7})
[dundi-e164-customers]
Modified: team/oej/realtimetext-t140/configs/sip.conf.sample
URL: http://svn.digium.com/view/asterisk/team/oej/realtimetext-t140/configs/sip.conf.sample?view=diff&rev=48260&r1=48259&r2=48260
==============================================================================
--- team/oej/realtimetext-t140/configs/sip.conf.sample (original)
+++ team/oej/realtimetext-t140/configs/sip.conf.sample Tue Dec 5 05:20:22 2006
@@ -95,12 +95,6 @@
;language=en ; Default language setting for all users/peers
; This may also be set for individual users/peers
;relaxdtmf=yes ; Relax dtmf handling
-;rtptimeout=60 ; Terminate call if 60 seconds of no RTP or RTCP activity
- ; when we're not on hold. This is to be able to hangup
- ; a call in the case of a phone disappearing from the net,
- ; like a powerloss or grandma tripping over a cable.
-;rtpholdtimeout=300 ; Terminate call if 300 seconds of no RTP or RTCP activity
- ; when we're on hold (must be > rtptimeout)
;trustrpid = no ; If Remote-Party-ID should be trusted
;sendrpid = yes ; If Remote-Party-ID should be sent
;progressinband=never ; If we should generate in-band ringing always
@@ -162,6 +156,21 @@
;
;regcontext=sipregistrations
;
+;--------------------------- RTP timers ----------------------------------------------------
+; These timers are currently used for both audio and video streams. The RTP timeouts
+; are only applied to the audio channel.
+; The settings are settable in the global section as well as per device
+;
+;rtptimeout=60 ; Terminate call if 60 seconds of no RTP or RTCP activity
+ ; on the audio channel
[... 1206 lines stripped ...]
More information about the asterisk-commits
mailing list