name: "BluetoothL2capSources",
srcs: [
"l2cap_layer.cc",
+ "classic_fixed_channel.cc",
+ "classic_fixed_channel_manager.cc",
+ "classic_fixed_channel_service.cc",
],
}
constexpr Cid kFirstDynamicChannel = kLastFixedChannel + 1;
constexpr Cid kLastDynamicChannel = (uint16_t)(0xffff + 1);
+constexpr Cid kClassicSignallingCid = 1;
+constexpr Cid kConnectionlessCid = 2;
+constexpr Cid kLeAttributeCid = 4;
+constexpr Cid kLeSignallingCid = 5;
+constexpr Cid kSmpCid = 6;
+constexpr Cid kSmpBrCid = 7;
+
} // namespace l2cap
} // namespace bluetooth
--- /dev/null
+/*
+ * Copyright 2019 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.
+ */
+
+#include "l2cap/classic_fixed_channel.h"
+
+namespace bluetooth {
+namespace l2cap {
+void ClassicFixedChannel::RegisterOnCloseCallback(os::Handler* handler, OnCloseCallback callback) {}
+void ClassicFixedChannel::Acquire() {}
+void ClassicFixedChannel::Release() {}
+common::BidiQueueEnd<packet::PacketView<packet::kLittleEndian>, packet::BasePacketBuilder>*
+ClassicFixedChannel::GetQueueUpEnd() const {
+ return nullptr;
+}
+} // namespace l2cap
+} // namespace bluetooth
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright 2019 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.
+ */
+#pragma once
+
+#include "common/bidi_queue.h"
+#include "common/callback.h"
+#include "os/handler.h"
+#include "packet/base_packet_builder.h"
+#include "packet/packet_view.h"
+
+namespace bluetooth {
+namespace l2cap {
+
+/**
+ * L2CAP fixed channel object. When a new object is created, it must be
+ * acquired through calling {@link FixedChannel#Acquire()} within X seconds.
+ * Otherwise, {@link FixeChannel#Release()} will be called automatically.
+ *
+ */
+class ClassicFixedChannel {
+ public:
+ using OnCloseCallback = common::Callback<void()>;
+
+ /**
+ * Register close callback. If close callback is registered, when a channel is closed, the channel's resource will
+ * only be freed after on_close callback is invoked. Otherwise, if no on_close callback is registered, the channel's
+ * resource will be freed immediately after closing.
+ *
+ * @param on_close The callback invoked upon channel closing.
+ */
+ void RegisterOnCloseCallback(os::Handler* handler, OnCloseCallback on_close);
+
+ /**
+ * Indicate that this Fixed Channel is being used. This will prevent ACL
+ * connection from being disconnected.
+ */
+ void Acquire();
+
+ /**
+ * Indicate that this Fixed Channel is no longer being used. ACL connection
+ * will be disconnected after X seconds if no other DynamicChannel is connected
+ * or no other Fixed Channel is using this ACL connection. However a module can
+ * still receive data on this channel as long as it remains open.
+ */
+ void Release();
+
+ /**
+ * This method will retrieve the data channel queue to send and receive packets.
+ *
+ * {@see BidiQueueEnd}
+ *
+ * @return The upper end of a bi-directional queue.
+ */
+ common::BidiQueueEnd<packet::PacketView<packet::kLittleEndian>, packet::BasePacketBuilder>* GetQueueUpEnd() const;
+};
+
+} // namespace l2cap
+} // namespace bluetooth
--- /dev/null
+/*
+ * Copyright 2019 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.
+ */
+
+#include "l2cap/classic_fixed_channel_manager.h"
+
+namespace bluetooth {
+namespace l2cap {
+
+bool ClassicFixedChannelManager::ConnectServices(common::Address device,
+ OnConnectionFailureCallback on_connection_failure,
+ os::Handler* handler) {
+ return false;
+}
+
+bool ClassicFixedChannelManager::RegisterService(Cid cid, const SecurityPolicy& security_policy,
+ OnRegistrationCompleteCallback on_registration_complete,
+ OnConnectionOpenCallback on_connection_open, os::Handler* handler) {
+ return true;
+}
+
+} // namespace l2cap
+} // namespace bluetooth
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright 2019 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.
+ */
+#pragma once
+
+#include <string>
+
+#include "common/address.h"
+#include "l2cap/cid.h"
+#include "l2cap/classic_fixed_channel.h"
+#include "l2cap/classic_fixed_channel_service.h"
+#include "l2cap/security_policy.h"
+#include "os/handler.h"
+
+namespace bluetooth {
+namespace l2cap {
+
+class ClassicFixedChannelManager {
+ /**
+ * OnConnectionFailureCallback(std::string failure_reason);
+ */
+ using OnConnectionFailureCallback = common::OnceCallback<void(std::string)>;
+
+ /**
+ * OnConnectionOpenCallback(ClassicFixedChannel channel);
+ */
+ using OnConnectionOpenCallback = common::OnceCallback<void(ClassicFixedChannel)>;
+
+ enum RegistrationResult { SUCCESS, FAIL };
+
+ /**
+ * OnRegistrationFailureCallback(RegistrationResult result, ClassicFixedChannelService service);
+ */
+ using OnRegistrationCompleteCallback = common::OnceCallback<void(RegistrationResult, ClassicFixedChannelService)>;
+
+ /**
+ * Connect to ALL fixed channels on a remote device
+ *
+ * - This method is asynchronous
+ * - When false is returned, the connection fails immediately
+ * - When true is returned, method caller should wait for on_fail_callback or on_open_callback registered through
+ * RegisterService() API.
+ * - If an ACL connection does not exist, this method will create an ACL connection. As a result, on_open_callback
+ * supplied through RegisterService() will be triggered to provide the actual ClassicFixedChannel objects
+ * - If fixed channel on a remote device is already reported as connected via on_open_callback and has been acquired
+ * via ClassicFixedChannel#Acquire() API, it won't be reported again
+ * - If no service is registered, this call is a no-op and on on_fail_callback will be triggered
+ *
+ * NOTE:
+ * This call will initiate an effort to connect all fixed channel services on a remote device.
+ * Due to the connectionless nature of fixed channels, all fixed channels will be connected together.
+ * If a fixed channel service does not need a particular fixed channel. It should release the received
+ * channel immediately after receiving on_open_callback via ClassicFixedChannel#Release()
+ *
+ * A module calling ConnectServices() must have called RegisterService() before.
+ * The callback will come back from on_open_callback in the service that is registered
+ *
+ * @param device: Remote device to make this connection.
+ * @param on_fail_callback: A callback to indicate connection failure along with a status code.
+ * @param handler: The handler context in which to execute the @callback parameters.
+ *
+ * Returns: true if connection was able to be initiated, false otherwise.
+ */
+ bool ConnectServices(common::Address device, OnConnectionFailureCallback on_fail_callback, os::Handler* handler);
+
+ /**
+ * Register a service to receive incoming connections bound to a specific channel.
+ *
+ * - This method is asynchronous.
+ * - When false is returned, the registration fails immediately.
+ * - When true is returned, method caller should wait for on_service_registered callback that contains a
+ * ClassicFixedChannelService object. The registered service can be managed from that object.
+ * - If a CID is already registered or some other error happens,
+ * - After a service is registered, any classic ACL connection will create a ClassicFixedChannel object that is
+ * delivered through on_open_callback
+ * - on_open_callback, if any, must be triggered after on_service_registered callback
+ *
+ * @param cid: Classic cid used to receive incoming connections
+ * @param security_policy: The security policy used for the connection.
+ * @param on_registration_complete: A callback to indicate the service setup has completed. If the return status is
+ * not SUCCESS, it means service is not registered due to reasons like CID already take
+ * @param on_open_callback: A callback to indicate success of a connection initiated from a remote device.
+ * @param handler: The handler context in which to execute the @callback parameter.
+ */
+ bool RegisterService(Cid cid, const SecurityPolicy& security_policy,
+ OnRegistrationCompleteCallback on_registration_complete,
+ OnConnectionOpenCallback on_connection_open, os::Handler* handler);
+};
+
+} // namespace l2cap
+} // namespace bluetooth
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright 2019 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.
+ */
+
+#include "l2cap/classic_fixed_channel_service.h"
+
+namespace bluetooth {
+namespace l2cap {
+
+void ClassicFixedChannelService::Unregister(OnUnregisteredCallback on_unregistered) {}
+
+} // namespace l2cap
+} // namespace bluetooth
\ No newline at end of file
--- /dev/null
+
+/*
+ * Copyright 2019 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.
+ */
+#pragma once
+
+#include "common/address.h"
+#include "common/callback.h"
+
+namespace bluetooth {
+namespace l2cap {
+
+class ClassicFixedChannelService {
+ public:
+ using OnUnregisteredCallback = common::OnceCallback<void()>;
+
+ /**
+ * Unregister a service from L2CAP module. This operation cannot fail.
+ * All channels opened for this service will be invalidated.
+ *
+ * @param on_unregistered will be triggered when unregistration is complete
+ */
+ void Unregister(OnUnregisteredCallback on_unregistered);
+};
+
+} // namespace l2cap
+} // namespace bluetooth
\ No newline at end of file
constexpr SignalId kInitialSignalId = SignalId(0x80);
-constexpr Cid kClassicSignallingCid = 1;
-constexpr Cid kConnectionlessCid = 2;
-constexpr Cid kLeAttributeCid = 4;
-constexpr Cid kLeSignallingCid = 5;
-constexpr Cid kSmpCid = 6;
-constexpr Cid kSmpBrCid = 7;
-
// Time after last channels closes before link is torn down
constexpr auto kLinkDisconnectTimeout = std::chrono::seconds(30);
void L2capLayer::Stop() {}
+std::unique_ptr<ClassicFixedChannelManager> L2capLayer::GetClassicFixedChannelManager() {
+ return std::make_unique<ClassicFixedChannelManager>();
+}
+
+struct L2capLayer::impl {};
+
} // namespace l2cap
} // namespace bluetooth
\ No newline at end of file
#include <memory>
+#include "l2cap/classic_fixed_channel_manager.h"
#include "module.h"
namespace bluetooth {
void Stop() override;
+ /**
+ * Get the api to the classic channel l2cap module
+ */
+ std::unique_ptr<ClassicFixedChannelManager> GetClassicFixedChannelManager();
+
private:
+ struct impl;
+ std::unique_ptr<impl> impl_;
DISALLOW_COPY_AND_ASSIGN(L2capLayer);
};
--- /dev/null
+/*
+ * Copyright 2019 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.
+ */
+#pragma once
+
+namespace bluetooth {
+namespace l2cap {
+
+class SecurityPolicy {};
+
+} // namespace l2cap
+} // namespace bluetooth
\ No newline at end of file