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