if (!ast_test_flag(outgoing, DIAL_RINGBACKONLY))
ast_indicate(in, AST_CONTROL_PROGRESS);
break;
+ case AST_CONTROL_VIDUPDATE:
+ if (option_verbose > 2)
+ ast_verbose ( VERBOSE_PREFIX_3 "%s requested a video update, passing it to %s\n", o->chan->name,in->name);
+ ast_indicate(in, AST_CONTROL_VIDUPDATE);
+ break;
case AST_CONTROL_PROCEEDING:
if (option_verbose > 2)
ast_verbose ( VERBOSE_PREFIX_3 "%s is proceeding passing it to %s\n", o->chan->name,in->name);
if (ast_write(outgoing->chan, f))
ast_log(LOG_WARNING, "Unable to forward voice\n");
}
+ if (single && (f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_VIDUPDATE)) {
+ if (option_verbose > 2)
+ ast_verbose ( VERBOSE_PREFIX_3 "%s requested a video update, passing it to %s\n", in->name,outgoing->chan->name);
+ ast_indicate(outgoing->chan, AST_CONTROL_VIDUPDATE);
+ }
ast_frfree(f);
}
if (!*to && (option_verbose > 2))
static int transmit_invite(struct sip_pvt *p, int sipmethod, int sendsdp, struct sip_invite_param *options, int init);
static int transmit_reinvite_with_sdp(struct sip_pvt *p);
static int transmit_info_with_digit(struct sip_pvt *p, char digit);
+static int transmit_info_with_vidupdate(struct sip_pvt *p);
static int transmit_message_with_text(struct sip_pvt *p, const char *text);
static int transmit_refer(struct sip_pvt *p, const char *dest);
static int sip_sipredirect(struct sip_pvt *p, const char *dest);
ast_log(LOG_DEBUG, "Bridged channel is back from hold, let's talk! : %s\n", p->callid);
res = -1;
break;
+ case AST_CONTROL_VIDUPDATE: /* Request a video frame update */
+ if (p->vrtp && !ast_test_flag(p, SIP_NOVIDEO)) {
+ transmit_info_with_vidupdate(p);
+ res = 0;
+ } else
+ res = -1;
+ break;
case -1:
res = -1;
break;
/* If we are cancelling an incoming invite for some reason, add information
about the reason why we are doing this in clear text */
if (p->owner && p->owner->hangupcause) {
- add_header(&resp, "X-Asterisk-HangupCause:", ast_cause2str(p->owner->hangupcause));
+ add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->owner->hangupcause));
}
add_blank_header(&resp);
return send_response(p, &resp, reliable, seqno);
return 0;
}
+/*--- add_vidupdate: add XML encoded media control with update ---*/
+/* XML: The only way to turn 0 bits of information into a few hundred. */
+static int add_vidupdate(struct sip_request *req)
+{
+ const char *xml_is_a_huge_waste_of_space =
+ "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\r\n"
+ " <media_control>\r\n"
+ " <vc_primitive>\r\n"
+ " <to_encoder>\r\n"
+ " <picture_fast_update\r\n"
+ " </picture_fast_update>\r\n"
+ " </to_encoder>\r\n"
+ " </vc_primitive>\r\n"
+ " </media_control>\r\n";
+ add_header(req, "Content-Type", "application/media_control+xml");
+ add_header_contentLength(req, strlen(xml_is_a_huge_waste_of_space));
+ add_line(req, xml_is_a_huge_waste_of_space);
+ return 0;
+}
+
/*--- add_sdp: Add Session Description Protocol message ---*/
static int add_sdp(struct sip_request *resp, struct sip_pvt *p)
{
return send_request(p, &req, 1, p->ocseq);
}
+/*--- transmit_info_with_vidupdate: Send SIP INFO with video update request ---*/
+static int transmit_info_with_vidupdate(struct sip_pvt *p)
+{
+ struct sip_request req;
+ reqprep(&req, p, SIP_INFO, 0, 1);
+ add_vidupdate(&req);
+ return send_request(p, &req, 1, p->ocseq);
+}
+
/*--- transmit_request: transmit generic SIP request ---*/
static int transmit_request(struct sip_pvt *p, int sipmethod, int seqno, int reliable, int newbranch)
{
ast_set_flag(p, SIP_NEEDDESTROY);
}
return;
+ } else if (!strcasecmp(get_header(req, "Content-Type"), "application/media_control+xml")) {
+ /* Eh, we'll just assume it's a fast picture update for now */
+ if (p->owner)
+ ast_queue_control(p->owner, AST_CONTROL_VIDUPDATE);
+ transmit_response(p, "200 OK", req);
+ return;
} else if ((c = get_header(req, "X-ClientCode"))) {
/* Client code (from SNOM phone) */
if (ast_test_flag(p, SIP_USECLIENTCODE)) {
rtp->rtp_lookup_code_cache_result = 0;
}
-/* Make a note of a RTP payload type that was seen in a SDP "m=" line. */
+/* Make a note of a RTP paymoad type that was seen in a SDP "m=" line. */
/* By default, use the well-known value for this type (although it may */
/* still be set to a different value by a subsequent "a=rtpmap:" line): */
void ast_rtp_set_m_type(struct ast_rtp* rtp, int pt) {
ast_log(LOG_WARNING, "Channel '%s' failed to break RTP bridge\n", c1->name);
}
return AST_BRIDGE_COMPLETE;
+ } else if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS)) {
+ if ((f->subclass == AST_CONTROL_HOLD) || (f->subclass == AST_CONTROL_UNHOLD) ||
+ (f->subclass == AST_CONTROL_VIDUPDATE)) {
+ ast_indicate(who == c0 ? c1 : c0, f->subclass);
+ ast_frfree(f);
+ } else {
+ *fo = f;
+ *rc = who;
+ ast_log(LOG_DEBUG, "Got a FRAME_CONTROL (%d) frame on channel %s\n", f->subclass, who->name);
+ return AST_BRIDGE_COMPLETE;
+ }
} else {
if ((f->frametype == AST_FRAME_DTMF) ||
(f->frametype == AST_FRAME_VOICE) ||