Jack He | 492dcf7 | 2019-09-26 18:27:41 -0700 | [diff] [blame] | 1 | /* |
| 2 | * Copyright 2019 The Android Open Source Project |
| 3 | * |
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | * you may not use this file except in compliance with the License. |
| 6 | * You may obtain a copy of the License at |
| 7 | * |
| 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | * |
| 10 | * Unless required by applicable law or agreed to in writing, software |
| 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | * See the License for the specific language governing permissions and |
| 14 | * limitations under the License. |
| 15 | */ |
| 16 | |
| 17 | #include <unordered_map> |
| 18 | |
| 19 | #include "l2cap/cid.h" |
Jack He | ff38d89 | 2019-10-03 17:11:07 -0700 | [diff] [blame] | 20 | #include "l2cap/classic/internal/fixed_channel_impl.h" |
| 21 | #include "l2cap/classic/internal/link.h" |
Jack He | 492dcf7 | 2019-09-26 18:27:41 -0700 | [diff] [blame] | 22 | #include "l2cap/security_policy.h" |
| 23 | #include "os/handler.h" |
| 24 | #include "os/log.h" |
| 25 | |
| 26 | namespace bluetooth { |
| 27 | namespace l2cap { |
Jack He | ff38d89 | 2019-10-03 17:11:07 -0700 | [diff] [blame] | 28 | namespace classic { |
Jack He | 492dcf7 | 2019-09-26 18:27:41 -0700 | [diff] [blame] | 29 | namespace internal { |
| 30 | |
Jack He | ff38d89 | 2019-10-03 17:11:07 -0700 | [diff] [blame] | 31 | FixedChannelImpl::FixedChannelImpl(Cid cid, Link* link, os::Handler* l2cap_handler) |
Jack He | 492dcf7 | 2019-09-26 18:27:41 -0700 | [diff] [blame] | 32 | : cid_(cid), device_(link->GetDevice()), link_(link), l2cap_handler_(l2cap_handler) { |
| 33 | ASSERT_LOG(cid_ >= kFirstFixedChannel && cid_ <= kLastFixedChannel, "Invalid cid: %d", cid_); |
Jack He | 492dcf7 | 2019-09-26 18:27:41 -0700 | [diff] [blame] | 34 | ASSERT(link_ != nullptr); |
| 35 | ASSERT(l2cap_handler_ != nullptr); |
| 36 | } |
| 37 | |
Jack He | ff38d89 | 2019-10-03 17:11:07 -0700 | [diff] [blame] | 38 | void FixedChannelImpl::RegisterOnCloseCallback(os::Handler* user_handler, |
| 39 | FixedChannel::OnCloseCallback on_close_callback) { |
Jack He | 492dcf7 | 2019-09-26 18:27:41 -0700 | [diff] [blame] | 40 | ASSERT_LOG(user_handler_ == nullptr, "OnCloseCallback can only be registered once"); |
| 41 | // If channel is already closed, call the callback immediately without saving it |
| 42 | if (closed_) { |
| 43 | user_handler->Post(common::BindOnce(std::move(on_close_callback), close_reason_)); |
| 44 | return; |
| 45 | } |
| 46 | user_handler_ = user_handler; |
| 47 | on_close_callback_ = std::move(on_close_callback); |
| 48 | } |
| 49 | |
Jack He | ff38d89 | 2019-10-03 17:11:07 -0700 | [diff] [blame] | 50 | void FixedChannelImpl::OnClosed(hci::ErrorCode status) { |
Jack He | 492dcf7 | 2019-09-26 18:27:41 -0700 | [diff] [blame] | 51 | ASSERT_LOG(!closed_, "Device %s Cid 0x%x closed twice, old status 0x%x, new status 0x%x", device_.ToString().c_str(), |
| 52 | cid_, static_cast<int>(close_reason_), static_cast<int>(status)); |
| 53 | closed_ = true; |
| 54 | close_reason_ = status; |
| 55 | acquired_ = false; |
| 56 | link_ = nullptr; |
| 57 | l2cap_handler_ = nullptr; |
| 58 | if (user_handler_ == nullptr) { |
| 59 | return; |
| 60 | } |
| 61 | // On close callback can only be called once |
| 62 | user_handler_->Post(common::BindOnce(std::move(on_close_callback_), status)); |
| 63 | user_handler_ = nullptr; |
| 64 | on_close_callback_.Reset(); |
| 65 | } |
| 66 | |
Jack He | ff38d89 | 2019-10-03 17:11:07 -0700 | [diff] [blame] | 67 | void FixedChannelImpl::Acquire() { |
Jack He | 492dcf7 | 2019-09-26 18:27:41 -0700 | [diff] [blame] | 68 | ASSERT_LOG(user_handler_ != nullptr, "Must register OnCloseCallback before calling any methods"); |
| 69 | if (closed_) { |
| 70 | LOG_WARN("%s is already closed", ToString().c_str()); |
| 71 | ASSERT(!acquired_); |
| 72 | return; |
| 73 | } |
| 74 | if (acquired_) { |
| 75 | LOG_DEBUG("%s was already acquired", ToString().c_str()); |
| 76 | return; |
| 77 | } |
| 78 | acquired_ = true; |
| 79 | link_->RefreshRefCount(); |
| 80 | } |
| 81 | |
Jack He | ff38d89 | 2019-10-03 17:11:07 -0700 | [diff] [blame] | 82 | void FixedChannelImpl::Release() { |
Jack He | 492dcf7 | 2019-09-26 18:27:41 -0700 | [diff] [blame] | 83 | ASSERT_LOG(user_handler_ != nullptr, "Must register OnCloseCallback before calling any methods"); |
| 84 | if (closed_) { |
| 85 | LOG_WARN("%s is already closed", ToString().c_str()); |
| 86 | ASSERT(!acquired_); |
| 87 | return; |
| 88 | } |
| 89 | if (!acquired_) { |
| 90 | LOG_DEBUG("%s was already released", ToString().c_str()); |
| 91 | return; |
| 92 | } |
| 93 | acquired_ = false; |
| 94 | link_->RefreshRefCount(); |
| 95 | } |
| 96 | |
| 97 | } // namespace internal |
Jack He | ff38d89 | 2019-10-03 17:11:07 -0700 | [diff] [blame] | 98 | } // namespace classic |
Jack He | 492dcf7 | 2019-09-26 18:27:41 -0700 | [diff] [blame] | 99 | } // namespace l2cap |
| 100 | } // namespace bluetooth |