[asterisk-commits] rizzo: branch rizzo/astobj2 r57927 -
/team/rizzo/astobj2/channels/chan_sip.c
asterisk-commits at lists.digium.com
asterisk-commits at lists.digium.com
Mon Mar 5 12:51:43 MST 2007
Author: rizzo
Date: Mon Mar 5 13:51:42 2007
New Revision: 57927
URL: http://svn.digium.com/view/asterisk?view=rev&rev=57927
Log:
merge from trunk up to svn 53098
(also fix a bug in 53092 original line 3162, *inuse = 0
must check for inuse != NULL
Modified:
team/rizzo/astobj2/channels/chan_sip.c
Modified: team/rizzo/astobj2/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/team/rizzo/astobj2/channels/chan_sip.c?view=diff&rev=57927&r1=57926&r2=57927
==============================================================================
--- team/rizzo/astobj2/channels/chan_sip.c (original)
+++ team/rizzo/astobj2/channels/chan_sip.c Mon Mar 5 13:51:42 2007
@@ -567,7 +567,6 @@
/*! \brief Codecs that we support by default: */
static int global_capability = AST_FORMAT_ULAW | AST_FORMAT_ALAW | AST_FORMAT_GSM | AST_FORMAT_H263;
-static int noncodeccapability = AST_RTP_DTMF;
/* Object counters */
static int suserobjs = 0; /*!< Static users */
@@ -990,6 +989,7 @@
int peercapability; /*!< Supported peer capability */
int prefcodec; /*!< Preferred codec (outbound only) */
int noncodeccapability; /*!< DTMF RFC2833 telephony-event */
+ int jointnoncodeccapability; /*!< Joint Non codec capability */
int redircodecs; /*!< Redirect codecs */
int maxcallbitrate; /*!< Maximum Call Bitrate for Video Calls */
struct t38properties t38; /*!< T38 settings */
@@ -1188,6 +1188,7 @@
int capability; /*!< Codec capability */
int inUse; /*!< Number of calls in use */
int call_limit; /*!< Limit of concurrent calls */
+ int busy_limit; /*!< Limit where we signal busy */
enum transfermodes allowtransfer; /*! SIP Refer restriction scheme */
struct ast_ha *ha; /*!< Access control list */
struct ast_variable *chanvars; /*!< Variables to set for channel created by user */
@@ -1551,7 +1552,6 @@
static struct sip_peer *temp_peer(const char *name);
static struct sip_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime);
static struct sip_user *build_user(const char *name, struct ast_variable *v, int realtime);
-static int update_call_counter(struct sip_pvt *fup, int event);
static void sip_destroy_peer(struct sip_peer *peer);
static void sip_destroy_user(struct sip_user *user);
static int sip_poke_peer(struct sip_peer *peer);
@@ -1835,10 +1835,20 @@
free(reg);
}
-static void *unref_registry(struct sip_registry *reg)
-{
+static void *registry_unref(struct sip_registry *reg)
+{
+ if (option_debug > 2)
+ ast_log(LOG_DEBUG, "SIP Registry %s: refcount now %d\n", reg->hostname, reg->refcount - 1);
ASTOBJ_UNREF(reg, sip_registry_destroy);
return NULL;
+}
+
+/*! \brief Add object reference to SIP registry */
+static struct sip_registry *registry_addref(struct sip_registry *reg)
+{
+ if (option_debug > 2)
+ ast_log(LOG_DEBUG, "SIP Registry %s: refcount now %d\n", reg->hostname, reg->refcount + 1);
+ return ASTOBJ_REF(reg); /* Add pointer to registry in packet */
}
static void registry_destroy_all(void)
@@ -1847,7 +1857,7 @@
* we need to remove them before doing the DESTROYALL
*/
ASTOBJ_CONTAINER_TRAVERSE(®l,1, do {
- unref_registry(iterator);
+ registry_unref(iterator);
} while (0));
ASTOBJ_CONTAINER_DESTROYALL(®l, sip_registry_destroy);
@@ -2230,7 +2240,7 @@
} else {
/* If no channel owner, destroy now */
/* Let the peerpoke system expire packets when the timer expires for poke_noanswer */
- if (pkt->method != SIP_OPTIONS)
+ if (pkt->method != SIP_OPTIONS && pkt->method != SIP_REGISTER)
set_destroy(pvt);
}
}
@@ -3028,7 +3038,7 @@
do_setnat(dialog, ast_test_flag(&dialog->flags[0], SIP_NAT) & SIP_NAT_ROUTE );
if (dialog->rtp) {
- ast_rtp_setdtmf(dialog->rtp, ast_test_flag(&dialog->flags[0], SIP_DTMF) != SIP_DTMF_INFO);
+ ast_rtp_setdtmf(dialog->rtp, ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833);
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);
@@ -3283,6 +3293,11 @@
if (sip_debug_test_pvt(p) || option_debug > 2)
ast_verbose("Really destroying SIP dialog '%s' Method: %s\n", p->callid, sip_methods[p->method].text);
+ if (ast_test_flag(&p->flags[0], SIP_INC_COUNT)) {
+ update_call_counter(p, DEC_CALL_LIMIT);
+ if (option_debug > 1)
+ ast_log(LOG_DEBUG, "This call did not properly clean up call limits. Call ID %s\n", p->callid);
+ }
/* Remove link from peer to subscription of MWI */
if (p->relatedpeer && p->relatedpeer->mwipvt) /* XXX sip_destroy ? */
@@ -3362,7 +3377,7 @@
*/
if (p->registry->register_pvt == p)
p->registry->register_pvt = pvt_unref(p->registry->register_pvt);
- p->registry = unref_registry(p->registry);
+ p->registry = registry_unref(p->registry);
}
/* Unlink us from the owner if we have one */
@@ -3428,6 +3443,7 @@
if (option_debug > 2)
ast_log(LOG_DEBUG, "Updating call counter for %s call\n", outgoing ? "outgoing" : "incoming");
+
/* Test if we need to check call limits, in order to avoid
realtime lookups if we do not need it */
if (!ast_test_flag(&fup->flags[0], SIP_CALL_LIMIT))
@@ -3455,28 +3471,27 @@
switch(event) {
/* incoming and outgoing affects the inUse counter */
case DEC_CALL_LIMIT:
- if ( *inuse > 0 ) {
- if (ast_test_flag(&fup->flags[0], SIP_INC_COUNT))
- (*inuse)--;
- } else {
+ /* Decrement inuse count if applicable */
+ if (inuse && ast_test_flag(&fup->flags[0], SIP_INC_COUNT)) {
+ ast_atomic_fetchadd_int(inuse, -1);
+ ast_clear_flag(&fup->flags[0], SIP_INC_COUNT);
+ } else if (inuse)
*inuse = 0;
- }
- if (inringing) {
- if (ast_test_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING)) {
- if (*inringing > 0)
- (*inringing)--;
- else
- ast_log(LOG_WARNING, "Inringing for peer '%s' < 0?\n", fup->peername);
- ast_clear_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING);
- }
- }
- if (option_debug > 1 || sipdebug) {
+ /* Decrement ringing count if applicable */
+ if (inringing && ast_test_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING)) {
+ ast_atomic_fetchadd_int(inringing, -1);
+ ast_clear_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING);
+ }
+ /* Decrement onhold count if applicable */
+ if (ast_test_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD) && global_notifyhold)
+ sip_peer_hold(fup, FALSE);
+ if (option_debug > 1 || sipdebug)
ast_log(LOG_DEBUG, "Call %s %s '%s' removed from call limit %d\n", outgoing ? "to" : "from", u ? "user":"peer", name, *call_limit);
- }
break;
case INC_CALL_RINGING:
case INC_CALL_LIMIT:
+ /* If call limit is active and we have reached the limit, reject the call */
if (*call_limit > 0 ) {
if (*inuse >= *call_limit) {
ast_log(LOG_ERROR, "Call %s %s '%s' rejected due to usage limit of %d\n", outgoing ? "to" : "from", u ? "user":"peer", name, *call_limit);
@@ -3489,12 +3504,12 @@
}
if (inringing && (event == INC_CALL_RINGING)) {
if (!ast_test_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING)) {
- (*inringing)++;
+ ast_atomic_fetchadd_int(inringing, +1);
ast_set_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING);
}
}
/* Continue */
- (*inuse)++;
+ ast_atomic_fetchadd_int(inuse, +1);
ast_set_flag(&fup->flags[0], SIP_INC_COUNT);
if (option_debug > 1 || sipdebug) {
ast_log(LOG_DEBUG, "Call %s %s '%s' is %d out of %d\n", outgoing ? "to" : "from", u ? "user":"peer", name, *inuse, *call_limit);
@@ -3502,14 +3517,9 @@
break;
case DEC_CALL_RINGING:
- if (inringing) {
- if (ast_test_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING)) {
- if (*inringing > 0)
- (*inringing)--;
- else
- ast_log(LOG_WARNING, "Inringing for peer '%s' < 0?\n", p->name);
- ast_clear_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING);
- }
+ if (inringing && ast_test_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING)) {
+ ast_atomic_fetchadd_int(inringing, -1);
+ ast_clear_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING);
}
break;
@@ -3749,6 +3759,7 @@
if (ast->tech_pvt)
ast->tech_pvt = pvt_unref(ast->tech_pvt);
+ ast_module_unref(ast_module_info->self);
/* Do not destroy this pvt until we have timeout or
get an answer to the BYE or INVITE/CANCEL
If we get no answer during retransmit period, drop the call anyway.
@@ -3941,7 +3952,7 @@
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)
+ if (p->udptl && ast->_state == AST_STATE_UP)
res = ast_udptl_write(p->udptl, frame);
sip_pvt_unlock(p);
}
@@ -4266,6 +4277,7 @@
if (!ast_strlen_zero(i->language))
ast_string_field_set(tmp, language, i->language);
i->owner = tmp;
+ ast_module_ref(ast_module_info->self);
ast_copy_string(tmp->context, i->context, sizeof(tmp->context));
ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten));
@@ -4660,7 +4672,7 @@
ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "and video" : "", strerror(errno));
return __sip_destroy(p);
}
- ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) != SIP_DTMF_INFO);
+ ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833);
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);
@@ -5006,7 +5018,7 @@
reg->callid_valid = FALSE;
reg->ocseq = INITIAL_CSEQ;
ASTOBJ_CONTAINER_LINK(®l, reg); /* Add the new registry entry to the list */
- unref_registry(reg); /* release the reference given by ASTOBJ_INIT. The container has another reference */
+ registry_unref(reg); /* release the reference given by ASTOBJ_INIT. The container has another reference */
return 0;
}
@@ -5606,7 +5618,7 @@
newjointcapability = p->capability & (peercapability | vpeercapability);
newpeercapability = (peercapability | vpeercapability);
- newnoncodeccapability = noncodeccapability & peernoncodeccapability;
+ newnoncodeccapability = p->noncodeccapability & peernoncodeccapability;
if (debug) {
@@ -5620,7 +5632,7 @@
ast_getformatname_multiple(s4, BUFSIZ, newjointcapability));
ast_verbose("Non-codec capabilities (dtmf): us - %s, peer - %s, combined - %s\n",
- ast_rtp_lookup_mime_multiple(s1, BUFSIZ, noncodeccapability, 0, 0),
+ ast_rtp_lookup_mime_multiple(s1, BUFSIZ, p->noncodeccapability, 0, 0),
ast_rtp_lookup_mime_multiple(s2, BUFSIZ, peernoncodeccapability, 0, 0),
ast_rtp_lookup_mime_multiple(s3, BUFSIZ, newnoncodeccapability, 0, 0));
}
@@ -5641,7 +5653,7 @@
they are acceptable */
p->jointcapability = newjointcapability; /* Our joint codec profile for this call */
p->peercapability = newpeercapability; /* The other sides capability in latest offer */
- p->noncodeccapability = newnoncodeccapability; /* DTMF capabilities */
+ p->jointnoncodeccapability = newnoncodeccapability; /* DTMF capabilities */
ast_rtp_pt_copy(p->rtp, newaudiortp);
if (p->vrtp)
@@ -5683,7 +5695,7 @@
if (option_debug > 3)
ast_log(LOG_DEBUG, "We have an owner, now see if we need to change this call\n");
- if (!(p->owner->nativeformats & p->jointcapability & AST_FORMAT_AUDIO_MASK)) {
+ if (!(p->owner->nativeformats & p->jointcapability) && (p->jointcapability & AST_FORMAT_AUDIO_MASK)) {
if (debug) {
char s1[BUFSIZ], s2[BUFSIZ];
ast_log(LOG_DEBUG, "Oooh, we need to change our audio formats since our peer supports only %s and not %s\n",
@@ -6762,7 +6774,7 @@
/* Now add DTMF RFC2833 telephony-event as a codec */
for (x = 1; x <= AST_RTP_MAX; x <<= 1) {
- if (!(p->noncodeccapability & x))
+ if (!(p->jointnoncodeccapability & x))
continue;
add_noncodec_to_sdp(p, x, 8000, &m_audio, &a_audio, debug);
@@ -7335,6 +7347,10 @@
pidfnote = "Unavailable";
break;
case AST_EXTENSION_ONHOLD:
+ statestring = "confirmed";
+ local_state = NOTIFY_INUSE;
+ pidfstate = "busy";
+ pidfnote = "On hold";
break;
case AST_EXTENSION_NOT_INUSE:
default:
@@ -7432,6 +7448,11 @@
else
ast_str_append(&tmp, 0, "<dialog id=\"%s\">\n", p->exten);
ast_str_append(&tmp, 0, "<state>%s</state>\n", statestring);
+ if (state == AST_EXTENSION_ONHOLD) {
+ ast_str_append(&tmp, 0, "<local>\n<target uri=\"%s\">\n"
+ "<param pname=\"+sip.rendering\" pvalue=\"no\">\n"
+ "</target>\n</local>\n", mto);
+ }
ast_str_append(&tmp, 0, "</dialog>\n</dialog-info>\n");
break;
case NONE:
@@ -7592,7 +7613,7 @@
/* decouple the two objects */
if (p->registry)
- p->registry = unref_registry(p->registry);
+ p->registry = registry_unref(p->registry);
r->register_pvt = pvt_unref(r->register_pvt); /* reference goes away */
}
@@ -7674,7 +7695,7 @@
r->portno = ntohs(p->sa.sin_port);
ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Registration is outgoing call */
r->register_pvt = pvt_ref(p); /* Save pointer to SIP dialog */
- p->registry = ASTOBJ_REF(r); /* Add pointer to registry in dialog */
+ p->registry = registry_addref(r); /* Add pointer to registry in dialog */
if (!ast_strlen_zero(r->secret)) /* Secret (password) */
ast_string_field_set(p, secret, r->secret);
if (!ast_strlen_zero(r->md5secret))
@@ -8603,14 +8624,9 @@
return;
/* If they put someone on hold, increment the value... otherwise decrement it */
- if (hold)
- peer->onHold++;
- else
- peer->onHold--;
-
+ ast_atomic_fetchadd_int(&peer->onHold, (hold ? +1 : -1) );
/* Request device state update */
ast_device_state_changed("SIP/%s", peer->name);
-
return;
}
@@ -10628,6 +10644,8 @@
ast_cli(fd, " VM Extension : %s\n", peer->vmexten);
ast_cli(fd, " LastMsgsSent : %d/%d\n", (peer->lastmsgssent & 0x7fff0000) >> 16, peer->lastmsgssent & 0xffff);
ast_cli(fd, " Call limit : %d\n", peer->call_limit);
+ if (peer->busy_limit)
+ ast_cli(fd, " Busy limit : %d\n", peer->busy_limit);
ast_cli(fd, " Dynamic : %s\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)?"Yes":"No"));
ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>"));
ast_cli(fd, " RegisterFrom : %s\n", S_OR(peer->register_from_hdr, ""));
@@ -10717,7 +10735,8 @@
astman_append(s, "VoiceMailbox: %s\r\n", peer->mailbox);
astman_append(s, "TransferMode: %s\r\n", transfermode2str(peer->allowtransfer));
astman_append(s, "LastMsgsSent: %d\r\n", peer->lastmsgssent);
- astman_append(s, "Call limit: %d\r\n", peer->call_limit);
+ astman_append(s, "Call-limit: %d\r\n", peer->call_limit);
+ astman_append(s, "Busy-limit: %d\r\n", peer->busy_limit);
astman_append(s, "MaxCallBR: %d kbps\r\n", peer->maxcallbitrate);
astman_append(s, "Dynamic: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)?"Y":"N"));
astman_append(s, "Callerid: %s\r\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, ""));
@@ -10866,6 +10885,7 @@
{
int realtimepeers;
int realtimeusers;
+ char codec_buf[BUFSIZ];
realtimepeers = ast_check_realtime("sippeers");
realtimeusers = ast_check_realtime("sipusers");
@@ -10920,6 +10940,9 @@
ast_cli(fd, "\nGlobal Signalling Settings:\n");
ast_cli(fd, "---------------------------\n");
ast_cli(fd, " Codecs: ");
+ ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, global_capability);
+ ast_cli(fd, "%s\n", codec_buf);
+ ast_cli(fd, " Codec Order: ");
print_codec_to_cli(fd, &default_prefs);
ast_cli(fd, "\n");
ast_cli(fd, " T1 minimum: %d\n", global_t1min);
@@ -12582,7 +12605,7 @@
struct sip_registry *r = p->registry;
r->register_pvt = pvt_unref(r->register_pvt);
- p->registry = unref_registry(r);
+ p->registry = registry_unref(r);
set_destroy(p);
}
@@ -13366,8 +13389,10 @@
/* Could not start thread */
free(d); /* We don't need it anymore. If thread is created, d will be free'd
by sip_park_thread() */
+ pthread_attr_destroy(&attr);
return 0;
}
+ pthread_attr_destroy(&attr);
}
return -1;
}
@@ -14093,7 +14118,7 @@
build_contact(p); /* Build our contact header */
if (p->rtp) {
- ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) != SIP_DTMF_INFO);
+ ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833);
ast_rtp_setdtmfcompensate(p->rtp, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE));
}
@@ -15976,6 +16001,9 @@
- registered AST_DEVICE_NOT_INUSE
- fixed IP (!dynamic) AST_DEVICE_NOT_INUSE
+ Peers that does not have a known call and can't be reached by OPTIONS
+ - unreachable AST_DEVICE_UNAVAILABLE
+
If we return AST_DEVICE_UNKNOWN, the device state engine will try to find
out a state by walking the channel list.
*/
@@ -16001,27 +16029,34 @@
if ((p = find_peer(host, NULL, 1))) {
if (p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) {
/* we have an address for the peer */
- /* if qualify is turned on, check the status */
- if (p->maxms && (p->lastms > p->maxms)) {
+
+ /* Check status in this order
+ - Hold
+ - Ringing
+ - Busy (enforced only by call limit)
+ - Inuse (we have a call)
+ - Unreachable (qualify)
+ If we don't find any of these state, report AST_DEVICE_NOT_INUSE
+ for registered devices */
+ if (p->onHold) /* First check for hold or ring states */
+ res = AST_DEVICE_ONHOLD;
+ else if (p->inRinging) {
+ if (p->inRinging == p->inUse)
+ res = AST_DEVICE_RINGING;
+ else
+ res = AST_DEVICE_RINGINUSE;
+ } else if (p->call_limit && (p->inUse == p->call_limit)) /* check call limit */
+ res = AST_DEVICE_BUSY;
+ else if (p->call_limit && p->busy_limit && p->inUse >= p->busy_limit)
+ /* We're forcing busy before we've reached the call limit */
+ res = AST_DEVICE_BUSY;
+ else if (p->call_limit && p->inUse) /* Not busy, but we do have a call */
+ res = AST_DEVICE_INUSE;
+ else if (p->maxms && (p->lastms > p->maxms))
+ /* We don't have a call. Are we reachable at all? Requires qualify= */
res = AST_DEVICE_UNAVAILABLE;
- } else {
- /* qualify is not on, or the peer is responding properly */
- /* check call limit */
- if (p->call_limit && (p->inUse == p->call_limit))
- res = AST_DEVICE_BUSY;
- else if (p->call_limit && p->inUse)
- res = AST_DEVICE_INUSE;
- else
- res = AST_DEVICE_NOT_INUSE;
- if (p->onHold)
- res = AST_DEVICE_ONHOLD;
- else if (p->inRinging) {
- if (p->inRinging == p->inUse)
- res = AST_DEVICE_RINGING;
- else
- res = AST_DEVICE_RINGINUSE;
- }
- }
+ else /* Default reply if we're registered and have no other data */
+ res = AST_DEVICE_NOT_INUSE;
} else {
/* there is no address, it's unavailable */
res = AST_DEVICE_UNAVAILABLE;
@@ -16664,7 +16699,7 @@
if (realtime) {
rpeerobjs++;
if (option_debug > 2)
- ast_log(LOG_DEBUG,"-REALTIME- peer built. Name: %s. Peer objects: %d\n", peer->name, rpeerobjs);
+ ast_log(LOG_DEBUG,"-REALTIME- peer built. Name: %s. Peer objects: %d\n", name, rpeerobjs);
} else
speerobjs++;
ASTOBJ_INIT(peer);
@@ -17756,7 +17791,7 @@
/* grab a reference to make sure objects do not go away when
* the timeout is canceled.
*/
- ASTOBJ_REF(iterator);
+ registry_addref(iterator);
iterator->timeout = ast_sched_add(sched, ms, sip_reregister, iterator);
ASTOBJ_UNLOCK(iterator);
} while (0)
More information about the asterisk-commits
mailing list