Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3a71bfb6 authored by Ashwini Munigala's avatar Ashwini Munigala Committed by Linux Build Service Account
Browse files

OBEX: Implementation of MAP and PBAP client role on Bluedroid.

Implementation changes to support MAP client and PBAP client
role on Bluedroid stack.

Change-Id: Ic75e0bea10b8420aef928d868cc25acd769d5620
CRs-fixed: 530274
(cherry picked from commit 8a9036e632092e7311e5009cb96a016b52bbacca)
(cherry picked from commit 1e4719192c82f89d0b2dba67ec99c72c77060f9a)
(cherry picked from commit abb73fd0ef2dd64c44944cff99dc81c1fd368d36)
parent 280665f0
Loading
Loading
Loading
Loading
+23 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2013 The Linux Foundation. All rights reserved
 * Not a Contribution.
 * Copyright (C) 2009 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
@@ -308,6 +310,11 @@ public final class BluetoothDevice implements Parcelable {
    public static final String ACTION_UUID =
            "android.bluetooth.device.action.UUID";

    /** @hide */
    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
    public static final String ACTION_MAS_INSTANCE =
            "org.codeaurora.bluetooth.device.action.MAS_INSTANCE";

    /**
     * Broadcast Action: Indicates a failure to retrieve the name of a remote
     * device.
@@ -514,6 +521,10 @@ public final class BluetoothDevice implements Parcelable {
     */
    public static final String EXTRA_UUID = "android.bluetooth.device.extra.UUID";

    /** @hide */
    public static final String EXTRA_MAS_INSTANCE =
        "org.codeaurora.bluetooth.device.extra.MAS_INSTANCE";

    /**
     * Lazy initialization. Guaranteed final after first object constructed, or
     * getService() called.
@@ -960,6 +971,18 @@ public final class BluetoothDevice implements Parcelable {
            return false;
    }

     /** @hide */
     public boolean fetchMasInstances() {
         if (sService == null) {
             Log.e(TAG, "BT not enabled. Cannot query remote device for MAS instances");
             return false;
         }
         try {
             return sService.fetchRemoteMasInstances(this);
         } catch (RemoteException e) {Log.e(TAG, "", e);}
         return false;
     }

    /** @hide */
    public int getServiceChannel(ParcelUuid uuid) {
        //TODO(BT)
+116 −0
Original line number Diff line number Diff line
/*
 * Copyright (c) 2013, The Linux Foundation. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *        * Redistributions of source code must retain the above copyright
 *            notice, this list of conditions and the following disclaimer.
 *        * Redistributions in binary form must reproduce the above copyright
 *            notice, this list of conditions and the following disclaimer in the
 *            documentation and/or other materials provided with the distribution.
 *        * Neither the name of The Linux Foundation nor
 *            the names of its contributors may be used to endorse or promote
 *            products derived from this software without specific prior written
 *            permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NON-INFRINGEMENT ARE DISCLAIMED.    IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */


package android.bluetooth;

import android.os.Parcel;
import android.os.Parcelable;

/** @hide */
public final class BluetoothMasInstance implements Parcelable {
    private final int mId;
    private final String mName;
    private final int mChannel;
    private final int mMsgTypes;

    public BluetoothMasInstance(int id, String name, int channel, int msgTypes) {
        mId = id;
        mName = name;
        mChannel = channel;
        mMsgTypes = msgTypes;
    }

    @Override
    public boolean equals(Object o) {
        if (o instanceof BluetoothMasInstance) {
            return mId == ((BluetoothMasInstance)o).mId;
        }
        return false;
    }

    @Override
    public int hashCode() {
        return mId + (mChannel << 8) + (mMsgTypes << 16);
    }

    @Override
    public String toString() {
        return Integer.toString(mId) + ":" + mName + ":" + mChannel + ":" +
                Integer.toHexString(mMsgTypes);
    }

    public int describeContents() {
        return 0;
    }

    public static final Parcelable.Creator<BluetoothMasInstance> CREATOR =
            new Parcelable.Creator<BluetoothMasInstance>() {
        public BluetoothMasInstance createFromParcel(Parcel in) {
            return new BluetoothMasInstance(in.readInt(), in.readString(),
                    in.readInt(), in.readInt());
        }
        public BluetoothMasInstance[] newArray(int size) {
            return new BluetoothMasInstance[size];
        }
    };

    public void writeToParcel(Parcel out, int flags) {
        out.writeInt(mId);
        out.writeString(mName);
        out.writeInt(mChannel);
        out.writeInt(mMsgTypes);
    }

    public static final class MessageType {
        public static final int EMAIL    = 0x01;
        public static final int SMS_GSM  = 0x02;
        public static final int SMS_CDMA = 0x04;
        public static final int MMS      = 0x08;
    }

    public int getId() {
        return mId;
    }

    public String getName() {
        return mName;
    }

    public int getChannel() {
        return mChannel;
    }

    public int getMsgTypes() {
        return mMsgTypes;
    }

    public boolean msgSupported(int msg) {
        return (mMsgTypes & msg) != 0;
    }
}
+3 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2013 The Linux Foundation. All rights reserved
 * Not a Contribution.
 * Copyright (C) 2008, The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
@@ -68,6 +70,7 @@ interface IBluetooth
    int getRemoteClass(in BluetoothDevice device);
    ParcelUuid[] getRemoteUuids(in BluetoothDevice device);
    boolean fetchRemoteUuids(in BluetoothDevice device);
    boolean fetchRemoteMasInstances(in BluetoothDevice device);

    boolean setPin(in BluetoothDevice device, boolean accept, int len, in byte[] pinCode);
    boolean setPasskey(in BluetoothDevice device, boolean accept, int len, in byte[]
+40 −9
Original line number Diff line number Diff line
@@ -67,6 +67,8 @@ public final class ClientOperation implements Operation, BaseStream {

    private boolean mGetOperation;

    private boolean mGetFinalFlag;

    private HeaderSet mRequestHeader;

    private HeaderSet mReplyHeader;
@@ -91,6 +93,7 @@ public final class ClientOperation implements Operation, BaseStream {
        mOperationDone = false;
        mMaxPacketSize = maxSize;
        mGetOperation = type;
        mGetFinalFlag = false;

        mPrivateInputOpen = false;
        mPrivateOutputOpen = false;
@@ -131,6 +134,15 @@ public final class ClientOperation implements Operation, BaseStream {
        }
    }

    /**
     * Allows to set flag which will force GET to be always sent as single packet request with
     * final flag set. This is to improve compatibility with some profiles, i.e. PBAP which
     * require requests to be sent this way.
     */
    public void setGetFinalFlag(boolean flag) {
        mGetFinalFlag = flag;
    }

    /**
     * Sends an ABORT message to the server. By calling this method, the
     * corresponding input and output streams will be closed along with this
@@ -552,6 +564,7 @@ public final class ClientOperation implements Operation, BaseStream {

        if (mGetOperation) {
            if (!mOperationDone) {
                if (!mGetFinalFlag) {
                    mReplyHeader.responseCode = ResponseCodes.OBEX_HTTP_CONTINUE;
                    while ((more) && (mReplyHeader.responseCode == ResponseCodes.OBEX_HTTP_CONTINUE)) {
                        more = sendRequest(0x03);
@@ -561,6 +574,15 @@ public final class ClientOperation implements Operation, BaseStream {
                        mParent.sendRequest(0x83, null, mReplyHeader, mPrivateInput);
                    }
                    if (mReplyHeader.responseCode != ResponseCodes.OBEX_HTTP_CONTINUE) {
                        mOperationDone = true;
                    }
                } else {
                    more = sendRequest(0x83);

                    if (more) {
                        throw new IOException("FINAL_GET forced but data did not fit into single packet!");
                    }

                    mOperationDone = true;
                }
            }
@@ -614,7 +636,16 @@ public final class ClientOperation implements Operation, BaseStream {
                if (mPrivateInput == null) {
                    mPrivateInput = new PrivateInputStream(this);
                }

                if (!mGetFinalFlag) {
                    sendRequest(0x03);
                } else {
                    sendRequest(0x83);

                    if (mReplyHeader.responseCode != ResponseCodes.OBEX_HTTP_CONTINUE) {
                        mOperationDone = true;
                    }
                }
                return true;

            } else if (mOperationDone) {
+24 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2013 The Linux Foundation. All rights reserved
 * Not a Contribution.
 * Copyright (c) 2008-2009, Motorola, Inc.
 *
 * All rights reserved.
@@ -181,6 +183,8 @@ public final class HeaderSet {

    private String mName; // null terminated Unicode text string

    private boolean mEmptyName;

    private String mType; // null terminated ASCII text string

    private Long mLength; // 4 byte unsigend integer
@@ -234,6 +238,25 @@ public final class HeaderSet {
        mRandom = new SecureRandom();
    }

    /**
     * Sets flag for special "value" of NAME header which should be empty. This
     * is not the same as NAME header with empty string in which case it will
     * have length of 5 bytes. It should be 3 bytes with only header id and
     * length field.
     */
    public void setEmptyNameHeader() {
        mName = null;
        mEmptyName = true;
    }

    /**
     * Gets flag for special "value" of NAME header which should be empty. See
     * above.
     */
    public boolean getEmptyNameHeader() {
        return mEmptyName;
    }

    /**
     * Sets the value of the header identifier to the value provided. The type
     * of object must correspond to the Java type defined in the description of
@@ -269,6 +292,7 @@ public final class HeaderSet {
                if ((headerValue != null) && (!(headerValue instanceof String))) {
                    throw new IllegalArgumentException("Name must be a String");
                }
                mEmptyName = false;
                mName = (String)headerValue;
                break;
            case TYPE:
Loading