1 // Copyright 2018 The Fuchsia Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #pragma once 6 7 #include <lib/zx/channel.h> 8 #include <zircon/fidl.h> 9 10 namespace devmgr { 11 12 // Manages state of a FIDL transaction so we can reply to the correct message. 13 // FidlTxn must not outlive the channel it is given 14 class FidlTxn { 15 public: FidlTxn(zx::unowned_channel channel,uint32_t txid)16 FidlTxn(zx::unowned_channel channel, uint32_t txid) : channel_(channel), txid_(txid) { } FidlTxn(const zx::channel & channel,uint32_t txid)17 FidlTxn(const zx::channel& channel, uint32_t txid) : channel_(channel), txid_(txid) { } 18 19 FidlTxn& operator=(const FidlTxn&) = delete; 20 FidlTxn(const FidlTxn&) = delete; 21 22 FidlTxn& operator=(FidlTxn&&) = delete; 23 FidlTxn(FidlTxn&&) = delete; 24 Reply(const fidl_msg_t * msg)25 zx_status_t Reply(const fidl_msg_t* msg) { 26 auto hdr = static_cast<fidl_message_header_t*>(msg->bytes); 27 hdr->txid = txid_; 28 return channel_->write(0, msg->bytes, msg->num_bytes, 29 msg->handles, msg->num_handles); 30 } 31 FidlReply(fidl_txn_t * reply,const fidl_msg_t * msg)32 static zx_status_t FidlReply(fidl_txn_t* reply, const fidl_msg_t* msg) { 33 static_assert(offsetof(FidlTxn, txn_) == 0); 34 return reinterpret_cast<FidlTxn*>(reply)->Reply(msg); 35 } 36 fidl_txn()37 fidl_txn_t* fidl_txn() { return &txn_; } 38 39 private: 40 // Due to the implementation of FidlReply, it is important that this be the 41 // first member variable. 42 fidl_txn_t txn_ = { .reply = FidlTxn::FidlReply }; 43 44 // Reply channel 45 const zx::unowned_channel channel_; 46 47 // Transaction id of the message we're replying to 48 const uint32_t txid_; 49 }; 50 51 } // namespace devmgr 52