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 java.io.DataOutputStream;
20 import java.io.IOException;
21 import java.io.InputStream;
22 
23 import javax.obex.ClientOperation;
24 import javax.obex.ClientSession;
25 import javax.obex.HeaderSet;
26 import javax.obex.Operation;
27 import javax.obex.ResponseCodes;
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     protected HeaderSet mHeaderSet;
73 
74     protected int mResponseCode;
75 
Request()76     Request() {
77         mHeaderSet = new HeaderSet();
78     }
79 
execute(ClientSession session)80     public abstract void execute(ClientSession session) throws IOException;
81 
executeGet(ClientSession session)82     protected void executeGet(ClientSession session) throws IOException {
83         ClientOperation op = null;
84 
85         try {
86             op = (ClientOperation) session.get(mHeaderSet);
87 
88             /*
89              * MAP spec does not explicitly require that GET request should be
90              * sent in single packet but for some reason PTS complains when
91              * final GET packet with no headers follows non-final GET with all
92              * headers. So this is workaround, at least temporary. TODO: check
93              * with PTS
94              */
95             op.setGetFinalFlag(true);
96 
97             /*
98              * this will trigger ClientOperation to use non-buffered stream so
99              * we can abort operation
100              */
101             op.continueOperation(true, false);
102 
103             readResponseHeaders(op.getReceivedHeader());
104 
105             InputStream is = op.openInputStream();
106             readResponse(is);
107             is.close();
108 
109             op.close();
110 
111             mResponseCode = op.getResponseCode();
112         } catch (IOException e) {
113             mResponseCode = ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
114 
115             throw e;
116         }
117     }
118 
executePut(ClientSession session, byte[] body)119     protected void executePut(ClientSession session, byte[] body) throws IOException {
120         Operation op = null;
121 
122         mHeaderSet.setHeader(HeaderSet.LENGTH, Long.valueOf(body.length));
123 
124         try {
125             op = session.put(mHeaderSet);
126 
127             DataOutputStream out = op.openDataOutputStream();
128             out.write(body);
129             out.close();
130 
131             readResponseHeaders(op.getReceivedHeader());
132 
133             op.close();
134             mResponseCode = op.getResponseCode();
135         } catch (IOException e) {
136             mResponseCode = ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
137 
138             throw e;
139         }
140     }
141 
isSuccess()142     public final boolean isSuccess() {
143         return (mResponseCode == ResponseCodes.OBEX_HTTP_OK);
144     }
145 
readResponse(InputStream stream)146     protected void readResponse(InputStream stream) throws IOException {
147         /* nothing here by default */
148     }
149 
readResponseHeaders(HeaderSet headerset)150     protected void readResponseHeaders(HeaderSet headerset) {
151         /* nothing here by default */
152     }
153 }
154