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