1 /*
2  * Copyright (C) 2018 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 
17 #ifndef android_hardware_automotive_vehicle_V2_0_VmsUtils_H_
18 #define android_hardware_automotive_vehicle_V2_0_VmsUtils_H_
19 
20 #include <memory>
21 #include <string>
22 #include <unordered_set>
23 
24 #include <android/hardware/automotive/vehicle/2.0/types.h>
25 
26 namespace android {
27 namespace hardware {
28 namespace automotive {
29 namespace vehicle {
30 namespace V2_0 {
31 namespace vms {
32 
33 // VmsUtils are a set of abstractions for creating and parsing Vehicle Property
34 // updates to VehicleProperty::VEHICLE_MAP_SERVICE. The format for parsing a
35 // VehiclePropValue update with a VMS message is specified in the Vehicle HIDL.
36 //
37 // This interface is meant for use by HAL clients of VMS; corresponding
38 // functionality is also provided by VMS in the embedded car service.
39 
40 // A VmsLayer is comprised of a type, subtype, and version.
41 struct VmsLayer {
VmsLayerVmsLayer42     VmsLayer(int type, int subtype, int version) : type(type), subtype(subtype), version(version) {}
43     int type;
44     int subtype;
45     int version;
46     bool operator==(const VmsLayer& layer) const {
47         return this->type == layer.type && this->subtype == layer.subtype &&
48                this->version == layer.version;
49     }
50 
51     // Class for hash function
52     class VmsLayerHashFunction {
53       public:
54         // Hash of the variables is returned.
operatorVmsLayer55         size_t operator()(const VmsLayer& layer) const {
56             return std::hash<int>()(layer.type) ^ std::hash<int>()(layer.type) ^
57                    std::hash<int>()(layer.type);
58         }
59     };
60 };
61 
62 struct VmsLayerAndPublisher {
VmsLayerAndPublisherVmsLayerAndPublisher63     VmsLayerAndPublisher(VmsLayer layer, int publisher_id)
64         : layer(std::move(layer)), publisher_id(publisher_id) {}
65     VmsLayer layer;
66     int publisher_id;
67 };
68 
69 // A VmsAssociatedLayer is used by subscribers to specify which publisher IDs
70 // are acceptable for a given layer.
71 struct VmsAssociatedLayer {
VmsAssociatedLayerVmsAssociatedLayer72     VmsAssociatedLayer(VmsLayer layer, std::vector<int> publisher_ids)
73         : layer(std::move(layer)), publisher_ids(std::move(publisher_ids)) {}
74     VmsLayer layer;
75     std::vector<int> publisher_ids;
76 };
77 
78 // A VmsLayerOffering refers to a single layer that can be published, along with
79 // its dependencies. Dependencies can be empty.
80 struct VmsLayerOffering {
VmsLayerOfferingVmsLayerOffering81     VmsLayerOffering(VmsLayer layer, std::vector<VmsLayer> dependencies)
82         : layer(std::move(layer)), dependencies(std::move(dependencies)) {}
VmsLayerOfferingVmsLayerOffering83     VmsLayerOffering(VmsLayer layer) : layer(layer), dependencies() {}
84     VmsLayer layer;
85     std::vector<VmsLayer> dependencies;
86 };
87 
88 // A VmsOffers refers to a list of layers that can be published by the publisher
89 // with the specified publisher ID.
90 struct VmsOffers {
VmsOffersVmsOffers91     VmsOffers(int publisher_id, std::vector<VmsLayerOffering> offerings)
92         : publisher_id(publisher_id), offerings(std::move(offerings)) {}
93     int publisher_id;
94     std::vector<VmsLayerOffering> offerings;
95 };
96 
97 // A VmsSubscriptionsState is delivered in response to a
98 // VmsMessageType.SUBSCRIPTIONS_REQUEST or on the first SUBSCRIBE or last
99 // UNSUBSCRIBE for a layer. It indicates which layers or associated_layers are
100 // currently being subscribed to in the system.
101 struct VmsSubscriptionsState {
102     int sequence_number;
103     std::vector<VmsLayer> layers;
104     std::vector<VmsAssociatedLayer> associated_layers;
105 };
106 
107 struct VmsAvailabilityState {
108     int sequence_number;
109     std::vector<VmsAssociatedLayer> associated_layers;
110 };
111 
112 // An enum to represent the result of parsing START_SESSION message from the VMS service.
113 enum VmsSessionStatus {
114     // When a new session is received, the client should acknowledge it with the correct
115     // IDs in the START_SESSION message.
116     kNewServerSession,
117     // When an acknowledgement it received, the client can start using the connection.
118     kAckToCurrentSession,
119     // Invalid message with either invalid format or unexpected data.
120     kInvalidMessage
121 };
122 
123 // Creates an empty base VMS message with some pre-populated default fields.
124 std::unique_ptr<VehiclePropValue> createBaseVmsMessage(size_t message_size);
125 
126 // Creates a VehiclePropValue containing a message of type
127 // VmsMessageType.SUBSCRIBE, specifying to the VMS service
128 // which layer to subscribe to.
129 std::unique_ptr<VehiclePropValue> createSubscribeMessage(const VmsLayer& layer);
130 
131 // Creates a VehiclePropValue containing a message of type
132 // VmsMessageType.SUBSCRIBE_TO_PUBLISHER, specifying to the VMS service
133 // which layer and publisher_id to subscribe to.
134 std::unique_ptr<VehiclePropValue> createSubscribeToPublisherMessage(
135     const VmsLayerAndPublisher& layer);
136 
137 // Creates a VehiclePropValue containing a message of type
138 // VmsMessageType.UNSUBSCRIBE, specifying to the VMS service
139 // which layer to unsubscribe from.
140 std::unique_ptr<VehiclePropValue> createUnsubscribeMessage(const VmsLayer& layer);
141 
142 // Creates a VehiclePropValue containing a message of type
143 // VmsMessageType.UNSUBSCRIBE_TO_PUBLISHER, specifying to the VMS service
144 // which layer and publisher_id to unsubscribe from.
145 std::unique_ptr<VehiclePropValue> createUnsubscribeToPublisherMessage(
146     const VmsLayerAndPublisher& layer);
147 
148 // Creates a VehiclePropValue containing a message of type
149 // VmsMessageType.OFFERING, specifying to the VMS service which layers are being
150 // offered and their dependencies, if any.
151 std::unique_ptr<VehiclePropValue> createOfferingMessage(const VmsOffers& offers);
152 
153 // Creates a VehiclePropValue containing a message of type
154 // VmsMessageType.AVAILABILITY_REQUEST.
155 std::unique_ptr<VehiclePropValue> createAvailabilityRequest();
156 
157 // Creates a VehiclePropValue containing a message of type
158 // VmsMessageType.SUBSCRIPTIONS_REQUEST.
159 std::unique_ptr<VehiclePropValue> createSubscriptionsRequest();
160 
161 // Creates a VehiclePropValue containing a message of type VmsMessageType.DATA.
162 // Returns a nullptr if the vms_packet string in bytes is empty or if the layer_publisher
163 // information in VmsLayerAndPublisher format is missing the later or publisher
164 // information.
165 //
166 // For example, to build a VehiclePropValue message containing a proto, the caller
167 // should first convert the proto to a byte string (vms_packet) using the
168 // SerializeToString proto API. Then, it use this interface to build the VehicleProperty
169 // by passing publisher and layer information (layer_publisher) and the vms_packet.
170 std::unique_ptr<VehiclePropValue> createDataMessageWithLayerPublisherInfo(
171         const VmsLayerAndPublisher& layer_publisher, const std::string& vms_packet);
172 
173 // Creates a VehiclePropValue containing a message of type
174 // VmsMessageType.PUBLISHER_ID_REQUEST with the given publisher information.
175 // Returns a nullptr if the input is empty.
176 std::unique_ptr<VehiclePropValue> createPublisherIdRequest(
177         const std::string& vms_provider_description);
178 
179 // Creates a VehiclePropValue message of type VmsMessageType.START_SESSION.
180 std::unique_ptr<VehiclePropValue> createStartSessionMessage(const int service_id,
181                                                             const int client_id);
182 
183 // Returns true if the VehiclePropValue pointed to by value contains a valid Vms
184 // message, i.e. the VehicleProperty, VehicleArea, and VmsMessageType are all
185 // valid. Note: If the VmsMessageType enum is extended, this function will
186 // return false for any new message types added.
187 bool isValidVmsMessage(const VehiclePropValue& value);
188 
189 // Returns the message type. Expects that the VehiclePropValue contains a valid
190 // Vms message, as verified by isValidVmsMessage.
191 VmsMessageType parseMessageType(const VehiclePropValue& value);
192 
193 // Constructs a string byte array from a message of type VmsMessageType.DATA.
194 // Returns an empty string if the message type doesn't match or if the
195 // VehiclePropValue does not contain a byte array.
196 //
197 // A proto message can then be constructed by passing the result of this
198 // function to ParseFromString.
199 std::string parseData(const VehiclePropValue& value);
200 
201 // Returns the publisher ID by parsing the VehiclePropValue containing the ID.
202 // Returns null if the message is invalid.
203 int32_t parsePublisherIdResponse(const VehiclePropValue& publisher_id_response);
204 
205 // Returns true if the new sequence number is greater than the last seen
206 // sequence number.
207 bool isSequenceNumberNewer(const VehiclePropValue& subscriptions_state,
208                            const int last_seen_sequence_number);
209 
210 // Returns sequence number of the message.
211 int32_t getSequenceNumberForSubscriptionsState(const VehiclePropValue& subscriptions_state);
212 
213 // Takes a subscriptions state message and returns the layers that have active
214 // subscriptions of the layers that are offered by your HAL client/publisher.
215 //
216 // A publisher can use this function when receiving a subscriptions response or subscriptions
217 // change message to determine which layers to publish data on.
218 // The caller of this function can optionally decide to not consume these layers
219 // if the subscription change has the sequence number less than the last seen
220 // sequence number.
221 std::vector<VmsLayer> getSubscribedLayers(const VehiclePropValue& subscriptions_state,
222                                           const VmsOffers& offers);
223 
224 // Takes an availability change message and returns true if the parsed message implies that
225 // the service has newly started or restarted.
226 // If the message has a sequence number 0, it means that the service
227 // has newly started or restarted.
228 bool hasServiceNewlyStarted(const VehiclePropValue& availability_change);
229 
230 // Takes a start session message, current service ID, current client ID; and returns the type/status
231 // of the message. It also populates the new service ID with the correct value.
232 VmsSessionStatus parseStartSessionMessage(const VehiclePropValue& start_session,
233                                           const int current_service_id, const int current_client_id,
234                                           int* new_service_id);
235 
236 // Returns true if the new sequence number of the availability state message is greater than
237 // the last seen availability sequence number.
238 bool isAvailabilitySequenceNumberNewer(const VehiclePropValue& availability_state,
239                                        const int last_seen_availability_sequence_number);
240 
241 // Returns sequence number of the availability state message.
242 int32_t getSequenceNumberForAvailabilityState(const VehiclePropValue& availability_state);
243 
244 // Takes a availability state message and returns the associated layers that are
245 // available to publish data.
246 //
247 // A subscriber can use this function when receiving an availability response or availability
248 // change message to determine which associated layers are ready to publish data.
249 // The caller of this function can optionally decide to not consume these layers
250 // if the availability change has the sequence number less than the last seen
251 // sequence number.
252 std::vector<VmsAssociatedLayer> getAvailableLayers(const VehiclePropValue& availability_state);
253 
254 }  // namespace vms
255 }  // namespace V2_0
256 }  // namespace vehicle
257 }  // namespace automotive
258 }  // namespace hardware
259 }  // namespace android
260 
261 #endif  // android_hardware_automotive_vehicle_V2_0_VmsUtils_H_
262