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

Commit 313a2167 authored by Jaikumar Ganesh's avatar Jaikumar Ganesh Committed by Matthew Xie
Browse files

Delete various Bluetooth files for stack integration.

parent d1cdfb3e
Loading
Loading
Loading
Loading
+0 −94
Original line number Diff line number Diff line
/*
 * Copyright (C) 2007 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.bluetooth;

import android.bluetooth.AtCommandResult;

/**
 * Handler Interface for {@link AtParser}.<p>
 * @hide
 */
public abstract class AtCommandHandler {

    /**
     * Handle Basic commands "ATA".<p>
     * These are single letter commands such as ATA and ATD. Anything following
     * the single letter command ('A' and 'D' respectively) will be passed as
     * 'arg'.<p>
     * For example, "ATDT1234" would result in the call
     * handleBasicCommand("T1234").<p>
     * @param arg Everything following the basic command character.
     * @return    The result of this command.
     */
    public AtCommandResult handleBasicCommand(String arg) {
        return new AtCommandResult(AtCommandResult.ERROR);
    }

    /**
     * Handle Actions command "AT+FOO".<p>
     * Action commands are part of the Extended command syntax, and are
     * typically used to signal an action on "FOO".<p>
     * @return The result of this command.
     */
    public AtCommandResult handleActionCommand() {
        return new AtCommandResult(AtCommandResult.ERROR);
    }

    /**
     * Handle Read command "AT+FOO?".<p>
     * Read commands are part of the Extended command syntax, and are
     * typically used to read the value of "FOO".<p>
     * @return The result of this command.
     */
    public AtCommandResult handleReadCommand() {
        return new AtCommandResult(AtCommandResult.ERROR);
    }

    /**
     * Handle Set command "AT+FOO=...".<p>
     * Set commands are part of the Extended command syntax, and are
     * typically used to set the value of "FOO". Multiple arguments can be
     * sent.<p>
     * AT+FOO=[<arg1>[,<arg2>[,...]]]<p>
     * Each argument will be either numeric (Integer) or String.
     * handleSetCommand is passed a generic Object[] array in which each
     * element will be an Integer (if it can be parsed with parseInt()) or
     * String.<p>
     * Missing arguments ",," are set to empty Strings.<p>
     * @param args Array of String and/or Integer's. There will always be at
     *             least one element in this array.
     * @return     The result of this command.
     */
    // Typically used to set this parameter
    public AtCommandResult handleSetCommand(Object[] args) {
        return new AtCommandResult(AtCommandResult.ERROR);
    }

    /**
     * Handle Test command "AT+FOO=?".<p>
     * Test commands are part of the Extended command syntax, and are typically
     * used to request an indication of the range of legal values that "FOO"
     * can take.<p>
     * By default we return an OK result, to indicate that this command is at
     * least recognized.<p>
     * @return The result of this command.
     */
    public AtCommandResult handleTestCommand() {
        return new AtCommandResult(AtCommandResult.OK);
    }

}
+0 −115
Original line number Diff line number Diff line
/*
 * Copyright (C) 2007 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.bluetooth;

/**
 * The result of execution of a single AT command.<p>
 *
 *
 * This class can represent the final response to an AT command line, and also
 * intermediate responses to a single command within a chained AT command
 * line.<p>
 *
 * The actual responses that are intended to be send in reply to the AT command
 * line are stored in a string array. The final response is stored as an
 * int enum, converted to a string when toString() is called. Only a single
 * final response is sent from multiple commands chained into a single command
 * line.<p>
 * @hide
 */
public class AtCommandResult {
    // Result code enumerations
    public static final int OK = 0;
    public static final int ERROR = 1;
    public static final int UNSOLICITED = 2;

    private static final String OK_STRING = "OK";
    private static final String ERROR_STRING = "ERROR";

    private int mResultCode;  // Result code
    private StringBuilder mResponse; // Response with CRLF line breaks

    /**
     * Construct a new AtCommandResult with given result code, and an empty
     * response array.
     * @param resultCode One of OK, ERROR or UNSOLICITED.
     */
    public AtCommandResult(int resultCode) {
        mResultCode = resultCode;
        mResponse = new StringBuilder();
    }

    /**
     * Construct a new AtCommandResult with result code OK, and the specified
     * single line response.
     * @param response The single line response.
     */
    public AtCommandResult(String response) {
        this(OK);
        addResponse(response);
    }

    public int getResultCode() {
        return mResultCode;
    }

    /**
     * Add another line to the response.
     */
    public void addResponse(String response) {
        appendWithCrlf(mResponse, response);
    }

    /**
     * Add the given result into this AtCommandResult object.<p>
     * Used to combine results from multiple commands in a single command line
     * (command chaining).
     * @param result The AtCommandResult to add to this result.
     */
    public void addResult(AtCommandResult result) {
        if (result != null) {
            appendWithCrlf(mResponse, result.mResponse.toString());
            mResultCode = result.mResultCode;
        }
    }

    /**
     * Generate the string response ready to send
     */
    public String toString() {
        StringBuilder result = new StringBuilder(mResponse.toString());
        switch (mResultCode) {
        case OK:
            appendWithCrlf(result, OK_STRING);
            break;
        case ERROR:
            appendWithCrlf(result, ERROR_STRING);
            break;
        }
        return result.toString();
    }

    /** Append a string to a string builder, joining with a double
     * CRLF. Used to create multi-line AT command replies
     */
    public static void appendWithCrlf(StringBuilder str1, String str2) {
        if (str1.length() > 0 && str2.length() > 0) {
            str1.append("\r\n\r\n");
        }
        str1.append(str2);
    }
};
+0 −367
Original line number Diff line number Diff line
/*
 * Copyright (C) 2007 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.bluetooth;

import java.util.*;

/**
 * An AT (Hayes command) Parser based on (a subset of) the ITU-T V.250 standard.
 * <p>
 *
 * Conformant with the subset of V.250 required for implementation of the
 * Bluetooth Headset and Handsfree Profiles, as per Bluetooth SIP
 * specifications. Also implements some V.250 features not required by
 * Bluetooth - such as chained commands.<p>
 *
 * Command handlers are registered with an AtParser object. These handlers are
 * invoked when command lines are processed by AtParser's process() method.<p>
 *
 * The AtParser object accepts a new command line to parse via its process()
 * method. It breaks each command line into one or more commands. Each command
 * is parsed for name, type, and (optional) arguments, and an appropriate
 * external handler method is called through the AtCommandHandler interface.
 *
 * The command types are<ul>
 * <li>Basic Command. For example "ATDT1234567890". Basic command names are a
 * single character (e.g. "D"), and everything following this character is
 * passed to the handler as a string argument (e.g. "T1234567890").
 * <li>Action Command. For example "AT+CIMI". The command name is "CIMI", and
 * there are no arguments for action commands.
 * <li>Read Command. For example "AT+VGM?". The command name is "VGM", and there
 * are no arguments for get commands.
 * <li>Set Command. For example "AT+VGM=14". The command name is "VGM", and
 * there is a single integer argument in this case. In the general case then
 * can be zero or more arguments (comma delimited) each of integer or string
 * form.
 * <li>Test Command. For example "AT+VGM=?. No arguments.
 * </ul>
 *
 * In V.250 the last four command types are known as Extended Commands, and
 * they are used heavily in Bluetooth.<p>
 *
 * Basic commands cannot be chained in this implementation. For Bluetooth
 * headset/handsfree use this is acceptable, because they only use the basic
 * commands ATA and ATD, which are not allowed to be chained. For general V.250
 * use we would need to improve this class to allow Basic command chaining -
 * however it's tricky to get right because there is no delimiter for Basic
 * command chaining.<p>
 *
 * Extended commands can be chained. For example:<p>
 * AT+VGM?;+VGM=14;+CIMI<p>
 * This is equivalent to:<p>
 * AT+VGM?
 * AT+VGM=14
 * AT+CIMI
 * Except that only one final result code is return (although several
 * intermediate responses may be returned), and as soon as one command in the
 * chain fails the rest are abandoned.<p>
 *
 * Handlers are registered by there command name via register(Char c, ...) or
 * register(String s, ...). Handlers for Basic command should be registered by
 * the basic command character, and handlers for Extended commands should be
 * registered by String.<p>
 *
 * Refer to:<ul>
 * <li>ITU-T Recommendation V.250
 * <li>ETSI TS 127.007  (AT Command set for User Equipment, 3GPP TS 27.007)
 * <li>Bluetooth Headset Profile Spec (K6)
 * <li>Bluetooth Handsfree Profile Spec (HFP 1.5)
 * </ul>
 * @hide
 */
public class AtParser {

    // Extended command type enumeration, only used internally
    private static final int TYPE_ACTION = 0;   // AT+FOO
    private static final int TYPE_READ = 1;     // AT+FOO?
    private static final int TYPE_SET = 2;      // AT+FOO=
    private static final int TYPE_TEST = 3;     // AT+FOO=?

    private HashMap<String, AtCommandHandler> mExtHandlers;
    private HashMap<Character, AtCommandHandler> mBasicHandlers;

    private String mLastInput;  // for "A/" (repeat last command) support

    /**
     * Create a new AtParser.<p>
     * No handlers are registered.
     */
    public AtParser() {
        mBasicHandlers = new HashMap<Character, AtCommandHandler>();
        mExtHandlers = new HashMap<String, AtCommandHandler>();
        mLastInput = "";
    }

    /**
     * Register a Basic command handler.<p>
     * Basic command handlers are later called via their
     * <code>handleBasicCommand(String args)</code> method.
     * @param  command Command name - a single character
     * @param  handler Handler to register
     */
    public void register(Character command, AtCommandHandler handler) {
        mBasicHandlers.put(command, handler);
    }

    /**
     * Register an Extended command handler.<p>
     * Extended command handlers are later called via:<ul>
     * <li><code>handleActionCommand()</code>
     * <li><code>handleGetCommand()</code>
     * <li><code>handleSetCommand()</code>
     * <li><code>handleTestCommand()</code>
     * </ul>
     * Only one method will be called for each command processed.
     * @param  command Command name - can be multiple characters
     * @param  handler Handler to register
     */
    public void register(String command, AtCommandHandler handler) {
        mExtHandlers.put(command, handler);
    }


    /**
     * Strip input of whitespace and force Uppercase - except sections inside
     * quotes. Also fixes unmatched quotes (by appending a quote). Double
     * quotes " are the only quotes allowed by V.250
     */
    static private String clean(String input) {
        StringBuilder out = new StringBuilder(input.length());

        for (int i = 0; i < input.length(); i++) {
            char c = input.charAt(i);
            if (c == '"') {
                int j = input.indexOf('"', i + 1 );  // search for closing "
                if (j == -1) {  // unmatched ", insert one.
                    out.append(input.substring(i, input.length()));
                    out.append('"');
                    break;
                }
                out.append(input.substring(i, j + 1));
                i = j;
            } else if (c != ' ') {
                out.append(Character.toUpperCase(c));
            }
        }

        return out.toString();
    }

    static private boolean isAtoZ(char c) {
        return (c >= 'A' && c <= 'Z');
    }

    /**
     * Find a character ch, ignoring quoted sections.
     * Return input.length() if not found.
     */
    static private int findChar(char ch, String input, int fromIndex) {
        for (int i = fromIndex; i < input.length(); i++) {
            char c = input.charAt(i);
            if (c == '"') {
                i = input.indexOf('"', i + 1);
                if (i == -1) {
                    return input.length();
                }
            } else if (c == ch) {
                return i;
            }
        }
        return input.length();
    }

    /**
     * Break an argument string into individual arguments (comma delimited).
     * Integer arguments are turned into Integer objects. Otherwise a String
     * object is used.
     */
    static private Object[] generateArgs(String input) {
        int i = 0;
        int j;
        ArrayList<Object> out = new ArrayList<Object>();
        while (i <= input.length()) {
            j = findChar(',', input, i);

            String arg = input.substring(i, j);
            try {
                out.add(new Integer(arg));
            } catch (NumberFormatException e) {
                out.add(arg);
            }

            i = j + 1; // move past comma
        }
        return out.toArray();
    }

    /**
     * Return the index of the end of character after the last character in
     * the extended command name. Uses the V.250 spec for allowed command
     * names.
     */
    static private int findEndExtendedName(String input, int index) {
        for (int i = index; i < input.length(); i++) {
            char c = input.charAt(i);

            // V.250 defines the following chars as legal extended command
            // names
            if (isAtoZ(c)) continue;
            if (c >= '0' && c <= '9') continue;
            switch (c) {
            case '!':
            case '%':
            case '-':
            case '.':
            case '/':
            case ':':
            case '_':
                continue;
            default:
                return i;
            }
        }
        return input.length();
    }

    /**
     * Processes an incoming AT command line.<p>
     * This method will invoke zero or one command handler methods for each
     * command in the command line.<p>
     * @param raw_input The AT input, without EOL delimiter (e.g. <CR>).
     * @return          Result object for this command line. This can be
     *                  converted to a String[] response with toStrings().
     */
    public AtCommandResult process(String raw_input) {
        String input = clean(raw_input);

        // Handle "A/" (repeat previous line)
        if (input.regionMatches(0, "A/", 0, 2)) {
            input = new String(mLastInput);
        } else {
            mLastInput = new String(input);
        }

        // Handle empty line - no response necessary
        if (input.equals("")) {
            // Return []
            return new AtCommandResult(AtCommandResult.UNSOLICITED);
        }

        // Anything else deserves an error
        if (!input.regionMatches(0, "AT", 0, 2)) {
            // Return ["ERROR"]
            return new AtCommandResult(AtCommandResult.ERROR);
        }

        // Ok we have a command that starts with AT. Process it
        int index = 2;
        AtCommandResult result =
                new AtCommandResult(AtCommandResult.UNSOLICITED);
        while (index < input.length()) {
            char c = input.charAt(index);

            if (isAtoZ(c)) {
                // Option 1: Basic Command
                // Pass the rest of the line as is to the handler. Do not
                // look for any more commands on this line.
                String args = input.substring(index + 1);
                if (mBasicHandlers.containsKey((Character)c)) {
                    result.addResult(mBasicHandlers.get(
                            (Character)c).handleBasicCommand(args));
                    return result;
                } else {
                    // no handler
                    result.addResult(
                            new AtCommandResult(AtCommandResult.ERROR));
                    return result;
                }
                // control never reaches here
            }

            if (c == '+') {
                // Option 2: Extended Command
                // Search for first non-name character. Short-circuit if
                // we don't handle this command name.
                int i = findEndExtendedName(input, index + 1);
                String commandName = input.substring(index, i);
                if (!mExtHandlers.containsKey(commandName)) {
                    // no handler
                    result.addResult(
                            new AtCommandResult(AtCommandResult.ERROR));
                    return result;
                }
                AtCommandHandler handler = mExtHandlers.get(commandName);

                // Search for end of this command - this is usually the end of
                // line
                int endIndex = findChar(';', input, index);

                // Determine what type of command this is.
                // Default to TYPE_ACTION if we can't find anything else
                // obvious.
                int type;

                if (i >= endIndex) {
                    type = TYPE_ACTION;
                } else if (input.charAt(i) == '?') {
                    type = TYPE_READ;
                } else if (input.charAt(i) == '=') {
                    if (i + 1 < endIndex) {
                        if (input.charAt(i + 1) == '?') {
                            type = TYPE_TEST;
                        } else {
                            type = TYPE_SET;
                        }
                    } else {
                        type = TYPE_SET;
                    }
                } else {
                    type = TYPE_ACTION;
                }

                // Call this command. Short-circuit as soon as a command fails
                switch (type) {
                case TYPE_ACTION:
                    result.addResult(handler.handleActionCommand());
                    break;
                case TYPE_READ:
                    result.addResult(handler.handleReadCommand());
                    break;
                case TYPE_TEST:
                    result.addResult(handler.handleTestCommand());
                    break;
                case TYPE_SET:
                    Object[] args =
                            generateArgs(input.substring(i + 1, endIndex));
                    result.addResult(handler.handleSetCommand(args));
                    break;
                }
                if (result.getResultCode() != AtCommandResult.OK) {
                    return result;   // short-circuit
                }

                index = endIndex;
            } else {
                // Can't tell if this is a basic or extended command.
                // Push forwards and hope we hit something.
                index++;
            }
        }
        // Finished processing (and all results were ok)
        return result;
    }
}
+2 −2
Original line number Diff line number Diff line
@@ -23,7 +23,6 @@ import android.os.IBinder;
import android.os.ParcelUuid;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.server.BluetoothA2dpService;
import android.util.Log;

import java.util.ArrayList;
@@ -112,7 +111,8 @@ public final class BluetoothA2dp implements BluetoothProfile {
     *
     */
    /*package*/ BluetoothA2dp(Context mContext, ServiceListener l) {
        IBinder b = ServiceManager.getService(BluetoothA2dpService.BLUETOOTH_A2DP_SERVICE);
        //TODO(BT): Fix this
        IBinder b = null;
        mServiceListener = l;
        mAdapter = BluetoothAdapter.getDefaultAdapter();
        if (b != null) {
+0 −1357

File deleted.

Preview size limit exceeded, changes collapsed.

Loading