1/*
2 * Copyright (C) 2016 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
17package com.android.bluetooth.pbapclient;
18
19import android.util.Log;
20
21import java.io.IOException;
22import java.io.InputStream;
23
24import javax.obex.ClientOperation;
25import javax.obex.ClientSession;
26import javax.obex.HeaderSet;
27import javax.obex.ResponseCodes;
28
29abstract class BluetoothPbapRequest {
30
31    private static final String TAG = "BluetoothPbapRequest";
32
33    protected static final byte OAP_TAGID_ORDER = 0x01;
34    protected static final byte OAP_TAGID_SEARCH_VALUE = 0x02;
35    protected static final byte OAP_TAGID_SEARCH_ATTRIBUTE = 0x03;
36    protected static final byte OAP_TAGID_MAX_LIST_COUNT = 0x04;
37    protected static final byte OAP_TAGID_LIST_START_OFFSET = 0x05;
38    protected static final byte OAP_TAGID_FILTER = 0x06;
39    protected static final byte OAP_TAGID_FORMAT = 0x07;
40    protected static final byte OAP_TAGID_PHONEBOOK_SIZE = 0x08;
41    protected static final byte OAP_TAGID_NEW_MISSED_CALLS = 0x09;
42    protected static final byte OAP_TAGID_PBAP_SUPPORTED_FEATURES = 0x10;
43
44    protected HeaderSet mHeaderSet;
45
46    protected int mResponseCode;
47
48    private boolean mAborted = false;
49
50    private ClientOperation mOp = null;
51
52    BluetoothPbapRequest() {
53        mHeaderSet = new HeaderSet();
54    }
55
56    public final boolean isSuccess() {
57        return (mResponseCode == ResponseCodes.OBEX_HTTP_OK);
58    }
59
60    public void execute(ClientSession session) throws IOException {
61        Log.v(TAG, "execute");
62
63        /* in case request is aborted before can be executed */
64        if (mAborted) {
65            mResponseCode = ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
66            return;
67        }
68
69        try {
70            mOp = (ClientOperation) session.get(mHeaderSet);
71
72            /* make sure final flag for GET is used (PBAP spec 6.2.2) */
73            mOp.setGetFinalFlag(true);
74
75            /*
76             * this will trigger ClientOperation to use non-buffered stream so
77             * we can abort operation
78             */
79            mOp.continueOperation(true, false);
80
81            readResponseHeaders(mOp.getReceivedHeader());
82
83            InputStream is = mOp.openInputStream();
84            readResponse(is);
85            is.close();
86
87            mOp.close();
88
89            mResponseCode = mOp.getResponseCode();
90
91            Log.d(TAG, "mResponseCode=" + mResponseCode);
92
93            checkResponseCode(mResponseCode);
94        } catch (IOException e) {
95            Log.e(TAG, "IOException occured when processing request", e);
96            mResponseCode = ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
97
98            throw e;
99        }
100    }
101
102    public void abort() {
103        mAborted = true;
104
105        if (mOp != null) {
106            try {
107                mOp.abort();
108            } catch (IOException e) {
109                Log.e(TAG, "Exception occured when trying to abort", e);
110            }
111        }
112    }
113
114    protected void readResponse(InputStream stream) throws IOException {
115        Log.v(TAG, "readResponse");
116
117        /* nothing here by default */
118    }
119
120    protected void readResponseHeaders(HeaderSet headerset) {
121        Log.v(TAG, "readResponseHeaders");
122
123        /* nothing here by dafault */
124    }
125
126    protected void checkResponseCode(int responseCode) throws IOException {
127        Log.v(TAG, "checkResponseCode");
128
129        /* nothing here by dafault */
130    }
131}
132