| // Copyright 2022 The Pigweed Authors |
| // |
| // 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 |
| // |
| // https://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. |
| |
| /** Functions for working with pw_rpc packets. */ |
| |
| import { Message } from 'google-protobuf'; |
| import { |
| RpcPacket, |
| PacketType, |
| } from 'pigweedjs/protos/pw_rpc/internal/packet_pb'; |
| import { Status } from 'pigweedjs/pw_status'; |
| import { MessageSerializer } from './descriptors'; |
| |
| // Channel, Service, Method, CallId |
| type idSet = [number, number, number, number]; |
| |
| export function decode(data: Uint8Array): RpcPacket { |
| return RpcPacket.deserializeBinary(data); |
| } |
| |
| function serializeMessage( |
| message?: Message, |
| serializers?: MessageSerializer, |
| ): Uint8Array { |
| let payload: Uint8Array; |
| if (typeof message !== 'undefined') { |
| if (serializers) { |
| payload = serializers.serialize(message); |
| } else { |
| payload = (message as any)['serializeBinary'](); |
| } |
| } else { |
| payload = new Uint8Array(0); |
| } |
| return payload; |
| } |
| |
| export function decodePayload( |
| payload: Uint8Array, |
| payloadType: any, |
| serializer?: MessageSerializer, |
| ): any { |
| if (serializer) { |
| return serializer.deserialize(payload); |
| } |
| return payloadType['deserializeBinary'](payload); |
| } |
| |
| export function forServer(packet: RpcPacket): boolean { |
| return packet.getType() % 2 == 0; |
| } |
| |
| export function encodeClientError( |
| packet: RpcPacket, |
| status: Status, |
| ): Uint8Array { |
| const errorPacket = new RpcPacket(); |
| errorPacket.setType(PacketType.CLIENT_ERROR); |
| errorPacket.setChannelId(packet.getChannelId()); |
| errorPacket.setMethodId(packet.getMethodId()); |
| errorPacket.setServiceId(packet.getServiceId()); |
| errorPacket.setCallId(packet.getCallId()); |
| errorPacket.setStatus(status); |
| return errorPacket.serializeBinary(); |
| } |
| |
| export function encodeClientStream( |
| ids: idSet, |
| message: Message, |
| customSerializer?: MessageSerializer, |
| ): Uint8Array { |
| const streamPacket = new RpcPacket(); |
| streamPacket.setType(PacketType.CLIENT_STREAM); |
| streamPacket.setChannelId(ids[0]); |
| streamPacket.setServiceId(ids[1]); |
| streamPacket.setMethodId(ids[2]); |
| streamPacket.setCallId(ids[3]); |
| const msgSerialized = serializeMessage(message, customSerializer); |
| streamPacket.setPayload(msgSerialized); |
| return streamPacket.serializeBinary(); |
| } |
| |
| export function encodeClientStreamEnd(ids: idSet): Uint8Array { |
| const streamEnd = new RpcPacket(); |
| streamEnd.setType(PacketType.CLIENT_REQUEST_COMPLETION); |
| streamEnd.setChannelId(ids[0]); |
| streamEnd.setServiceId(ids[1]); |
| streamEnd.setMethodId(ids[2]); |
| streamEnd.setCallId(ids[3]); |
| return streamEnd.serializeBinary(); |
| } |
| |
| export function encodeRequest( |
| ids: idSet, |
| request?: Message, |
| customSerializer?: MessageSerializer, |
| ): Uint8Array { |
| const payload = serializeMessage(request, customSerializer); |
| const packet = new RpcPacket(); |
| packet.setType(PacketType.REQUEST); |
| packet.setChannelId(ids[0]); |
| packet.setServiceId(ids[1]); |
| packet.setMethodId(ids[2]); |
| packet.setCallId(ids[3]); |
| packet.setPayload(payload); |
| return packet.serializeBinary(); |
| } |
| |
| export function encodeResponse(ids: idSet, response: Message): Uint8Array { |
| const packet = new RpcPacket(); |
| packet.setType(PacketType.RESPONSE); |
| packet.setChannelId(ids[0]); |
| packet.setServiceId(ids[1]); |
| packet.setMethodId(ids[2]); |
| packet.setCallId(ids[3]); |
| const msgSerialized = (response as any)['serializeBinary'](); |
| packet.setPayload(msgSerialized); |
| return packet.serializeBinary(); |
| } |
| |
| export function encodeCancel(ids: idSet): Uint8Array { |
| const packet = new RpcPacket(); |
| packet.setType(PacketType.CLIENT_ERROR); |
| packet.setStatus(Status.CANCELLED); |
| packet.setChannelId(ids[0]); |
| packet.setServiceId(ids[1]); |
| packet.setMethodId(ids[2]); |
| packet.setCallId(ids[3]); |
| return packet.serializeBinary(); |
| } |