aboutsummaryrefslogtreecommitdiffstats
path: root/channels
diff options
context:
space:
mode:
authorbbryant <bbryant@f38db490-d61c-443f-a65b-d21fe96a405b>2010-09-09 18:50:13 +0000
committerbbryant <bbryant@f38db490-d61c-443f-a65b-d21fe96a405b>2010-09-09 18:50:13 +0000
commit12ad49e444d6108b7312a46b389090d51b670a7f (patch)
treefe20338149990fed28e3936bbbd7162e69d1f938 /channels
parentf8d0dcac122feafe9ebd0aba502263f829c77667 (diff)
Fixes an issue with dialplan pattern matching where the specificity for pattern ranges and pattern special characters was inconsistent.
(closes issue #16903) Reported by: Nick_Lewis Patches: pbx.c-specificity.patch uploaded by Nick Lewis (license 657) Tested by: Nick_Lewis git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.6.2@285710 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'channels')
-rw-r--r--channels/chan_dahdi.c15
-rw-r--r--channels/chan_iax2.c3
-rw-r--r--channels/chan_local.c20
-rw-r--r--channels/chan_misdn.c43
-rw-r--r--channels/chan_phone.c80
-rw-r--r--channels/chan_sip.c369
-rw-r--r--channels/chan_usbradio.c161
-rw-r--r--channels/console_video.c239
8 files changed, 528 insertions, 402 deletions
diff --git a/channels/chan_dahdi.c b/channels/chan_dahdi.c
index fb45564e3..8026ca574 100644
--- a/channels/chan_dahdi.c
+++ b/channels/chan_dahdi.c
@@ -3601,7 +3601,16 @@ static int dahdi_call(struct ast_channel *ast, char *rdest, int timeout)
l = NULL;
n = NULL;
if (!p->hidecallerid) {
- l = ast->cid.cid_num;
+ /* If we get to the end of this loop without breaking, there's no
+ * numeric calleridnum. This is done instead of testing for
+ * "unknown" or the thousands of other ways that the calleridnum
+ * could be invalid. */
+ for (l = ast->cid.cid_num; l && *l; l++) {
+ if (strchr("0123456789", *l)) {
+ l = ast->cid.cid_num;
+ break;
+ }
+ }
if (!p->hidecalleridname) {
n = ast->cid.cid_name;
}
@@ -7372,7 +7381,7 @@ static int dahdi_indicate(struct ast_channel *chan, int condition, const void *d
ast_debug(1,"Received AST_CONTROL_PROGRESS on %s\n",chan->name);
#ifdef HAVE_PRI
p->digital = 0; /* Digital-only calls isn't allows any inband progress messages */
- if (!p->progress && ((p->sig == SIG_PRI) || (p->sig == SIG_BRI) || (p->sig == SIG_BRI_PTMP))
+ if (!p->progress && !p->alerting && ((p->sig == SIG_PRI) || (p->sig == SIG_BRI) || (p->sig == SIG_BRI_PTMP))
&& p->pri && !p->outgoing) {
if (p->pri->pri) {
if (!pri_grab(p, p->pri)) {
@@ -13542,7 +13551,7 @@ static void *pri_dchannel(void *vpri)
}
break;
case PRI_EVENT_CONFIG_ERR:
- ast_log(LOG_WARNING, "PRI Error on span %d: %s\n", pri->trunkgroup, e->err.err);
+ ast_log(LOG_WARNING, "PRI Error on span %d: %s\n", pri->span, e->err.err);
break;
case PRI_EVENT_RESTART_ACK:
chanpos = pri_find_principle(pri, e->restartack.channel);
diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c
index e9e86bd76..4b4367845 100644
--- a/channels/chan_iax2.c
+++ b/channels/chan_iax2.c
@@ -6809,13 +6809,14 @@ static int manager_iax2_show_registry(struct mansession *s, const struct message
astman_append(s,
"Event: RegistryEntry\r\n"
+ "%s"
"Host: %s\r\n"
"DNSmanager: %s\r\n"
"Username: %s\r\n"
"Perceived: %s\r\n"
"Refresh: %d\r\n"
"State: %s\r\n"
- "\r\n", host, (reg->dnsmgr) ? "Y" : "N", reg->username, perceived,
+ "\r\n", idtext, host, (reg->dnsmgr) ? "Y" : "N", reg->username, perceived,
reg->refresh, regstate2str(reg->regstate));
total++;
diff --git a/channels/chan_local.c b/channels/chan_local.c
index a26b8f718..46451776f 100644
--- a/channels/chan_local.c
+++ b/channels/chan_local.c
@@ -384,6 +384,26 @@ static void check_bridge(struct local_pvt *p)
p->chan->audiohooks = p->owner->audiohooks;
p->owner->audiohooks = audiohooks_swapper;
}
+
+ /* If any Caller ID was set, preserve it after masquerade like above. We must check
+ * to see if Caller ID was set because otherwise we'll mistakingly copy info not
+ * set from the dialplan and will overwrite the real channel Caller ID. The reason
+ * for this whole preswapping action is because the Caller ID is set on the channel
+ * thread (which is the to be masqueraded away local channel) before both local
+ * channels are optimized away.
+ */
+ if (p->owner->cid.cid_dnid || p->owner->cid.cid_num ||
+ p->owner->cid.cid_name || p->owner->cid.cid_ani ||
+ p->owner->cid.cid_rdnis || p->owner->cid.cid_pres ||
+ p->owner->cid.cid_ani2 || p->owner->cid.cid_ton ||
+ p->owner->cid.cid_tns) {
+
+ struct ast_callerid tmpcid;
+ tmpcid = p->owner->cid;
+ p->owner->cid = p->chan->_bridge->cid;
+ p->chan->_bridge->cid = tmpcid;
+ }
+
ast_app_group_update(p->chan, p->owner);
ast_channel_masquerade(p->owner, p->chan->_bridge);
ast_set_flag(p, LOCAL_ALREADY_MASQED);
diff --git a/channels/chan_misdn.c b/channels/chan_misdn.c
index cd48ef43b..718051231 100644
--- a/channels/chan_misdn.c
+++ b/channels/chan_misdn.c
@@ -3033,15 +3033,14 @@ static struct ast_frame *process_ast_dsp(struct chan_list *tmp, struct ast_frame
static struct ast_frame *misdn_read(struct ast_channel *ast)
{
struct chan_list *tmp;
- fd_set rrfs;
- struct timeval tv = { 0, 20000 };
int len, t;
+ struct pollfd pfd = { .fd = -1, .events = POLLIN };
if (!ast) {
chan_misdn_log(1, 0, "misdn_read called without ast\n");
return NULL;
}
- if (!(tmp = MISDN_ASTERISK_TECH_PVT(ast))) {
+ if (!(tmp = MISDN_ASTERISK_TECH_PVT(ast))) {
chan_misdn_log(1, 0, "misdn_read called without ast->pvt\n");
return NULL;
}
@@ -3051,20 +3050,18 @@ static struct ast_frame *misdn_read(struct ast_channel *ast)
return NULL;
}
- FD_ZERO(&rrfs);
- FD_SET(tmp->pipe[0], &rrfs);
-
- if (!(t = select(FD_SETSIZE, &rrfs, NULL, NULL, &tv))) {
- chan_misdn_log(3, tmp->bc->port, "read Select Timed out\n");
- len = 160;
- }
+ pfd.fd = tmp->pipe[0];
+ t = ast_poll(&pfd, 1, 20);
if (t < 0) {
- chan_misdn_log(-1, tmp->bc->port, "Select Error (err=%s)\n", strerror(errno));
+ chan_misdn_log(-1, tmp->bc->port, "poll() error (err=%s)\n", strerror(errno));
return NULL;
}
- if (FD_ISSET(tmp->pipe[0], &rrfs)) {
+ if (!t) {
+ chan_misdn_log(3, tmp->bc->port, "poll() timed out\n");
+ len = 160;
+ } else if (pfd.revents & POLLIN) {
len = read(tmp->pipe[0], tmp->ast_rd_buf, sizeof(tmp->ast_rd_buf));
if (len <= 0) {
@@ -5172,26 +5169,22 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
if (ch->ast)
ast_queue_frame(ch->ast, &frame);
} else {
- fd_set wrfs;
- struct timeval tv = { 0, 0 };
+ struct pollfd pfd = { .fd = ch->pipe[1], .events = POLLOUT };
int t;
- FD_ZERO(&wrfs);
- FD_SET(ch->pipe[1], &wrfs);
+ t = ast_poll(&pfd, 1, 0);
- t = select(FD_SETSIZE, NULL, &wrfs, NULL, &tv);
-
- if (!t) {
- chan_misdn_log(9, bc->port, "Select Timed out\n");
+ if (t < 0) {
+ chan_misdn_log(-1, bc->port, "poll() error (err=%s)\n", strerror(errno));
break;
}
-
- if (t < 0) {
- chan_misdn_log(-1, bc->port, "Select Error (err=%s)\n", strerror(errno));
+
+ if (!t) {
+ chan_misdn_log(9, bc->port, "poll() timed out\n");
break;
}
-
- if (FD_ISSET(ch->pipe[1], &wrfs)) {
+
+ if (pfd.revents & POLLOUT) {
chan_misdn_log(9, bc->port, "writing %d bytes to asterisk\n", bc->bframe_len);
if (write(ch->pipe[1], bc->bframe, bc->bframe_len) <= 0) {
chan_misdn_log(0, bc->port, "Write returned <=0 (err=%s) --> hanging up channel\n", strerror(errno));
diff --git a/channels/chan_phone.c b/channels/chan_phone.c
index 295d2eb89..904207345 100644
--- a/channels/chan_phone.c
+++ b/channels/chan_phone.c
@@ -1011,12 +1011,12 @@ static void phone_check_exception(struct phone_pvt *i)
static void *do_monitor(void *data)
{
- fd_set rfds, efds;
- int n, res;
+ struct pollfd *fds = NULL;
+ int nfds = 0, inuse_fds = 0, res;
struct phone_pvt *i;
int tonepos = 0;
/* The tone we're playing this round */
- struct timeval wait = {0,0};
+ struct timeval tv = { 0, 0 };
int dotone;
/* This thread monitors all the frame relay interfaces which are not yet in use
(and thus do not have a separate thread) indefinitely */
@@ -1030,33 +1030,38 @@ static void *do_monitor(void *data)
}
/* Build the stuff we're going to select on, that is the socket of every
phone_pvt that does not have an associated owner channel */
- n = -1;
- FD_ZERO(&rfds);
- FD_ZERO(&efds);
i = iflist;
dotone = 0;
- while (i) {
- if (FD_ISSET(i->fd, &rfds))
- ast_log(LOG_WARNING, "Descriptor %d appears twice (%s)?\n", i->fd, i->dev);
+ inuse_fds = 0;
+ for (i = iflist; i; i = i->next) {
if (!i->owner) {
/* This needs to be watched, as it lacks an owner */
- FD_SET(i->fd, &rfds);
- FD_SET(i->fd, &efds);
- if (i->fd > n)
- n = i->fd;
+ if (inuse_fds == nfds) {
+ void *tmp = ast_realloc(fds, (nfds + 1) * sizeof(*fds));
+ if (!tmp) {
+ /* Avoid leaking */
+ continue;
+ }
+ fds = tmp;
+ nfds++;
+ }
+ fds[inuse_fds].fd = i->fd;
+ fds[inuse_fds].events = POLLIN | POLLERR;
+ fds[inuse_fds].revents = 0;
+ inuse_fds++;
+
if (i->dialtone && i->mode != MODE_SIGMA) {
/* Remember we're going to have to come back and play
more dialtones */
- if (ast_tvzero(wait)) {
+ if (ast_tvzero(tv)) {
/* If we're due for a dialtone, play one */
- if (write(i->fd, DialTone + tonepos, 240) != 240)
+ if (write(i->fd, DialTone + tonepos, 240) != 240) {
ast_log(LOG_WARNING, "Dial tone write error\n");
+ }
}
dotone++;
}
}
-
- i = i->next;
}
/* Okay, now that we know what to do, release the interface lock */
ast_mutex_unlock(&iflock);
@@ -1065,26 +1070,28 @@ static void *do_monitor(void *data)
if (dotone && i && i->mode != MODE_SIGMA) {
/* If we're ready to recycle the time, set it to 30 ms */
tonepos += 240;
- if (tonepos >= sizeof(DialTone))
- tonepos = 0;
- if (ast_tvzero(wait)) {
- wait = ast_tv(30000, 0);
+ if (tonepos >= sizeof(DialTone)) {
+ tonepos = 0;
}
- res = ast_select(n + 1, &rfds, NULL, &efds, &wait);
+ if (ast_tvzero(tv)) {
+ tv = ast_tv(0, 30000);
+ }
+ res = ast_poll2(fds, inuse_fds, &tv);
} else {
- res = ast_select(n + 1, &rfds, NULL, &efds, NULL);
- wait = ast_tv(0,0);
+ res = ast_poll(fds, inuse_fds, -1);
+ tv = ast_tv(0, 0);
tonepos = 0;
}
/* Okay, select has finished. Let's see what happened. */
if (res < 0) {
- ast_debug(1, "select return %d: %s\n", res, strerror(errno));
+ ast_debug(1, "poll returned %d: %s\n", res, strerror(errno));
continue;
}
/* If there are no fd's changed, just continue, it's probably time
to play some more dialtones */
- if (!res)
+ if (!res) {
continue;
+ }
/* Alright, lock the interface list again, and let's look and see what has
happened */
if (ast_mutex_lock(&iflock)) {
@@ -1092,15 +1099,27 @@ static void *do_monitor(void *data)
continue;
}
- i = iflist;
- for(; i; i=i->next) {
- if (FD_ISSET(i->fd, &rfds)) {
+ for (i = iflist; i; i = i->next) {
+ int j;
+ /* Find the record */
+ for (j = 0; j < inuse_fds; j++) {
+ if (fds[j].fd == i->fd) {
+ break;
+ }
+ }
+
+ /* Not found? */
+ if (j == inuse_fds) {
+ continue;
+ }
+
+ if (fds[j].revents & POLLIN) {
if (i->owner) {
continue;
}
phone_mini_packet(i);
}
- if (FD_ISSET(i->fd, &efds)) {
+ if (fds[j].revents & POLLERR) {
if (i->owner) {
continue;
}
@@ -1110,7 +1129,6 @@ static void *do_monitor(void *data)
ast_mutex_unlock(&iflock);
}
return NULL;
-
}
static int restart_monitor()
diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index dc8e98713..2768b3a4c 100644
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -948,13 +948,6 @@ static const struct cfsip_options {
*/
#define ALLOWED_METHODS "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY, INFO"
-/*! \brief SIP Extensions we support
- \note This should be generated based on the previous array
- in combination with settings.
- \todo We should not have "timer" if it's disabled in the configuration file.
-*/
-#define SUPPORTED_EXTENSIONS "replaces, timer"
-
/*! \brief Standard SIP unsecure port for UDP and TCP from RFC 3261. DO NOT CHANGE THIS */
#define STANDARD_SIP_PORT 5060
/*! \brief Standard SIP TLS port from RFC 3261. DO NOT CHANGE THIS */
@@ -3104,6 +3097,32 @@ cleanup:
return NULL;
}
+/* this func is used with ao2_callback to unlink/delete all marked
+ peers */
+static int peer_is_marked(void *peerobj, void *arg, int flags)
+{
+ struct sip_peer *peer = peerobj;
+ return peer->the_mark ? CMP_MATCH : 0;
+}
+
+
+/* \brief Unlink all marked peers from ao2 containers */
+static void unlink_marked_peers_from_tables(void)
+{
+ ao2_t_callback(peers, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, peer_is_marked, NULL,
+ "initiating callback to remove marked peers");
+ ao2_t_callback(peers_by_ip, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, peer_is_marked, NULL,
+ "initiating callback to remove marked peers");
+}
+
+/* \brief Unlink single peer from all ao2 containers */
+static void unlink_peer_from_tables(struct sip_peer *peer)
+{
+ ao2_t_unlink(peers, peer, "ao2_unlink of peer from peers table");
+ if (peer->addr.sin_addr.s_addr) {
+ ao2_t_unlink(peers_by_ip, peer, "ao2_unlink of peer from peers_by_ip table");
+ }
+}
/*!
* helper functions to unreference various types of objects.
@@ -3754,34 +3773,34 @@ static int retrans_pkt(const void *data)
struct sip_pkt *pkt = (struct sip_pkt *)data, *prev, *cur = NULL;
int reschedule = DEFAULT_RETRANS;
int xmitres = 0;
-
+
/* Lock channel PVT */
sip_pvt_lock(pkt->owner);
if (pkt->retrans < MAX_RETRANS) {
pkt->retrans++;
- if (!pkt->timer_t1) { /* Re-schedule using timer_a and timer_t1 */
+ if (!pkt->timer_t1) { /* Re-schedule using timer_a and timer_t1 */
if (sipdebug)
- ast_debug(4, "SIP TIMER: Not rescheduling id #%d:%s (Method %d) (No timer T1)\n", pkt->retransid, sip_methods[pkt->method].text, pkt->method);
+ ast_debug(4, "SIP TIMER: Not rescheduling id #%d:%s (Method %d) (No timer T1)\n", pkt->retransid, sip_methods[pkt->method].text, pkt->method);
} else {
- int siptimer_a;
-
- if (sipdebug)
- ast_debug(4, "SIP TIMER: Rescheduling retransmission #%d (%d) %s - %d\n", pkt->retransid, pkt->retrans, sip_methods[pkt->method].text, pkt->method);
- if (!pkt->timer_a)
- pkt->timer_a = 2 ;
- else
- pkt->timer_a = 2 * pkt->timer_a;
-
- /* For non-invites, a maximum of 4 secs */
- siptimer_a = pkt->timer_t1 * pkt->timer_a; /* Double each time */
- if (pkt->method != SIP_INVITE && siptimer_a > 4000)
- siptimer_a = 4000;
-
- /* Reschedule re-transmit */
+ int siptimer_a;
+
+ if (sipdebug)
+ ast_debug(4, "SIP TIMER: Rescheduling retransmission #%d (%d) %s - %d\n", pkt->retransid, pkt->retrans, sip_methods[pkt->method].text, pkt->method);
+ if (!pkt->timer_a)
+ pkt->timer_a = 2 ;
+ else
+ pkt->timer_a = 2 * pkt->timer_a;
+
+ /* For non-invites, a maximum of 4 secs */
+ siptimer_a = pkt->timer_t1 * pkt->timer_a; /* Double each time */
+ if (pkt->method != SIP_INVITE && siptimer_a > 4000)
+ siptimer_a = 4000;
+
+ /* Reschedule re-transmit */
reschedule = siptimer_a;
- ast_debug(4, "** SIP timers: Rescheduling retransmission %d to %d ms (t1 %d ms (Retrans id #%d)) \n", pkt->retrans +1, siptimer_a, pkt->timer_t1, pkt->retransid);
- }
+ ast_debug(4, "** SIP timers: Rescheduling retransmission %d to %d ms (t1 %d ms (Retrans id #%d)) \n", pkt->retrans +1, siptimer_a, pkt->timer_t1, pkt->retransid);
+ }
if (sip_debug_test_pvt(pkt->owner)) {
const struct sockaddr_in *dst = sip_real_dst(pkt->owner);
@@ -3793,12 +3812,13 @@ static int retrans_pkt(const void *data)
append_history(pkt->owner, "ReTx", "%d %s", reschedule, pkt->data->str);
xmitres = __sip_xmit(pkt->owner, pkt->data, pkt->packetlen);
- sip_pvt_unlock(pkt->owner);
- if (xmitres == XMIT_ERROR)
+ if (xmitres == XMIT_ERROR) {
ast_log(LOG_WARNING, "Network error on retransmit in dialog %s\n", pkt->owner->callid);
- else
+ } else {
+ sip_pvt_unlock(pkt->owner);
return reschedule;
- }
+ }
+ }
/* Too many retries */
if (pkt->owner && pkt->method != SIP_OPTIONS && xmitres == 0) {
if (pkt->is_fatal || sipdebug) /* Tell us if it's critical or if we're debugging */
@@ -3808,13 +3828,13 @@ static int retrans_pkt(const void *data)
} else if (pkt->method == SIP_OPTIONS && sipdebug) {
ast_log(LOG_WARNING, "Cancelling retransmit of OPTIONs (call id %s) -- See doc/sip-retransmit.txt.\n", pkt->owner->callid);
- }
+ }
if (xmitres == XMIT_ERROR) {
ast_log(LOG_WARNING, "Transmit error :: Cancelling transmission on Call ID %s\n", pkt->owner->callid);
append_history(pkt->owner, "XmitErr", "%s", pkt->is_fatal ? "(Critical)" : "(Non-critical)");
- } else
+ } else {
append_history(pkt->owner, "MaxRetries", "%s", pkt->is_fatal ? "(Critical)" : "(Non-critical)");
-
+ }
pkt->retransid = -1;
if (pkt->is_fatal) {
@@ -3824,9 +3844,9 @@ static int retrans_pkt(const void *data)
sip_pvt_lock(pkt->owner);
}
- if (pkt->owner->owner && !pkt->owner->owner->hangupcause)
+ if (pkt->owner->owner && !pkt->owner->owner->hangupcause)
pkt->owner->owner->hangupcause = AST_CAUSE_NO_USER_RESPONSE;
-
+
if (pkt->owner->owner) {
sip_alreadygone(pkt->owner);
ast_log(LOG_WARNING, "Hanging up call %s - no reply to our critical packet (see doc/sip-retransmit.txt).\n", pkt->owner->callid);
@@ -3846,7 +3866,7 @@ static int retrans_pkt(const void *data)
if (pkt->method == SIP_BYE) {
/* We're not getting answers on SIP BYE's. Tear down the call anyway. */
- if (pkt->owner->owner)
+ if (pkt->owner->owner)
ast_channel_unlock(pkt->owner->owner);
append_history(pkt->owner, "ByeFailure", "Remote peer doesn't respond to bye. Destroying call anyway.");
pvt_set_needdestroy(pkt->owner, "no response to BYE");
@@ -3985,10 +4005,6 @@ static int __sip_autodestruct(const void *data)
}
}
- if (p->subscribed == MWI_NOTIFICATION)
- if (p->relatedpeer)
- p->relatedpeer = unref_peer(p->relatedpeer, "__sip_autodestruct: unref peer p->relatedpeer"); /* Remove link to peer. If it's realtime, make sure it's gone from memory) */
-
/* Reset schedule ID */
p->autokillid = -1;
@@ -6090,7 +6106,6 @@ static int sip_hangup(struct ast_channel *ast)
if (p->invitestate == INV_CALLING) {
/* We can't send anything in CALLING state */
ast_set_flag(&p->flags[0], SIP_PENDINGBYE);
- __sip_pretend_ack(p);
/* Do we need a timer here if we don't hear from them at all? Yes we do or else we will get hung dialogs and those are no fun. */
sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
append_history(p, "DELAY", "Not sending cancel, waiting for timeout");
@@ -8130,10 +8145,10 @@ static int process_sdp(struct sip_pvt *p, struct sip_request *req, int t38action
int vportno = -1; /*!< RTP Video port number */
int tportno = -1; /*!< RTP Text port number */
int udptlportno = -1; /*!< UDPTL Image port number */
- struct sockaddr_in sin; /*!< media socket address */
- struct sockaddr_in vsin; /*!< video socket address */
- struct sockaddr_in isin; /*!< image socket address */
- struct sockaddr_in tsin; /*!< text socket address */
+ struct sockaddr_in sin = { 0, }; /*!< media socket address */
+ struct sockaddr_in vsin = { 0, }; /*!< video socket address */
+ struct sockaddr_in isin = { 0, }; /*!< image socket address */
+ struct sockaddr_in tsin = { 0, }; /*!< text socket address */
/* Peer capability is the capability in the SDP, non codec is RFC2833 DTMF (101) */
int peercapability = 0, peernoncodeccapability = 0;
@@ -8648,7 +8663,10 @@ static int process_sdp(struct sip_pvt *p, struct sip_request *req, int t38action
ast_set_write_format(p->owner, p->owner->writeformat);
}
- if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) && sin.sin_addr.s_addr && (!sendonly || sendonly == -1)) {
+ if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)
+ && (sin.sin_addr.s_addr || vsin.sin_addr.s_addr ||
+ isin.sin_addr.s_addr || tsin.sin_addr.s_addr)
+ && (!sendonly || sendonly == -1)) {
ast_queue_control(p->owner, AST_CONTROL_UNHOLD);
/* Activate a re-invite */
ast_queue_frame(p->owner, &ast_null_frame);
@@ -8664,7 +8682,9 @@ static int process_sdp(struct sip_pvt *p, struct sip_request *req, int t38action
if (sip_cfg.notifyhold)
sip_peer_hold(p, FALSE);
ast_clear_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD); /* Clear both flags */
- } else if (!sin.sin_addr.s_addr || (sendonly && sendonly != -1)) {
+ } else if (!(sin.sin_addr.s_addr || vsin.sin_addr.s_addr ||
+ isin.sin_addr.s_addr || tsin.sin_addr.s_addr)
+ || (sendonly && sendonly != -1)) {
int already_on_hold = ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD);
ast_queue_control_data(p->owner, AST_CONTROL_HOLD,
S_OR(p->mohsuggest, NULL),
@@ -9096,6 +9116,20 @@ static void ts_ast_rtp_destroy(void *data)
}
#endif
+/*! \brief Add "Supported" header to sip message. Since some options may
+ * be disabled in the config, the sip_pvt must be inspected to determine what
+ * is supported for this dialog. */
+static int add_supported_header(struct sip_pvt *pvt, struct sip_request *req)
+{
+ int res;
+ if (st_get_mode(pvt) != SESSION_TIMER_MODE_REFUSE) {
+ res = add_header(req, "Supported", "replaces, timer");
+ } else {
+ res = add_header(req, "Supported", "replaces");
+ }
+ return res;
+}
+
/*! \brief Add header to SIP message */
static int add_header(struct sip_request *req, const char *var, const char *value)
{
@@ -9507,14 +9541,13 @@ static int respprep(struct sip_request *resp, struct sip_pvt *p, const char *msg
if (!ast_strlen_zero(global_useragent))
add_header(resp, "Server", global_useragent);
add_header(resp, "Allow", ALLOWED_METHODS);
- add_header(resp, "Supported", SUPPORTED_EXTENSIONS);
+ add_supported_header(p, resp);
/* If this is an invite, add Session-Timers related headers if the feature is active for this session */
if (p->method == SIP_INVITE && p->stimer && p->stimer->st_active == TRUE && p->stimer->st_active_peer_ua == TRUE) {
char se_hdr[256];
snprintf(se_hdr, sizeof(se_hdr), "%d;refresher=%s", p->stimer->st_interval,
strefresher2str(p->stimer->st_ref));
- add_header(resp, "Require", "timer");
add_header(resp, "Session-Expires", se_hdr);
}
@@ -10607,7 +10640,7 @@ static int transmit_reinvite_with_sdp(struct sip_pvt *p, int t38version, int old
reqprep(&req, p, ast_test_flag(&p->flags[0], SIP_REINVITE_UPDATE) ? SIP_UPDATE : SIP_INVITE, 0, 1);
add_header(&req, "Allow", ALLOWED_METHODS);
- add_header(&req, "Supported", SUPPORTED_EXTENSIONS);
+ add_supported_header(p, &req);
if (sipdebug) {
if (oldsdp == TRUE)
add_header(&req, "X-asterisk-Info", "SIP re-invite (Session-Timers)");
@@ -10983,7 +11016,7 @@ static int transmit_invite(struct sip_pvt *p, int sipmethod, int sdp, int init)
}
add_header(&req, "Allow", ALLOWED_METHODS);
- add_header(&req, "Supported", SUPPORTED_EXTENSIONS);
+ add_supported_header(p, &req);
if(p->notify_headers) {
char buf[512];
@@ -11315,27 +11348,36 @@ static int transmit_state_notify(struct sip_pvt *p, int state, int full, int tim
int need = strlen(caller->cid.cid_num) + strlen(p->fromdomain) + sizeof("sip:@");
local_target = alloca(need);
snprintf(local_target, need, "sip:%s@%s", caller->cid.cid_num, p->fromdomain);
- local_display = ast_strdupa(caller->cid.cid_name);
+ if (!(ast_strlen_zero(caller->cid.cid_name))) {
+ local_display = ast_strdupa(caller->cid.cid_name);
+ }
ast_channel_unlock(caller);
caller = NULL;
}
+ /* We create a fake call-id which the phone will send back in an INVITE
+ * Replaces header which we can grab and do some magic with. */
+ if (sip_cfg.pedanticsipchecking) {
+ ast_str_append(&tmp, 0, "<dialog id=\"%s\" call-id=\"pickup-%s\" local-tag=\"%s\" remote-tag=\"%s\" direction=\"recipient\">\n",
+ p->exten, p->callid, p->theirtag, p->tag);
+ } else {
+ ast_str_append(&tmp, 0, "<dialog id=\"%s\" call-id=\"pickup-%s\" direction=\"recipient\">\n",
+ p->exten, p->callid);
+ }
+ ast_str_append(&tmp, 0,
+ "<remote>\n"
+ /* See the limitations of this above. Luckily the phone seems to still be
+ happy when these values are not correct. */
+ "<identity display=\"%s\">%s</identity>\n"
+ "<target uri=\"%s\"/>\n"
+ "</remote>\n"
+ "<local>\n"
+ "<identity>%s</identity>\n"
+ "<target uri=\"%s\"/>\n"
+ "</local>\n",
+ local_display, local_target, local_target, mto, mto);
+ } else {
+ ast_str_append(&tmp, 0, "<dialog id=\"%s\" direction=\"recipient\">\n", p->exten);
}
-
- /* We create a fake call-id which the phone will send back in an INVITE
- Replaces header which we can grab and do some magic with. */
- ast_str_append(&tmp, 0,
- "<dialog id=\"%s\" call-id=\"pickup-%s\" direction=\"recipient\">\n"
- "<remote>\n"
- /* See the limitations of this above. Luckily the phone seems to still be
- happy when these values are not correct. */
- "<identity display=\"%s\">%s</identity>\n"
- "<target uri=\"%s\"/>\n"
- "</remote>\n"
- "<local>\n"
- "<identity>%s</identity>\n"
- "<target uri=\"%s\"/>\n"
- "</local>\n",
- p->exten, p->callid, local_display, local_target, local_target, mto, mto);
} else {
ast_str_append(&tmp, 0, "<dialog id=\"%s\">\n", p->exten);
}
@@ -11424,7 +11466,7 @@ static int transmit_notify_with_sipfrag(struct sip_pvt *p, int cseq, char *messa
add_header(&req, "Subscription-state", terminate ? "terminated;reason=noresource" : "active");
add_header(&req, "Content-Type", "message/sipfrag;version=2.0");
add_header(&req, "Allow", ALLOWED_METHODS);
- add_header(&req, "Supported", SUPPORTED_EXTENSIONS);
+ add_supported_header(p, &req);
snprintf(tmp, sizeof(tmp), "SIP/2.0 %s\r\n", message);
add_content(&req, tmp);
@@ -11976,7 +12018,7 @@ static int transmit_refer(struct sip_pvt *p, const char *dest)
add_header(&req, "Refer-To", referto);
add_header(&req, "Allow", ALLOWED_METHODS);
- add_header(&req, "Supported", SUPPORTED_EXTENSIONS);
+ add_supported_header(p, &req);
if (!ast_strlen_zero(p->our_contact))
add_header(&req, "Referred-By", p->our_contact);
@@ -12114,7 +12156,6 @@ static int expire_register(const void *data)
peer->expire = -1;
peer->portinuri = 0;
- memset(&peer->addr, 0, sizeof(peer->addr));
destroy_association(peer); /* remove registration data from storage */
set_socket_transport(&peer->socket, peer->default_outbound_transport);
@@ -12136,12 +12177,13 @@ static int expire_register(const void *data)
if (peer->selfdestruct ||
ast_test_flag(&peer->flags[1], SIP_PAGE2_RTAUTOCLEAR)) {
- ao2_t_unlink(peers, peer, "ao2_unlink of peer from peers table");
- if (peer->addr.sin_addr.s_addr) {
- ao2_t_unlink(peers_by_ip, peer, "ao2_unlink of peer from peers_by_ip table");
- }
+ unlink_peer_from_tables(peer);
}
+ /* Only clear the addr after we check for destruction. The addr must remain
+ * in order to unlink from the peers_by_ip container correctly */
+ memset(&peer->addr, 0, sizeof(peer->addr));
+
unref_peer(peer, "removing peer ref for expire_register");
return 0;
@@ -15131,14 +15173,6 @@ static int dialog_needdestroy(void *dialogobj, void *arg, int flags)
return 0;
}
-/* this func is used with ao2_callback to unlink/delete all marked
- peers */
-static int peer_is_marked(void *peerobj, void *arg, int flags)
-{
- struct sip_peer *peer = peerobj;
- return peer->the_mark ? CMP_MATCH : 0;
-}
-
/*! \brief Remove temporary realtime objects from memory (CLI) */
/*! \todo XXXX Propably needs an overhaul after removal of the devices */
static char *sip_prune_realtime(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
@@ -15241,8 +15275,7 @@ static char *sip_prune_realtime(struct ast_cli_entry *e, int cmd, struct ast_cli
}
ao2_iterator_destroy(&i);
if (pruned) {
- ao2_t_callback(peers, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, peer_is_marked, NULL,
- "initiating callback to remove marked peers");
+ unlink_marked_peers_from_tables();
ast_cli(a->fd, "%d peers pruned.\n", pruned);
} else
ast_cli(a->fd, "No peers found to prune.\n");
@@ -17642,7 +17675,11 @@ static void parse_moved_contact(struct sip_pvt *p, struct sip_request *req)
}
}
-/*! \brief Check pending actions on SIP call */
+/*! \brief Check pending actions on SIP call
+ *
+ * \note both sip_pvt and sip_pvt's owner channel (if present)
+ * must be locked for this function.
+ */
static void check_pendings(struct sip_pvt *p)
{
if (ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
@@ -17657,6 +17694,9 @@ static void check_pendings(struct sip_pvt *p)
if (p->pendinginvite)
return;
+ if (p->owner) {
+ ast_softhangup_nolock(p->owner, AST_SOFTHANGUP_DEV);
+ }
/* Perhaps there is an SD change INVITE outstanding */
transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, TRUE);
}
@@ -17682,12 +17722,21 @@ static void check_pendings(struct sip_pvt *p)
static int sip_reinvite_retry(const void *data)
{
struct sip_pvt *p = (struct sip_pvt *) data;
+ struct ast_channel *owner;
sip_pvt_lock(p); /* called from schedule thread which requires a lock */
+ while ((owner = p->owner) && ast_channel_trylock(owner)) {
+ sip_pvt_unlock(p);
+ usleep(1);
+ sip_pvt_lock(p);
+ }
ast_set_flag(&p->flags[0], SIP_NEEDREINVITE);
p->waitid = -1;
check_pendings(p);
sip_pvt_unlock(p);
+ if (owner) {
+ ast_channel_unlock(owner);
+ }
dialog_unref(p, "unref the dialog ptr from sip_reinvite_retry, because it held a dialog ptr");
return 0;
}
@@ -17840,7 +17889,7 @@ static void handle_response_invite(struct sip_pvt *p, int resp, char *rest, stru
/* Check for Session-Timers related headers */
if (st_get_mode(p) != SESSION_TIMER_MODE_REFUSE && p->outgoing_call == TRUE && !reinvite) {
p_hdrval = (char*)get_header(req, "Session-Expires");
- if (!ast_strlen_zero(p_hdrval)) {
+ if (!ast_strlen_zero(p_hdrval)) {
/* UAS supports Session-Timers */
enum st_refresher tmp_st_ref = SESSION_TIMER_REFRESHER_AUTO;
int tmp_st_interval = 0;
@@ -19970,7 +20019,7 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, int
struct sip_pvt *subscription = NULL;
replace_id += 7; /* Worst case we are looking at \0 */
- if ((subscription = get_sip_pvt_byid_locked(replace_id, NULL, NULL)) == NULL) {
+ if ((subscription = get_sip_pvt_byid_locked(replace_id, totag, fromtag)) == NULL) {
ast_log(LOG_NOTICE, "Unable to find subscription with call-id: %s\n", replace_id);
transmit_response_reliable(p, "481 Call Leg Does Not Exist (Replaces)", req);
error = 1;
@@ -20215,10 +20264,10 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, int
}
/* Session-Timers */
- if (p->sipoptions & SIP_OPT_TIMER) {
+ if ((p->sipoptions & SIP_OPT_TIMER) && !ast_strlen_zero(get_header(req, "Session-Expires"))) {
/* The UAC has requested session-timers for this session. Negotiate
the session refresh interval and who will be the refresher */
- ast_debug(2, "Incoming INVITE with 'timer' option enabled\n");
+ ast_debug(2, "Incoming INVITE with 'timer' option supported and \"Session-Expires\" header.\n");
/* Allocate Session-Timers struct w/in the dialog */
if (!p->stimer)
@@ -20226,17 +20275,15 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, int
/* Parse the Session-Expires header */
p_uac_se_hdr = get_header(req, "Session-Expires");
- if (!ast_strlen_zero(p_uac_se_hdr)) {
- rtn = parse_session_expires(p_uac_se_hdr, &uac_max_se, &st_ref);
- if (rtn != 0) {
- transmit_response_reliable(p, "400 Session-Expires Invalid Syntax", req);
- p->invitestate = INV_COMPLETED;
- if (!p->lastinvite) {
- sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
- }
- res = -1;
- goto request_invite_cleanup;
+ rtn = parse_session_expires(p_uac_se_hdr, &uac_max_se, &st_ref);
+ if (rtn != 0) {
+ transmit_response_reliable(p, "400 Session-Expires Invalid Syntax", req);
+ p->invitestate = INV_COMPLETED;
+ if (!p->lastinvite) {
+ sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
}
+ res = -1;
+ goto request_invite_cleanup;
}
/* Parse the Min-SE header */
@@ -21303,7 +21350,6 @@ static int handle_request_subscribe(struct sip_pvt *p, struct sip_request *req,
int firststate = AST_EXTENSION_REMOVED;
struct sip_peer *authpeer = NULL;
const char *eventheader = get_header(req, "Event"); /* Get Event package name */
- const char *acceptheader = get_header(req, "Accept");
int resubscribe = (p->subscribed != NONE);
char *temp, *event;
struct ao2_iterator i;
@@ -21429,51 +21475,94 @@ static int handle_request_subscribe(struct sip_pvt *p, struct sip_request *req,
if (!strcmp(event, "presence") || !strcmp(event, "dialog")) { /* Presence, RFC 3842 */
unsigned int pidf_xml;
+ const char *accept;
+ int start = 0;
+ enum subscriptiontype subscribed = NONE;
+ const char *unknown_acceptheader = NULL;
if (authpeer) /* We do not need the authpeer any more */
unref_peer(authpeer, "unref_peer, from handle_request_subscribe (authpeer 2)");
/* Header from Xten Eye-beam Accept: multipart/related, application/rlmi+xml, application/pidf+xml, application/xpidf+xml */
- pidf_xml = strstr(acceptheader, "application/pidf+xml") ? 1 : 0;
-
- /* Older versions of Polycom firmware will claim pidf+xml, but really
- * they only support xpidf+xml. */
- if (pidf_xml && strstr(p->useragent, "Polycom")) {
- p->subscribed = XPIDF_XML;
- } else if (pidf_xml) {
- p->subscribed = PIDF_XML; /* RFC 3863 format */
- } else if (strstr(acceptheader, "application/dialog-info+xml")) {
- p->subscribed = DIALOG_INFO_XML;
- /* IETF draft: draft-ietf-sipping-dialog-package-05.txt */
- } else if (strstr(acceptheader, "application/cpim-pidf+xml")) {
- p->subscribed = CPIM_PIDF_XML; /* RFC 3863 format */
- } else if (strstr(acceptheader, "application/xpidf+xml")) {
- p->subscribed = XPIDF_XML; /* Early pre-RFC 3863 format with MSN additions (Microsoft Messenger) */
- } else if (ast_strlen_zero(acceptheader)) {
+ accept = __get_header(req, "Accept", &start);
+ while ((subscribed == NONE) && !ast_strlen_zero(accept)) {
+ pidf_xml = strstr(accept, "application/pidf+xml") ? 1 : 0;
+
+ /* Older versions of Polycom firmware will claim pidf+xml, but really
+ * they only support xpidf+xml. */
+ if (pidf_xml && strstr(p->useragent, "Polycom")) {
+ subscribed = XPIDF_XML;
+ } else if (pidf_xml) {
+ subscribed = PIDF_XML; /* RFC 3863 format */
+ } else if (strstr(accept, "application/dialog-info+xml")) {
+ subscribed = DIALOG_INFO_XML;
+ /* IETF draft: draft-ietf-sipping-dialog-package-05.txt */
+ } else if (strstr(accept, "application/cpim-pidf+xml")) {
+ subscribed = CPIM_PIDF_XML; /* RFC 3863 format */
+ } else if (strstr(accept, "application/xpidf+xml")) {
+ subscribed = XPIDF_XML; /* Early pre-RFC 3863 format with MSN additions (Microsoft Messenger) */
+ } else {
+ unknown_acceptheader = accept;
+ }
+ /* check to see if there is another Accept header present */
+ accept = __get_header(req, "Accept", &start);
+ }
+
+ if (!start) {
if (p->subscribed == NONE) { /* if the subscribed field is not already set, and there is no accept header... */
transmit_response(p, "489 Bad Event", req);
-
- ast_log(LOG_WARNING, "SUBSCRIBE failure: no Accept header: pvt: stateid: %d, laststate: %d, dialogver: %d, subscribecont: '%s', subscribeuri: '%s'\n",
- p->stateid, p->laststate, p->dialogver, p->subscribecontext, p->subscribeuri);
+ ast_log(LOG_WARNING,"SUBSCRIBE failure: no Accept header: pvt: "
+ "stateid: %d, laststate: %d, dialogver: %d, subscribecont: "
+ "'%s', subscribeuri: '%s'\n",
+ p->stateid,
+ p->laststate,
+ p->dialogver,
+ p->subscribecontext,
+ p->subscribeuri);
pvt_set_needdestroy(p, "no Accept header");
return 0;
}
/* if p->subscribed is non-zero, then accept is not obligatory; according to rfc 3265 section 3.1.3, at least.
so, we'll just let it ride, keeping the value from a previous subscription, and not abort the subscription */
- } else {
+ } else if (subscribed == NONE) {
/* Can't find a format for events that we know about */
char mybuf[200];
- snprintf(mybuf, sizeof(mybuf), "489 Bad Event (format %s)", acceptheader);
+ if (!ast_strlen_zero(unknown_acceptheader)) {
+ snprintf(mybuf, sizeof(mybuf), "489 Bad Event (format %s)", unknown_acceptheader);
+ } else {
+ snprintf(mybuf, sizeof(mybuf), "489 Bad Event");
+ }
transmit_response(p, mybuf, req);
-
- ast_log(LOG_WARNING, "SUBSCRIBE failure: unrecognized format: '%s' pvt: subscribed: %d, stateid: %d, laststate: %d, dialogver: %d, subscribecont: '%s', subscribeuri: '%s'\n",
- acceptheader, (int)p->subscribed, p->stateid, p->laststate, p->dialogver, p->subscribecontext, p->subscribeuri);
+ ast_log(LOG_WARNING,"SUBSCRIBE failure: unrecognized format:"
+ "'%s' pvt: subscribed: %d, stateid: %d, laststate: %d,"
+ "dialogver: %d, subscribecont: '%s', subscribeuri: '%s'\n",
+ unknown_acceptheader,
+ (int)p->subscribed,
+ p->stateid,
+ p->laststate,
+ p->dialogver,
+ p->subscribecontext,
+ p->subscribeuri);
pvt_set_needdestroy(p, "unrecognized format");
return 0;
+ } else {
+ p->subscribed = subscribed;
+ }
+ } else if (!strcmp(event, "message-summary")) {
+ int start = 0;
+ int found_supported = 0;
+ const char *acceptheader;
+
+ acceptheader = __get_header(req, "Accept", &start);
+ while (!found_supported && !ast_strlen_zero(acceptheader)) {
+ found_supported = strcmp(acceptheader, "application/simple-message-summary") ? 0 : 1;
+ if (!found_supported && (option_debug > 2)) {
+ ast_log(LOG_DEBUG, "Received SIP mailbox subscription for unknown format: %s\n", acceptheader);
+ }
+ acceptheader = __get_header(req, "Accept", &start);
}
- } else if (!strcmp(event, "message-summary")) {
- if (!ast_strlen_zero(acceptheader) && strcmp(acceptheader, "application/simple-message-summary")) {
+ if (start && !found_supported) {
/* Format requested that we do not support */
transmit_response(p, "406 Not Acceptable", req);
ast_debug(2, "Received SIP mailbox subscription for unknown format: %s\n", acceptheader);
@@ -21482,6 +21571,7 @@ static int handle_request_subscribe(struct sip_pvt *p, struct sip_request *req,
unref_peer(authpeer, "unref_peer, from handle_request_subscribe (authpeer 3)");
return 0;
}
+
/* Looks like they actually want a mailbox status
This version of Asterisk supports mailbox subscriptions
The subscribed URI needs to exist in the dial plan
@@ -22954,7 +23044,7 @@ enum st_mode st_get_mode(struct sip_pvt *p)
static int sip_poke_noanswer(const void *data)
{
struct sip_peer *peer = (struct sip_peer *)data;
-
+
peer->pokeexpire = -1;
if (peer->lastms > -1) {
@@ -22973,12 +23063,15 @@ static int sip_poke_noanswer(const void *data)
peer->call = dialog_unref(peer->call, "unref dialog peer->call");
/* peer->call = sip_destroy(peer->call);*/
}
-
- peer->lastms = -1;
- ast_devstate_changed(AST_DEVICE_UNKNOWN, "SIP/%s", peer->name);
+
+ /* Don't send a devstate change if nothing changed. */
+ if (peer->lastms > -1) {
+ peer->lastms = -1;
+ ast_devstate_changed(AST_DEVICE_UNKNOWN, "SIP/%s", peer->name);
+ }
/* Try again quickly */
- AST_SCHED_REPLACE_UNREF(peer->pokeexpire, sched,
+ AST_SCHED_REPLACE_UNREF(peer->pokeexpire, sched,
DEFAULT_FREQ_NOTOK, sip_poke_peer_s, peer,
unref_peer(_data, "removing poke peer ref"),
unref_peer(peer, "removing poke peer ref"),
@@ -23772,6 +23865,8 @@ static void set_peer_defaults(struct sip_peer *peer)
peer->timer_t1 = global_t1;
peer->timer_b = global_timer_b;
clear_peer_mailboxes(peer);
+ peer->transports = default_transports;
+ peer->default_outbound_transport = default_primary_transport;
}
/*! \brief Create temporary peer (used in autocreatepeer mode) */
@@ -23914,6 +24009,7 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, str
/* If we have realm authentication information, remove them (reload) */
clear_realm_authentication(peer->auth);
peer->auth = NULL;
+ /* clear the transport information. We will detect if a default value is required after parsing the config */
peer->default_outbound_transport = 0;
peer->transports = 0;
@@ -25145,6 +25241,8 @@ static int reload_config(enum channelreloadreason reason)
ast_netsock_set_qos(sipsock, global_tos_sip, global_cos_sip, "SIP");
}
}
+ } else {
+ ast_netsock_set_qos(sipsock, global_tos_sip, global_cos_sip, "SIP");
}
if (stunaddr.sin_addr.s_addr != 0) {
ast_debug(1, "stun to %s:%d\n",
@@ -25803,9 +25901,8 @@ static int sip_do_reload(enum channelreloadreason reason)
start_poke = time(0);
/* Prune peers who still are supposed to be deleted */
- ao2_t_callback(peers, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, peer_is_marked, NULL,
- "callback to remove marked peers");
-
+ unlink_marked_peers_from_tables();
+
ast_debug(4, "--------------- Done destroying pruned peers\n");
/* Send qualify (OPTIONS) to all peers */
diff --git a/channels/chan_usbradio.c b/channels/chan_usbradio.c
index 4a0984cdd..f2eae27c4 100644
--- a/channels/chan_usbradio.c
+++ b/channels/chan_usbradio.c
@@ -644,7 +644,7 @@ static struct chan_usbradio_pvt usbradio_default = {
/* DECLARE FUNCTION PROTOTYPES */
-static void store_txtoctype(struct chan_usbradio_pvt *o, char *s);
+static void store_txtoctype(struct chan_usbradio_pvt *o, const char *s);
static int hidhdwconfig(struct chan_usbradio_pvt *o);
static int set_txctcss_level(struct chan_usbradio_pvt *o);
static void pmrdump(struct chan_usbradio_pvt *o);
@@ -1118,8 +1118,7 @@ static void *hidthread(void *arg)
struct usb_device *usb_dev;
struct usb_dev_handle *usb_handle;
struct chan_usbradio_pvt *o = (struct chan_usbradio_pvt *) arg;
- struct timeval to;
- fd_set rfds;
+ struct pollfd pfd = { .events = POLLIN };
usb_dev = hid_device_init(o->devstr);
if (usb_dev == NULL) {
@@ -1155,63 +1154,49 @@ static void *hidthread(void *arg)
traceusb1(("hidthread: Starting normally on %s!!\n",o->name));
lastrx = 0;
// popen
- while(!o->stophid)
- {
- to.tv_sec = 0;
- to.tv_usec = 50000; // maw sph
+ while (!o->stophid) {
+ pfd.fd = o->pttkick[0];
+ pfd.revents = 0;
- FD_ZERO(&rfds);
- FD_SET(o->pttkick[0],&rfds);
- /* ast_select emulates linux behaviour in terms of timeout handling */
- res = ast_select(o->pttkick[0] + 1, &rfds, NULL, NULL, &to);
+ res = ast_poll(&pfd, 1, 50);
if (res < 0) {
- ast_log(LOG_WARNING, "select failed: %s\n", strerror(errno));
+ ast_log(LOG_WARNING, "poll() failed: %s\n", strerror(errno));
usleep(10000);
continue;
}
- if (FD_ISSET(o->pttkick[0],&rfds))
- {
+ if (pfd.revents & POLLIN) {
char c;
- if (read(o->pttkick[0],&c,1) < 0) {
+ if (read(o->pttkick[0], &c, 1) < 0) {
ast_log(LOG_ERROR, "read() failed: %s\n", strerror(errno));
}
}
- if(o->wanteeprom)
- {
+ if (o->wanteeprom) {
ast_mutex_lock(&o->eepromlock);
- if (o->eepromctl == 1) /* to read */
- {
+ if (o->eepromctl == 1) { /* to read */
/* if CS okay */
- if (!get_eeprom(usb_handle,o->eeprom))
- {
- if (o->eeprom[EEPROM_MAGIC_ADDR] != EEPROM_MAGIC)
- {
- ast_log(LOG_NOTICE,"UNSUCCESSFUL: EEPROM MAGIC NUMBER BAD on channel %s\n",o->name);
- }
- else
- {
+ if (!get_eeprom(usb_handle, o->eeprom)) {
+ if (o->eeprom[EEPROM_MAGIC_ADDR] != EEPROM_MAGIC) {
+ ast_log(LOG_NOTICE, "UNSUCCESSFUL: EEPROM MAGIC NUMBER BAD on channel %s\n", o->name);
+ } else {
o->rxmixerset = o->eeprom[EEPROM_RXMIXERSET];
- o->txmixaset = o->eeprom[EEPROM_TXMIXASET];
+ o->txmixaset = o->eeprom[EEPROM_TXMIXASET];
o->txmixbset = o->eeprom[EEPROM_TXMIXBSET];
- memcpy(&o->rxvoiceadj,&o->eeprom[EEPROM_RXVOICEADJ],sizeof(float));
- memcpy(&o->rxctcssadj,&o->eeprom[EEPROM_RXCTCSSADJ],sizeof(float));
+ memcpy(&o->rxvoiceadj, &o->eeprom[EEPROM_RXVOICEADJ], sizeof(float));
+ memcpy(&o->rxctcssadj, &o->eeprom[EEPROM_RXCTCSSADJ], sizeof(float));
o->txctcssadj = o->eeprom[EEPROM_TXCTCSSADJ];
o->rxsquelchadj = o->eeprom[EEPROM_RXSQUELCHADJ];
ast_log(LOG_NOTICE,"EEPROM Loaded on channel %s\n",o->name);
}
- }
- else
- {
- ast_log(LOG_NOTICE,"USB Adapter has no EEPROM installed or Checksum BAD on channel %s\n",o->name);
+ } else {
+ ast_log(LOG_NOTICE, "USB Adapter has no EEPROM installed or Checksum BAD on channel %s\n", o->name);
}
hid_set_outputs(usb_handle,bufsave);
- }
- if (o->eepromctl == 2) /* to write */
- {
+ }
+ if (o->eepromctl == 2) { /* to write */
put_eeprom(usb_handle,o->eeprom);
hid_set_outputs(usb_handle,bufsave);
- ast_log(LOG_NOTICE,"USB Parameters written to EEPROM on %s\n",o->name);
+ ast_log(LOG_NOTICE, "USB Parameters written to EEPROM on %s\n", o->name);
}
o->eepromctl = 0;
ast_mutex_unlock(&o->eepromlock);
@@ -1219,38 +1204,43 @@ static void *hidthread(void *arg)
buf[o->hid_gpio_ctl_loc] = o->hid_gpio_ctl;
hid_get_inputs(usb_handle,buf);
keyed = !(buf[o->hid_io_cor_loc] & o->hid_io_cor);
- if (keyed != o->rxhidsq)
- {
- if(o->debuglevel)printf("chan_usbradio() hidthread: update rxhidsq = %d\n",keyed);
+ if (keyed != o->rxhidsq) {
+ if (o->debuglevel) {
+ printf("chan_usbradio() hidthread: update rxhidsq = %d\n", keyed);
+ }
o->rxhidsq=keyed;
}
/* if change in tx state as controlled by xpmr */
- txtmp=o->pmrChan->txPttOut;
-
- if (o->lasttx != txtmp)
- {
- o->pmrChan->txPttHid=o->lasttx = txtmp;
- if(o->debuglevel)printf("hidthread: tx set to %d\n",txtmp);
- buf[o->hid_gpio_loc] = 0;
- if (!o->invertptt)
- {
- if (txtmp) buf[o->hid_gpio_loc] = o->hid_io_ptt;
+ txtmp = o->pmrChan->txPttOut;
+
+ if (o->lasttx != txtmp) {
+ o->pmrChan->txPttHid = o->lasttx = txtmp;
+ if (o->debuglevel) {
+ ast_debug(0, "hidthread: tx set to %d\n", txtmp);
}
- else
- {
- if (!txtmp) buf[o->hid_gpio_loc] = o->hid_io_ptt;
+ buf[o->hid_gpio_loc] = 0;
+ if (!o->invertptt) {
+ if (txtmp) {
+ buf[o->hid_gpio_loc] = o->hid_io_ptt;
+ }
+ } else {
+ if (!txtmp) {
+ buf[o->hid_gpio_loc] = o->hid_io_ptt;
+ }
}
buf[o->hid_gpio_ctl_loc] = o->hid_gpio_ctl;
- memcpy(bufsave,buf,sizeof(buf));
- hid_set_outputs(usb_handle,buf);
+ memcpy(bufsave, buf, sizeof(buf));
+ hid_set_outputs(usb_handle, buf);
}
time(&o->lasthidtime);
}
buf[o->hid_gpio_loc] = 0;
- if (o->invertptt) buf[o->hid_gpio_loc] = o->hid_io_ptt;
+ if (o->invertptt) {
+ buf[o->hid_gpio_loc] = o->hid_io_ptt;
+ }
buf[o->hid_gpio_ctl_loc] = o->hid_gpio_ctl;
- hid_set_outputs(usb_handle,buf);
+ hid_set_outputs(usb_handle, buf);
pthread_exit(0);
}
@@ -1451,37 +1441,29 @@ static void *sound_thread(void *arg)
*/
read(o->sounddev, ign, sizeof(ign));
for (;;) {
- fd_set rfds, wfds;
- int maxfd, res;
-
- FD_ZERO(&rfds);
- FD_ZERO(&wfds);
- FD_SET(o->sndcmd[0], &rfds);
- maxfd = o->sndcmd[0]; /* pipe from the main process */
- if (o->cursound > -1 && o->sounddev < 0)
+ struct pollfd pfd[2] = { { .fd = o->sndcmd[0], .events = POLLIN }, { .fd = o->sounddev } };
+ int res;
+
+ if (o->cursound > -1 && o->sounddev < 0) {
setformat(o, O_RDWR); /* need the channel, try to reopen */
- else if (o->cursound == -1 && o->owner == NULL)
- {
+ } else if (o->cursound == -1 && o->owner == NULL) {
setformat(o, O_CLOSE); /* can close */
}
if (o->sounddev > -1) {
if (!o->owner) { /* no one owns the audio, so we must drain it */
- FD_SET(o->sounddev, &rfds);
- maxfd = MAX(o->sounddev, maxfd);
+ pfd[1].events = POLLIN;
}
if (o->cursound > -1) {
- FD_SET(o->sounddev, &wfds);
- maxfd = MAX(o->sounddev, maxfd);
+ pfd[1].events |= POLLOUT;
}
}
- /* ast_select emulates linux behaviour in terms of timeout handling */
- res = ast_select(maxfd + 1, &rfds, &wfds, NULL, NULL);
+ res = ast_poll(pfd, o->sounddev > -1 ? 2 : 1, -1);
if (res < 1) {
- ast_log(LOG_WARNING, "select failed: %s\n", strerror(errno));
+ ast_log(LOG_WARNING, "poll failed: %s\n", strerror(errno));
sleep(1);
continue;
}
- if (FD_ISSET(o->sndcmd[0], &rfds)) {
+ if (pfd[0].revents & POLLIN) {
/* read which sound to play from the pipe */
int i, what = -1;
@@ -1494,14 +1476,17 @@ static void *sound_thread(void *arg)
break;
}
}
- if (sounds[i].ind == -1)
+ if (sounds[i].ind == -1) {
ast_log(LOG_WARNING, "invalid sound index: %d\n", what);
+ }
}
if (o->sounddev > -1) {
- if (FD_ISSET(o->sounddev, &rfds)) /* read and ignore errors */
+ if (pfd[1].revents & POLLIN) { /* read and ignore errors */
read(o->sounddev, ign, sizeof(ign));
- if (FD_ISSET(o->sounddev, &wfds))
+ }
+ if (pfd[1].revents & POLLOUT) {
send_sound(o);
+ }
}
}
return NULL; /* Never reached */
@@ -2694,7 +2679,7 @@ static void store_callerid(struct chan_usbradio_pvt *o, char *s)
}
#endif
-static void store_rxdemod(struct chan_usbradio_pvt *o, char *s)
+static void store_rxdemod(struct chan_usbradio_pvt *o, const char *s)
{
if (!strcasecmp(s,"no")){
o->rxdemod = RX_AUDIO_NONE;
@@ -2713,7 +2698,7 @@ static void store_rxdemod(struct chan_usbradio_pvt *o, char *s)
}
-static void store_txmixa(struct chan_usbradio_pvt *o, char *s)
+static void store_txmixa(struct chan_usbradio_pvt *o, const char *s)
{
if (!strcasecmp(s,"no")){
o->txmixa = TX_OUT_OFF;
@@ -2737,7 +2722,7 @@ static void store_txmixa(struct chan_usbradio_pvt *o, char *s)
//ast_log(LOG_WARNING, "set txmixa = %s\n", s);
}
-static void store_txmixb(struct chan_usbradio_pvt *o, char *s)
+static void store_txmixb(struct chan_usbradio_pvt *o, const char *s)
{
if (!strcasecmp(s,"no")){
o->txmixb = TX_OUT_OFF;
@@ -2762,7 +2747,7 @@ static void store_txmixb(struct chan_usbradio_pvt *o, char *s)
}
/*
*/
-static void store_rxcdtype(struct chan_usbradio_pvt *o, char *s)
+static void store_rxcdtype(struct chan_usbradio_pvt *o, const char *s)
{
if (!strcasecmp(s,"no")){
o->rxcdtype = CD_IGNORE;
@@ -2787,7 +2772,7 @@ static void store_rxcdtype(struct chan_usbradio_pvt *o, char *s)
}
/*
*/
-static void store_rxsdtype(struct chan_usbradio_pvt *o, char *s)
+static void store_rxsdtype(struct chan_usbradio_pvt *o, const char *s)
{
if (!strcasecmp(s,"no") || !strcasecmp(s,"SD_IGNORE")){
o->rxsdtype = SD_IGNORE;
@@ -2809,7 +2794,7 @@ static void store_rxsdtype(struct chan_usbradio_pvt *o, char *s)
}
/*
*/
-static void store_rxgain(struct chan_usbradio_pvt *o, char *s)
+static void store_rxgain(struct chan_usbradio_pvt *o, const char *s)
{
float f;
sscanf(s, "%30f", &f);
@@ -2818,7 +2803,7 @@ static void store_rxgain(struct chan_usbradio_pvt *o, char *s)
}
/*
*/
-static void store_rxvoiceadj(struct chan_usbradio_pvt *o, char *s)
+static void store_rxvoiceadj(struct chan_usbradio_pvt *o, const char *s)
{
float f;
sscanf(s, "%30f", &f);
@@ -2827,7 +2812,7 @@ static void store_rxvoiceadj(struct chan_usbradio_pvt *o, char *s)
}
/*
*/
-static void store_rxctcssadj(struct chan_usbradio_pvt *o, char *s)
+static void store_rxctcssadj(struct chan_usbradio_pvt *o, const char *s)
{
float f;
sscanf(s, "%30f", &f);
@@ -2836,7 +2821,7 @@ static void store_rxctcssadj(struct chan_usbradio_pvt *o, char *s)
}
/*
*/
-static void store_txtoctype(struct chan_usbradio_pvt *o, char *s)
+static void store_txtoctype(struct chan_usbradio_pvt *o, const char *s)
{
if (!strcasecmp(s,"no") || !strcasecmp(s,"TOC_NONE")){
o->txtoctype = TOC_NONE;
diff --git a/channels/console_video.c b/channels/console_video.c
index 88bf807d5..c26ac983f 100644
--- a/channels/console_video.c
+++ b/channels/console_video.c
@@ -234,34 +234,34 @@ struct video_out_desc {
* and contain all configurtion info.
*/
struct video_desc {
- char codec_name[64]; /* the codec we use */
+ char codec_name[64]; /* the codec we use */
- int stayopen; /* set if gui starts manually */
- pthread_t vthread; /* video thread */
- ast_mutex_t dec_lock; /* sync decoder and video thread */
- int shutdown; /* set to shutdown vthread */
- struct ast_channel *owner; /* owner channel */
+ int stayopen; /* set if gui starts manually */
+ pthread_t vthread; /* video thread */
+ ast_mutex_t dec_lock; /* sync decoder and video thread */
+ int shutdown; /* set to shutdown vthread */
+ struct ast_channel *owner; /* owner channel */
- struct fbuf_t enc_in; /* encoder input buffer, allocated in video_out_init() */
+ struct fbuf_t enc_in; /* encoder input buffer, allocated in video_out_init() */
- char keypad_file[256]; /* image for the keypad */
- char keypad_font[256]; /* font for the keypad */
+ char keypad_file[256]; /* image for the keypad */
+ char keypad_font[256]; /* font for the keypad */
- char sdl_videodriver[256];
+ char sdl_videodriver[256];
- struct fbuf_t rem_dpy; /* display remote video, no buffer (it is in win[WIN_REMOTE].bmp) */
- struct fbuf_t loc_dpy; /* display local source, no buffer (managed by SDL in bmp[1]) */
+ struct fbuf_t rem_dpy; /* display remote video, no buffer (it is in win[WIN_REMOTE].bmp) */
+ struct fbuf_t loc_dpy; /* display local source, no buffer (managed by SDL in bmp[1]) */
/* geometry of the thumbnails for all video sources. */
- struct fbuf_t src_dpy[MAX_VIDEO_SOURCES]; /* no buffer allocated here */
+ struct fbuf_t src_dpy[MAX_VIDEO_SOURCES]; /* no buffer allocated here */
- int frame_freeze; /* flag to freeze the incoming frame */
+ int frame_freeze; /* flag to freeze the incoming frame */
/* local information for grabbers, codecs, gui */
- struct gui_info *gui;
- struct video_dec_desc *in; /* remote video descriptor */
- struct video_out_desc out; /* local video descriptor */
+ struct gui_info *gui;
+ struct video_dec_desc *in; /* remote video descriptor */
+ struct video_out_desc out; /* local video descriptor */
};
static AVPicture *fill_pict(struct fbuf_t *b, AVPicture *p);
@@ -387,8 +387,9 @@ static struct fbuf_t *grabber_read(struct video_device *dev, int fps)
*/
static void grabber_move(struct video_device *dev, int dx, int dy)
{
- if (dev->grabber && dev->grabber->move)
- dev->grabber->move(dev->grabber_data, dx, dy);
+ if (dev->grabber && dev->grabber->move) {
+ dev->grabber->move(dev->grabber_data, dx, dy);
+ }
}
/*
@@ -508,33 +509,32 @@ static int video_out_init(struct video_desc *env)
/* now setup the parameters for the encoder.
* XXX should be codec-specific
*/
- {
- AVCodecContext *enc_ctx = avcodec_alloc_context();
- v->enc_ctx = enc_ctx;
- enc_ctx->pix_fmt = enc_in->pix_fmt;
- enc_ctx->width = enc_in->w;
- enc_ctx->height = enc_in->h;
- /* XXX rtp_callback ?
- * rtp_mode so ffmpeg inserts as many start codes as possible.
- */
- enc_ctx->rtp_mode = 1;
- enc_ctx->rtp_payload_size = v->mtu / 2; // mtu/2
- enc_ctx->bit_rate = v->bitrate;
- enc_ctx->bit_rate_tolerance = enc_ctx->bit_rate/2;
- enc_ctx->qmin = v->qmin; /* should be configured */
- enc_ctx->time_base = (AVRational){1, v->fps};
- enc_ctx->gop_size = v->fps*5; // emit I frame every 5 seconds
-
- v->enc->enc_init(v->enc_ctx);
-
- if (avcodec_open(enc_ctx, v->codec) < 0) {
- ast_log(LOG_WARNING, "Unable to initialize the encoder %d\n",
- codec);
- av_free(enc_ctx);
- v->enc_ctx = NULL;
- return video_out_uninit(env);
+ {
+ AVCodecContext *enc_ctx = avcodec_alloc_context();
+ v->enc_ctx = enc_ctx;
+ enc_ctx->pix_fmt = enc_in->pix_fmt;
+ enc_ctx->width = enc_in->w;
+ enc_ctx->height = enc_in->h;
+ /* XXX rtp_callback ?
+ * rtp_mode so ffmpeg inserts as many start codes as possible.
+ */
+ enc_ctx->rtp_mode = 1;
+ enc_ctx->rtp_payload_size = v->mtu / 2; // mtu/2
+ enc_ctx->bit_rate = v->bitrate;
+ enc_ctx->bit_rate_tolerance = enc_ctx->bit_rate/2;
+ enc_ctx->qmin = v->qmin; /* should be configured */
+ enc_ctx->time_base = (AVRational){1, v->fps};
+ enc_ctx->gop_size = v->fps*5; // emit I frame every 5 seconds
+
+ v->enc->enc_init(v->enc_ctx);
+
+ if (avcodec_open(enc_ctx, v->codec) < 0) {
+ ast_log(LOG_WARNING, "Unable to initialize the encoder %d\n", codec);
+ av_free(enc_ctx);
+ v->enc_ctx = NULL;
+ return video_out_uninit(env);
+ }
}
- }
/*
* Allocate enough for the encoded bitstream. As we are compressing,
* we hope that the output is never larger than the input size.
@@ -637,9 +637,9 @@ static void my_scale(struct fbuf_t *in, AVPicture *p_in,
p_in = fill_pict(in, &my_p_in);
if (p_out == NULL)
p_out = fill_pict(out, &my_p_out);
-
- /*if win_w is different from zero then we must change
- the size of the scaled buffer (the position is already
+
+ /*if win_w is different from zero then we must change
+ the size of the scaled buffer (the position is already
encoded into the out parameter)*/
if (out->win_w) { /* picture in picture enabled */
eff_w=out->win_w;
@@ -650,26 +650,26 @@ static void my_scale(struct fbuf_t *in, AVPicture *p_in,
img_convert(p_out, out->pix_fmt,
p_in, in->pix_fmt, in->w, in->h);
#else /* XXX replacement */
- {
- struct SwsContext *convert_ctx;
-
- convert_ctx = sws_getContext(in->w, in->h, in->pix_fmt,
- eff_w, eff_h, out->pix_fmt,
- SWS_BICUBIC, NULL, NULL, NULL);
- if (convert_ctx == NULL) {
- ast_log(LOG_ERROR, "FFMPEG::convert_cmodel : swscale context initialization failed");
- return;
+ {
+ struct SwsContext *convert_ctx;
+
+ convert_ctx = sws_getContext(in->w, in->h, in->pix_fmt,
+ eff_w, eff_h, out->pix_fmt,
+ SWS_BICUBIC, NULL, NULL, NULL);
+ if (convert_ctx == NULL) {
+ ast_log(LOG_ERROR, "FFMPEG::convert_cmodel : swscale context initialization failed");
+ return;
+ }
+ if (0)
+ ast_log(LOG_WARNING, "in %d %dx%d out %d %dx%d\n",
+ in->pix_fmt, in->w, in->h, out->pix_fmt, eff_w, eff_h);
+ sws_scale(convert_ctx,
+ p_in->data, p_in->linesize,
+ in->w, in->h, /* src slice */
+ p_out->data, p_out->linesize);
+
+ sws_freeContext(convert_ctx);
}
- if (0)
- ast_log(LOG_WARNING, "in %d %dx%d out %d %dx%d\n",
- in->pix_fmt, in->w, in->h, out->pix_fmt, eff_w, eff_h);
- sws_scale(convert_ctx,
- p_in->data, p_in->linesize,
- in->w, in->h, /* src slice */
- p_out->data, p_out->linesize);
-
- sws_freeContext(convert_ctx);
- }
#endif /* XXX replacement */
}
@@ -873,18 +873,20 @@ static void *video_thread(void *arg)
}
}
sdl_setup(env);
- if (!ast_strlen_zero(save_display))
+ if (!ast_strlen_zero(save_display)) {
setenv("DISPLAY", save_display, 1);
+ }
ast_mutex_init(&env->dec_lock); /* used to sync decoder and renderer */
if (grabber_open(&env->out)) {
ast_log(LOG_WARNING, "cannot open local video source\n");
- }
+ }
- if (env->out.device_num)
+ if (env->out.device_num) {
env->out.devices[env->out.device_primary].status_index |= IS_PRIMARY | IS_SECONDARY;
-
+ }
+
/* even if no device is connected, we must call video_out_init,
* as some of the data structures it initializes are
* used in get_video_frames()
@@ -893,14 +895,14 @@ static void *video_thread(void *arg)
/* Writes intial status of the sources. */
if (env->gui) {
- for (i = 0; i < env->out.device_num; i++) {
- print_message(env->gui->thumb_bd_array[i].board,
- src_msgs[env->out.devices[i].status_index]);
- }
+ for (i = 0; i < env->out.device_num; i++) {
+ print_message(env->gui->thumb_bd_array[i].board,
+ src_msgs[env->out.devices[i].status_index]);
+ }
}
for (;;) {
- struct timeval t = { 0, 50000 }; /* XXX 20 times/sec */
+ struct timespec t = { 0, 50000000 }; /* XXX 20 times/sec */
struct ast_frame *p, *f;
struct ast_channel *chan;
int fd;
@@ -908,13 +910,14 @@ static void *video_thread(void *arg)
/* determine if video format changed */
if (count++ % 10 == 0) {
- if (env->out.sendvideo && env->out.devices)
- sprintf(buf, "%s %s %dx%d @@ %dfps %dkbps",
+ if (env->out.sendvideo && env->out.devices) {
+ snprintf(buf, sizeof(buf), "%s %s %dx%d @@ %dfps %dkbps",
env->out.devices[env->out.device_primary].name, env->codec_name,
env->enc_in.w, env->enc_in.h,
- env->out.fps, env->out.bitrate/1000);
- else
- sprintf(buf, "hold");
+ env->out.fps, env->out.bitrate / 1000);
+ } else {
+ sprintf(buf, "hold");
+ }
caption = buf;
}
@@ -923,36 +926,36 @@ static void *video_thread(void *arg)
* otherwise the drag will not work */
if (env->gui)
eventhandler(env, caption);
-
+
/* sleep for a while */
- ast_select(0, NULL, NULL, NULL, &t);
+ nanosleep(&t, NULL);
if (env->in) {
- struct video_dec_desc *v = env->in;
-
- /*
- * While there is something to display, call the decoder and free
- * the buffer, possibly enabling the receiver to store new data.
- */
- while (v->dec_in_dpy) {
- struct fbuf_t *tmp = v->dec_in_dpy; /* store current pointer */
-
- /* decode the frame, but show it only if not frozen */
- if (v->d_callbacks->dec_run(v, tmp) && !env->frame_freeze)
- show_frame(env, WIN_REMOTE);
- tmp->used = 0; /* mark buffer as free */
- tmp->ebit = 0;
- ast_mutex_lock(&env->dec_lock);
- if (++v->dec_in_dpy == &v->dec_in[N_DEC_IN]) /* advance to next, circular */
- v->dec_in_dpy = &v->dec_in[0];
-
- if (v->dec_in_cur == NULL) /* receiver was idle, enable it... */
- v->dec_in_cur = tmp; /* using the slot just freed */
- else if (v->dec_in_dpy == v->dec_in_cur) /* this was the last slot */
- v->dec_in_dpy = NULL; /* nothing more to display */
- ast_mutex_unlock(&env->dec_lock);
+ struct video_dec_desc *v = env->in;
+
+ /*
+ * While there is something to display, call the decoder and free
+ * the buffer, possibly enabling the receiver to store new data.
+ */
+ while (v->dec_in_dpy) {
+ struct fbuf_t *tmp = v->dec_in_dpy; /* store current pointer */
+
+ /* decode the frame, but show it only if not frozen */
+ if (v->d_callbacks->dec_run(v, tmp) && !env->frame_freeze)
+ show_frame(env, WIN_REMOTE);
+ tmp->used = 0; /* mark buffer as free */
+ tmp->ebit = 0;
+ ast_mutex_lock(&env->dec_lock);
+ if (++v->dec_in_dpy == &v->dec_in[N_DEC_IN]) /* advance to next, circular */
+ v->dec_in_dpy = &v->dec_in[0];
+
+ if (v->dec_in_cur == NULL) /* receiver was idle, enable it... */
+ v->dec_in_cur = tmp; /* using the slot just freed */
+ else if (v->dec_in_dpy == v->dec_in_cur) /* this was the last slot */
+ v->dec_in_dpy = NULL; /* nothing more to display */
+ ast_mutex_unlock(&env->dec_lock);
+ }
}
- }
if (env->shutdown)
break;
@@ -988,7 +991,7 @@ static void *video_thread(void *arg)
for (p = f; p; p = AST_LIST_NEXT(p, frame_list)) {
if (write(fd, &blah, l) != l)
ast_log(LOG_WARNING, "Unable to write to alert pipe on %s, frametype/subclass %d/%d: %s!\n",
- chan->name, f->frametype, f->subclass, strerror(errno));
+ chan->name, f->frametype, f->subclass, strerror(errno));
}
}
ast_channel_unlock(chan);
@@ -1194,13 +1197,13 @@ int console_video_cli(struct video_desc *env, const char *var, int fd)
if (env == NULL)
return 1; /* unrecognised */
- if (!strcasecmp(var, "videodevice")) {
+ if (!strcasecmp(var, "videodevice")) {
ast_cli(fd, "videodevice is [%s]\n", env->out.devices[env->out.device_primary].name);
- } else if (!strcasecmp(var, "videocodec")) {
+ } else if (!strcasecmp(var, "videocodec")) {
ast_cli(fd, "videocodec is [%s]\n", env->codec_name);
- } else if (!strcasecmp(var, "sendvideo")) {
+ } else if (!strcasecmp(var, "sendvideo")) {
ast_cli(fd, "sendvideo is [%s]\n", env->out.sendvideo ? "on" : "off");
- } else if (!strcasecmp(var, "video_size")) {
+ } else if (!strcasecmp(var, "video_size")) {
int in_w = 0, in_h = 0;
if (env->in) {
in_w = env->in->dec_out.w;
@@ -1212,22 +1215,22 @@ int console_video_cli(struct video_desc *env, const char *var, int fd)
env->loc_dpy.w, env->loc_dpy.h,
env->rem_dpy.w, env->rem_dpy.h,
in_w, in_h);
- } else if (!strcasecmp(var, "bitrate")) {
+ } else if (!strcasecmp(var, "bitrate")) {
ast_cli(fd, "bitrate is [%d]\n", env->out.bitrate);
- } else if (!strcasecmp(var, "qmin")) {
+ } else if (!strcasecmp(var, "qmin")) {
ast_cli(fd, "qmin is [%d]\n", env->out.qmin);
- } else if (!strcasecmp(var, "fps")) {
+ } else if (!strcasecmp(var, "fps")) {
ast_cli(fd, "fps is [%d]\n", env->out.fps);
- } else if (!strcasecmp(var, "startgui")) {
+ } else if (!strcasecmp(var, "startgui")) {
env->stayopen = 1;
console_video_start(env, NULL);
- } else if (!strcasecmp(var, "stopgui") && env->stayopen != 0) {
+ } else if (!strcasecmp(var, "stopgui") && env->stayopen != 0) {
env->stayopen = 0;
if (env->gui && env->owner)
ast_cli_command(-1, "console hangup");
else /* not in a call */
console_video_uninit(env);
- } else {
+ } else {
return 1; /* unrecognised */
}
return 0; /* recognised */