1 #include <BpBootDone.h>
set_boot_done()2 int BpBootDone::set_boot_done() {
3     if (!mChan.ok()) {
4         return ERR_INVALID_ARGS;
5     }
6     ::tidl::RequestHeader req_hdr = {
7             .cmd = CMD_set_boot_done,
8     };
9     Request_set_boot_done req = {};
10     constexpr uint32_t req_num_handles =
11             ::tidl::HandleOps<Request_set_boot_done>::num_handles;
12     ::tidl::Handle req_handles[req_num_handles];
13     ::tidl::Handle* hptr = req_handles;
14     req.send_handles(hptr);
15     assert(hptr == &req_handles[req_num_handles]);
16     int rc = ::tidl::ipc::send(mChan.get(), &req_hdr, sizeof(req_hdr), &req,
17                                sizeof(req), req_handles, req_num_handles);
18     if (rc < 0) {
19         return rc;
20     }
21     if (static_cast<size_t>(rc) != sizeof(req_hdr) + sizeof(req)) {
22         return ERR_BAD_LEN;
23     }
24     rc = ::tidl::ipc::wait_for_msg(mChan.get());
25     if (rc != NO_ERROR) {
26         return rc;
27     }
28     ::tidl::ResponseHeader resp_hdr;
29     rc = ::tidl::ipc::recv(mChan.get(), sizeof(resp_hdr), &resp_hdr,
30                            sizeof(resp_hdr), nullptr, 0);
31     if (rc < 0) {
32         return rc;
33     }
34     if (static_cast<size_t>(rc) < sizeof(resp_hdr)) {
35         return ERR_BAD_LEN;
36     }
37     if (resp_hdr.cmd != (CMD_set_boot_done | RESP_BIT)) {
38         return ERR_CMD_UNKNOWN;
39     }
40     if (resp_hdr.rc != NO_ERROR) {
41         if (static_cast<size_t>(rc) != sizeof(resp_hdr)) {
42             return ERR_BAD_LEN;
43         }
44         return resp_hdr.rc;
45     }
46     if (static_cast<size_t>(rc) != sizeof(resp_hdr)) {
47         return ERR_BAD_LEN;
48     }
49     return NO_ERROR;
50 }
connect(const char * port,uint32_t flags)51 int BpBootDone::connect(const char* port, uint32_t flags) {
52     if (mChan.ok()) {
53         return ERR_INVALID_ARGS;
54     }
55     return ::tidl::ipc::connect(port, flags, mChan);
56 }
57 
is_connected()58 bool BpBootDone::is_connected() {
59     return (mChan.ok());
60 }
reset()61 void BpBootDone::reset() {
62     mChan.reset();
63 }
64 #if !defined(__QL_TIPC__)
65 #include <BnBootDone.h>
66 struct TIDL_PACKED_ATTR Request {
67     ::tidl::RequestHeader hdr;
68     union TIDL_PACKED_ATTR {
69         BnBootDone::Request_set_boot_done set_boot_done;
70     } req;
71 };
72 struct TIDL_PACKED_ATTR Response {
73     ::tidl::ResponseHeader hdr;
74     union TIDL_PACKED_ATTR {
75     } resp;
76 };
77 union TIDL_PACKED_ATTR LongestMessage {
78     Request req;
79     Response resp;
80 };
BnBootDone(const char * port,const::tidl::Service::PortAcl * acl,uint32_t maximum_payload_size)81 BnBootDone::BnBootDone(const char* port,
82                        const ::tidl::Service::PortAcl* acl,
83                        uint32_t maximum_payload_size)
84         : Service("BnBootDone",
85                   port,
86                   sizeof(LongestMessage) + maximum_payload_size,
87                   acl,
88                   &kOps) {}
get_instance(IBootDone * & instance,const struct uuid *)89 int BnBootDone::get_instance(IBootDone*& instance, const struct uuid*) {
90     instance = this;
91     return NO_ERROR;
92 }
93 ::tidl::Service::Ops BnBootDone::kOps = {
94         .on_connect = BnBootDone::on_connect,
95         .on_message = BnBootDone::on_message,
96         .on_channel_cleanup = BnBootDone::on_channel_cleanup,
97 };
on_connect(const::tidl::Service::Port * port,::tidl::Handle chan,const struct uuid * peer,void ** ctx_p)98 int BnBootDone::on_connect(const ::tidl::Service::Port* port,
99                            ::tidl::Handle chan,
100                            const struct uuid* peer,
101                            void** ctx_p) {
102     auto* bn_impl = static_cast<BnBootDone*>(
103             reinterpret_cast<Service*>(const_cast<void*>(port->priv)));
104     assert(bn_impl);
105     IBootDone* instance;
106     int rc = bn_impl->get_instance(instance, peer);
107     if (rc != NO_ERROR) {
108         return rc;
109     }
110     *ctx_p = instance;
111     return NO_ERROR;
112 }
on_channel_cleanup(void * ctx)113 void BnBootDone::on_channel_cleanup(void* ctx) {
114     auto* impl = reinterpret_cast<IBootDone*>(ctx);
115     assert(impl);
116     impl->destroy();
117 }
on_message(const::tidl::Service::Port * port,::tidl::Handle chan,void * ctx)118 int BnBootDone::on_message(const ::tidl::Service::Port* port,
119                            ::tidl::Handle chan,
120                            void* ctx) {
121     auto* impl = reinterpret_cast<IBootDone*>(ctx);
122     auto* bn_impl = static_cast<BnBootDone*>(
123             reinterpret_cast<Service*>(const_cast<void*>(port->priv)));
124     assert(impl);
125     assert(bn_impl);
126     ::tidl::Payload req_payload;
127     ::tidl::Payload resp_payload;
128     ipc_msg_info_t mi;
129     int rc = get_msg(chan, &mi);
130     if (rc != NO_ERROR) {
131         return rc;
132     }
133     bool call_put_msg = true;
134     ::tidl::RequestHeader req_hdr;
135     struct iovec req_hdr_iov = {.iov_base = &req_hdr,
136                                 .iov_len = sizeof(req_hdr)};
137     ipc_msg_t req_hdr_msg = {.num_iov = 1,
138                              .iov = &req_hdr_iov,
139                              .num_handles = 0,
140                              .handles = nullptr};
141     rc = read_msg(chan, mi.id, 0, &req_hdr_msg);
142     if (rc < 0) {
143         goto done;
144     }
145     if (static_cast<size_t>(rc) < sizeof(req_hdr)) {
146         rc = ERR_BAD_LEN;
147         goto done;
148     }
149     switch (req_hdr.cmd) {
150     case CMD_set_boot_done: {
151         Request_set_boot_done req;
152         constexpr uint32_t req_num_handles = Request_set_boot_done::num_handles;
153         ::tidl::Handle req_handles[req_num_handles];
154         struct iovec req_iov[] = {
155                 {.iov_base = &req, .iov_len = sizeof(req)},
156         };
157         ipc_msg_t req_msg = {.num_iov = countof(req_iov),
158                              .iov = req_iov,
159                              .num_handles = req_num_handles,
160                              .handles = req_handles};
161         rc = read_msg(chan, mi.id, sizeof(req_hdr), &req_msg);
162         if (rc < 0) {
163             goto done;
164         }
165         if (static_cast<size_t>(rc) < sizeof(req)) {
166             rc = ERR_BAD_LEN;
167             goto send_rc;
168         }
169         put_msg(chan, mi.id);
170         call_put_msg = false;
171         ::tidl::Handle* hptr = req_handles;
172         req.recv_handles(hptr);
173         assert(hptr == &req_handles[req_num_handles]);
174         rc = impl->set_boot_done();
175         if (rc != NO_ERROR) {
176             goto send_rc;
177         }
178         ::tidl::ResponseHeader resp_hdr = {
179                 .cmd = req_hdr.cmd | RESP_BIT,
180                 .rc = rc,
181         };
182         rc = ::tidl::ipc::send(chan, &resp_hdr, sizeof(resp_hdr), nullptr, 0);
183         if (rc < 0) {
184             goto done;
185         }
186         if (static_cast<size_t>(rc) != sizeof(resp_hdr)) {
187             rc = ERR_BAD_LEN;
188             goto done;
189         }
190         break;
191     }
192     default:
193         put_msg(chan, mi.id);
194         call_put_msg = false;
195         rc = ERR_CMD_UNKNOWN;
196         goto send_rc;
197         break;
198     }
199     rc = NO_ERROR;
200 done:
201     if (call_put_msg) {
202         put_msg(chan, mi.id);
203     }
204     bn_impl->free_payload_buffer(tidl::move(req_payload));
205     bn_impl->free_payload_buffer(tidl::move(resp_payload));
206     return rc;
207 send_rc:
208     ::tidl::ResponseHeader resp_hdr = {.cmd = req_hdr.cmd | RESP_BIT, .rc = rc};
209     rc = ::tidl::ipc::send(chan, &resp_hdr, sizeof(resp_hdr), nullptr, 0);
210     if (rc < 0) {
211         goto done;
212     }
213     if (static_cast<size_t>(rc) != sizeof(resp_hdr)) {
214         rc = ERR_BAD_LEN;
215         goto done;
216     }
217     goto done;
218 }
219 #endif  // #if !defined(__QL_TIPC__)
220