[Pkg-voip-commits] [janus] 83/282: Added support for SIP INFO to the SIPre plugin
Jonas Smedegaard
dr at jones.dk
Wed Dec 20 21:53:30 UTC 2017
This is an automated email from the git hooks/post-receive script.
js pushed a commit to annotated tag debian/0.2.6-1
in repository janus.
commit b04afbe3a2a0a63cb138d4f7b50137d0c9ff0802
Author: Lorenzo Miniero <lminiero at gmail.com>
Date: Thu Jun 29 16:44:15 2017 +0200
Added support for SIP INFO to the SIPre plugin
---
plugins/janus_sipre.c | 180 +++++++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 162 insertions(+), 18 deletions(-)
diff --git a/plugins/janus_sipre.c b/plugins/janus_sipre.c
index 7e4a57d..d1ba8d2 100644
--- a/plugins/janus_sipre.c
+++ b/plugins/janus_sipre.c
@@ -17,13 +17,19 @@
* as events with the same transaction.
*
* The supported requests are \c register , \c unregister , \c call ,
- * \c accept, \c hold , \c unhold and \c hangup . \c register can be used,
+ * \c accept, \c info , \c message , \c dtmf_info , \c recording ,
+ * \c hold , \c unhold and \c hangup . \c register can be used,
* as the name suggests, to register a username at a SIP registrar to
* call and be called, while \c unregister unregisters it; \c call is used
- * to send an INVITE to a different SIPre URI through the plugin, while
+ * to send an INVITE to a different SIP URI through the plugin, while
* \c accept is used to accept the call in case one is invited instead
- * of inviting; ; \c hold and \c unhold can be used respectively to put a
- * call on-hold and to resume it; finally, \c hangup can be used to terminate the
+ * of inviting; \c hold and \c unhold can be used respectively to put a
+ * call on-hold and to resume it; \c info allows you to send a generic
+ * SIP INFO request, while \c dtmf_info is focused on using INFO for DTMF
+ * instead; \c message is the method you use to send a SIP message
+ * to the other peer; \c recording is used, instead, to record the
+ * conversation to one or more .mjr files (depending on the direction you
+ * want to record); finally, \c hangup can be used to terminate the
* communication at any time, either to hangup (BYE) an ongoing call or
* to cancel/decline (CANCEL/BYE) a call that hasn't started yet.
*
@@ -172,6 +178,13 @@ static struct janus_json_parameter dtmf_info_parameters[] = {
{"digit", JANUS_JSON_STRING, JANUS_JSON_PARAM_REQUIRED},
{"duration", JANUS_JSON_INTEGER, JANUS_JSON_PARAM_POSITIVE}
};
+static struct janus_json_parameter info_parameters[] = {
+ {"type", JSON_STRING, JANUS_JSON_PARAM_REQUIRED},
+ {"content", JSON_STRING, JANUS_JSON_PARAM_REQUIRED}
+};
+static struct janus_json_parameter sipmessage_parameters[] = {
+ {"content", JSON_STRING, JANUS_JSON_PARAM_REQUIRED}
+};
/* Useful stuff */
static volatile gint initialized = 0, stopping = 0;
@@ -231,7 +244,8 @@ typedef enum janus_sipre_mqueue_event {
janus_sipre_mqueue_event_do_accept,
janus_sipre_mqueue_event_do_rcode,
janus_sipre_mqueue_event_do_update,
- janus_sipre_mqueue_event_do_sipinfo,
+ janus_sipre_mqueue_event_do_info,
+ janus_sipre_mqueue_event_do_message,
janus_sipre_mqueue_event_do_bye,
janus_sipre_mqueue_event_do_destroy,
/* TODO Add other events here */
@@ -253,8 +267,10 @@ static const char *janus_sipre_mqueue_event_string(janus_sipre_mqueue_event even
return "rcode";
case janus_sipre_mqueue_event_do_update:
return "update";
- case janus_sipre_mqueue_event_do_sipinfo:
- return "sipinfo";
+ case janus_sipre_mqueue_event_do_info:
+ return "info";
+ case janus_sipre_mqueue_event_do_message:
+ return "message";
case janus_sipre_mqueue_event_do_bye:
return "bye";
case janus_sipre_mqueue_event_do_destroy:
@@ -624,6 +640,7 @@ void janus_sipre_cb_incoming(const struct sip_msg *msg, void *arg);
int janus_sipre_cb_offer(struct mbuf **mbp, const struct sip_msg *msg, void *arg);
int janus_sipre_cb_answer(const struct sip_msg *msg, void *arg);
void janus_sipre_cb_established(const struct sip_msg *msg, void *arg);
+void janus_sipre_cb_info(struct sip *sip, const struct sip_msg *msg, void *arg);
void janus_sipre_cb_closed(int err, const struct sip_msg *msg, void *arg);
void janus_sipre_cb_exit(void *arg);
@@ -2400,6 +2417,60 @@ static void *janus_sipre_handler(void *data) {
/* Notify the result */
result = json_object();
json_object_set_new(result, "event", json_string("recordingupdated"));
+ } else if(!strcasecmp(request_text, "info")) {
+ /* Send a SIP INFO request: we'll need the payload type and content */
+ if(!(session->status == janus_sipre_call_status_inviting || session->status == janus_sipre_call_status_incall)) {
+ JANUS_LOG(LOG_ERR, "Wrong state (not in a call? status=%s)\n", janus_sipre_call_status_string(session->status));
+ g_snprintf(error_cause, 512, "Wrong state (not in a call?)");
+ goto error;
+ }
+ if(session->callee == NULL) {
+ JANUS_LOG(LOG_ERR, "Wrong state (no callee?)\n");
+ error_code = JANUS_SIPRE_ERROR_WRONG_STATE;
+ g_snprintf(error_cause, 512, "Wrong state (no callee?)");
+ goto error;
+ }
+ JANUS_VALIDATE_JSON_OBJECT(root, info_parameters,
+ error_code, error_cause, TRUE,
+ JANUS_SIPRE_ERROR_MISSING_ELEMENT, JANUS_SIPRE_ERROR_INVALID_ELEMENT);
+ if(error_code != 0)
+ goto error;
+ const char *info_type = json_string_value(json_object_get(root, "type"));
+ const char *info_content = json_string_value(json_object_get(root, "content"));
+ json_t *info = json_object();
+ json_object_set_new(info, "type", json_string(info_type));
+ json_object_set_new(info, "content", json_string(info_content));
+ /* Send SIP INFO */
+ mqueue_push(mq, janus_sipre_mqueue_event_do_info,
+ janus_sipre_mqueue_payload_create(session, NULL, 0, info));
+ /* Notify the operation */
+ result = json_object();
+ json_object_set_new(result, "event", json_string("infosent"));
+ } else if(!strcasecmp(request_text, "message")) {
+ /* Send a SIP MESSAGE request: we'll only need the content */
+ if(!(session->status == janus_sipre_call_status_inviting || session->status == janus_sipre_call_status_incall)) {
+ JANUS_LOG(LOG_ERR, "Wrong state (not in a call? status=%s)\n", janus_sipre_call_status_string(session->status));
+ g_snprintf(error_cause, 512, "Wrong state (not in a call?)");
+ goto error;
+ }
+ if(session->callee == NULL) {
+ JANUS_LOG(LOG_ERR, "Wrong state (no callee?)\n");
+ error_code = JANUS_SIPRE_ERROR_WRONG_STATE;
+ g_snprintf(error_cause, 512, "Wrong state (no callee?)");
+ goto error;
+ }
+ JANUS_VALIDATE_JSON_OBJECT(root, sipmessage_parameters,
+ error_code, error_cause, TRUE,
+ JANUS_SIPRE_ERROR_MISSING_ELEMENT, JANUS_SIPRE_ERROR_INVALID_ELEMENT);
+ if(error_code != 0)
+ goto error;
+ const char *msg_content = json_string_value(json_object_get(root, "content"));
+ /* Send SIP MESSAGE */
+ mqueue_push(mq, janus_sipre_mqueue_event_do_message,
+ janus_sipre_mqueue_payload_create(session, NULL, 0, g_strdup(msg_content)));
+ /* Notify the operation */
+ result = json_object();
+ json_object_set_new(result, "event", json_string("messagesent"));
} else if(!strcasecmp(request_text, "dtmf_info")) {
/* Send DMTF tones using SIPre INFO
* (https://tools.ietf.org/html/draft-kaplan-dispatch-info-dtmf-package-00)
@@ -2436,9 +2507,12 @@ static void *janus_sipre_handler(void *data) {
}
char payload[64];
g_snprintf(payload, sizeof(payload), "Signal=%s\r\nDuration=%d", digit_text, duration_ms);
+ json_t *info = json_object();
+ json_object_set_new(info, "type", json_string("application/dtmf-relay"));
+ json_object_set_new(info, "content", json_string(payload));
/* Send "application/dtmf-relay" SIP INFO */
- mqueue_push(mq, janus_sipre_mqueue_event_do_sipinfo,
- janus_sipre_mqueue_payload_create(session, NULL, 0, g_strdup(payload)));
+ mqueue_push(mq, janus_sipre_mqueue_event_do_info,
+ janus_sipre_mqueue_payload_create(session, NULL, 0, info));
/* Notify the result */
result = json_object();
json_object_set_new(result, "event", json_string("dtmfsent"));
@@ -3536,6 +3610,52 @@ void janus_sipre_cb_established(const struct sip_msg *msg, void *arg) {
/* FIXME Anything to do here? */
}
+/* Called when an incoming SIP INFO arrives */
+void janus_sipre_cb_info(struct sip *sip, const struct sip_msg *msg, void *arg) {
+ janus_sipre_session *session = (janus_sipre_session *)arg;
+ if(session == NULL) {
+ JANUS_LOG(LOG_WARN, "[SIPre-??] janus_sipre_cb_info\n");
+ return;
+ }
+ JANUS_LOG(LOG_HUGE, "[SIPre-%s] janus_sipre_cb_info\n", session->account.username);
+ char *from = NULL;
+ re_sdprintf(&from, "%H", uri_encode, &msg->from.uri);
+ JANUS_LOG(LOG_HUGE, "[SIPre-%s] -- Sender: %s\n", session->account.username, from);
+ char dname[256];
+ dname[0] = '\0';
+ if(msg->from.dname.l > 0) {
+ g_snprintf(dname, sizeof(dname), "%.*s", (int)msg->from.dname.l, msg->from.dname.p);
+ JANUS_LOG(LOG_HUGE, "[SIPre-%s] -- Display: %s\n", session->account.username, dname);
+ }
+ char type[200];
+ type[0] = '\0';
+ if(msg->ctyp.type.l > 0) {
+ g_snprintf(type, sizeof(type), "%.*s", (int)msg->ctyp.type.l, msg->ctyp.type.p);
+ JANUS_LOG(LOG_HUGE, "[SIPre-%s] -- Type: %s\n", session->account.username, type);
+ }
+ const char *payload = (const char *)mbuf_buf(msg->mb);
+ char content[1024];
+ g_snprintf(content, sizeof(content), "%.*s", (int)mbuf_get_left(msg->mb), payload);
+ JANUS_LOG(LOG_HUGE, "[SIPre-%s] -- Content: %s\n", session->account.username, content);
+ /* Notify the application */
+ json_t *info = json_object();
+ json_object_set_new(info, "sip", json_string("event"));
+ json_t *result = json_object();
+ json_object_set_new(result, "event", json_string("info"));
+ json_object_set_new(result, "sender", json_string(from));
+ if(strlen(dname)) {
+ json_object_set_new(result, "displayname", json_string(dname));
+ }
+ json_object_set_new(result, "type", json_string(type));
+ json_object_set_new(result, "content", json_string(content));
+ json_object_set_new(info, "result", result);
+ int ret = gateway->push_event(session->handle, &janus_sipre_plugin, session->transaction, info, NULL);
+ JANUS_LOG(LOG_VERB, " >> Pushing event to peer: %d (%s)\n", ret, janus_get_api_error(ret));
+ json_decref(info);
+ /* Send a 200 back */
+ mqueue_push(mq, janus_sipre_mqueue_event_do_rcode, janus_sipre_mqueue_payload_create(session, msg, 200, session));
+}
+
/* Called when the session fails to connect or is terminated by the peer */
void janus_sipre_cb_closed(int err, const struct sip_msg *msg, void *arg) {
janus_sipre_session *session = (janus_sipre_session *)arg;
@@ -3845,7 +3965,7 @@ void janus_sipre_mqueue_handler(int id, void *data, void *arg) {
"application/sdp", NULL,
janus_sipre_cb_auth, session, FALSE,
janus_sipre_cb_offer, janus_sipre_cb_answer,
- janus_sipre_cb_established, NULL, NULL,
+ janus_sipre_cb_established, janus_sipre_cb_info, NULL,
janus_sipre_cb_closed, session, NULL);
} else {
/* Connection already accepted */
@@ -3912,29 +4032,53 @@ void janus_sipre_mqueue_handler(int id, void *data, void *arg) {
g_free(payload);
break;
}
- case janus_sipre_mqueue_event_do_sipinfo: {
+ case janus_sipre_mqueue_event_do_info: {
janus_sipre_mqueue_payload *payload = (janus_sipre_mqueue_payload *)data;
janus_sipre_session *session = (janus_sipre_session *)payload->session;
- JANUS_LOG(LOG_VERB, "[SIPre-%s] Sending SIP INFO (DTMF): %s\n", session->account.username, (char *)payload->data);
+ json_t *info = (json_t *)payload->data;
+ const char *type = json_string_value(json_object_get(info, "type"));
+ const char *content = json_string_value(json_object_get(info, "content"));
+ JANUS_LOG(LOG_VERB, "[SIPre-%s] Sending SIP INFO (%s, %s)\n", session->account.username, type, content);
/* Convert the SDP into a struct mbuf */
- struct mbuf *mb = mbuf_alloc(strlen((char *)payload->data)+1);
- mbuf_printf(mb, "%s", (char *)payload->data);
+ struct mbuf *mb = mbuf_alloc(strlen(content)+1);
+ mbuf_printf(mb, "%s", content);
mbuf_set_pos(mb, 0);
- g_free(payload->data);
- /* Send the 200 OK */
- int err = sipsess_info(session->stack.sess, "application/dtmf-relay", mb, NULL, NULL);
+ /* Send the SIP INFO */
+ int err = sipsess_info(session->stack.sess, type, mb, NULL, NULL);
if(err != 0) {
JANUS_LOG(LOG_ERR, "Error attempting to send the SIP INFO: %d (%s)\n", err, strerror(err));
/* Tell the browser... */
json_t *event = json_object();
json_object_set_new(event, "sip", json_string("event"));
json_t *result = json_object();
- json_object_set_new(result, "event", json_string("dtmferror"));
+ json_object_set_new(result, "event", json_string("infoerror"));
json_object_set_new(result, "code", json_integer(err));
json_object_set_new(result, "reason", json_string(strerror(err)));
json_object_set_new(event, "result", result);
}
mem_deref(mb);
+ json_decref(info);
+ g_free(payload);
+ break;
+ }
+ case janus_sipre_mqueue_event_do_message: {
+ janus_sipre_mqueue_payload *payload = (janus_sipre_mqueue_payload *)data;
+ janus_sipre_session *session = (janus_sipre_session *)payload->session;
+ JANUS_LOG(LOG_VERB, "[SIPre-%s] Sending SIP MESSAGE: %s\n", session->account.username, (char *)payload->data);
+ /* Convert the SDP into a struct mbuf */
+ struct mbuf *mb = mbuf_alloc(strlen((char *)payload->data)+1);
+ mbuf_printf(mb, "%s", (char *)payload->data);
+ mbuf_set_pos(mb, 0);
+ g_free(payload->data);
+ /* FIXME This is only a placeholder... there's no way to send SIP MESSAGE apparently? */
+ json_t *event = json_object();
+ json_object_set_new(event, "sip", json_string("event"));
+ json_t *result = json_object();
+ json_object_set_new(result, "event", json_string("messageerror"));
+ json_object_set_new(result, "code", json_integer(-1));
+ json_object_set_new(result, "reason", json_string("SIP MESSAGE currently unsupported"));
+ json_object_set_new(event, "result", result);
+ mem_deref(mb);
g_free(payload);
break;
}
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-voip/janus.git
More information about the Pkg-voip-commits
mailing list