OSDN Git Service

Port Mock Ril from master branch to GB. DO NOT MERGE
[android-x86/hardware-ril.git] / mock-ril / src / java / com / android / internal / communication / Msg.java
1 /*
2  * Copyright (C) 2010, 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.communication;
18
19 import android.util.Log;
20
21 import com.android.internal.communication.MsgHeader;
22 import com.android.internal.telephony.RilChannel;
23 import com.google.protobuf.micro.InvalidProtocolBufferMicroException;
24 import com.google.protobuf.micro.MessageMicro;
25
26 import java.io.IOException;
27 import java.nio.ByteBuffer;
28 import java.nio.ByteOrder;
29
30 /**
31  * A message
32  */
33 public class Msg {
34     private MsgHeader  mHeader;
35     private ByteBuffer mData;
36
37     /**
38      * Send a message header
39      *
40      * @param mh is message header to write
41      * @throws IOException
42      */
43     private static void sendHeader(RilChannel rc, MsgHeader mh) throws IOException {
44         ByteBuffer lenBuffer = ByteBuffer.allocateDirect(4);
45         lenBuffer.order(ByteOrder.LITTLE_ENDIAN);
46         lenBuffer.putInt(mh.getSerializedSize());
47
48         ByteBuffer mhBuffer = ByteBuffer.allocateDirect(mh.getCachedSize());
49         mhBuffer.put(mh.toByteArray());
50
51         rc.rewindSendAll(lenBuffer);
52         rc.rewindSendAll(mhBuffer);
53     }
54
55     /**
56      * Read a message header
57      *
58      * @returns message header
59      * @throws IOException
60      */
61     private static MsgHeader recvHeader(RilChannel rc) throws IOException {
62         ByteBuffer lenBuffer = ByteBuffer.allocate(4);
63         lenBuffer.order(ByteOrder.LITTLE_ENDIAN);
64         int lenRead = rc.recvAllRewind(lenBuffer);
65         int lenHeader = lenBuffer.getInt();
66
67         ByteBuffer mhBuffer = ByteBuffer.allocate(lenHeader);
68         lenRead = rc.recvAllRewind(mhBuffer);
69         MsgHeader mh = MsgHeader.parseFrom(mhBuffer.array());
70         return mh;
71     }
72
73     /**
74      * Msg Constructor
75      */
76     private Msg() {
77     }
78
79     /**
80      * Get a message
81      */
82     public static Msg obtain() {
83         // TODO: Get from a free list
84         return new Msg();
85     }
86
87     /**
88      * Release a message
89      */
90     public void release() {
91         // TODO: place back on free list
92     }
93
94     /**
95      * Send a message header followed by the data if present
96      *
97      * The length data field will be filled in as appropriate
98      * @param mh header
99      * @param data if not null and length > 0 sent after header
100      * @throws IOException
101      */
102     public static final void send(RilChannel rc, MsgHeader mh, ByteBuffer data)
103             throws IOException {
104         int lenData;
105
106         if (data == null) {
107             lenData = 0;
108         } else {
109             data.rewind();
110             lenData = data.remaining();
111         }
112         mh.setLengthData(lenData);
113         sendHeader(rc, mh);
114         if (lenData > 0) {
115             rc.sendAll(data);
116         }
117     }
118
119     /**
120      * Send a message with cmd, token, status followed by the data.
121      *
122      * The length data field will be filled in as appropriate
123      * @param cmd for the header
124      * @param token for the header
125      * @param status for the header
126      * @param pb is the protobuf to send
127      * @throws IOException
128      */
129     public static final void send(RilChannel rc, int cmd, long token, int status, MessageMicro pb)
130             throws IOException {
131         MsgHeader mh = new MsgHeader();
132         mh.setCmd(cmd);
133         mh.setToken(token);
134         mh.setStatus(status);
135
136         ByteBuffer data;
137         if (pb != null) {
138             data = ByteBuffer.wrap(pb.toByteArray());
139         } else {
140             data = null;
141         }
142         send(rc, mh, data);
143     }
144
145     /**
146      * Send a message with cmd, token, status followed by the data.
147      *
148      * The length data field will be filled in as appropriate
149      * @param cmd for the header
150      * @param token for the header
151      * @param pb is the protobuf to send
152      * @throws IOException
153      */
154     public static final void send(RilChannel rc, int cmd, long token, MessageMicro pb)
155             throws IOException {
156         send(rc, cmd, token, 0, pb);
157     }
158
159     /**
160      * Send a message with cmd followed by the data.
161      *
162      * The length data field will be filled in as appropriate
163      * @param cmd for the header
164      * @param pb is the protobuf to send
165      * @throws IOException
166      */
167     public static final void send(RilChannel rc, int cmd, MessageMicro pb) throws IOException {
168         send(rc, cmd, 0, 0, pb);
169     }
170
171     /**
172      * Send a message with cmd, token and status but no data
173      *
174      * The length data field will be filled in as appropriate
175      * @param cmd for the header
176      * @param token for the header
177      * @param status for the header
178      * @throws IOException
179      */
180     public static final void send(RilChannel rc, int cmd, long token, int status)
181             throws IOException {
182         send(rc, cmd, token, status, null);
183     }
184
185     /**
186      * Send a message with cmd and token but no data
187      *
188      * The length data field will be filled in as appropriate
189      * @param cmd for the header
190      * @param token for the header
191      * @throws IOException
192      */
193     public static final void send(RilChannel rc, int cmd, long token) throws IOException {
194         send(rc, cmd, token, 0, null);
195     }
196
197     /**
198      * Send a message with cmd but no data
199      *
200      * The length data field will be filled in as appropriate
201      * @param cmd for the header
202      * @throws IOException
203      */
204     public static final void send(RilChannel rc, int cmd) throws IOException {
205         send(rc, cmd, 0, 0, null);
206     }
207
208     /**
209      * Read a message
210      *
211      * @return Msg
212      * @throws IOException
213      */
214     public static final Msg recv(RilChannel rc) throws IOException {
215         Msg msg = Msg.obtain();
216         msg.read(rc);
217         return msg;
218     }
219
220     /**
221      * Read a message header and data.
222      *
223      * @throws IOException
224      */
225     public void read(RilChannel rc) throws IOException {
226         mHeader = recvHeader(rc);
227         if (mHeader.getLengthData() > 0) {
228             ByteBuffer bb = ByteBuffer.allocate(mHeader.getLengthData());
229             rc.recvAllRewind(bb);
230             mData = bb;
231         }
232     }
233
234     /**
235      * Print the message header.
236      *
237      * @param tag for the header
238      */
239     public void printHeader(String tag) {
240         Log.d(tag, " cmd=" + mHeader.getCmd() + " token=" + mHeader.getToken() + " status="
241                         + mHeader.getStatus() + " lengthData=" + mHeader.getLengthData());
242     }
243
244     /**
245      * Set data (for testing purposes only).
246      */
247     public void setData(ByteBuffer data) {
248         mData = data;
249     }
250
251     /**
252      * Set header (for testing purposes only).
253      */
254     public void setHeader(MsgHeader header) {
255         mHeader = header;
256     }
257
258     /**
259      * @return cmd
260      */
261     public int getCmd() {
262         return mHeader.getCmd();
263     }
264
265     /**
266      * @return token
267      */
268     public long getToken() {
269         return mHeader.getToken();
270     }
271
272     /**
273      * @return status
274      */
275     public int getStatus() {
276         return mHeader.getStatus();
277     }
278
279     /**
280      * @return data ByteBuffer
281      */
282     public ByteBuffer getData() {
283         return mData;
284     }
285
286     /**
287      * @return data at index
288      */
289     public byte getData(int index) {
290         return mData.get(index);
291     }
292
293     /**
294      * Return data as a Class<T>.
295      *
296      * @param <T> a class that extends MessageMicro.
297      * @param c the T.class to create from the data.
298      * @param data is the MessageMicro protobuf to be converted.
299      * @return null if an error occurs.
300      */
301     @SuppressWarnings("unchecked")
302     public static final <T extends MessageMicro> T getAs(Class<T> c, byte[] data) {
303         Object o = null;
304         if ((data != null) && (data.length > 0)) {
305             try {
306                 o = c.newInstance().mergeFrom(data);
307             } catch (InvalidProtocolBufferMicroException e) {
308                 e.printStackTrace();
309             } catch (InstantiationException e) {
310                 e.printStackTrace();
311             } catch (IllegalAccessException e) {
312                 e.printStackTrace();
313             }
314         }
315         return (T)o;
316     }
317
318     /**
319      * Return data as a Class<T>.
320      *
321      * @param <T> a class that extends MessageMicro.
322      * @param c the T.class to create from data.
323      * @return null if an error occurs
324      */
325     @SuppressWarnings("unchecked")
326     public <T extends MessageMicro> T getDataAs(Class<T> c) {
327         Object o;
328
329         if ((mData != null) && (mData.remaining() > 0)) {
330             o = getAs(c, mData.array());
331         } else {
332             o = null;
333         }
334         return (T)o;
335     }
336 }