2 * Copyright (C) 2010, The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package com.android.internal.communication;
19 import android.util.Log;
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;
26 import java.io.IOException;
27 import java.nio.ByteBuffer;
28 import java.nio.ByteOrder;
34 private MsgHeader mHeader;
35 private ByteBuffer mData;
38 * Send a message header
40 * @param mh is message header to write
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());
48 ByteBuffer mhBuffer = ByteBuffer.allocateDirect(mh.getCachedSize());
49 mhBuffer.put(mh.toByteArray());
51 rc.rewindSendAll(lenBuffer);
52 rc.rewindSendAll(mhBuffer);
56 * Read a message header
58 * @returns message header
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();
67 ByteBuffer mhBuffer = ByteBuffer.allocate(lenHeader);
68 lenRead = rc.recvAllRewind(mhBuffer);
69 MsgHeader mh = MsgHeader.parseFrom(mhBuffer.array());
82 public static Msg obtain() {
83 // TODO: Get from a free list
90 public void release() {
91 // TODO: place back on free list
95 * Send a message header followed by the data if present
97 * The length data field will be filled in as appropriate
99 * @param data if not null and length > 0 sent after header
100 * @throws IOException
102 public static final void send(RilChannel rc, MsgHeader mh, ByteBuffer data)
110 lenData = data.remaining();
112 mh.setLengthData(lenData);
120 * Send a message with cmd, token, status followed by the data.
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
129 public static final void send(RilChannel rc, int cmd, long token, int status, MessageMicro pb)
131 MsgHeader mh = new MsgHeader();
134 mh.setStatus(status);
138 data = ByteBuffer.wrap(pb.toByteArray());
146 * Send a message with cmd, token, status followed by the data.
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
154 public static final void send(RilChannel rc, int cmd, long token, MessageMicro pb)
156 send(rc, cmd, token, 0, pb);
160 * Send a message with cmd followed by the data.
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
167 public static final void send(RilChannel rc, int cmd, MessageMicro pb) throws IOException {
168 send(rc, cmd, 0, 0, pb);
172 * Send a message with cmd, token and status but no data
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
180 public static final void send(RilChannel rc, int cmd, long token, int status)
182 send(rc, cmd, token, status, null);
186 * Send a message with cmd and token but no data
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
193 public static final void send(RilChannel rc, int cmd, long token) throws IOException {
194 send(rc, cmd, token, 0, null);
198 * Send a message with cmd but no data
200 * The length data field will be filled in as appropriate
201 * @param cmd for the header
202 * @throws IOException
204 public static final void send(RilChannel rc, int cmd) throws IOException {
205 send(rc, cmd, 0, 0, null);
212 * @throws IOException
214 public static final Msg recv(RilChannel rc) throws IOException {
215 Msg msg = Msg.obtain();
221 * Read a message header and data.
223 * @throws IOException
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);
235 * Print the message header.
237 * @param tag for the header
239 public void printHeader(String tag) {
240 Log.d(tag, " cmd=" + mHeader.getCmd() + " token=" + mHeader.getToken() + " status="
241 + mHeader.getStatus() + " lengthData=" + mHeader.getLengthData());
245 * Set data (for testing purposes only).
247 public void setData(ByteBuffer data) {
252 * Set header (for testing purposes only).
254 public void setHeader(MsgHeader header) {
261 public int getCmd() {
262 return mHeader.getCmd();
268 public long getToken() {
269 return mHeader.getToken();
275 public int getStatus() {
276 return mHeader.getStatus();
280 * @return data ByteBuffer
282 public ByteBuffer getData() {
287 * @return data at index
289 public byte getData(int index) {
290 return mData.get(index);
294 * Return data as a Class<T>.
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.
301 @SuppressWarnings("unchecked")
302 public static final <T extends MessageMicro> T getAs(Class<T> c, byte[] data) {
304 if ((data != null) && (data.length > 0)) {
306 o = c.newInstance().mergeFrom(data);
307 } catch (InvalidProtocolBufferMicroException e) {
309 } catch (InstantiationException e) {
311 } catch (IllegalAccessException e) {
319 * Return data as a Class<T>.
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
325 @SuppressWarnings("unchecked")
326 public <T extends MessageMicro> T getDataAs(Class<T> c) {
329 if ((mData != null) && (mData.remaining() > 0)) {
330 o = getAs(c, mData.array());