⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 l2caplink.java

📁 蓝牙协议栈可是要钱的喔
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
            }
        }
        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 + -