]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
Fix an issue that caused one-way audio on some newer devices (specifically the 7921),
authorJason Parker <jparker@digium.com>
Wed, 1 Aug 2007 21:08:42 +0000 (21:08 +0000)
committerJason Parker <jparker@digium.com>
Wed, 1 Aug 2007 21:08:42 +0000 (21:08 +0000)
 due to sending packets in the wrong order during hangup.

Also make sure we clear tones/messages on the correct line/instance.

Issue 10291, patch by DEA, tested by sbisker and myself.

git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.4@77883 65c4cc65-6c06-0410-ace0-fbb531ad65f3

channels/chan_skinny.c

index 3c1530c64c07091433a7aa1312e94709588c8433..d9daf6514ebea1a63af7566a21463014550b4ee1 100644 (file)
@@ -264,12 +264,15 @@ struct register_ack_message {
 #define START_TONE_MESSAGE 0x0082
 struct start_tone_message {
        uint32_t tone;
-       uint32_t space[3];
+       uint32_t space;
+       uint32_t instance;
+       uint32_t reference;
 };
 
 #define STOP_TONE_MESSAGE 0x0083
 struct stop_tone_message {
-       uint32_t space[2];
+       uint32_t instance;
+       uint32_t reference;
 };
 
 #define SET_RINGER_MESSAGE 0x0085
@@ -723,6 +726,7 @@ union skinny_data {
        struct clear_prompt_message clearpromptstatus;
        struct definetimedate_message definetimedate;
        struct start_tone_message starttone;
+       struct stop_tone_message stoptone;
        struct speed_dial_stat_res_message speeddial;
        struct line_state_req_message line;
        struct line_stat_res_message linestat;
@@ -1489,16 +1493,6 @@ static void transmit_callstate(struct skinnysession *s, int instance, int state,
 {
        struct skinny_req *req;
 
-       if (!(req = req_alloc(sizeof(struct call_state_message), CALL_STATE_MESSAGE)))
-               return;
-
-       if (state == SKINNY_ONHOOK) {
-               transmit_speaker_mode(s, SKINNY_SPEAKEROFF);
-       }
-       req->data.callstate.callState = htolel(state);
-       req->data.callstate.lineInstance = htolel(instance);
-       req->data.callstate.callReference = htolel(callid);
-       transmit_response(s, req);
        if (state == SKINNY_OFFHOOK) {
                if (!(req = req_alloc(sizeof(struct activate_call_plane_message), ACTIVATE_CALL_PLANE_MESSAGE)))
                        return;
@@ -1506,6 +1500,8 @@ static void transmit_callstate(struct skinnysession *s, int instance, int state,
                req->data.activatecallplane.lineInstance = htolel(instance);
                transmit_response(s, req);
        } else if (state == SKINNY_ONHOOK) {
+               transmit_speaker_mode(s, SKINNY_SPEAKEROFF);
+
                if (!(req = req_alloc(sizeof(struct activate_call_plane_message), ACTIVATE_CALL_PLANE_MESSAGE)))
                        return;
 
@@ -1515,17 +1511,25 @@ static void transmit_callstate(struct skinnysession *s, int instance, int state,
                if (!(req = req_alloc(sizeof(struct close_receive_channel_message), CLOSE_RECEIVE_CHANNEL_MESSAGE)))
                        return;
 
-               req->data.closereceivechannel.conferenceId = 0;
+               req->data.closereceivechannel.conferenceId = htolel(callid);
                req->data.closereceivechannel.partyId = htolel(callid);
                transmit_response(s, req);
 
                if (!(req = req_alloc(sizeof(struct stop_media_transmission_message), STOP_MEDIA_TRANSMISSION_MESSAGE)))
                        return;
 
-               req->data.stopmedia.conferenceId = 0;
+               req->data.stopmedia.conferenceId = htolel(callid);
                req->data.stopmedia.passThruPartyId = htolel(callid);
                transmit_response(s, req);
        }
+
+       if (!(req = req_alloc(sizeof(struct call_state_message), CALL_STATE_MESSAGE)))
+               return;
+
+       req->data.callstate.callState = htolel(state);
+       req->data.callstate.lineInstance = htolel(instance);
+       req->data.callstate.callReference = htolel(callid);
+       transmit_response(s, req);
 }
 
 static void transmit_callinfo(struct skinnysession *s, const char *fromname, const char *fromnum, const char *toname, const char *tonum, int instance, int callid, int calltype)
@@ -1567,7 +1571,7 @@ static void transmit_connect(struct skinnysession *s, struct skinny_subchannel *
 
        fmt = ast_codec_pref_getsize(&l->prefs, ast_best_codec(l->capability));
 
-       req->data.openreceivechannel.conferenceId = htolel(0);
+       req->data.openreceivechannel.conferenceId = htolel(sub->callid);
        req->data.openreceivechannel.partyId = htolel(sub->callid);
        req->data.openreceivechannel.packets = htolel(fmt.cur_ms);
        req->data.openreceivechannel.capability = htolel(codec_ast2skinny(fmt.bits));
@@ -1576,7 +1580,7 @@ static void transmit_connect(struct skinnysession *s, struct skinny_subchannel *
        transmit_response(s, req);
 }
 
-static void transmit_tone(struct skinnysession *s, int tone)
+static void transmit_tone(struct skinnysession *s, int tone, int instance, int reference)
 {
        struct skinny_req *req;
 
@@ -1588,9 +1592,14 @@ static void transmit_tone(struct skinnysession *s, int tone)
        if (tone > 0) {
                if (!(req = req_alloc(sizeof(struct start_tone_message), START_TONE_MESSAGE)))
                        return;
+               req->data.starttone.tone = htolel(tone);
+               req->data.starttone.instance = htolel(instance);
+               req->data.starttone.reference = htolel(reference);
        } else {
                if (!(req = req_alloc(sizeof(struct stop_tone_message), STOP_TONE_MESSAGE)))
                        return;
+               req->data.stoptone.instance = htolel(instance);
+               req->data.stoptone.reference = htolel(reference);
        }
 
        if (tone > 0) {
@@ -1651,7 +1660,7 @@ static void transmit_ringer_mode(struct skinnysession *s, int mode)
        transmit_response(s, req);
 }
 
-static void transmit_displaymessage(struct skinnysession *s, const char *text)
+static void transmit_displaymessage(struct skinnysession *s, const char *text, int instance, int reference)
 {
        struct skinny_req *req;
 
@@ -1659,6 +1668,9 @@ static void transmit_displaymessage(struct skinnysession *s, const char *text)
                if (!(req = req_alloc(0, CLEAR_DISPLAY_MESSAGE)))
                        return;
 
+               req->data.clearpromptstatus.lineInstance = instance;
+               req->data.clearpromptstatus.callReference = reference;
+
                if (skinnydebug)
                        ast_verbose("Clearing Display\n");
        } else {
@@ -2305,7 +2317,7 @@ static void *skinny_newcall(void *data)
        res = ast_pbx_run(c);
        if (res) {
                ast_log(LOG_WARNING, "PBX exited non-zero\n");
-               transmit_tone(s, SKINNY_REORDER);
+               transmit_tone(s, SKINNY_REORDER, l->instance, sub->callid);
        }
        return NULL;
 }
@@ -2341,8 +2353,8 @@ static void *skinny_ss(void *data)
 
                len = strlen(d->exten);
 
-               if (len && !ast_ignore_pattern(c->context, d->exten)) {
-                       transmit_tone(s, SKINNY_SILENCE);
+               if (!ast_ignore_pattern(c->context, d->exten)) {
+                       transmit_tone(s, SKINNY_SILENCE, l->instance, sub->callid);
                }
 
                if (ast_exists_extension(c, c->context, d->exten, 1, l->cid_num)) {
@@ -2353,7 +2365,7 @@ static void *skinny_ss(void *data)
                                        if (option_verbose > 2)
                                                ast_verbose(VERBOSE_PREFIX_3 "Setting call forward to '%s' on channel %s\n",
                                                        l->call_forward, c->name);
-                                       transmit_tone(s, SKINNY_DIALTONE);
+                                       transmit_tone(s, SKINNY_DIALTONE, l->instance, sub->callid);
                                        if (res) {
                                                break;
                                        }
@@ -2361,7 +2373,7 @@ static void *skinny_ss(void *data)
                                        ast_indicate(c, -1);
                                        ast_safe_sleep(c, 1000);
                                        memset(d->exten, 0, sizeof(d->exten));
-                                       transmit_tone(s, SKINNY_DIALTONE);
+                                       transmit_tone(s, SKINNY_DIALTONE, l->instance, sub->callid);
                                        len = 0;
                                        getforward = 0;
                                } else {
@@ -2379,7 +2391,7 @@ static void *skinny_ss(void *data)
                } else if (res == 0) {
                        ast_log(LOG_DEBUG, "Not enough digits (and no ambiguous match)...\n");
                        memset(d->exten, 0, sizeof(d->exten));
-                       transmit_tone(s, SKINNY_REORDER);
+                       transmit_tone(s, SKINNY_REORDER, l->instance, sub->callid);
                        if (sub->owner && sub->owner->_state != AST_STATE_UP) {
                                ast_indicate(c, -1);
                                ast_hangup(c);
@@ -2389,7 +2401,7 @@ static void *skinny_ss(void *data)
                           ((d->exten[0] != '*') || (!ast_strlen_zero(d->exten) > 2))) {
                        ast_log(LOG_WARNING, "Can't match [%s] from '%s' in context %s\n", d->exten, c->cid.cid_num ? c->cid.cid_num : "<Unknown Caller>", c->context);
                        memset(d->exten, 0, sizeof(d->exten));
-                       transmit_tone(s, SKINNY_REORDER);
+                       transmit_tone(s, SKINNY_REORDER, l->instance, sub->callid);
                        /* hang out for 3 seconds to let congestion play */
                        ast_safe_sleep(c, 3000);
                        break;
@@ -2486,10 +2498,9 @@ static int skinny_hangup(struct ast_channel *ast)
                        transmit_lamp_indication(s, STIMULUS_LINE, l->instance, SKINNY_LAMP_OFF);
                        transmit_speaker_mode(s, SKINNY_SPEAKEROFF);
                } else if ((l->type = TYPE_LINE) && (l->hookstate == SKINNY_ONHOOK)) {
+                       transmit_tone(s, SKINNY_SILENCE, l->instance, sub->callid);
                        transmit_callstate(s, l->instance, SKINNY_ONHOOK, sub->callid);
-                       transmit_speaker_mode(s, SKINNY_SPEAKEROFF);
                        transmit_ringer_mode(s, SKINNY_RING_OFF);
-                       transmit_tone(s, SKINNY_SILENCE);
                        transmit_lamp_indication(s, STIMULUS_LINE, l->instance, SKINNY_LAMP_OFF);
                        do_housekeeping(s);
                }
@@ -2525,7 +2536,7 @@ static int skinny_answer(struct ast_channel *ast)
                ast_setstate(ast, AST_STATE_UP);
        }
 
-       transmit_tone(s, SKINNY_SILENCE);
+       transmit_tone(s, SKINNY_SILENCE, l->instance, sub->callid);
        /* order matters here...
           for some reason, transmit_callinfo must be before transmit_callstate,
           or you won't get keypad messages in some situations. */
@@ -2648,7 +2659,7 @@ static int skinny_senddigit_end(struct ast_channel *ast, char digit, unsigned in
        int tmp;
        /* not right */
        sprintf(tmp, "%d", digit);
-       transmit_tone(d->session, digit);
+       transmit_tone(d->session, digit, l->instance, sub->callid);
 #endif
        return -1; /* Stop inband indications */
 }
@@ -2715,7 +2726,7 @@ static int skinny_indicate(struct ast_channel *ast, int ind, const void *data, s
        case AST_CONTROL_RINGING:
                if (ast->_state != AST_STATE_UP) {
                        if (!sub->progress) {
-                               transmit_tone(s, SKINNY_ALERT);
+                               transmit_tone(s, SKINNY_ALERT, l->instance, sub->callid);
                                transmit_callstate(s, l->instance, SKINNY_RINGOUT, sub->callid);
                                transmit_dialednumber(s, ast->exten, l->instance, sub->callid);
                                transmit_displaypromptstatus(s, "Ring Out", 0, l->instance, sub->callid);
@@ -2727,7 +2738,7 @@ static int skinny_indicate(struct ast_channel *ast, int ind, const void *data, s
                return -1;
        case AST_CONTROL_BUSY:
                if (ast->_state != AST_STATE_UP) {
-                       transmit_tone(s, SKINNY_BUSYTONE);
+                       transmit_tone(s, SKINNY_BUSYTONE, l->instance, sub->callid);
                        transmit_callstate(s, l->instance, SKINNY_BUSY, sub->callid);
                        sub->alreadygone = 1;
                        ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV);
@@ -2736,7 +2747,7 @@ static int skinny_indicate(struct ast_channel *ast, int ind, const void *data, s
                return -1;
        case AST_CONTROL_CONGESTION:
                if (ast->_state != AST_STATE_UP) {
-                       transmit_tone(s, SKINNY_REORDER);
+                       transmit_tone(s, SKINNY_REORDER, l->instance, sub->callid);
                        transmit_callstate(s, l->instance, SKINNY_CONGESTION, sub->callid);
                        sub->alreadygone = 1;
                        ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV);
@@ -2745,7 +2756,7 @@ static int skinny_indicate(struct ast_channel *ast, int ind, const void *data, s
                return -1;
        case AST_CONTROL_PROGRESS:
                if ((ast->_state != AST_STATE_UP) && !sub->progress && !sub->outgoing) {
-                       transmit_tone(s, SKINNY_ALERT);
+                       transmit_tone(s, SKINNY_ALERT, l->instance, sub->callid);
                        transmit_callstate(s, l->instance, SKINNY_PROGRESS, sub->callid);
                        transmit_displaypromptstatus(s, "Call Progress", 0, l->instance, sub->callid);
                        transmit_callinfo(s, ast->cid.cid_name, ast->cid.cid_num, ast->exten, ast->exten, l->instance, sub->callid, 2); /* 2 = outgoing from phone */
@@ -2754,7 +2765,7 @@ static int skinny_indicate(struct ast_channel *ast, int ind, const void *data, s
                }
                return -1;
        case -1:
-               transmit_tone(s, SKINNY_SILENCE);
+               transmit_tone(s, SKINNY_SILENCE, l->instance, sub->callid);
                break;
        case AST_CONTROL_HOLD:
                ast_moh_start(ast, data, l->mohinterpret);
@@ -2885,14 +2896,14 @@ static int skinny_hold(struct skinny_subchannel *sub)
        if (!(req = req_alloc(sizeof(struct close_receive_channel_message), CLOSE_RECEIVE_CHANNEL_MESSAGE)))
                return 0;
 
-       req->data.closereceivechannel.conferenceId = htolel(0);
+       req->data.closereceivechannel.conferenceId = htolel(sub->callid);
        req->data.closereceivechannel.partyId = htolel(sub->callid);
        transmit_response(s, req);
 
        if (!(req = req_alloc(sizeof(struct stop_media_transmission_message), STOP_MEDIA_TRANSMISSION_MESSAGE)))
                return 0;
 
-       req->data.stopmedia.conferenceId = htolel(0);
+       req->data.stopmedia.conferenceId = htolel(sub->callid);
        req->data.stopmedia.passThruPartyId = htolel(sub->callid);
        transmit_response(s, req);
 
@@ -3110,12 +3121,12 @@ static int handle_stimulus_message(struct skinny_req *req, struct skinnysession
                        transmit_callstate(s, l->instance, SKINNY_OFFHOOK, sub->callid);
                        if (skinnydebug)
                                ast_verbose("Attempting to Clear display on Skinny %s@%s\n", l->name, d->name);
-                       transmit_displaymessage(s, NULL); /* clear display */
-                       transmit_tone(s, SKINNY_DIALTONE);
+                       transmit_displaymessage(s, NULL, l->instance, sub->callid); /* clear display */
+                       transmit_tone(s, SKINNY_DIALTONE, l->instance, sub->callid);
                        transmit_selectsoftkeys(s, l->instance, sub->callid, KEYDEF_RINGOUT);
 
                        if (!ast_ignore_pattern(c->context, l->lastnumberdialed)) {
-                               transmit_tone(s, SKINNY_SILENCE);
+                               transmit_tone(s, SKINNY_SILENCE, l->instance, sub->callid);
                        }
                        ast_copy_string(c->exten, l->lastnumberdialed, sizeof(c->exten));
                        if (ast_pthread_create(&t, NULL, skinny_newcall, c)) {
@@ -3149,12 +3160,12 @@ static int handle_stimulus_message(struct skinny_req *req, struct skinnysession
                        transmit_callstate(s, l->instance, SKINNY_OFFHOOK, sub->callid);
                        if (skinnydebug)
                                ast_verbose("Attempting to Clear display on Skinny %s@%s\n", l->name, d->name);
-                       transmit_displaymessage(s, NULL); /* clear display */
-                       transmit_tone(s, SKINNY_DIALTONE);
+                       transmit_displaymessage(s, NULL, l->instance, sub->callid); /* clear display */
+                       transmit_tone(s, SKINNY_DIALTONE, l->instance, sub->callid);
                        transmit_selectsoftkeys(s, l->instance, sub->callid, KEYDEF_RINGOUT);
 
                        if (!ast_ignore_pattern(c->context, sd->exten)) {
-                               transmit_tone(s, SKINNY_SILENCE);
+                               transmit_tone(s, SKINNY_SILENCE, l->instance, sub->callid);
                        }
                        if (ast_exists_extension(c, c->context, sd->exten, 1, l->cid_num)) {
                                if (!ast_matchmore_extension(c, c->context, sd->exten, 1, l->cid_num)) {
@@ -3257,7 +3268,7 @@ static int handle_stimulus_message(struct skinny_req *req, struct skinnysession
                        /* We're answering a ringing call */
                        ast_queue_control(sub->owner, AST_CONTROL_ANSWER);
                        transmit_callstate(s, l->instance, SKINNY_OFFHOOK, sub->callid);
-                       transmit_tone(s, SKINNY_SILENCE);
+                       transmit_tone(s, SKINNY_SILENCE, l->instance, sub->callid);
                        transmit_callstate(s, l->instance, SKINNY_CONNECTED, sub->callid);
                        transmit_displaypromptstatus(s, "Connected", 0, l->instance, sub->callid);
                        transmit_selectsoftkeys(s, l->instance, sub->callid, KEYDEF_CONNECTED);
@@ -3273,8 +3284,8 @@ static int handle_stimulus_message(struct skinny_req *req, struct skinnysession
                                        transmit_callstate(s, l->instance, SKINNY_OFFHOOK, sub->callid);
                                        if (skinnydebug)
                                                ast_verbose("Attempting to Clear display on Skinny %s@%s\n", l->name, d->name);
-                                       transmit_displaymessage(s, NULL); /* clear display */
-                                       transmit_tone(s, SKINNY_DIALTONE);
+                                       transmit_displaymessage(s, NULL, l->instance, sub->callid); /* clear display */
+                                       transmit_tone(s, SKINNY_DIALTONE, l->instance, sub->callid);
                                        transmit_selectsoftkeys(s, l->instance, sub->callid, KEYDEF_OFFHOOK);
 
                                        /* start the switch thread */
@@ -3333,7 +3344,7 @@ static int handle_offhook_message(struct skinny_req *req, struct skinnysession *
                /* We're answering a ringing call */
                ast_queue_control(sub->owner, AST_CONTROL_ANSWER);
                transmit_callstate(s, l->instance, SKINNY_OFFHOOK, sub->callid);
-               transmit_tone(s, SKINNY_SILENCE);
+               transmit_tone(s, SKINNY_SILENCE, l->instance, sub->callid);
                transmit_callstate(s, l->instance, SKINNY_CONNECTED, sub->callid);
                transmit_selectsoftkeys(s, l->instance, sub->callid, KEYDEF_CONNECTED);
                start_rtp(sub);
@@ -3348,8 +3359,8 @@ static int handle_offhook_message(struct skinny_req *req, struct skinnysession *
                                transmit_callstate(s, l->instance, SKINNY_OFFHOOK, sub->callid);
                                if (skinnydebug)
                                        ast_verbose("Attempting to Clear display on Skinny %s@%s\n", l->name, d->name);
-                               transmit_displaymessage(s, NULL); /* clear display */
-                               transmit_tone(s, SKINNY_DIALTONE);
+                               transmit_displaymessage(s, NULL, l->instance, sub->callid); /* clear display */
+                               transmit_tone(s, SKINNY_DIALTONE, l->instance, sub->callid);
                                transmit_selectsoftkeys(s, l->instance, sub->callid, KEYDEF_OFFHOOK);
 
                                /* start the switch thread */
@@ -3737,7 +3748,7 @@ static int handle_open_receive_channel_ack_message(struct skinny_req *req, struc
        if (skinnydebug)
                ast_verbose("Setting payloadType to '%d' (%d ms)\n", fmt.bits, fmt.cur_ms);
 
-       req->data.startmedia.conferenceId = htolel(0);
+       req->data.startmedia.conferenceId = htolel(sub->callid);
        req->data.startmedia.passThruPartyId = htolel(sub->callid);
        req->data.startmedia.remoteIp = htolel(d->ourip.s_addr);
        req->data.startmedia.remotePort = htolel(ntohs(us.sin_port));
@@ -3785,11 +3796,11 @@ static int handle_enbloc_call_message(struct skinny_req *req, struct skinnysessi
                transmit_callstate(s, l->instance, SKINNY_OFFHOOK, sub->callid);
                if (skinnydebug)
                        ast_verbose("Attempting to Clear display on Skinny %s@%s\n", l->name, d->name);
-               transmit_displaymessage(s, NULL); /* clear display */
-               transmit_tone(s, SKINNY_DIALTONE);
+               transmit_displaymessage(s, NULL, l->instance, sub->callid); /* clear display */
+               transmit_tone(s, SKINNY_DIALTONE, l->instance, sub->callid);
 
                if (!ast_ignore_pattern(c->context, req->data.enbloccallmessage.calledParty)) {
-                       transmit_tone(s, SKINNY_SILENCE);
+                       transmit_tone(s, SKINNY_SILENCE, l->instance, sub->callid);
                }
                ast_copy_string(c->exten, req->data.enbloccallmessage.calledParty, sizeof(c->exten));
                if (ast_pthread_create(&t, NULL, skinny_newcall, c)) {
@@ -3889,12 +3900,12 @@ static int handle_soft_key_event_message(struct skinny_req *req, struct skinnyse
                        transmit_callstate(s, l->instance, SKINNY_OFFHOOK, sub->callid);
                        if (skinnydebug)
                                ast_verbose("Attempting to Clear display on Skinny %s@%s\n", l->name, d->name);
-                       transmit_displaymessage(s, NULL); /* clear display */
-                       transmit_tone(s, SKINNY_DIALTONE);
+                       transmit_displaymessage(s, NULL, l->instance, sub->callid); /* clear display */
+                       transmit_tone(s, SKINNY_DIALTONE, l->instance, sub->callid);
                        transmit_selectsoftkeys(s, l->instance, sub->callid, KEYDEF_RINGOUT);
 
                        if (!ast_ignore_pattern(c->context, l->lastnumberdialed)) {
-                               transmit_tone(s, SKINNY_SILENCE);
+                               transmit_tone(s, SKINNY_SILENCE, l->instance, sub->callid);
                        }
                        ast_copy_string(c->exten, l->lastnumberdialed, sizeof(c->exten));
                        if (ast_pthread_create(&t, NULL, skinny_newcall, c)) {
@@ -3926,8 +3937,8 @@ static int handle_soft_key_event_message(struct skinny_req *req, struct skinnyse
 
                        if (skinnydebug)
                                ast_verbose("Attempting to Clear display on Skinny %s@%s\n", l->name, d->name);
-                       transmit_displaymessage(s, NULL); /* clear display */
-                       transmit_tone(s, SKINNY_DIALTONE);
+                       transmit_displaymessage(s, NULL, l->instance, sub->callid); /* clear display */
+                       transmit_tone(s, SKINNY_DIALTONE, l->instance, sub->callid);
                        transmit_selectsoftkeys(s, l->instance, sub->callid, KEYDEF_OFFHOOK);
 
                        /* start the switch thread */
@@ -4048,7 +4059,7 @@ static int handle_soft_key_event_message(struct skinny_req *req, struct skinnyse
                        /* We're answering a ringing call */
                        ast_queue_control(sub->owner, AST_CONTROL_ANSWER);
                        transmit_callstate(s, l->instance, SKINNY_OFFHOOK, sub->callid);
-                       transmit_tone(s, SKINNY_SILENCE);
+                       transmit_tone(s, SKINNY_SILENCE, l->instance, sub->callid);
                        transmit_callstate(s, l->instance, SKINNY_CONNECTED, sub->callid);
                        transmit_selectsoftkeys(s, l->instance, sub->callid, KEYDEF_CONNECTED);
                        start_rtp(sub);