MnsService.java revision b68b83c0463161ce65922ec606f12244446efab1
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.mapclient;
18
19import android.bluetooth.BluetoothDevice;
20import android.bluetooth.BluetoothServerSocket;
21import android.bluetooth.BluetoothSocket;
22import android.os.Handler;
23import android.util.Log;
24
25import com.android.bluetooth.BluetoothObexTransport;
26import com.android.bluetooth.IObexConnectionHandler;
27import com.android.bluetooth.ObexServerSockets;
28import com.android.bluetooth.sdp.SdpManager;
29
30import java.io.IOException;
31
32import javax.obex.ServerSession;
33
34class MnsService {
35    static final int MSG_EVENT = 1;
36    /* for Client */
37    static final int EVENT_REPORT = 1001;
38    private static final String TAG = "MnsService";
39    private static final Boolean DBG = MapClientService.DBG;
40    private static final Boolean VDBG = MapClientService.VDBG;
41    /* MAP version 1.1 */
42    private static final int MNS_VERSION = 0x0101;
43    /* MNS features: Notification Feature */
44    private static final int MNS_FEATURE_BITS = 0x0002;
45    /* these are shared across instances */
46    static private SocketAcceptor mAcceptThread = null;
47    static private Handler mSessionHandler = null;
48    static private BluetoothServerSocket mServerSocket = null;
49    static private ObexServerSockets mServerSockets = null;
50
51    static private MapClientService mContext;
52    private volatile boolean mShutdown = false;         // Used to interrupt socket accept thread
53
54    MnsService(MapClientService context) {
55        if (VDBG) Log.v(TAG, "MnsService()");
56        mContext = context;
57        mAcceptThread = new SocketAcceptor();
58        mServerSockets = ObexServerSockets.create(mAcceptThread);
59        SdpManager.getDefaultManager().createMapMnsRecord(
60                "MAP Message Notification Service", mServerSockets.getRfcommChannel(), -1,
61                MNS_VERSION, MNS_FEATURE_BITS);
62    }
63
64    void stop() {
65        if (VDBG) Log.v(TAG, "stop()");
66        mShutdown = true;
67        if (mServerSockets != null) {
68            mServerSockets.shutdown(false);
69            mServerSockets = null;
70        }
71    }
72
73
74    private class SocketAcceptor implements IObexConnectionHandler {
75
76        private boolean mInterrupted = false;
77
78        /**
79         * Called when an unrecoverable error occurred in an accept thread.
80         * Close down the server socket, and restart.
81         * TODO: Change to message, to call start in correct context.
82         */
83        @Override
84        public synchronized void onAcceptFailed() {
85            Log.e(TAG, "OnAcceptFailed");
86            mServerSockets = null; // Will cause a new to be created when calling start.
87            if (mShutdown) {
88                Log.e(TAG, "Failed to accept incomming connection - " + "shutdown");
89            }
90        }
91
92        @Override
93        public synchronized boolean onConnect(BluetoothDevice device, BluetoothSocket socket) {
94            if (DBG) Log.d(TAG, "onConnect" + device + " SOCKET: " + socket);
95            /* Signal to the service that we have received an incoming connection.*/
96            MnsObexServer srv = new MnsObexServer(
97                    mContext.mMceStateMachine, mServerSockets);
98            BluetoothObexTransport transport = new BluetoothObexTransport(socket);
99            try {
100                new ServerSession(transport, srv, null);
101                return true;
102            } catch (IOException e) {
103                Log.e(TAG, e.toString());
104                return false;
105            }
106        }
107    }
108}
109