Loading system/gd/cert/gd_cert_device.py +2 −0 Original line number Diff line number Diff line Loading @@ -79,3 +79,5 @@ class GdCertDevice(GdDeviceBase): self.hci.disconnection_stream = EventStream(self.hci.FetchDisconnection) self.hci.connection_failed_stream = EventStream(self.hci.FetchConnectionFailed) self.hci.acl_stream = EventStream(self.hci.FetchAclData) self.l2cap.packet_stream = EventStream(self.l2cap.FetchL2capData) self.l2cap.connection_complete_stream = EventStream(self.l2cap.FetchConnectionComplete) system/gd/cert/gd_device.py +2 −0 Original line number Diff line number Diff line Loading @@ -81,3 +81,5 @@ class GdDevice(GdDeviceBase): self.hci.connection_failed_stream = EventStream(self.hci.FetchConnectionFailed) self.hci.acl_stream = EventStream(self.hci.FetchAclData) self.hci_classic_security.command_complete_stream = EventStream(self.hci_classic_security.FetchCommandCompleteEvent) self.l2cap.packet_stream = EventStream(self.l2cap.FetchL2capData) self.l2cap.connection_complete_stream = EventStream(self.l2cap.FetchConnectionComplete) system/gd/hci/acl_manager.cc +0 −1 Original line number Diff line number Diff line Loading @@ -441,7 +441,6 @@ struct AclManager::impl { AclConnection::QueueUpEnd* get_acl_queue_end(uint16_t handle) { auto& connection = check_and_get_connection(handle); ASSERT_LOG(connection.disconnect_handler_ != nullptr, "No disconnect handler registered."); return connection.queue_->GetUpEnd(); } Loading system/gd/l2cap/cert/api.proto +13 −1 Original line number Diff line number Diff line Loading @@ -6,5 +6,17 @@ import "google/protobuf/empty.proto"; import "facade/common.proto"; service L2capModuleCert { rpc NoOp(google.protobuf.Empty) returns (google.protobuf.Empty) {} rpc SendL2capPacket(L2capPacket) returns (google.protobuf.Empty) {} rpc FetchL2capData(facade.EventStreamRequest) returns (stream L2capPacket) {} rpc FetchConnectionComplete(facade.EventStreamRequest) returns (stream ConnectionCompleteEvent) {} } message L2capPacket { facade.BluetoothAddress remote = 1; uint32 channel = 2; bytes payload = 3; } message ConnectionCompleteEvent { facade.BluetoothAddress remote = 1; } system/gd/l2cap/cert/cert.cc +100 −11 Original line number Diff line number Diff line Loading @@ -19,10 +19,13 @@ #include <cstdint> #include <memory> #include <mutex> #include <queue> #include <unordered_map> #include "common/blocking_queue.h" #include "grpc/grpc_event_stream.h" #include "hci/acl_manager.h" #include "hci/cert/cert.h" #include "l2cap/cert/api.grpc.pb.h" #include "l2cap/l2cap_layer.h" #include "l2cap/l2cap_packets.h" Loading @@ -44,31 +47,117 @@ using namespace facade; class L2capModuleCertService : public L2capModuleCert::Service { public: L2capModuleCertService(l2cap::L2capLayer* l2cap_layer, ::bluetooth::os::Handler* facade_handler) : l2cap_layer_(l2cap_layer), facade_handler_(facade_handler) { ASSERT(l2cap_layer_ != nullptr); ASSERT(facade_handler_ != nullptr); L2capModuleCertService(hci::AclManager* acl_manager, os::Handler* facade_handler) : handler_(facade_handler), acl_manager_(acl_manager) { ASSERT(handler_ != nullptr); acl_manager_->RegisterCallbacks(&acl_callbacks, handler_); } ::grpc::Status NoOp(::grpc::ServerContext* context, const ::google::protobuf::Empty* request, class ConnectionCompleteCallback : public grpc::GrpcEventStreamCallback<ConnectionCompleteEvent, ConnectionCompleteEvent> { public: void OnWriteResponse(ConnectionCompleteEvent* response, const ConnectionCompleteEvent& event) override { response->CopyFrom(event); } } connection_complete_callback_; ::bluetooth::grpc::GrpcEventStream<ConnectionCompleteEvent, ConnectionCompleteEvent> connection_complete_stream_{ &connection_complete_callback_}; ::grpc::Status FetchConnectionComplete( ::grpc::ServerContext* context, const ::bluetooth::facade::EventStreamRequest* request, ::grpc::ServerWriter<::bluetooth::l2cap::cert::ConnectionCompleteEvent>* writer) override { return connection_complete_stream_.HandleRequest(context, request, writer); } ::grpc::Status SendL2capPacket(::grpc::ServerContext* context, const ::bluetooth::l2cap::cert::L2capPacket* request, ::google::protobuf::Empty* response) override { std::unique_ptr<RawBuilder> packet = std::make_unique<RawBuilder>(); auto req_string = request->payload(); packet->AddOctets(std::vector<uint8_t>(req_string.begin(), req_string.end())); std::unique_ptr<BasicFrameBuilder> l2cap_builder = BasicFrameBuilder::Create(request->channel(), std::move(packet)); outgoing_packet_queue_.push(std::move(l2cap_builder)); if (outgoing_packet_queue_.size() == 1) { acl_connection_->GetAclQueueEnd()->RegisterEnqueue( handler_, common::Bind(&L2capModuleCertService::enqueue_packet_to_acl, common::Unretained(this))); } return ::grpc::Status::OK; } private: l2cap::L2capLayer* l2cap_layer_; ::bluetooth::os::Handler* facade_handler_; std::unique_ptr<packet::BasePacketBuilder> enqueue_packet_to_acl() { auto basic_frame_builder = std::move(outgoing_packet_queue_.front()); outgoing_packet_queue_.pop(); if (outgoing_packet_queue_.size() == 0) { acl_connection_->GetAclQueueEnd()->UnregisterEnqueue(); } return basic_frame_builder; } ::grpc::Status FetchL2capData(::grpc::ServerContext* context, const ::bluetooth::facade::EventStreamRequest* request, ::grpc::ServerWriter<L2capPacket>* writer) override { return l2cap_stream_.HandleRequest(context, request, writer); } class L2capStreamCallback : public ::bluetooth::grpc::GrpcEventStreamCallback<L2capPacket, L2capPacket> { public: void OnWriteResponse(L2capPacket* response, const L2capPacket& event) override { response->CopyFrom(event); } } l2cap_stream_callback_; ::bluetooth::grpc::GrpcEventStream<L2capPacket, L2capPacket> l2cap_stream_{&l2cap_stream_callback_}; void on_incoming_packet() { auto packet = acl_connection_->GetAclQueueEnd()->TryDequeue(); BasicFrameView basic_frame_view = BasicFrameView::Create(*packet); ASSERT(basic_frame_view.IsValid()); L2capPacket l2cap_packet; std::string data = std::string(packet->begin(), packet->end()); l2cap_packet.set_payload(data); l2cap_packet.set_channel(basic_frame_view.GetChannelId()); l2cap_stream_.OnIncomingEvent(l2cap_packet); } std::queue<std::unique_ptr<BasicFrameBuilder>> outgoing_packet_queue_; ::bluetooth::os::Handler* handler_; hci::AclManager* acl_manager_; std::unique_ptr<hci::AclConnection> acl_connection_; class AclCallbacks : public hci::ConnectionCallbacks { public: AclCallbacks(L2capModuleCertService* module) : module_(module) {} void OnConnectSuccess(std::unique_ptr<hci::AclConnection> connection) override { ConnectionCompleteEvent event; event.mutable_remote()->set_address(connection->GetAddress().ToString()); module_->connection_complete_stream_.OnIncomingEvent(event); module_->acl_connection_ = std::move(connection); module_->acl_connection_->RegisterDisconnectCallback(common::BindOnce([](hci::ErrorCode) {}), module_->handler_); module_->acl_connection_->GetAclQueueEnd()->RegisterDequeue( module_->handler_, common::Bind(&L2capModuleCertService::on_incoming_packet, common::Unretained(module_))); } void OnConnectFail(hci::Address address, hci::ErrorCode reason) override {} ~AclCallbacks() { module_->acl_connection_->GetAclQueueEnd()->UnregisterDequeue(); } L2capModuleCertService* module_; } acl_callbacks{this}; std::mutex mutex_; }; void L2capModuleCertModule::ListDependencies(ModuleList* list) { ::bluetooth::grpc::GrpcFacadeModule::ListDependencies(list); list->add<l2cap::L2capLayer>(); list->add<hci::AclManager>(); list->add<hci::HciLayer>(); } void L2capModuleCertModule::Start() { ::bluetooth::grpc::GrpcFacadeModule::Start(); service_ = new L2capModuleCertService(GetDependency<l2cap::L2capLayer>(), GetHandler()); GetDependency<hci::HciLayer>()->EnqueueCommand(hci::WriteScanEnableBuilder::Create(hci::ScanEnable::PAGE_SCAN_ONLY), common::BindOnce([](hci::CommandCompleteView) {}), GetHandler()); service_ = new L2capModuleCertService(GetDependency<hci::AclManager>(), GetHandler()); } void L2capModuleCertModule::Stop() { Loading Loading
system/gd/cert/gd_cert_device.py +2 −0 Original line number Diff line number Diff line Loading @@ -79,3 +79,5 @@ class GdCertDevice(GdDeviceBase): self.hci.disconnection_stream = EventStream(self.hci.FetchDisconnection) self.hci.connection_failed_stream = EventStream(self.hci.FetchConnectionFailed) self.hci.acl_stream = EventStream(self.hci.FetchAclData) self.l2cap.packet_stream = EventStream(self.l2cap.FetchL2capData) self.l2cap.connection_complete_stream = EventStream(self.l2cap.FetchConnectionComplete)
system/gd/cert/gd_device.py +2 −0 Original line number Diff line number Diff line Loading @@ -81,3 +81,5 @@ class GdDevice(GdDeviceBase): self.hci.connection_failed_stream = EventStream(self.hci.FetchConnectionFailed) self.hci.acl_stream = EventStream(self.hci.FetchAclData) self.hci_classic_security.command_complete_stream = EventStream(self.hci_classic_security.FetchCommandCompleteEvent) self.l2cap.packet_stream = EventStream(self.l2cap.FetchL2capData) self.l2cap.connection_complete_stream = EventStream(self.l2cap.FetchConnectionComplete)
system/gd/hci/acl_manager.cc +0 −1 Original line number Diff line number Diff line Loading @@ -441,7 +441,6 @@ struct AclManager::impl { AclConnection::QueueUpEnd* get_acl_queue_end(uint16_t handle) { auto& connection = check_and_get_connection(handle); ASSERT_LOG(connection.disconnect_handler_ != nullptr, "No disconnect handler registered."); return connection.queue_->GetUpEnd(); } Loading
system/gd/l2cap/cert/api.proto +13 −1 Original line number Diff line number Diff line Loading @@ -6,5 +6,17 @@ import "google/protobuf/empty.proto"; import "facade/common.proto"; service L2capModuleCert { rpc NoOp(google.protobuf.Empty) returns (google.protobuf.Empty) {} rpc SendL2capPacket(L2capPacket) returns (google.protobuf.Empty) {} rpc FetchL2capData(facade.EventStreamRequest) returns (stream L2capPacket) {} rpc FetchConnectionComplete(facade.EventStreamRequest) returns (stream ConnectionCompleteEvent) {} } message L2capPacket { facade.BluetoothAddress remote = 1; uint32 channel = 2; bytes payload = 3; } message ConnectionCompleteEvent { facade.BluetoothAddress remote = 1; }
system/gd/l2cap/cert/cert.cc +100 −11 Original line number Diff line number Diff line Loading @@ -19,10 +19,13 @@ #include <cstdint> #include <memory> #include <mutex> #include <queue> #include <unordered_map> #include "common/blocking_queue.h" #include "grpc/grpc_event_stream.h" #include "hci/acl_manager.h" #include "hci/cert/cert.h" #include "l2cap/cert/api.grpc.pb.h" #include "l2cap/l2cap_layer.h" #include "l2cap/l2cap_packets.h" Loading @@ -44,31 +47,117 @@ using namespace facade; class L2capModuleCertService : public L2capModuleCert::Service { public: L2capModuleCertService(l2cap::L2capLayer* l2cap_layer, ::bluetooth::os::Handler* facade_handler) : l2cap_layer_(l2cap_layer), facade_handler_(facade_handler) { ASSERT(l2cap_layer_ != nullptr); ASSERT(facade_handler_ != nullptr); L2capModuleCertService(hci::AclManager* acl_manager, os::Handler* facade_handler) : handler_(facade_handler), acl_manager_(acl_manager) { ASSERT(handler_ != nullptr); acl_manager_->RegisterCallbacks(&acl_callbacks, handler_); } ::grpc::Status NoOp(::grpc::ServerContext* context, const ::google::protobuf::Empty* request, class ConnectionCompleteCallback : public grpc::GrpcEventStreamCallback<ConnectionCompleteEvent, ConnectionCompleteEvent> { public: void OnWriteResponse(ConnectionCompleteEvent* response, const ConnectionCompleteEvent& event) override { response->CopyFrom(event); } } connection_complete_callback_; ::bluetooth::grpc::GrpcEventStream<ConnectionCompleteEvent, ConnectionCompleteEvent> connection_complete_stream_{ &connection_complete_callback_}; ::grpc::Status FetchConnectionComplete( ::grpc::ServerContext* context, const ::bluetooth::facade::EventStreamRequest* request, ::grpc::ServerWriter<::bluetooth::l2cap::cert::ConnectionCompleteEvent>* writer) override { return connection_complete_stream_.HandleRequest(context, request, writer); } ::grpc::Status SendL2capPacket(::grpc::ServerContext* context, const ::bluetooth::l2cap::cert::L2capPacket* request, ::google::protobuf::Empty* response) override { std::unique_ptr<RawBuilder> packet = std::make_unique<RawBuilder>(); auto req_string = request->payload(); packet->AddOctets(std::vector<uint8_t>(req_string.begin(), req_string.end())); std::unique_ptr<BasicFrameBuilder> l2cap_builder = BasicFrameBuilder::Create(request->channel(), std::move(packet)); outgoing_packet_queue_.push(std::move(l2cap_builder)); if (outgoing_packet_queue_.size() == 1) { acl_connection_->GetAclQueueEnd()->RegisterEnqueue( handler_, common::Bind(&L2capModuleCertService::enqueue_packet_to_acl, common::Unretained(this))); } return ::grpc::Status::OK; } private: l2cap::L2capLayer* l2cap_layer_; ::bluetooth::os::Handler* facade_handler_; std::unique_ptr<packet::BasePacketBuilder> enqueue_packet_to_acl() { auto basic_frame_builder = std::move(outgoing_packet_queue_.front()); outgoing_packet_queue_.pop(); if (outgoing_packet_queue_.size() == 0) { acl_connection_->GetAclQueueEnd()->UnregisterEnqueue(); } return basic_frame_builder; } ::grpc::Status FetchL2capData(::grpc::ServerContext* context, const ::bluetooth::facade::EventStreamRequest* request, ::grpc::ServerWriter<L2capPacket>* writer) override { return l2cap_stream_.HandleRequest(context, request, writer); } class L2capStreamCallback : public ::bluetooth::grpc::GrpcEventStreamCallback<L2capPacket, L2capPacket> { public: void OnWriteResponse(L2capPacket* response, const L2capPacket& event) override { response->CopyFrom(event); } } l2cap_stream_callback_; ::bluetooth::grpc::GrpcEventStream<L2capPacket, L2capPacket> l2cap_stream_{&l2cap_stream_callback_}; void on_incoming_packet() { auto packet = acl_connection_->GetAclQueueEnd()->TryDequeue(); BasicFrameView basic_frame_view = BasicFrameView::Create(*packet); ASSERT(basic_frame_view.IsValid()); L2capPacket l2cap_packet; std::string data = std::string(packet->begin(), packet->end()); l2cap_packet.set_payload(data); l2cap_packet.set_channel(basic_frame_view.GetChannelId()); l2cap_stream_.OnIncomingEvent(l2cap_packet); } std::queue<std::unique_ptr<BasicFrameBuilder>> outgoing_packet_queue_; ::bluetooth::os::Handler* handler_; hci::AclManager* acl_manager_; std::unique_ptr<hci::AclConnection> acl_connection_; class AclCallbacks : public hci::ConnectionCallbacks { public: AclCallbacks(L2capModuleCertService* module) : module_(module) {} void OnConnectSuccess(std::unique_ptr<hci::AclConnection> connection) override { ConnectionCompleteEvent event; event.mutable_remote()->set_address(connection->GetAddress().ToString()); module_->connection_complete_stream_.OnIncomingEvent(event); module_->acl_connection_ = std::move(connection); module_->acl_connection_->RegisterDisconnectCallback(common::BindOnce([](hci::ErrorCode) {}), module_->handler_); module_->acl_connection_->GetAclQueueEnd()->RegisterDequeue( module_->handler_, common::Bind(&L2capModuleCertService::on_incoming_packet, common::Unretained(module_))); } void OnConnectFail(hci::Address address, hci::ErrorCode reason) override {} ~AclCallbacks() { module_->acl_connection_->GetAclQueueEnd()->UnregisterDequeue(); } L2capModuleCertService* module_; } acl_callbacks{this}; std::mutex mutex_; }; void L2capModuleCertModule::ListDependencies(ModuleList* list) { ::bluetooth::grpc::GrpcFacadeModule::ListDependencies(list); list->add<l2cap::L2capLayer>(); list->add<hci::AclManager>(); list->add<hci::HciLayer>(); } void L2capModuleCertModule::Start() { ::bluetooth::grpc::GrpcFacadeModule::Start(); service_ = new L2capModuleCertService(GetDependency<l2cap::L2capLayer>(), GetHandler()); GetDependency<hci::HciLayer>()->EnqueueCommand(hci::WriteScanEnableBuilder::Create(hci::ScanEnable::PAGE_SCAN_ONLY), common::BindOnce([](hci::CommandCompleteView) {}), GetHandler()); service_ = new L2capModuleCertService(GetDependency<hci::AclManager>(), GetHandler()); } void L2capModuleCertModule::Stop() { Loading