diff options
author | mogorman <mogorman@f38db490-d61c-443f-a65b-d21fe96a405b> | 2006-08-02 01:00:24 +0000 |
---|---|---|
committer | mogorman <mogorman@f38db490-d61c-443f-a65b-d21fe96a405b> | 2006-08-02 01:00:24 +0000 |
commit | 3e0e07cad2b4f2ba50c0c9cce1bf733e6aaac8b7 (patch) | |
tree | b0019a1d2b575a4173be8941f20f6d03e329acbf /channels/chan_jingle.c | |
parent | 1a10d2d3b4f24514fdcc6e75c6ac744dcac51fa7 (diff) |
dtmf support. not everything else, trying to clear out those other bugs
but more to come i guess.
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@38714 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'channels/chan_jingle.c')
-rw-r--r-- | channels/chan_jingle.c | 111 |
1 files changed, 102 insertions, 9 deletions
diff --git a/channels/chan_jingle.c b/channels/chan_jingle.c index 7ba3bc539..bf55b93b0 100644 --- a/channels/chan_jingle.c +++ b/channels/chan_jingle.c @@ -442,7 +442,7 @@ static int jingle_set_rtp_peer(struct ast_channel *chan, struct ast_rtp *rtp, st return 0; } -static int jingle_response(struct jingle *client, ikspak *pak, const char *reasonstr) +static int jingle_response(struct jingle *client, ikspak *pak, const char *reasonstr, const char *reasonstr2) { iks *response, *error = NULL, *reason = NULL; int res = -1; @@ -490,10 +490,58 @@ static int jingle_is_answered(struct jingle *client, ikspak *pak) ast_queue_control(tmp->owner, AST_CONTROL_ANSWER); } else ast_log(LOG_NOTICE, "Whoa, didn't find call!\n"); - jingle_response(client, pak, NULL); + jingle_response(client, pak, NULL, NULL); return 1; } +static int jingle_handle_dtmf(struct jingle *client, ikspak *pak) +{ + struct jingle_pvt *tmp; + iks *dtmfnode = NULL; + char *dtmf; + /* Make sure our new call doesn't exist yet */ + for (tmp = client->p; tmp; tmp = tmp->next) { + if (iks_find_with_attrib(pak->x, GOOGLE_NODE, GOOGLE_SID, tmp->sid)) + break; + } + + if (tmp) { + if(iks_find_with_attrib(pak->x, "dtmf-method", "method", "rtp")) { + jingle_response(client,pak, + "feature-not-implemented xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'", + "unsupported-dtmf-method xmlns='http://jabber.org/protocol/jingle/info/dtmf#errors'"); + return -1; + } + if ((dtmfnode = iks_find(pak->x, "dtmf"))) { + if((dtmf = iks_find_attrib(dtmfnode, "code"))) { + if(iks_find_with_attrib(pak->x, "dtmf", "action", "button-up")) { + struct ast_frame f = {AST_FRAME_DTMF_BEGIN, }; + f.subclass = dtmf[0]; + ast_queue_frame(tmp->owner, &f); + ast_verbose("JINGLE! DTMF-relay event received: %c\n", f.subclass); + } else if(iks_find_with_attrib(pak->x, "dtmf", "action", "button-down")) { + struct ast_frame f = {AST_FRAME_DTMF_END, }; + f.subclass = dtmf[0]; + ast_queue_frame(tmp->owner, &f); + ast_verbose("JINGLE! DTMF-relay event received: %c\n", f.subclass); + } else if(iks_find_attrib(pak->x, "dtmf")) { /* 250 millasecond default */ + struct ast_frame f = {AST_FRAME_DTMF, }; + f.subclass = dtmf[0]; + ast_queue_frame(tmp->owner, &f); + ast_verbose("JINGLE! DTMF-relay event received: %c\n", f.subclass); + } + } + } + jingle_response(client, pak, NULL, NULL); + return 1; + } else + ast_log(LOG_NOTICE, "Whoa, didn't find call!\n"); + + jingle_response(client, pak, NULL, NULL); + return 1; +} + + static int jingle_hangup_farend(struct jingle *client, ikspak *pak) { struct jingle_pvt *tmp; @@ -510,7 +558,7 @@ static int jingle_hangup_farend(struct jingle *client, ikspak *pak) ast_queue_hangup(tmp->owner); } else ast_log(LOG_NOTICE, "Whoa, didn't find call!\n"); - jingle_response(client, pak, NULL); + jingle_response(client, pak, NULL, NULL); return 1; } @@ -858,7 +906,7 @@ static int jingle_newcall(struct jingle *client, ikspak *pak) while (tmp) { if (iks_find_with_attrib(pak->x, GOOGLE_NODE, GOOGLE_SID, tmp->sid)) { ast_log(LOG_NOTICE, "Ignoring duplicate call setup on SID %s\n", tmp->sid); - jingle_response(client, pak, "out-of-order"); + jingle_response(client, pak, "out-of-order", NULL); return -1; } tmp = tmp->next; @@ -893,14 +941,14 @@ static int jingle_newcall(struct jingle *client, ikspak *pak) switch (res) { case AST_PBX_FAILED: ast_log(LOG_WARNING, "Failed to start PBX :(\n"); - jingle_response(client, pak, "service-unavailable"); + jingle_response(client, pak, "service-unavailable", NULL); break; case AST_PBX_CALL_LIMIT: ast_log(LOG_WARNING, "Failed to start PBX (call limit reached) \n"); - jingle_response(client, pak, "service-unavailable"); + jingle_response(client, pak, "service-unavailable", NULL); break; case AST_PBX_SUCCESS: - jingle_response(client, pak, NULL); + jingle_response(client, pak, NULL, NULL); jingle_create_candidates(client, p, iks_find_attrib(pak->query, GOOGLE_SID), iks_find_attrib(pak->x, "from")); @@ -1135,9 +1183,52 @@ static int jingle_indicate(struct ast_channel *ast, int condition, const void *d static int jingle_digit(struct ast_channel *ast, char digit) { - ast_log(LOG_NOTICE, "XXX Implement jingle digit XXX\n"); + struct jingle_pvt *p = ast->tech_pvt; + struct jingle *client = p->parent; + iks *iq, *jingle, *dtmf; + char buffer[2] = {digit, '\0'}; + iq = iks_new("iq"); + jingle = iks_new("jingle"); + dtmf = iks_new("dtmf"); + if(!iq || !jingle || !dtmf) { + if(iq) + iks_delete(iq); + if(jingle) + iks_delete(jingle); + if(dtmf) + iks_delete(dtmf); + ast_log(LOG_ERROR, "Did not send dtmf do to memory issue\n"); + return -1; + } - return -1; + iks_insert_attrib(iq, "type", "set"); + iks_insert_attrib(iq, "to", p->from); + iks_insert_attrib(iq, "from", client->connection->jid->full); + iks_insert_attrib(iq, "id", client->connection->mid); + ast_aji_increment_mid(client->connection->mid); + iks_insert_attrib(jingle, "xmlns", "http://jabber.org/protocol/jingle"); + iks_insert_attrib(jingle, "action", "content-info"); + iks_insert_attrib(jingle, "initiator", p->initiator ? client->connection->jid->full : p->from); + iks_insert_attrib(jingle, "sid", p->sid); + iks_insert_attrib(dtmf, "xmlns", "http://jabber.org/protocol/jingle/info/dtmf"); + iks_insert_attrib(dtmf, "code", buffer); + iks_insert_node(iq, jingle); + iks_insert_node(jingle, dtmf); + + ast_mutex_lock(&p->lock); + if(ast->dtmff.frametype == AST_FRAME_DTMF) { + ast_verbose("Sending 250ms dtmf!\n"); + } else if (ast->dtmff.frametype == AST_FRAME_DTMF_BEGIN) { + iks_insert_attrib(dtmf, "action", "button-down"); + } else if (ast->dtmff.frametype == AST_FRAME_DTMF_END) { + iks_insert_attrib(dtmf, "action", "button-up"); + } + iks_send(client->connection->p, iq); + iks_delete(iq); + iks_delete(jingle); + iks_delete(dtmf); + ast_mutex_unlock(&p->lock); + return 0; } static int jingle_sendhtml(struct ast_channel *ast, int subclass, const char *data, int datalen) @@ -1333,6 +1424,8 @@ static int jingle_parser(void *data, ikspak *pak) ast_log(LOG_DEBUG, "Candidate Added!\n"); } else if (iks_find_with_attrib(pak->x, GOOGLE_NODE, "type", GOOGLE_ACCEPT)) { jingle_is_answered(client, pak); + } else if (iks_find_with_attrib(pak->x, GOOGLE_NODE, "type", "content-info")) { + jingle_handle_dtmf(client, pak); } else if (iks_find_with_attrib(pak->x, GOOGLE_NODE, "type", "terminate")) { jingle_hangup_farend(client, pak); } else if (iks_find_with_attrib(pak->x, GOOGLE_NODE, "type", "reject")) { |