aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoroej <oej@f38db490-d61c-443f-a65b-d21fe96a405b>2006-06-29 07:15:12 +0000
committeroej <oej@f38db490-d61c-443f-a65b-d21fe96a405b>2006-06-29 07:15:12 +0000
commitead171c77dfdbdcd9d556f11d9e047a897236987 (patch)
treec998ab7b916c915ab3fade5cd1c5916c0313c09a
parente73494f5eb7c2d0e9736fe8ab1d968494b8bf374 (diff)
Add support for a=inactive in SDP for holding. This is not very well documented
in RFCs, as they keep referring to each other in a circular pattern in regards to this item, but since the Nokia SIP/GSM phones use this, we might as well start supporting it. git-svn-id: http://svn.digium.com/svn/asterisk/trunk@36252 f38db490-d61c-443f-a65b-d21fe96a405b
-rw-r--r--channels/chan_sip.c39
1 files changed, 23 insertions, 16 deletions
diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index e44679f9e..2d686fdd1 100644
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -701,7 +701,7 @@ struct sip_auth {
#define SIP_PROG_INBAND_NEVER (0 << 25)
#define SIP_PROG_INBAND_NO (1 << 25)
#define SIP_PROG_INBAND_YES (2 << 25)
-#define SIP_CALL_ONHOLD (1 << 27) /*!< Call states */
+#define SIP_FREE_BIT (1 << 27) /*!< Undefined bit - not in use */
#define SIP_CALL_LIMIT (1 << 28) /*!< Call limit enforced for this call */
#define SIP_SENDRPID (1 << 29) /*!< Remote Party-ID Support */
#define SIP_INC_COUNT (1 << 30) /*!< Did this connection increment the counter of in-use calls? */
@@ -711,7 +711,7 @@ struct sip_auth {
SIP_PROG_INBAND | SIP_USECLIENTCODE | SIP_NAT | \
SIP_USEREQPHONE | SIP_INSECURE_PORT | SIP_INSECURE_INVITE)
-/* a new page of flags for peers */
+/* a new page of flags */
#define SIP_PAGE2_RTCACHEFRIENDS (1 << 0)
#define SIP_PAGE2_RTUPDATE (1 << 1)
#define SIP_PAGE2_RTAUTOCLEAR (1 << 2)
@@ -731,6 +731,9 @@ struct sip_auth {
#define SIP_PAGE2_T38SUPPORT_UDPTL (1 << 14) /*!< 14: T38 Fax Passthrough Support */
#define SIP_PAGE2_T38SUPPORT_RTP (2 << 14) /*!< 15: T38 Fax Passthrough Support */
#define SIP_PAGE2_T38SUPPORT_TCP (4 << 14) /*!< 16: T38 Fax Passthrough Support */
+#define SIP_PAGE2_CALL_ONHOLD (2 << 17) /*!< Call states */
+#define SIP_PAGE2_CALL_ONHOLD_ONEDIR (1 << 17) /*!< 17: One directional hold */
+#define SIP_PAGE2_CALL_ONHOLD_INACTIVE (2 << 17) /*!< 18: Inactive */
#define SIP_PAGE2_FLAGS_TO_COPY \
(SIP_PAGE2_ALLOWSUBSCRIBE | SIP_PAGE2_ALLOWOVERLAP | SIP_PAGE2_VIDEOSUPPORT | SIP_PAGE2_T38SUPPORT)
@@ -4659,12 +4662,7 @@ static int process_sdp(struct sip_pvt *p, struct sip_request *req)
int breakout = FALSE;
/* If we're debugging, check for unsupported sdp options */
- if (!strcasecmp(a, "inactive")) {
- /* Inactive media streams: Not supported */
- if (debug)
- ast_verbose("Got unsupported a:inactive in SDP offer \n");
- breakout = TRUE;
- } else if (!strncasecmp(a, "rtcp:", (size_t) 5)) {
+ if (!strncasecmp(a, "rtcp:", (size_t) 5)) {
if (debug)
ast_verbose("Got unsupported a:rtcp in SDP offer \n");
breakout = TRUE;
@@ -4702,6 +4700,9 @@ static int process_sdp(struct sip_pvt *p, struct sip_request *req)
if (!strcasecmp(a, "sendonly")) {
sendonly = 1;
continue;
+ } else if (!strcasecmp(a, "inactive")) {
+ sendonly = 2;
+ continue;
} else if (!strcasecmp(a, "sendrecv")) {
sendonly = 0;
continue;
@@ -4930,7 +4931,7 @@ static int process_sdp(struct sip_pvt *p, struct sip_request *req)
/* Activate a re-invite */
ast_queue_frame(p->owner, &ast_null_frame);
- } else {
+ } else if (!sin.sin_addr.s_addr || sendonly ) {
/* No address for RTP, we're on hold */
ast_moh_start(bridgepeer, NULL);
if (sendonly)
@@ -4940,11 +4941,12 @@ static int process_sdp(struct sip_pvt *p, struct sip_request *req)
/* Activate a re-invite */
ast_queue_frame(p->owner, &ast_null_frame);
}
+ /* guess we got a re-invite for changing media or IP - not hold/unhold */
}
/* Manager Hold and Unhold events must be generated, if necessary */
if (sin.sin_addr.s_addr && !sendonly) {
- if (ast_test_flag(&p->flags[0], SIP_CALL_ONHOLD)) {
+ if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) {
append_history(p, "Unhold", "%s", req->data);
if (global_callevents)
manager_event(EVENT_FLAG_CALL, "Unhold",
@@ -4954,19 +4956,22 @@ static int process_sdp(struct sip_pvt *p, struct sip_request *req)
p->owner->uniqueid);
}
- ast_clear_flag(&p->flags[0], SIP_CALL_ONHOLD);
- } else {
+ ast_clear_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD); /* Clear both flags */
+ } else if (!sin.sin_addr.s_addr || sendonly ) {
/* No address for RTP, we're on hold */
append_history(p, "Hold", "%s", req->data);
- if (global_callevents && !ast_test_flag(&p->flags[0], SIP_CALL_ONHOLD)) {
+ if (global_callevents && !ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) {
manager_event(EVENT_FLAG_CALL, "Hold",
"Channel: %s\r\n"
"Uniqueid: %s\r\n",
p->owner->name,
p->owner->uniqueid);
}
- ast_set_flag(&p->flags[0], SIP_CALL_ONHOLD);
+ if (sendonly == 1) /* One directional hold (sendonly/recvonly)
+ ast_set_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD_ONEDIR);
+ else if (sendonly == 2) /* Inactive stream */
+ ast_set_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD_INACTIVE);
}
return 0;
@@ -5873,8 +5878,10 @@ static int add_sdp(struct sip_request *resp, struct sip_pvt *p)
snprintf(connection, sizeof(connection), "c=IN IP4 %s\r\n", ast_inet_ntoa(iabuf, sizeof(iabuf), dest.sin_addr));
ast_build_string(&m_audio_next, &m_audio_left, "m=audio %d RTP/AVP", ntohs(dest.sin_port));
- if (ast_test_flag(&p->flags[0], SIP_CALL_ONHOLD))
+ if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD_ONEDIR))
hold = "a=recvonly\r\n";
+ else if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD_INACTIVE))
+ hold = "a=inactive\r\n";
else
hold = "a=sendrecv\r\n";
@@ -10012,7 +10019,7 @@ static int __sip_show_channels(int fd, int argc, char *argv[], int subscriptions
cur->callid,
cur->ocseq, cur->icseq,
ast_getformatname(cur->owner ? cur->owner->nativeformats : 0),
- ast_test_flag(&cur->flags[0], SIP_CALL_ONHOLD) ? "Yes" : "No",
+ ast_test_flag(&cur->flags[1], SIP_PAGE2_CALL_ONHOLD) ? "Yes" : "No",
ast_test_flag(&cur->flags[0], SIP_NEEDDESTROY) ? "(d)" : "",
cur->lastmsg ,
referstatus