• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.bluetooth.mapclient;
18 
19 import com.android.obex.ClientOperation;
20 import com.android.obex.ClientSession;
21 import com.android.obex.HeaderSet;
22 import com.android.obex.Operation;
23 import com.android.obex.ResponseCodes;
24 
25 import java.io.DataOutputStream;
26 import java.io.IOException;
27 import java.io.InputStream;
28 
29 abstract class Request {
30 
31     protected static final byte OAP_TAGID_MAX_LIST_COUNT = 0x01;
32     protected static final byte OAP_TAGID_START_OFFSET = 0x02;
33     protected static final byte OAP_TAGID_FILTER_MESSAGE_TYPE = 0x03;
34     protected static final byte OAP_TAGID_FILTER_PERIOD_BEGIN = 0x04;
35     protected static final byte OAP_TAGID_FILTER_PERIOD_END = 0x05;
36     protected static final byte OAP_TAGID_FILTER_READ_STATUS = 0x06;
37     protected static final byte OAP_TAGID_FILTER_RECIPIENT = 0x07;
38     protected static final byte OAP_TAGID_FILTER_ORIGINATOR = 0x08;
39     protected static final byte OAP_TAGID_FILTER_PRIORITY = 0x09;
40     protected static final byte OAP_TAGID_ATTACHMENT = 0x0a;
41     protected static final byte OAP_TAGID_TRANSPARENT = 0xb;
42     protected static final byte OAP_TAGID_RETRY = 0xc;
43     protected static final byte OAP_TAGID_NEW_MESSAGE = 0x0d;
44     protected static final byte OAP_TAGID_NOTIFICATION_STATUS = 0x0e;
45     protected static final byte OAP_TAGID_MAS_INSTANCE_ID = 0x0f;
46     protected static final byte OAP_TAGID_PARAMETER_MASK = 0x10;
47     protected static final byte OAP_TAGID_FOLDER_LISTING_SIZE = 0x11;
48     protected static final byte OAP_TAGID_MESSAGES_LISTING_SIZE = 0x12;
49     protected static final byte OAP_TAGID_SUBJECT_LENGTH = 0x13;
50     protected static final byte OAP_TAGID_CHARSET = 0x14;
51     protected static final byte OAP_TAGID_STATUS_INDICATOR = 0x17;
52     protected static final byte OAP_TAGID_STATUS_VALUE = 0x18;
53     protected static final byte OAP_TAGID_MSE_TIME = 0x19;
54     /* used for PUT requests which require filler byte */
55     protected static final byte[] FILLER_BYTE = {
56             0x30
57     };
58     protected static final byte NOTIFICATION_ON = 0x01;
59     protected static final byte NOTIFICATION_OFF = 0x00;
60     protected static final byte ATTACHMENT_ON = 0x01;
61     protected static final byte ATTACHMENT_OFF = 0x00;
62     protected static final byte CHARSET_NATIVE = 0x00;
63     protected static final byte CHARSET_UTF8 = 0x01;
64     protected static final byte STATUS_INDICATOR_READ = 0x00;
65     protected static final byte STATUS_INDICATOR_DELETED = 0x01;
66     protected static final byte STATUS_NO = 0x00;
67     protected static final byte STATUS_YES = 0x01;
68     protected static final byte TRANSPARENT_OFF = 0x00;
69     protected static final byte TRANSPARENT_ON = 0x01;
70     protected static final byte RETRY_OFF = 0x00;
71     protected static final byte RETRY_ON = 0x01;
72 
73     protected HeaderSet mHeaderSet;
74     protected int mResponseCode;
75     private boolean mAborted = false;
76     private ClientOperation mOp = null;
77 
Request()78     Request() {
79         mHeaderSet = new HeaderSet();
80     }
81 
execute(ClientSession session)82     public abstract void execute(ClientSession session) throws IOException;
83 
executeGet(ClientSession session)84     protected void executeGet(ClientSession session) throws IOException {
85         /* in case request is aborted before can be executed */
86         if (mAborted) {
87             mResponseCode = ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
88             return;
89         }
90 
91         try {
92             mOp = (ClientOperation) session.get(mHeaderSet);
93 
94             /*
95              * MAP spec does not explicitly require that GET request should be
96              * sent in single packet but for some reason PTS complains when
97              * final GET packet with no headers follows non-final GET with all
98              * headers. So this is workaround, at least temporary. TODO: check
99              * with PTS
100              */
101             mOp.setGetFinalFlag(true);
102 
103             /*
104              * this will trigger ClientOperation to use non-buffered stream so
105              * we can abort operation
106              */
107             mOp.continueOperation(true, false);
108 
109             readResponseHeaders(mOp.getReceivedHeader());
110 
111             InputStream is = mOp.openInputStream();
112             readResponse(is);
113             is.close();
114 
115             mOp.close();
116 
117             mResponseCode = mOp.getResponseCode();
118         } catch (IOException e) {
119             mResponseCode = ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
120 
121             throw e;
122         }
123     }
124 
executePut(ClientSession session, byte[] body)125     protected void executePut(ClientSession session, byte[] body) throws IOException {
126         Operation op = null;
127 
128         mHeaderSet.setHeader(HeaderSet.LENGTH, Long.valueOf(body.length));
129 
130         try {
131             op = session.put(mHeaderSet);
132 
133             DataOutputStream out = op.openDataOutputStream();
134             out.write(body);
135             out.close();
136 
137             readResponseHeaders(op.getReceivedHeader());
138 
139             op.close();
140             mResponseCode = op.getResponseCode();
141         } catch (IOException e) {
142             mResponseCode = ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
143 
144             throw e;
145         }
146     }
147 
abort()148     public void abort() {
149         mAborted = true;
150 
151         if (mOp != null) {
152             try {
153                 mOp.abort();
154             } catch (IOException e) {
155                 // Do nothing
156             }
157         }
158     }
159 
isSuccess()160     public final boolean isSuccess() {
161         return (mResponseCode == ResponseCodes.OBEX_HTTP_OK);
162     }
163 
readResponse(InputStream stream)164     protected void readResponse(InputStream stream) throws IOException {
165         /* nothing here by default */
166     }
167 
readResponseHeaders(HeaderSet headerset)168     protected void readResponseHeaders(HeaderSet headerset) {
169         /* nothing here by default */
170     }
171 }
172