xref: /aosp_15_r20/external/pigweed/pw_rpc/ts/packets.ts (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1// Copyright 2022 The Pigweed Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License"); you may not
4// use this file except in compliance with the License. You may obtain a copy of
5// the License at
6//
7//     https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12// License for the specific language governing permissions and limitations under
13// the License.
14
15/** Functions for working with pw_rpc packets. */
16
17import { Message } from 'google-protobuf';
18import {
19  RpcPacket,
20  PacketType,
21} from 'pigweedjs/protos/pw_rpc/internal/packet_pb';
22import { Status } from 'pigweedjs/pw_status';
23import { MessageSerializer } from './descriptors';
24
25// Channel, Service, Method, CallId
26type idSet = [number, number, number, number];
27
28export function decode(data: Uint8Array): RpcPacket {
29  return RpcPacket.deserializeBinary(data);
30}
31
32function serializeMessage(
33  message?: Message,
34  serializers?: MessageSerializer,
35): Uint8Array {
36  let payload: Uint8Array;
37  if (typeof message !== 'undefined') {
38    if (serializers) {
39      payload = serializers.serialize(message);
40    } else {
41      payload = (message as any)['serializeBinary']();
42    }
43  } else {
44    payload = new Uint8Array(0);
45  }
46  return payload;
47}
48
49export function decodePayload(
50  payload: Uint8Array,
51  payloadType: any,
52  serializer?: MessageSerializer,
53): any {
54  if (serializer) {
55    return serializer.deserialize(payload);
56  }
57  return payloadType['deserializeBinary'](payload);
58}
59
60export function forServer(packet: RpcPacket): boolean {
61  return packet.getType() % 2 == 0;
62}
63
64export function encodeClientError(
65  packet: RpcPacket,
66  status: Status,
67): Uint8Array {
68  const errorPacket = new RpcPacket();
69  errorPacket.setType(PacketType.CLIENT_ERROR);
70  errorPacket.setChannelId(packet.getChannelId());
71  errorPacket.setMethodId(packet.getMethodId());
72  errorPacket.setServiceId(packet.getServiceId());
73  errorPacket.setCallId(packet.getCallId());
74  errorPacket.setStatus(status);
75  return errorPacket.serializeBinary();
76}
77
78export function encodeClientStream(
79  ids: idSet,
80  message: Message,
81  customSerializer?: MessageSerializer,
82): Uint8Array {
83  const streamPacket = new RpcPacket();
84  streamPacket.setType(PacketType.CLIENT_STREAM);
85  streamPacket.setChannelId(ids[0]);
86  streamPacket.setServiceId(ids[1]);
87  streamPacket.setMethodId(ids[2]);
88  streamPacket.setCallId(ids[3]);
89  const msgSerialized = serializeMessage(message, customSerializer);
90  streamPacket.setPayload(msgSerialized);
91  return streamPacket.serializeBinary();
92}
93
94export function encodeClientStreamEnd(ids: idSet): Uint8Array {
95  const streamEnd = new RpcPacket();
96  streamEnd.setType(PacketType.CLIENT_REQUEST_COMPLETION);
97  streamEnd.setChannelId(ids[0]);
98  streamEnd.setServiceId(ids[1]);
99  streamEnd.setMethodId(ids[2]);
100  streamEnd.setCallId(ids[3]);
101  return streamEnd.serializeBinary();
102}
103
104export function encodeRequest(
105  ids: idSet,
106  request?: Message,
107  customSerializer?: MessageSerializer,
108): Uint8Array {
109  const payload = serializeMessage(request, customSerializer);
110  const packet = new RpcPacket();
111  packet.setType(PacketType.REQUEST);
112  packet.setChannelId(ids[0]);
113  packet.setServiceId(ids[1]);
114  packet.setMethodId(ids[2]);
115  packet.setCallId(ids[3]);
116  packet.setPayload(payload);
117  return packet.serializeBinary();
118}
119
120export function encodeResponse(ids: idSet, response: Message): Uint8Array {
121  const packet = new RpcPacket();
122  packet.setType(PacketType.RESPONSE);
123  packet.setChannelId(ids[0]);
124  packet.setServiceId(ids[1]);
125  packet.setMethodId(ids[2]);
126  packet.setCallId(ids[3]);
127  const msgSerialized = (response as any)['serializeBinary']();
128  packet.setPayload(msgSerialized);
129  return packet.serializeBinary();
130}
131
132export function encodeCancel(ids: idSet): Uint8Array {
133  const packet = new RpcPacket();
134  packet.setType(PacketType.CLIENT_ERROR);
135  packet.setStatus(Status.CANCELLED);
136  packet.setChannelId(ids[0]);
137  packet.setServiceId(ids[1]);
138  packet.setMethodId(ids[2]);
139  packet.setCallId(ids[3]);
140  return packet.serializeBinary();
141}
142