blob: b4748e20934853dc2da7d5e769d7a27a373393e8 [file] [log] [blame]
Michael Ryleev7a2bc372016-03-08 15:16:11 -08001/*
2 * Copyright (C) 2016 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#include <assert.h>
17#include <errno.h>
18#include <stdbool.h>
19#include <stdint.h>
20#include <stdlib.h>
21#include <string.h>
22#include <sys/uio.h>
23
24#include <trusty/tipc.h>
25
26#include "ipc.h"
27#include "log.h"
28
29#define MAX_RECONNECT_RETRY_COUNT 5
30#define TRUSTY_RECONNECT_TIMEOUT_SEC 5
31
32static int tipc_fd = -1;
33
34int ipc_connect(const char *device, const char *port)
35{
36 int rc;
37 uint retry_cnt = 0;
38
39 assert(tipc_fd == -1);
40
41 while(true) {
42 rc = tipc_connect(device, port);
43 if (rc >= 0)
44 break;
45
46 ALOGE("failed (%d) to connect to storage server\n", rc);
47 if (++retry_cnt > MAX_RECONNECT_RETRY_COUNT) {
48 ALOGE("max number of reconnect retries (%d) has been reached\n",
49 retry_cnt);
50 return -1;
51 }
52 sleep(TRUSTY_RECONNECT_TIMEOUT_SEC);
53 }
54 tipc_fd = rc;
55 return 0;
56}
57
58void ipc_disconnect(void)
59{
60 assert(tipc_fd >= 0);
61
62 tipc_close(tipc_fd);
63 tipc_fd = -1;
64}
65
66ssize_t ipc_get_msg(struct storage_msg *msg, void *req_buf, size_t req_buf_len)
67{
68 ssize_t rc;
69 struct iovec iovs[2] = {{msg, sizeof(*msg)}, {req_buf, req_buf_len}};
70
71 assert(tipc_fd >= 0);
72
73 rc = readv(tipc_fd, iovs, 2);
74 if (rc < 0) {
75 ALOGE("failed to read request: %s\n", strerror(errno));
76 return rc;
77 }
78
79 /* check for minimum size */
80 if ((size_t)rc < sizeof(*msg)) {
81 ALOGE("message is too short (%zu bytes received)\n", rc);
82 return -1;
83 }
84
85 /* check for message completeness */
86 if (msg->size != (uint32_t)rc) {
87 ALOGE("inconsistent message size [cmd=%d] (%u != %u)\n",
88 msg->cmd, msg->size, (uint32_t)rc);
89 return -1;
90 }
91
92 return rc - sizeof(*msg);
93}
94
95int ipc_respond(struct storage_msg *msg, void *out, size_t out_size)
96{
97 ssize_t rc;
98 struct iovec iovs[2] = {{msg, sizeof(*msg)}, {out, out_size}};
99
100 assert(tipc_fd >= 0);
101
102 msg->cmd |= STORAGE_RESP_BIT;
103
104 rc = writev(tipc_fd, iovs, out ? 2 : 1);
105 if (rc < 0) {
106 ALOGE("error sending response 0x%x: %s\n",
107 msg->cmd, strerror(errno));
108 return -1;
109 }
110
111 return 0;
112}
113
114