📄 bluetoothstack.java
字号:
/*
* (c) Copyright 2003 Christian Lorenz ALL RIGHTS RESERVED.
*
* This file is part of the JavaBluetooth Stack.
*
* The JavaBluetooth Stack is free software; you can redistribute it
* and/or modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* The JavaBluetooth Stack is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* Created on Jun 12, 2003
* by Christian Lorenz
*
*/
package org.javabluetooth.stack;
import javax.bluetooth.DiscoveryAgent;
import javax.bluetooth.RemoteDevice;
import org.javabluetooth.stack.hci.HCIException;
import org.javabluetooth.stack.l2cap.L2CAPChannel;
/**
* This abstract class provides the upper half of the bluetooth stack.
* It provides implementations for HCI Commands, common entry
* points for HCIEvents. This abstract class expects all implementing
* methods to connect to a <code>HCITransport</code>. This may
* happen locally (<code>BluetoothLocal</code>) or remotely (<code>BluetoothTCPClient</code> and
* <code>BluetoothTCPServer</code>. The HCI Command methods provided by this class are called from
* this <code>javax.bluetooth</code> implementation.
* @see javax.bluetooth
* @see org.javabluetooth.stack.BluetoothLocal
* @see org.javabluetooth.stack.BluetoothTCPClient
* @see org.javabluetooth.stack.hci.HCIReceiver
* @see org.javabluetooth.stack.hci.HCITransport
* @author Christian Lorenz
*/
public abstract class BluetoothStack {
private static final byte CMD_PKT = 0x01;
private static BluetoothStack bluetoothStack;
private DiscoveryAgent discoveryAgent;
protected abstract byte[] send_HCI_Command_Packet(byte[] cmdPacket) throws HCIException;
public abstract void connectL2CAPChannel(L2CAPChannel channel, RemoteDevice remoteDevice, short psm) throws HCIException;
public abstract void registerL2CAPService(L2CAPChannel channel, short serviceUUID, short browseUUID,
byte[] serviceRecord) throws HCIException;
/**
* Sets which instance of <code>BluetoothStack</code> should be returned by
* <code>BluetoothStack.getBluetoothStack()</code>. This allows easy switching
* between <code>BluetoothLocal</code> and <code>BluetoothTCPClient</code>.
* @param bluetoothStack
*/
public static void init(BluetoothStack bluetoothStack) { BluetoothStack.bluetoothStack = bluetoothStack; }
/**
* Returns the <code>BluetoothStack</code> instance set by <code>BluetoothStach.init(BluetoothStack)</code>. This
* method is used by <code>javax.bluetooth.LocalDevice</code>
* to determine which implementation of <code>BluetoothStack</code> to use.
* @return BluetoothStack instance set by BluetoothStack.init(BluetoothStack)
* @throws HCIException if no BluetoothStack was initialized via BluetoothStack.init(BluetoothStack)
*/
public static BluetoothStack getBluetoothStack() throws HCIException {
if (bluetoothStack == null) throw new HCIException("BluetoothStack not initalized. ");
return bluetoothStack;
}
/**
* Registers a <code>DiscoveryListener</code> which will be notified of all Inquiry Results.
* This will usually be the <code>DiscoveryAgent</code>.
* @see javax.bluetooth.DiscoveryListener
* @see javax.bluetooth.DiscoveryAgent
* @param listener
*/
public void registerDiscoveryAgent(DiscoveryAgent discoveryAgent) { this.discoveryAgent = discoveryAgent; }
/**
* Receives an HCI Inquiry Complete Packet. If a <code>javax.bluetooth.DiscoveryAgent</code>
* was registered, the packed will be passed along.
* @see javax.bluetooth.DiscoveryAgent
* @param eventPacket
*/
protected void receive_HCI_Event_Inquiry_Complete(byte[] eventPacket) { //Debug.println("Inquiry Complete");
if (discoveryAgent != null) { discoveryAgent.receive_HCI_Event_Inquiry_Complete(eventPacket); }
}
/**
* Receives an Inquiry Result Event Packet. If a <code>javax.bluetooth.DiscoveryAgent</code>
* is registered the packet will be passed along.
* @see javax.bluetooth.DiscoveryAgent
* @param eventPacket
*/
protected void receive_HCI_Event_Inquiry_Result(byte[] eventPacket) { //Debug.println("Inquiry Result");
if (discoveryAgent != null) { discoveryAgent.receive_HCI_Event_Inquiry_Result(eventPacket); }
}
/**
* Receives a Remote Name Request Event Packet. If a <code>javax.bluetooth.DiscoveryAgent</code> was registered the
* packet will be passed along.
* @see javax.bluetooth.DiscoveryAgent
* @param eventPacket
*/
protected void receive_HCI_Event_Remote_Name_Request_Complete(byte[] eventPacket) { //Debug.println("Remote Name Request Complete");
if (discoveryAgent != null) { discoveryAgent.receive_HCI_Event_Remote_Name_Request_Complete(eventPacket); }
}
/**
* This command will cause the Bluetooth device to enter Inquiry Mode. Inquiry
* Mode is used to discover other nearby Bluetooth devices. When the Inquiry
* process is completed, the Host Controller will send an Inquiry Complete event
* to the Host indicating that the Inquiry has finished. When a Bluetooth device responds to the Inquiry message, an
* Inquiry Result event will occur to notify the Host of the discovery.
* For details see Page 561 of the Bluetooth Core Specification Version 1.1
* @param accessCode is the LAP from which the inquiry access code should be derived.
* Valid values are DiscoveryAgent.GIAC and DiscoveryAgent.LIAC.
* @param inquiryLength specifies the total duration of the Inquiry Mode. When this time expires, Inquiry will be halted.
* @param numResponses specifies the number of responses that can be received before the Inquiry is halted.
* @return 0x00 if the command succeeded. 0x01-0xFF if the command failed. See Table 6.1 on page 766
* for list of Error Codes.
* @throws org.javabluetooth.stack.bluetooth.hci.HCIException
*/
public byte send_HCI_LC_Inquiry(int accessCode, int inquiryLength, byte numResponses) throws HCIException {
byte time = (byte)(inquiryLength / 1.28);
if (inquiryLength > 61.44) time = (byte)0xff;
byte[] data = {
CMD_PKT, 0x01, 0x04, 0x05, (byte)((accessCode) & 0xff), (byte)((accessCode >> 8) & 0xff), (byte)((accessCode >> 16) & 0xff), time, numResponses
};
byte[] resultData = send_HCI_Command_Packet(data);
return resultData[3];
}
/**
* This command will cause the Bluetooth device to stop the current Inquiry if the Bluetooth device is in Inquiry Mode.
* For details see Page 563 of the Bluetooth Core Specification Version 1.1
* @return 0x00 if the command succeeded. 0x01-0xFF if the command failed. See Table 6.1 on page 766
* for list of Error Codes.
* @throws org.javabluetooth.stack.bluetooth.hci.HCIException
*/
public byte send_HCI_LC_Inquiry_Cancel() throws HCIException {
byte[] data = { CMD_PKT, 0x02, 0x04, 0x00 };
byte[] resultData = send_HCI_Command_Packet(data);
return resultData[3];
}
/**
* The Remote_Name_Request command is used to obtain the user-friendly name of another Bluetooth device.
* The user-friendly name is used to enable the user to distinguish one Bluetooth device from another. The BD_ADDR command
* parameter is used to identify the device for which the user-friendly
* name is to be obtained. The Page_Scan_Repetition_Mode and Page_Scan_Mode command parameters specify the page scan modes
* supported by the remote device with the BD_ADDR. This is the information that was acquired during the inquiry process.
* The Clock_Offset parameter is the difference between its own clock and the clock of the remote device with BD_ADDR.
* Only bits 2 through 16 of the difference are used and they are mapped to this parameter as bits 0 through 14
* respectively. A Clock_Offset_Valid_Flag, located in bit 15 of the Clock_Offset command parameter, is used to indicate
* if the Clock Offset is valid or not. Note: if no connection exists between the local device and the device
* corresponding to the BD_ADDR, a temporary link layer connection will
* be established to obtain the name of the remote device.
* For details see Page 590 of the Bluetooth Core Specification Version 1.1
* @param bd_addr BD_ADDR for the device whose name is requested.
* @param pageScanRepetitionMode 0x00 = R0 0x01 = R1 0x02 = R2
* @param pageScanMode 0x00 Mandatory Page Scan Mode. 0x01 Optional Page Scan Mode I.
* 0x02 Optional Page Scan Mode II. 0x03 Optional Page Scan Mode III.
* @param clockOffset Bit 14.0 Bit 16.2 of CLKslave-CLKmaster.
* Bit 15 Clock_Offset_Valid_Flag ( Invalid Clock Offfset = 0 Valid Clock Offset = 1 )
* @return 0x00 if the command succeeded. 0x01-0xFF if the command failed. See Table 6.1 on page 766
* for list of Error Codes.
* @throws org.javabluetooth.stack.bluetooth.hci.HCIException
*/
public byte send_HCI_LC_Remote_Name_Request(long bd_addr, byte pageScanRepetitionMode, byte pageScanMode,
short clockOffset) throws HCIException {
byte[] data = {
CMD_PKT, 0x19, 0x04, 0x0a, (byte)((bd_addr) & 0xff), (byte)((bd_addr >> 8) & 0xff), (byte)((bd_addr >> 16) & 0xff),
(byte)((bd_addr >> 24) & 0xff), (byte)((bd_addr >> 32) & 0xff), (byte)((bd_addr >> 40) & 0xff),
pageScanRepetitionMode, pageScanMode, (byte)((clockOffset) & 0xff), (byte)((clockOffset >> 8) & 0xff)
};
byte[] resultData = send_HCI_Command_Packet(data);
return resultData[3];
}
/**
* Clears all Event Filters. For details see Page 623 of the Bluetooth Core Specification Version 1.1
* @return 0x00 if the command succeeded. 0x01-0xFF if the command failed. See Table 6.1 on page 766
* for list of Error Codes.
* @throws org.javabluetooth.stack.bluetooth.hci.HCIException
*/
public byte send_HCI_HC_Set_Event_Filter_Clear() throws HCIException {
byte[] data = { CMD_PKT, 0x05, 0x0c, 0x01, 0x00 };
byte[] resultData = send_HCI_Command_Packet(data);
return resultData[6];
}
/**
* Adds Connection Setup Filters for Connections from all devices.
* @param condition 0x01 Do NOT Auto accept the connection. (Auto accept is off)
* 0x02 Do Auto accept the connection with role switch disabled. (Auto accept is on).
* 0x03 Do Auto accept the connection with role switch enabled. (Auto accept is on). Note: When auto accepting an incoming
* SCO connection, no role switch will be performed. The value 0x03 of the Auto_Accept_Flag will then get the same
* effect as if the value had been 0x02. For details see Page 623 of the Bluetooth Core Specification Version 1.1
* @return 0x00 if the command succeeded. 0x01-0xFF if the command failed. See Table 6.1 on page 766
* for list of Error Codes.
* @throws org.javabluetooth.stack.bluetooth.hci.HCIException
*/
public byte send_HCI_HC_Write_Event_Filter_Connection_Setup(byte condition) throws HCIException {
byte[] data = { CMD_PKT, 0x05, 0x0c, 0x03, 002, 0x00, condition };
byte[] resultData = send_HCI_Command_Packet(data);
return resultData[6];
}
/**
* Adds Connection Setup Filters for Connections from a device with a specific BD_ADDR.
* @param bd_addr specifies the Bluetooth Address of the device to be filtered.
* @param condition 0x01 Do NOT Auto accept the connection. (Auto accept is off)
* 0x02 Do Auto accept the connection with role switch disabled. (Auto accept is on).
* 0x03 Do Auto accept the connection with role switch enabled. (Auto accept is on). Note: When auto accepting an incoming
* SCO connection, no role switch will be performed. The value 0x03 of the Auto_Accept_Flag will then get the same
* effect as if the value had been 0x02. For details see Page 623 of the Bluetooth Core Specification Version 1.1
* @return 0x00 if the command succeeded. 0x01-0xFF if the command failed. See Table 6.1 on page 766
* for list of Error Codes.
* @throws org.javabluetooth.stack.bluetooth.hci.HCIException
*/
public byte send_HCI_HC_Write_Event_Filter_Connection_Setup(long bd_addr, byte condition) throws HCIException {
byte[] data = {
CMD_PKT, 0x05, 0x0c, 0x09, 0x02, 0x02, (byte)((bd_addr) & 0xff), (byte)((bd_addr >> 8) & 0xff), (byte)((bd_addr >> 16) & 0xff),
(byte)((bd_addr >> 24) & 0xff), (byte)((bd_addr >> 32) & 0xff), (byte)((bd_addr >> 40) & 0xff), condition
};
byte[] resultData = send_HCI_Command_Packet(data);
return resultData[6];
}
/**
* Adds Connection Setup Filters for Connections from devices with a specific Class Of Device.
* @param classOfDevice specifies the Class Of Device of the devices to be filtered.
* @param mask Bit Mask used to determine which bits of the Class of Device parameter
* are `don't care'. Zero-value bits in the mask indicate the `don't care' bits of the Class of Device.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -