1 /*
2  * Copyright (C) 2014 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.internal.telephony.dataconnection;
18 
19 import android.net.NetworkRequest;
20 import android.os.Message;
21 import android.telephony.Rlog;
22 import android.util.LocalLog;
23 
24 import com.android.internal.util.AsyncChannel;
25 import com.android.internal.util.Protocol;
26 import com.android.internal.telephony.PhoneConstants;
27 
28 public class DcSwitchAsyncChannel extends AsyncChannel {
29     private static final boolean DBG = true;
30     private static final boolean VDBG = false;
31     private static final String LOG_TAG = "DcSwitchAsyncChannel";
32 
33     private int tagId = 0;
34     private DcSwitchStateMachine mDcSwitchState;
35 
36     // ***** Event codes for driving the state machine
37     private static final int BASE = Protocol.BASE_DATA_CONNECTION_TRACKER + 0x00002000;
38     static final int REQ_CONNECT =                    BASE + 0;
39     static final int REQ_RETRY_CONNECT  =             BASE + 1;
40     static final int REQ_DISCONNECT_ALL =             BASE + 2;
41     static final int REQ_IS_IDLE_STATE =              BASE + 3;
42     static final int RSP_IS_IDLE_STATE =              BASE + 4;
43     static final int REQ_IS_IDLE_OR_DETACHING_STATE = BASE + 5;
44     static final int RSP_IS_IDLE_OR_DETACHING_STATE = BASE + 6;
45     static final int EVENT_DATA_ATTACHED =            BASE + 7;
46     static final int EVENT_DATA_DETACHED =            BASE + 8;
47     static final int EVENT_EMERGENCY_CALL_STARTED =   BASE + 9;
48     static final int EVENT_EMERGENCY_CALL_ENDED =     BASE + 10;
49 
50     private static final int CMD_TO_STRING_COUNT = EVENT_EMERGENCY_CALL_ENDED - BASE + 1;
51     private static String[] sCmdToString = new String[CMD_TO_STRING_COUNT];
52     static {
53         sCmdToString[REQ_CONNECT - BASE] = "REQ_CONNECT";
54         sCmdToString[REQ_RETRY_CONNECT - BASE] = "REQ_RETRY_CONNECT";
55         sCmdToString[REQ_DISCONNECT_ALL - BASE] = "REQ_DISCONNECT_ALL";
56         sCmdToString[REQ_IS_IDLE_STATE - BASE] = "REQ_IS_IDLE_STATE";
57         sCmdToString[RSP_IS_IDLE_STATE - BASE] = "RSP_IS_IDLE_STATE";
58         sCmdToString[REQ_IS_IDLE_OR_DETACHING_STATE - BASE] = "REQ_IS_IDLE_OR_DETACHING_STATE";
59         sCmdToString[RSP_IS_IDLE_OR_DETACHING_STATE - BASE] = "RSP_IS_IDLE_OR_DETACHING_STATE";
60         sCmdToString[EVENT_DATA_ATTACHED - BASE] = "EVENT_DATA_ATTACHED";
61         sCmdToString[EVENT_DATA_DETACHED - BASE] = "EVENT_DATA_DETACHED";
62         sCmdToString[EVENT_EMERGENCY_CALL_STARTED - BASE] = "EVENT_EMERGENCY_CALL_STARTED";
63         sCmdToString[EVENT_EMERGENCY_CALL_ENDED - BASE] = "EVENT_EMERGENCY_CALL_ENDED";
64     }
65 
66     public static class RequestInfo {
67         boolean executed;
68         final NetworkRequest request;
69         final int priority;
70         final int phoneId;
71         private final LocalLog requestLog;
72 
RequestInfo(NetworkRequest request, int priority, LocalLog l, int phoneId)73         public RequestInfo(NetworkRequest request, int priority, LocalLog l, int phoneId) {
74             this.request = request;
75             this.priority = priority;
76             this.requestLog = l;
77             this.executed = false;
78             this.phoneId = phoneId;
79         }
80 
log(String str)81         public void log(String str) {
82             requestLog.log(str);
83         }
84 
getLog()85         public LocalLog getLog() {
86             return requestLog;
87         }
88 
89         @Override
toString()90         public String toString() {
91             return "[ request=" + request + ", executed=" + executed +
92                 ", priority=" + priority + ", phoneId=" + phoneId + "]";
93         }
94     }
95 
cmdToString(int cmd)96     protected static String cmdToString(int cmd) {
97         cmd -= BASE;
98         if ((cmd >= 0) && (cmd < sCmdToString.length)) {
99             return sCmdToString[cmd];
100         } else {
101             return AsyncChannel.cmdToString(cmd + BASE);
102         }
103     }
104 
DcSwitchAsyncChannel(DcSwitchStateMachine dcSwitchState, int id)105     public DcSwitchAsyncChannel(DcSwitchStateMachine dcSwitchState, int id) {
106         mDcSwitchState = dcSwitchState;
107         tagId = id;
108     }
109 
connect(RequestInfo apnRequest)110     public int connect(RequestInfo apnRequest) {
111         sendMessage(REQ_CONNECT, apnRequest);
112         return PhoneConstants.APN_REQUEST_STARTED;
113     }
114 
retryConnect()115     public void retryConnect() {
116         sendMessage(REQ_RETRY_CONNECT);
117     }
118 
disconnectAll()119     public int disconnectAll() {
120         sendMessage(REQ_DISCONNECT_ALL);
121         return PhoneConstants.APN_REQUEST_STARTED;
122     }
123 
notifyDataAttached()124     public void notifyDataAttached() {
125         sendMessage(EVENT_DATA_ATTACHED);
126     }
127 
notifyDataDetached()128     public void notifyDataDetached() {
129         sendMessage(EVENT_DATA_DETACHED);
130     }
131 
notifyEmergencyCallToggled(int start)132     public void notifyEmergencyCallToggled(int start) {
133         if (start != 0) {
134             sendMessage(EVENT_EMERGENCY_CALL_STARTED);
135         } else {
136             sendMessage(EVENT_EMERGENCY_CALL_ENDED);
137         }
138     }
139 
rspIsIdle(Message response)140     private boolean rspIsIdle(Message response) {
141         boolean retVal = response.arg1 == 1;
142         if (DBG) log("rspIsIdle=" + retVal);
143         return retVal;
144     }
145 
isIdleSync()146     public boolean isIdleSync() {
147         Message response = sendMessageSynchronously(REQ_IS_IDLE_STATE);
148         if ((response != null) && (response.what == RSP_IS_IDLE_STATE)) {
149             return rspIsIdle(response);
150         } else {
151             if (DBG) log("rspIsIndle error response=" + response);
152             return false;
153         }
154     }
155 
reqIsIdleOrDetaching()156     public void reqIsIdleOrDetaching() {
157         sendMessage(REQ_IS_IDLE_OR_DETACHING_STATE);
158         if (DBG) log("reqIsIdleOrDetaching");
159     }
160 
rspIsIdleOrDetaching(Message response)161     public boolean rspIsIdleOrDetaching(Message response) {
162         boolean retVal = response.arg1 == 1;
163         if (DBG) log("rspIsIdleOrDetaching=" + retVal);
164         return retVal;
165     }
166 
isIdleOrDetachingSync()167     public boolean isIdleOrDetachingSync() {
168         Message response = sendMessageSynchronously(REQ_IS_IDLE_OR_DETACHING_STATE);
169         if ((response != null) && (response.what == RSP_IS_IDLE_OR_DETACHING_STATE)) {
170             return rspIsIdleOrDetaching(response);
171         } else {
172             if (DBG) log("rspIsIdleOrDetaching error response=" + response);
173             return false;
174         }
175     }
176 
177     @Override
toString()178     public String toString() {
179         return mDcSwitchState.getName();
180     }
181 
log(String s)182     private void log(String s) {
183         Rlog.d(LOG_TAG, "[DcSwitchAsyncChannel-" + tagId + "]: " + s);
184     }
185 
186 }
187