---
 src/stk.c |   64 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 64 insertions(+), 0 deletions(-)

diff --git a/src/stk.c b/src/stk.c
index 835922f..8426af7 100644
--- a/src/stk.c
+++ b/src/stk.c
@@ -502,6 +502,28 @@ static void cancel_pending_dtmf(struct ofono_stk *stk)
                __ofono_voicecall_tone_cancel(vc, stk->dtmf_id);
 }
 
+static void ofono_stk_deactivate_context_cb(int error, void *data)
+{
+}
+
+static void stk_close_channel(struct ofono_stk *stk)
+{
+       int err;
+
+       err = __ofono_gprs_deactivate_context(stk->context.cid,
+                       ofono_stk_deactivate_context_cb, stk);
+
+       if (err < 0) {
+               stk->channel.id = 0;
+               stk->channel.status =
+                               STK_CHANNEL_PACKET_DATA_SERVICE_NOT_ACTIVATED;
+
+               if (stk->pending_cmd && stk->pending_cmd->type ==
+                               STK_COMMAND_TYPE_CLOSE_CHANNEL)
+                       send_simple_response(stk, STK_RESULT_TYPE_NOT_CAPABLE);
+       }
+}
+
 static void user_termination_cb(enum stk_agent_result result, void *user_data)
 {
        struct ofono_stk *stk = user_data;
@@ -516,6 +538,9 @@ static void user_termination_cb(enum stk_agent_result 
result, void *user_data)
        }
 
        send_simple_response(stk, STK_RESULT_TYPE_USER_TERMINATED);
+
+       if (stk->channel.id)
+               stk_close_channel(stk);
 }
 
 static void stk_alpha_id_set(struct ofono_stk *stk,
@@ -650,6 +675,8 @@ out:
        if (stk_respond(stk, &rsp, stk_command_cb))
                stk_command_cb(&failure, stk);
 
+       if (rsp.result.type != STK_RESULT_TYPE_SUCCESS)
+               stk_close_channel(stk);
 }
 
 
@@ -2817,6 +2844,38 @@ static gboolean handle_command_open_channel(const struct 
stk_command *cmd,
        return FALSE;
 }
 
+static gboolean handle_command_close_channel(const struct stk_command *cmd,
+                                               struct stk_response *rsp,
+                                               struct ofono_stk *stk)
+{
+       const struct stk_command_close_channel *cc = &cmd->close_channel;
+
+       /* Check if channel identifier is valid */
+       if (cmd->dst != (stk->channel.id | 0x20)) {
+               unsigned char addnl_info[1];
+
+               addnl_info[1] = STK_RESULT_ADDNL_BIP_PB_CHANNEL_ID_NOT_VALID;
+               ADD_ERROR_RESULT(rsp->result, STK_RESULT_TYPE_BIP_ERROR,
+                                       addnl_info);
+               return TRUE;
+       }
+
+       /*
+        * Don't inform the user about the link closing phase if AID is
+        * a null data object or is not provided
+        */
+       if (cc->alpha_id && cc->alpha_id[0] != '\0')
+               stk_alpha_id_set(stk, cc->alpha_id, &cc->text_attr,
+                                                       &cc->icon_id);
+
+       stk->respond_on_exit = TRUE;
+       stk->cancel_cmd = stk_request_cancel;
+
+       stk_close_channel(stk);
+
+       return FALSE;
+}
+
 static gboolean handle_command_get_channel_status(const struct stk_command 
*cmd,
                                                struct stk_response *rsp,
                                                struct ofono_stk *stk)
@@ -3025,6 +3084,11 @@ void ofono_stk_proactive_command_notify(struct ofono_stk 
*stk,
                                                        &rsp, stk);
                break;
 
+       case STK_COMMAND_TYPE_CLOSE_CHANNEL:
+               respond = handle_command_close_channel(stk->pending_cmd,
+                                                       &rsp, stk);
+               break;
+
        case STK_COMMAND_TYPE_GET_CHANNEL_STATUS:
                respond = handle_command_get_channel_status(stk->pending_cmd,
                                                        &rsp, stk);
-- 
1.7.1

_______________________________________________
ofono mailing list
[email protected]
http://lists.ofono.org/listinfo/ofono

Reply via email to