File: RpcWireFormat.h

package info (click to toggle)
android-platform-tools 34.0.5-12
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 150,900 kB
  • sloc: cpp: 805,786; java: 293,500; ansic: 128,288; xml: 127,491; python: 41,481; sh: 14,245; javascript: 9,665; cs: 3,846; asm: 2,049; makefile: 1,917; yacc: 440; awk: 368; ruby: 183; sql: 140; perl: 88; lex: 67
file content (170 lines) | stat: -rw-r--r-- 4,987 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#pragma once

namespace android {

#pragma clang diagnostic push
#pragma clang diagnostic error "-Wpadded"

constexpr uint8_t RPC_CONNECTION_OPTION_INCOMING = 0x1; // default is outgoing

constexpr uint32_t RPC_WIRE_ADDRESS_OPTION_CREATED = 1 << 0; // distinguish from '0' address
constexpr uint32_t RPC_WIRE_ADDRESS_OPTION_FOR_SERVER = 1 << 1;

struct RpcWireAddress {
    uint32_t options;
    uint32_t address;

    static inline RpcWireAddress fromRaw(uint64_t raw) {
        return *reinterpret_cast<RpcWireAddress*>(&raw);
    }
    static inline uint64_t toRaw(RpcWireAddress addr) {
        return *reinterpret_cast<uint64_t*>(&addr);
    }
};
static_assert(sizeof(RpcWireAddress) == sizeof(uint64_t));

/**
 * This is sent to an RpcServer in order to request a new connection is created,
 * either as part of a new session or an existing session
 */
struct RpcConnectionHeader {
    uint32_t version; // maximum supported by caller
    uint8_t options;
    uint8_t fileDescriptorTransportMode;
    uint8_t reservered[8];
    // Follows is sessionIdSize bytes.
    // if size is 0, this is requesting a new session.
    uint16_t sessionIdSize;
};
static_assert(sizeof(RpcConnectionHeader) == 16);

/**
 * In response to an RpcConnectionHeader which corresponds to a new session,
 * this returns information to the server.
 */
struct RpcNewSessionResponse {
    uint32_t version; // maximum supported by callee <= maximum supported by caller
    uint8_t reserved[4];
};
static_assert(sizeof(RpcNewSessionResponse) == 8);

#define RPC_CONNECTION_INIT_OKAY "cci"

/**
 * Whenever a client connection is setup, this is sent as the initial
 * transaction. The main use of this is in order to control the timing for when
 * an incoming connection is setup.
 */
struct RpcOutgoingConnectionInit {
    char msg[4];
    uint8_t reserved[4];
};
static_assert(sizeof(RpcOutgoingConnectionInit) == 8);

enum : uint32_t {
    /**
     * follows is RpcWireTransaction, if flags != oneway, reply w/ RPC_COMMAND_REPLY expected
     */
    RPC_COMMAND_TRANSACT = 0,
    /**
     * follows is RpcWireReply
     */
    RPC_COMMAND_REPLY,
    /**
     * follows is RpcDecStrong
     *
     * note - this in the protocol directly instead of as a 'special
     * transaction' in order to keep it as lightweight as possible (we don't
     * want to create a 'Parcel' object for every decref)
     */
    RPC_COMMAND_DEC_STRONG,
};

/**
 * These commands are used when the address in an RpcWireTransaction is zero'd
 * out (no address). This allows the transact/reply flow to be used for
 * additional server commands, without making the protocol for
 * transactions/replies more complicated.
 */
enum : uint32_t {
    RPC_SPECIAL_TRANSACT_GET_ROOT = 0,
    RPC_SPECIAL_TRANSACT_GET_MAX_THREADS = 1,
    RPC_SPECIAL_TRANSACT_GET_SESSION_ID = 2,
};

// serialization is like:
// |RpcWireHeader|struct desginated by 'command'| (over and over again)
//
// When file descriptors are included in out-of-band data (e.g. in unix domain
// sockets), they are always paired with the RpcWireHeader bytes of the
// transaction or reply the file descriptors belong to.

struct RpcWireHeader {
    uint32_t command; // RPC_COMMAND_*
    uint32_t bodySize;

    uint32_t reserved[2];
};
static_assert(sizeof(RpcWireHeader) == 16);

struct RpcDecStrong {
    RpcWireAddress address;
    uint32_t amount;
    uint32_t reserved;
};
static_assert(sizeof(RpcDecStrong) == 16);

struct RpcWireTransaction {
    RpcWireAddress address;
    uint32_t code;
    uint32_t flags;

    uint64_t asyncNumber;

    // The size of the Parcel data directly following RpcWireTransaction.
    uint32_t parcelDataSize;

    uint32_t reserved[3];

    uint8_t data[];
};
static_assert(sizeof(RpcWireTransaction) == 40);

struct RpcWireReply {
    int32_t status; // transact return

    // -- Fields below only transmitted starting at protocol version 1 --

    // The size of the Parcel data directly following RpcWireReply.
    uint32_t parcelDataSize;

    uint32_t reserved[3];

    // Byte size of RpcWireReply in the wire protocol.
    static size_t wireSize(uint32_t protocolVersion) {
        if (protocolVersion == 0) {
            return sizeof(int32_t);
        }
        return sizeof(RpcWireReply);
    }
};
static_assert(sizeof(RpcWireReply) == 20);

#pragma clang diagnostic pop

} // namespace android