BluetoothOppObexServerSession.java revision df7415da0e510ab8e4b73831a5ade38306982fe1
109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly/*
209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * Copyright (c) 2008-2009, Motorola, Inc.
309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly *
409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * All rights reserved.
509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly *
609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * Redistribution and use in source and binary forms, with or without
709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * modification, are permitted provided that the following conditions are met:
809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly *
909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * - Redistributions of source code must retain the above copyright notice,
1009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * this list of conditions and the following disclaimer.
1109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly *
1209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * - Redistributions in binary form must reproduce the above copyright notice,
1309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * this list of conditions and the following disclaimer in the documentation
1409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * and/or other materials provided with the distribution.
1509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly *
1609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * - Neither the name of the Motorola, Inc. nor the names of its contributors
1709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * may be used to endorse or promote products derived from this software
1809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * without specific prior written permission.
1909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly *
2009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
2109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
2409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
3009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * POSSIBILITY OF SUCH DAMAGE.
3109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly */
3209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
3309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellypackage com.android.bluetooth.opp;
3409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
3509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport java.io.BufferedOutputStream;
3609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport java.io.File;
3709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport java.io.FileNotFoundException;
3809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport java.io.FileOutputStream;
3909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport java.io.IOException;
4009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport java.io.InputStream;
4109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
4209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport android.content.ContentValues;
4309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport android.content.Context;
4409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport android.content.Intent;
4509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport android.net.Uri;
4609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport android.os.Handler;
4709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport android.os.Message;
4809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport android.util.Log;
4909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport android.webkit.MimeTypeMap;
5009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
5109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport javax.obex.HeaderSet;
5209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport javax.obex.ObexTransport;
5309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport javax.obex.Operation;
5409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport javax.obex.ResponseCodes;
5509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport javax.obex.ServerRequestHandler;
5609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport javax.obex.ServerSession;
5709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
5809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly/**
5909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * This class runs as an OBEX server
6009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly */
6109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellypublic class BluetoothOppObexServerSession extends ServerRequestHandler implements
6209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        BluetoothOppObexSession {
6309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
6409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    private static final String TAG = "BtOpp Server";
6509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
6609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    private ObexTransport mTransport;
6709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
6809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    private Context mContext;
6909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
7009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    private Handler mCallback = null;
7109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
7209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    /* status when server is blocking for user/auto confirmation */
7309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    private boolean mServerBlocking = true;
7409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
7509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    /* the current transfer info */
7609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    private BluetoothOppShareInfo mInfo;
7709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
7809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    /* info id when we insert the record */
7909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    private int mLocalShareInfoId;
8009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
8109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    private int mAccepted = BluetoothShare.USER_CONFIRMATION_PENDING;
8209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
8309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    private boolean mInterrupted = false;
8409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
8509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    private ServerSession mSession;
8609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
8709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    private long mTimestamp;
8809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
8909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    private BluetoothOppReceiveFileInfo mFileInfo;
9009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
9109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    public BluetoothOppObexServerSession(Context context, ObexTransport transport) {
9209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        mContext = context;
9309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        mTransport = transport;
9409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    }
9509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
9609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    public void unblock() {
9709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        mServerBlocking = false;
9809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    }
9909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
10009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    /**
10109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly     * Called when connection is accepted from remote, to retrieve the first
10209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly     * Header then wait for user confirmation
10309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly     */
10409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    public void preStart() {
10509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        try {
10609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            if (Constants.LOGV) {
10709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                Log.v(TAG, "Create ServerSession with transport " + mTransport.toString());
10809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            }
10909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            mSession = new ServerSession(mTransport, this, null);
11009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        } catch (IOException e) {
11109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            Log.e(TAG, "Create server session error" + e);
11209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        }
11309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    }
11409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
11509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    /**
11609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly     * Called from BluetoothOppTransfer to start the "Transfer"
11709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly     */
11809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    public void start(Handler handler) {
11909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        if (Constants.LOGV) {
12009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            Log.v(TAG, "Start!");
12109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        }
12209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        mCallback = handler;
12309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
12409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    }
12509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
12609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    /**
1276769b59d715ea98bd72eafcfea9acd2714a887daTao Liejun     * Called from BluetoothOppTransfer to cancel the "Transfer" Otherwise,
1286769b59d715ea98bd72eafcfea9acd2714a887daTao Liejun     * server should end by itself.
12909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly     */
13009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    public void stop() {
13109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        /*
13209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly         * TODO now we implement in a tough way, just close the socket.
13309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly         * maybe need nice way
13409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly         */
13509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        if (Constants.LOGV) {
13609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            Log.v(TAG, "Stop!");
13709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        }
13809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        mInterrupted = true;
13909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        if (mSession != null) {
14009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            try {
14109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                mSession.close();
14209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                mTransport.close();
14309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            } catch (IOException e) {
14409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                Log.e(TAG, "close mTransport error" + e);
14509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            }
14609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        }
14709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    }
14809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
14909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    public void addShare(BluetoothOppShareInfo info) {
15009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        if (Constants.LOGV) {
15109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            Log.v(TAG, "addShare for id " + info.mId);
15209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        }
15309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        mInfo = info;
15409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        mFileInfo = processShareInfo();
15509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    }
15609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
15709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    @Override
15809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    public int onPut(Operation op) {
15909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        if (Constants.LOGV) {
16009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            Log.v(TAG, "onPut " + op.toString());
16109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        }
16209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        HeaderSet request;
16309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        String name, mimeType;
16409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        Long length;
16509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
16609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        int obexResponse = ResponseCodes.OBEX_HTTP_OK;
16709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
16809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        /**
16909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly         * For multiple objects, reject further objects after user deny the
17009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly         * first one
17109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly         */
17209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        if (mAccepted == BluetoothShare.USER_CONFIRMATION_DENIED) {
17309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            return ResponseCodes.OBEX_HTTP_FORBIDDEN;
17409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        }
17509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
17609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        try {
17709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            boolean pre_reject = false;
1786769b59d715ea98bd72eafcfea9acd2714a887daTao Liejun            request = op.getReceivedHeader();
17909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            if (Constants.LOGVV) {
18009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                logHeader(request);
18109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            }
18209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            name = (String)request.getHeader(HeaderSet.NAME);
18309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            length = (Long)request.getHeader(HeaderSet.LENGTH);
18409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            mimeType = (String)request.getHeader(HeaderSet.TYPE);
18509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
18609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            if (length == 0) {
18709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                if (Constants.LOGV) {
18809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                    Log.w(TAG, "length is 0, reject the transfer");
18909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                }
19009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                pre_reject = true;
19109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                obexResponse = ResponseCodes.OBEX_HTTP_LENGTH_REQUIRED;
19209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            }
19309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
19409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            if (name == null || name.equals("")) {
19509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                if (Constants.LOGV) {
19609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                    Log.w(TAG, "name is null or empty, reject the transfer");
19709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                }
19809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                pre_reject = true;
19909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                obexResponse = ResponseCodes.OBEX_HTTP_BAD_REQUEST;
20009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            }
20109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
20209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            if (!pre_reject) {
20309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                /* first we look for Mimetype in Android map */
20409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                String extension, type;
20509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                int dotIndex = name.indexOf('.');
20609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                if (dotIndex < 0) {
20709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                    if (Constants.LOGV) {
20809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                        Log.w(TAG, "There is no file extension, reject the transfer");
20909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                    }
21009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                    pre_reject = true;
21109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                    obexResponse = ResponseCodes.OBEX_HTTP_BAD_REQUEST;
21209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                } else {
21309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                    extension = name.substring(dotIndex + 1);
21409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                    MimeTypeMap map = MimeTypeMap.getSingleton();
21509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                    type = map.getMimeTypeFromExtension(extension);
21609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                    if (Constants.LOGVV) {
21709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                        Log.v(TAG, "Mimetype guessed from extension " + extension + " is "
21809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                                + mimeType);
21909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                    }
22009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                    if (type != null) {
22109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                        mimeType = type;
22209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
22309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                    } else {
22409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                        if (mimeType == null) {
22509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                            if (Constants.LOGV) {
22609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                                Log.w(TAG, "Can't get mimetype, reject the transfer");
22709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                            }
22809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                            pre_reject = true;
22909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                            obexResponse = ResponseCodes.OBEX_HTTP_BAD_REQUEST;
23009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                        }
23109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                    }
23209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                    if (mimeType != null) {
23309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                        mimeType = mimeType.toLowerCase();
23409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                    }
23509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                }
23609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            }
23709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
23809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            if (!pre_reject
23909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                    && (mimeType == null || Constants.mimeTypeMatches(mimeType,
24009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                            Constants.UNACCEPTABLE_SHARE_INBOUND_TYPES))) {
24109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                if (Constants.LOGV) {
24209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                    Log.w(TAG, "mimeType is null or in unacceptable list, reject the transfer");
24309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                }
24409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                pre_reject = true;
24509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                obexResponse = ResponseCodes.OBEX_HTTP_UNSUPPORTED_TYPE;
24609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            }
24709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
24809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            if (pre_reject && obexResponse != ResponseCodes.OBEX_HTTP_OK) {
24909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                return obexResponse;
25009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            }
25109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
25209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        } catch (IOException e) {
25309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            Log.e(TAG, "get getReceivedHeaders error " + e);
25409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            return ResponseCodes.OBEX_HTTP_BAD_REQUEST;
25509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        }
25609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
25709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        ContentValues values = new ContentValues();
25809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
25909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        values.put(BluetoothShare.FILENAME_HINT, name);
26009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        values.put(BluetoothShare.TOTAL_BYTES, length.intValue());
26109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        values.put(BluetoothShare.MIMETYPE, mimeType);
26209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
26309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        if (mTransport instanceof BluetoothOppRfcommTransport) {
26409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            String a = ((BluetoothOppRfcommTransport)mTransport).getRemoteAddress();
26509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            values.put(BluetoothShare.DESTINATION, a);
26609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        } else {
26709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            values.put(BluetoothShare.DESTINATION, "FF:FF:FF:00:00:00");
26809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        }
26909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
27009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        values.put(BluetoothShare.DIRECTION, BluetoothShare.DIRECTION_INBOUND);
27109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        values.put(BluetoothShare.TIMESTAMP, mTimestamp);
27209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
27309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        boolean needConfirm = true;
27409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        /** It's not first put if !serverBlocking, so we auto accept it */
27509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        if (!mServerBlocking) {
27609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            values.put(BluetoothShare.USER_CONFIRMATION,
27709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                    BluetoothShare.USER_CONFIRMATION_AUTO_CONFIRMED);
27809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            needConfirm = false;
27909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        }
28009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
28109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        Uri contentUri = mContext.getContentResolver().insert(BluetoothShare.CONTENT_URI, values);
28209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        mLocalShareInfoId = Integer.parseInt(contentUri.getPathSegments().get(1));
28309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
28409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        if (needConfirm) {
28509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            Intent in = new Intent(BluetoothShare.INCOMING_FILE_CONFIRMATION_REQUEST_ACTION);
28609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            in.setClassName(Constants.THIS_PACKAGE_NAME, BluetoothOppReceiver.class.getName());
28709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            mContext.sendBroadcast(in);
28809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        }
28909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
29009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        if (Constants.LOGVV) {
29109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            Log.v(TAG, "insert contentUri: " + contentUri);
29209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            Log.v(TAG, "mLocalShareInfoId = " + mLocalShareInfoId);
29309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        }
29409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
29509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        // TODO add server wait timeout
29609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        mServerBlocking = true;
297df7415da0e510ab8e4b73831a5ade38306982fe1Tao Liejun        boolean msgSent = false;
29809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        synchronized (this) {
29909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            try {
300df7415da0e510ab8e4b73831a5ade38306982fe1Tao Liejun
30109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                while (mServerBlocking) {
30209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                    wait(1000);
30309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                    if (mCallback != null && !msgSent) {
30409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                        mCallback.sendMessageDelayed(mCallback
30509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                                .obtainMessage(BluetoothOppObexSession.MSG_CONNECT_TIMEOUT),
30609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                                BluetoothOppObexSession.SESSION_TIMEOUT);
30709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                        msgSent = true;
30809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                        if (Constants.LOGVV) {
30909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                            Log.v(TAG, "MSG_CONNECT_TIMEOUT sent");
31009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                        }
31109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                    }
31209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                }
31309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            } catch (InterruptedException e) {
31409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                if (Constants.LOGVV) {
31509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                    Log.v(TAG, "Interrupted in onPut blocking");
31609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                }
31709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            }
31809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        }
31909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        if (Constants.LOGV) {
32009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            Log.v(TAG, "Server unblocked ");
32109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        }
322df7415da0e510ab8e4b73831a5ade38306982fe1Tao Liejun        if (mCallback != null && msgSent) {
3236769b59d715ea98bd72eafcfea9acd2714a887daTao Liejun            mCallback.removeMessages(BluetoothOppObexSession.MSG_CONNECT_TIMEOUT);
3246769b59d715ea98bd72eafcfea9acd2714a887daTao Liejun        }
32509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
32609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        /* we should have mInfo now */
32709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
32809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        /*
32909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly         * TODO check if this mInfo match the one that we insert before server
33009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly         * blocking? just to make sure no error happens
33109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly         */
33209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        if (mInfo.mId != mLocalShareInfoId) {
33309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            Log.e(TAG, "Unexpected error!");
33409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        }
33509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        mAccepted = mInfo.mConfirm;
33609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
33709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        if (Constants.LOGVV) {
33809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            Log.v(TAG, "after confirm: userAccepted=" + mAccepted);
33909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        }
34009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        int status = BluetoothShare.STATUS_SUCCESS;
34109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
34209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        if (mAccepted == BluetoothShare.USER_CONFIRMATION_CONFIRMED
343df7415da0e510ab8e4b73831a5ade38306982fe1Tao Liejun                || mAccepted == BluetoothShare.USER_CONFIRMATION_AUTO_CONFIRMED) {
34409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            /* Confirm or auto-confirm */
34509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
34609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            if (mFileInfo.mFileName == null) {
34709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                status = mFileInfo.mStatus;
34809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                /* TODO need to check if this line is correct */
34909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                mInfo.mStatus = mFileInfo.mStatus;
35009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                Constants.updateShareStatus(mContext, mInfo.mId, status);
35109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                obexResponse = ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
35209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
35309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            }
35409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
35509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            if (mFileInfo.mFileName != null) {
35609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
35709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                ContentValues updateValues = new ContentValues();
35809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                contentUri = Uri.parse(BluetoothShare.CONTENT_URI + "/" + mInfo.mId);
35909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                updateValues.put(BluetoothShare._DATA, mFileInfo.mFileName);
36009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                updateValues.put(BluetoothShare.STATUS, BluetoothShare.STATUS_RUNNING);
36109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                mContext.getContentResolver().update(contentUri, updateValues, null, null);
36209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
36309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                status = receiveFile(mFileInfo, op);
36409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                /*
36509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                 * TODO map status to obex response code
36609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                 */
36709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                if (status != BluetoothShare.STATUS_SUCCESS) {
36809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                    obexResponse = ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
36909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                }
37009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                Constants.updateShareStatus(mContext, mInfo.mId, status);
37109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            }
37209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
37309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            if (status == BluetoothShare.STATUS_SUCCESS) {
37409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                Message msg = Message.obtain(mCallback, BluetoothOppObexSession.MSG_SHARE_COMPLETE);
37509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                msg.obj = mInfo;
37609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                msg.sendToTarget();
37709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            } else {
37809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                Message msg = Message.obtain(mCallback, BluetoothOppObexSession.MSG_SESSION_ERROR);
37909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                msg.obj = mInfo;
38009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                msg.sendToTarget();
38109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            }
38209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        } else if (mAccepted == BluetoothShare.USER_CONFIRMATION_DENIED
38309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                || mAccepted == BluetoothShare.USER_CONFIRMATION_TIMEOUT) {
38409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            /* user actively deny the inbound transfer */
38509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            /*
38609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly             * Note There is a question: what's next if user deny the first obj?
38709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly             * Option 1 :continue prompt for next objects
38809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly             * Option 2 :reject next objects and finish the session
38909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly             * Now we take option 2:
39009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly             */
39109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            if (Constants.LOGVV) {
39209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                Log.v(TAG, "request forbidden, indicate interrupted");
39309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            }
39409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            status = BluetoothShare.STATUS_FORBIDDEN;
39509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            Constants.updateShareStatus(mContext, mInfo.mId, status);
39609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            obexResponse = ResponseCodes.OBEX_HTTP_FORBIDDEN;
39709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            Message msg = Message.obtain(mCallback);
39809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            /* TODO check which message should be sent */
39909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            msg.what = BluetoothOppObexSession.MSG_SHARE_INTERRUPTED;
40009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            msg.obj = mInfo;
40109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            msg.sendToTarget();
40209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        }
40309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        return obexResponse;
40409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    }
40509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
40609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    private int receiveFile(BluetoothOppReceiveFileInfo fileInfo, Operation op) {
40709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        /*
40809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly         * implement receive file
40909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly         */
41009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        int status = -1;
41109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        BufferedOutputStream bos = null;
41209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
41309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        InputStream is = null;
41409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        boolean error = false;
41509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        try {
41609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            is = op.openInputStream();
41709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        } catch (IOException e1) {
41809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            Log.e(TAG, "Error when openInputStream");
41909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            status = BluetoothShare.STATUS_OBEX_DATA_ERROR;
42009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            error = true;
42109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        }
42209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
42309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        Uri contentUri = Uri.parse(BluetoothShare.CONTENT_URI + "/" + mInfo.mId);
42409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
42509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        if (!error) {
42609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            ContentValues updateValues = new ContentValues();
42709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            updateValues.put(BluetoothShare._DATA, fileInfo.mFileName);
42809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            mContext.getContentResolver().update(contentUri, updateValues, null, null);
42909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        }
43009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
43109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        int position = 0;
43209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        if (!error) {
43309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            File f = new File(fileInfo.mFileName);
43409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            try {
43509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                bos = new BufferedOutputStream(new FileOutputStream(f), 0x10000);
43609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            } catch (FileNotFoundException e1) {
43709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                Log.e(TAG, "Error when open file " + f.toString());
43809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                status = BluetoothShare.STATUS_FILE_ERROR;
43909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                error = true;
44009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            }
44109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        }
44209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
44309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        if (!error) {
44409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            int outputBufferSize = op.getMaxPacketSize();
44509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            byte[] b = new byte[outputBufferSize];
44609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            int readLength = 0;
44709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            long timestamp;
44809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            try {
44909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                while ((!mInterrupted) && (position != fileInfo.mLength)) {
45009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
45109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                    if (Constants.LOGVV) {
45209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                        timestamp = System.currentTimeMillis();
45309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                    }
45409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
45509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                    readLength = is.read(b);
45609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
45709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                    if (readLength == -1) {
45809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                        if (Constants.LOGV) {
45909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                            Log.v(TAG, "Receive file reached stream end at position" + position);
46009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                        }
46109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                        break;
46209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                    }
46309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
46409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                    bos.write(b, 0, readLength);
46509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                    position += readLength;
46609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
46709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                    if (Constants.USE_EMULATOR_DEBUG) {
46809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                        synchronized (this) {
46909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                            try {
47009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                                wait(300);
47109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                            } catch (InterruptedException e) {
47209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                                status = BluetoothShare.STATUS_CANCELED;
47309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                                mInterrupted = true;
47409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                                if (Constants.LOGVV) {
47509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                                    Log.v(TAG, "ReceiveFile interrupted when receive file "
47609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                                            + fileInfo.mFileName + " at " + position + " of "
47709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                                            + position);
47809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                                }
47909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                                Constants.updateShareStatus(mContext, mInfo.mId, status);
48009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                            }
48109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                        }
48209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                    }
48309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
48409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                    if (Constants.LOGVV) {
48509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                        Log.v(TAG, "Receive file position = " + position + " readLength "
48609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                                + readLength + " bytes took "
48709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                                + (System.currentTimeMillis() - timestamp) + " ms");
48809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                    }
48909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
49009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                    ContentValues updateValues = new ContentValues();
49109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                    updateValues.put(BluetoothShare.CURRENT_BYTES, position);
49209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                    mContext.getContentResolver().update(contentUri, updateValues, null, null);
49309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                }
49409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            } catch (IOException e1) {
49509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                Log.e(TAG, "Error when receiving file");
49609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                status = BluetoothShare.STATUS_OBEX_DATA_ERROR;
49709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                error = true;
49809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            }
49909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        }
50009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
50109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        if (mInterrupted) {
50209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            if (Constants.LOGV) {
50309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                Log.v(TAG, "receiving file interrupted by user.");
50409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            }
50509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            status = BluetoothShare.STATUS_CANCELED;
50609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        } else {
50709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            if (position == fileInfo.mLength) {
50809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                if (Constants.LOGV) {
50909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                    Log.v(TAG, "Receiving file completed for " + fileInfo.mFileName);
51009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                }
51109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                status = BluetoothShare.STATUS_SUCCESS;
51209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            } else {
51309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                if (Constants.LOGV) {
51409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                    Log.v(TAG, "Reading file failed at " + position + " of " + fileInfo.mLength);
51509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                }
51609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                if (status == -1) {
51709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                    status = BluetoothShare.STATUS_UNKNOWN_ERROR;
51809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                }
51909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            }
52009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        }
52109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
52209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        Constants.updateShareStatus(mContext, mInfo.mId, status);
52309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        if (bos != null) {
52409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            try {
52509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                bos.close();
52609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            } catch (IOException e) {
52709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                Log.e(TAG, "Error when closing stream after send");
52809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            }
52909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        }
53009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        return status;
53109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    }
53209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
53309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    private BluetoothOppReceiveFileInfo processShareInfo() {
53409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        if (Constants.LOGV) {
53509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            Log.v(TAG, "processShareInfo() " + mInfo.mId);
53609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        }
53709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        BluetoothOppReceiveFileInfo fileInfo = BluetoothOppReceiveFileInfo.generateFileInfo(
53809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                mContext, mInfo.mId);
53909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        if (Constants.LOGVV) {
54009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            Log.v(TAG, "Generate BluetoothOppReceiveFileInfo:");
54109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            Log.v(TAG, "filename  :" + fileInfo.mFileName);
54209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            Log.v(TAG, "length    :" + fileInfo.mLength);
54309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            Log.v(TAG, "status    :" + fileInfo.mStatus);
54409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        }
54509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        return fileInfo;
54609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    }
54709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
54809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    @Override
54909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    public int onConnect(HeaderSet request, HeaderSet reply) {
55009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
55109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        if (Constants.LOGV) {
55209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            Log.v(TAG, "onConnect");
55309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        }
55409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        if (Constants.LOGVV) {
55509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            logHeader(request);
55609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        }
55709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
55809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        mTimestamp = System.currentTimeMillis();
55909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        return ResponseCodes.OBEX_HTTP_OK;
56009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    }
56109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
56209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    @Override
56309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    public void onDisconnect(HeaderSet req, HeaderSet resp) {
56409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
56509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        if (Constants.LOGV) {
56609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            Log.v(TAG, "onDisconnect");
56709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        }
56809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        resp.responseCode = ResponseCodes.OBEX_HTTP_OK;
56909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        /* onDisconnect could happen even before start() where mCallback is set */
57009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        if (mCallback != null) {
57109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            Message msg = Message.obtain(mCallback);
57209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            msg.what = BluetoothOppObexSession.MSG_SESSION_COMPLETE;
57309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            msg.obj = mInfo;
57409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            msg.sendToTarget();
57509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        }
57609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    }
57709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
57809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    @Override
57909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    public void onClose() {
58009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    }
58109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
58209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    private void logHeader(HeaderSet hs) {
58309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        Log.v(TAG, "Dumping HeaderSet " + hs.toString());
58409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        try {
58509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
58609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            Log.v(TAG, "COUNT : " + hs.getHeader(HeaderSet.COUNT));
58709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            Log.v(TAG, "NAME : " + hs.getHeader(HeaderSet.NAME));
58809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            Log.v(TAG, "TYPE : " + hs.getHeader(HeaderSet.TYPE));
58909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            Log.v(TAG, "LENGTH : " + hs.getHeader(HeaderSet.LENGTH));
59009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            Log.v(TAG, "TIME_ISO_8601 : " + hs.getHeader(HeaderSet.TIME_ISO_8601));
59109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            Log.v(TAG, "TIME_4_BYTE : " + hs.getHeader(HeaderSet.TIME_4_BYTE));
59209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            Log.v(TAG, "DESCRIPTION : " + hs.getHeader(HeaderSet.DESCRIPTION));
59309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            Log.v(TAG, "TARGET : " + hs.getHeader(HeaderSet.TARGET));
59409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            Log.v(TAG, "HTTP : " + hs.getHeader(HeaderSet.HTTP));
59509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            Log.v(TAG, "WHO : " + hs.getHeader(HeaderSet.WHO));
59609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            Log.v(TAG, "OBJECT_CLASS : " + hs.getHeader(HeaderSet.OBJECT_CLASS));
59709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            Log.v(TAG, "APPLICATION_PARAMETER : " + hs.getHeader(HeaderSet.APPLICATION_PARAMETER));
59809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        } catch (IOException e) {
59909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            Log.e(TAG, "dump HeaderSet error " + e);
60009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        }
60109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
60209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    }
60309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly}
604