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 #pragma once 17 18 namespace android { 19 20 #pragma clang diagnostic push 21 #pragma clang diagnostic error "-Wpadded" 22 23 constexpr uint8_t RPC_CONNECTION_OPTION_INCOMING = 0x1; // default is outgoing 24 25 constexpr uint32_t RPC_WIRE_ADDRESS_OPTION_CREATED = 1 << 0; // distinguish from '0' address 26 constexpr uint32_t RPC_WIRE_ADDRESS_OPTION_FOR_SERVER = 1 << 1; 27 28 struct RpcWireAddress { 29 uint32_t options; 30 uint32_t address; 31 fromRawRpcWireAddress32 static inline RpcWireAddress fromRaw(uint64_t raw) { 33 return *reinterpret_cast<RpcWireAddress*>(&raw); 34 } toRawRpcWireAddress35 static inline uint64_t toRaw(RpcWireAddress addr) { 36 return *reinterpret_cast<uint64_t*>(&addr); 37 } 38 }; 39 static_assert(sizeof(RpcWireAddress) == sizeof(uint64_t)); 40 41 /** 42 * This is sent to an RpcServer in order to request a new connection is created, 43 * either as part of a new session or an existing session 44 */ 45 struct RpcConnectionHeader { 46 uint32_t version; // maximum supported by caller 47 uint8_t options; 48 uint8_t fileDescriptorTransportMode; 49 uint8_t reservered[8]; 50 // Follows is sessionIdSize bytes. 51 // if size is 0, this is requesting a new session. 52 uint16_t sessionIdSize; 53 }; 54 static_assert(sizeof(RpcConnectionHeader) == 16); 55 56 /** 57 * In response to an RpcConnectionHeader which corresponds to a new session, 58 * this returns information to the server. 59 */ 60 struct RpcNewSessionResponse { 61 uint32_t version; // maximum supported by callee <= maximum supported by caller 62 uint8_t reserved[4]; 63 }; 64 static_assert(sizeof(RpcNewSessionResponse) == 8); 65 66 #define RPC_CONNECTION_INIT_OKAY "cci" 67 68 /** 69 * Whenever a client connection is setup, this is sent as the initial 70 * transaction. The main use of this is in order to control the timing for when 71 * an incoming connection is setup. 72 */ 73 struct RpcOutgoingConnectionInit { 74 char msg[4]; 75 uint8_t reserved[4]; 76 }; 77 static_assert(sizeof(RpcOutgoingConnectionInit) == 8); 78 79 enum : uint32_t { 80 /** 81 * follows is RpcWireTransaction, if flags != oneway, reply w/ RPC_COMMAND_REPLY expected 82 */ 83 RPC_COMMAND_TRANSACT = 0, 84 /** 85 * follows is RpcWireReply 86 */ 87 RPC_COMMAND_REPLY, 88 /** 89 * follows is RpcDecStrong 90 * 91 * note - this in the protocol directly instead of as a 'special 92 * transaction' in order to keep it as lightweight as possible (we don't 93 * want to create a 'Parcel' object for every decref) 94 */ 95 RPC_COMMAND_DEC_STRONG, 96 }; 97 98 /** 99 * These commands are used when the address in an RpcWireTransaction is zero'd 100 * out (no address). This allows the transact/reply flow to be used for 101 * additional server commands, without making the protocol for 102 * transactions/replies more complicated. 103 */ 104 enum : uint32_t { 105 RPC_SPECIAL_TRANSACT_GET_ROOT = 0, 106 RPC_SPECIAL_TRANSACT_GET_MAX_THREADS = 1, 107 RPC_SPECIAL_TRANSACT_GET_SESSION_ID = 2, 108 }; 109 110 // serialization is like: 111 // |RpcWireHeader|struct desginated by 'command'| (over and over again) 112 // 113 // When file descriptors are included in out-of-band data (e.g. in unix domain 114 // sockets), they are always paired with the RpcWireHeader bytes of the 115 // transaction or reply the file descriptors belong to. 116 117 struct RpcWireHeader { 118 uint32_t command; // RPC_COMMAND_* 119 uint32_t bodySize; 120 121 uint32_t reserved[2]; 122 }; 123 static_assert(sizeof(RpcWireHeader) == 16); 124 125 struct RpcDecStrong { 126 RpcWireAddress address; 127 uint32_t amount; 128 uint32_t reserved; 129 }; 130 static_assert(sizeof(RpcDecStrong) == 16); 131 132 struct RpcWireTransaction { 133 RpcWireAddress address; 134 uint32_t code; 135 uint32_t flags; 136 137 uint64_t asyncNumber; 138 139 // The size of the Parcel data directly following RpcWireTransaction. 140 uint32_t parcelDataSize; 141 142 uint32_t reserved[3]; 143 144 uint8_t data[]; 145 }; 146 static_assert(sizeof(RpcWireTransaction) == 40); 147 148 struct RpcWireReply { 149 int32_t status; // transact return 150 151 // -- Fields below only transmitted starting at protocol version 1 -- 152 153 // The size of the Parcel data directly following RpcWireReply. 154 uint32_t parcelDataSize; 155 156 uint32_t reserved[3]; 157 158 // Byte size of RpcWireReply in the wire protocol. wireSizeRpcWireReply159 static size_t wireSize(uint32_t protocolVersion) { 160 if (protocolVersion == 0) { 161 return sizeof(int32_t); 162 } 163 return sizeof(RpcWireReply); 164 } 165 }; 166 static_assert(sizeof(RpcWireReply) == 20); 167 168 #pragma clang diagnostic pop 169 170 } // namespace android 171