📄 l2caplink.java
字号:
}
}
int resultCode = 0x0000;
short localChannelID = (short)(localCID + 2);
if (localCID == -1) {
resultCode = 0x0004; //Error: No Resources
}
else {
L2CAPChannel channel = sddb.resolveAndCreateL2CAPChannel(psm, this, localChannelID, remoteCID);
if (channel == null) {
resultCode = 0x0002; //Error: No Psm
}
else {
channels[localCID] = channel;
channel.channelState = L2CAPChannel.CLOSED;
channel.l2capSender = this;
channel.localChannelID = localChannelID;
channel.remoteChannelID = remoteCID;
}
}
byte[] connectionResponse = {
0x03, packet[1], 0x08, 0x00, (byte)(localChannelID & 0xff), (byte)((localChannelID >> 8) & 0xff),
packet[6], packet[7], (byte)((resultCode) & 0xff), (byte)((resultCode >> 8) & 0xff), 0x00, 0x00
};
try {
Debug.println(3, "L2CAP: Sending Connection Response Signal to " + remoteAddress);
sendL2CAPPacket(remoteAddress, (short)0x0001, connectionResponse);
}
catch (IOException e) { this.close(); }
}
private void receive_L2CAP_Connection_Response(byte[] packet) {
Debug.println(3, "L2CAP: Received Connection Response Signal from " + remoteAddress);
short remoteCID = (short)(((short)packet[5] & 0xff) << 8 | ((short)packet[4] & 0xff));
short localCID = (short)(((short)packet[7] & 0xff) << 8 | ((short)packet[6] & 0xff));
short result = (short)(((short)packet[9] & 0xff) << 8 | ((short)packet[8] & 0xff));
short status = (short)(((short)packet[11] & 0xff) << 8 | ((short)packet[10] & 0xff));
L2CAPChannel channel = channels[localCID - 2];
if (channel != null) {
channel.remoteChannelID = remoteCID;
channel.channelState = L2CAPChannel.CONFIG;
try { send_L2CAP_Configuration_Request(channel); }
catch (IOException e) { this.close(); }
}
}
private void receive_L2CAP_Configuration_Request(byte[] packet) {
Debug.println(3, "L2CAP: Received Configuration Request Signal from " + remoteAddress);
short localCID = (short)(((short)packet[5] & 0xff) << 8 | ((short)packet[4] & 0xff));
short optionLength = (short)((((short)packet[3] & 0xff) << 8 | ((short)packet[2] & 0xff)) - 4);
//TODO parse configuration options in a propper way... this implementation just acknowledges but never challenges the proposed authentication
L2CAPChannel channel = channels[localCID - 2];
if (channel != null) {
byte[] configurationResponse = new byte[/*optionLength+*/ 10];
configurationResponse[0] = 0x05;
configurationResponse[1] = packet[1];
configurationResponse[2] = (byte)((/*optionLength+*/ 6) & 0xff);
configurationResponse[3] = (byte)(((/*optionLength+*/ 6) >> 8) & 0xff);
configurationResponse[4] = (byte)((channel.remoteChannelID) & 0xff);
configurationResponse[5] = (byte)((channel.remoteChannelID >> 8) & 0xff);
configurationResponse[6] = 0x00; //no flags
configurationResponse[7] = 0x00; //no flags
configurationResponse[8] = 0x00; //result ok
configurationResponse[9] = 0x00; //result ok
//System.arraycopy(packet,8,configurationResponse,10,optionLength);
//configurationResponse[12]=0x00;//new mtu
//configurationResponse[13]=(byte) 0xff;//new mtu
try {
Debug.println(3, "L2CAP: Sending Cofiguration Response Signal to " + remoteAddress);
sendL2CAPPacket(remoteAddress, (short)0x0001, configurationResponse);
if (channel.channelState == L2CAPChannel.CLOSED) {
channel.channelState = L2CAPChannel.CONFIG;
send_L2CAP_Configuration_Request(channel);
}
}
catch (IOException e) { this.close(); }
}
}
private void receive_L2CAP_Configuration_Response(byte[] packet) {
Debug.println(3, "L2CAP: Received Configuration Response Signal from " + remoteAddress);
short localCID = (short)(((short)packet[5] & 0xff) << 8 | ((short)packet[4] & 0xff));
short result = (short)(((short)packet[9] & 0xff) << 8 | ((short)packet[8] & 0xff));
if (result == 0) {
L2CAPChannel channel = channels[localCID - 2];
if (channel != null) {
if (channel.channelState == L2CAPChannel.CLOSED) channel.channelState = L2CAPChannel.CONFIG;
else if (channel.channelState == L2CAPChannel.CONFIG) channel.channelState = L2CAPChannel.OPEN;
}
}
//TODO Z: add possible challenge to the response... this implementation just nods and agrees...
}
private void receive_L2CAP_Disconnection_Request(byte[] packet) {
Debug.println(3, "L2CAP: Received Disconnection Request Signal from " + remoteAddress);
short localCID = (short)(((short)packet[5] & 0xff) << 8 | ((short)packet[4] & 0xff));
//short remoteCID=(short)(((short) packet[7] & 0xff) << 8 | ((short) packet[6]& 0xff));
L2CAPChannel channel = channels[localCID - 2];
channels[localCID - 2] = null;
if (channel != null) { channel.wasDisconnected(); }
byte[] disconnectionResponse = { 0x07, packet[1], 0x04, 0x00, packet[4], packet[5], packet[6], packet[7] };
try {
Debug.println(3, "L2CAP: Sending Disconnection Response Signal to " + remoteAddress);
sendL2CAPPacket(remoteAddress, (short)0x0001, disconnectionResponse);
}
catch (IOException e) { wasDisconnected(); }
}
private void receive_L2CAP_Disconnection_Response(byte[] packet) {
Debug.println(3, "L2CAP: Received Disconnection Response Signal from " + remoteAddress);
short localCID = (short)(((short)packet[8] & 0xff) << 8 | ((short)packet[7] & 0xff));
L2CAPChannel channel = channels[localCID - 2];
channels[localCID - 2] = null;
if (channel != null) { channel.wasDisconnected(); }
}
private void receive_L2CAP_Echo_Request(byte[] packet) {
Debug.println(3, "L2CAP: Received Echo Request Signal from " + remoteAddress);
}
private void receive_L2CAP_Echo_Response(byte[] packet) {
Debug.println(3, "L2CAP: Received Echo Response Signal from " + remoteAddress);
}
private void receive_L2CAP_Information_Request(byte[] packet) {
Debug.println(3, "L2CAP: Received Information Request Signal from " + remoteAddress);
}
private void receive_L2CAP_Information_Response(byte[] packet) {
Debug.println(3, "L2CAP: Received Information Response Signal from " + remoteAddress);
}
private void receive_L2CAP_Unknown_Signalling_Packet(byte[] packet) {
System.err.println("L2CAP: Received unknown signalling packet:" + Debug.printByteArray(packet));
send_L2CAP_Command_Reject();
}
public void send_L2CAP_Command_Reject()
{ Debug.println(3, "L2CAP: Sending Command Rejected Signal from " + remoteAddress); }
public void send_L2CAP_Connection_Request(L2CAPChannel channel, short psm) throws HCIException, IOException {
channel.channelState = L2CAPChannel.CLOSED;
for (short i = 0; i < channels.length; i++) {
if (channels[i] == null) {
channels[i] = channel;
channel.channelState = L2CAPChannel.CLOSED;
channel.remoteAddress = remoteAddress;
channel.l2capSender = this;
channel.localChannelID = (short)(i + 2);
break;
}
}
if (channel.localChannelID == -1)
throw new HCIException("L2CAP Connection Request failed. No Local Channels available.");
byte[] connectionRequest = {
0x02, identifierCount++, 0x04, //fixed length
0x00, //fixed length
(byte)((psm) & 0xff), (byte)((psm >> 8) & 0xff), (byte)((channel.localChannelID) & 0xff),
(byte)((channel.localChannelID >> 8) & 0xff)
};
Debug.println(3, "L2CAP: Sending Connection Request Signal to " + remoteAddress);
sendL2CAPPacket(remoteAddress, (short)0x0001, connectionRequest);
}
public void send_L2CAP_Configuration_Request(L2CAPChannel channel) throws IOException {
byte[] configurationRequest = {
0x04, identifierCount++, 0x04, //fixed length
0x00, //fixed length
(byte)((channel.remoteChannelID) & 0xff), (byte)((channel.remoteChannelID >> 8) & 0xff), 0x00, //no flags
0x00
};
Debug.println(3, "L2CAP: Sending Configuration Request Signal to " + remoteAddress);
sendL2CAPPacket(remoteAddress, (short)0x0001, configurationRequest);
}
public void send_L2CAP_Disconnection_Request(L2CAPChannel channel) throws IOException {
byte[] disconnectionRequest = {
0x06, identifierCount++, 0x04, 0x00, (byte)((channel.remoteChannelID) & 0xff), (byte)((channel.remoteChannelID >> 8) & 0xff),
(byte)((channel.localChannelID) & 0xff), (byte)((channel.localChannelID >> 8) & 0xff)
};
channel.channelState = L2CAPChannel.CLOSED;
Debug.println(3, "L2CAP: Sending Disconnection Request Signal to " + remoteAddress);
sendL2CAPPacket(remoteAddress, (short)0x0001, disconnectionRequest);
}
public void send_L2CAP_Echo_Request(L2CAPChannel channel) { //Debug.println("L2CAP: Sending Echo Request to
// ("+remoteAddress+"): "+Debug.printByteArray(packet));
//TODO send echo request
}
public void send_L2CAP_Information_Request(L2CAPChannel channel) { //Debug.println("L2CAP: Sending Information Request to
// ("+remoteAddress+"): "+Debug.printByteArray(packet));
//TODO send information request
}
/**
* @param psm
* @return
*/
public void connectL2CAPChannel(L2CAPChannel channel, short psm) throws HCIException {
try { send_L2CAP_Connection_Request(channel, psm); }
catch (IOException e) { throw new HCIException("L2CAPChannel Connection Request Failed."); }
int timeout = 0;
while (channel.channelState != L2CAPChannel.OPEN) {
try {
Thread.sleep(1000);
timeout++;
}
catch (InterruptedException e) { }
if (timeout > 50) throw new HCIException("L2CAPChannel Connection Request timed out.");
}
}
/** @see org.javabluetooth.stack.l2cap.L2CAPSender#closeL2CAPChannel(org.javabluetooth.stack.l2cap.L2CAPChannel) */
public void closeL2CAPChannel(L2CAPChannel channel) {
try { send_L2CAP_Disconnection_Request(channel); }
catch (IOException e) { }
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -