1 /*
2 * Copyright (C) 2020 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 #define TLOG_TAG "lib_system_state_server"
18
19 #include <lib/system_state_server/system_state_server.h>
20 #include <lib/tipc/tipc_srv.h>
21 #include <trusty_log.h>
22 #include <uapi/err.h>
23
system_state_on_message(const struct tipc_port * port,handle_t chan,void * ctx)24 static int system_state_on_message(const struct tipc_port* port,
25 handle_t chan,
26 void* ctx) {
27 int ret;
28 struct {
29 struct system_state_req hdr;
30 union {
31 struct system_state_get_flag_req get_flag;
32 };
33 } req;
34 size_t req_payload_size;
35 struct {
36 struct system_state_resp hdr;
37 union {
38 struct system_state_get_flag_resp get_flag;
39 };
40 } resp = {};
41 size_t resp_payload_size = 0;
42
43 ret = tipc_recv1(chan, sizeof(req.hdr), &req, sizeof(req));
44 if (ret < 0) {
45 TLOGE("tipc_recv1 failed (%d)\n", ret);
46 return ret;
47 }
48 if ((size_t)ret < sizeof(req.hdr)) {
49 TLOGE("request too short (%d)\n", ret);
50 return ERR_BAD_LEN;
51 }
52 req_payload_size = ret - sizeof(req.hdr);
53 if (req.hdr.reserved) {
54 TLOGE("bad request, reserved not 0, (%d)\n", req.hdr.reserved);
55 return ERR_INVALID_ARGS;
56 }
57
58 switch (req.hdr.cmd) {
59 case SYSTEM_STATE_CMD_GET_FLAG:
60 if (req_payload_size != sizeof(req.get_flag)) {
61 TLOGE("bad get_flags payload size (%zd)\n", req_payload_size);
62 ret = ERR_INVALID_ARGS;
63 break;
64 }
65 ret = system_state_server_get_flag(req.get_flag.flag,
66 &resp.get_flag.value);
67 if (!ret) {
68 resp.get_flag.flag = req.get_flag.flag;
69 resp_payload_size = sizeof(resp.get_flag);
70 }
71 break;
72 default:
73 ret = ERR_CMD_UNKNOWN;
74 }
75 resp.hdr.cmd = req.hdr.cmd | SYSTEM_STATE_CMD_RESP_BIT;
76 resp.hdr.result = ret;
77 ret = tipc_send1(chan, &resp, sizeof(resp.hdr) + resp_payload_size);
78 if (ret < 0) {
79 TLOGE("tipc_send1 failed (%d)\n", ret);
80 return ret;
81 }
82 if ((size_t)ret != sizeof(resp.hdr) + resp_payload_size) {
83 TLOGE("bad len (%d) from send_msg()\n", ret);
84 return ERR_IO;
85 }
86 return 0;
87 }
88
add_system_state_service(struct tipc_hset * hset)89 int add_system_state_service(struct tipc_hset* hset) {
90 static struct tipc_port_acl acl = {
91 .flags = IPC_PORT_ALLOW_TA_CONNECT,
92 };
93 static struct tipc_port port = {
94 .name = SYSTEM_STATE_PORT,
95 .msg_max_size = SYSTEM_STATE_MAX_MESSAGE_SIZE,
96 .msg_queue_len = 1,
97 .acl = &acl,
98 };
99 static struct tipc_srv_ops ops = {
100 .on_message = system_state_on_message,
101 };
102 return tipc_add_service(hset, &port, 1, 1, &ops);
103 }
104