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(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 { 72 VmsLayer layer; 73 std::vector<int> publisher_ids; 74 }; 75 76 // A VmsLayerOffering refers to a single layer that can be published, along with 77 // its dependencies. Dependencies can be empty. 78 struct VmsLayerOffering { VmsLayerOfferingVmsLayerOffering79 VmsLayerOffering(VmsLayer layer, std::vector<VmsLayer> dependencies) 80 : layer(layer), dependencies(dependencies) {} VmsLayerOfferingVmsLayerOffering81 VmsLayerOffering(VmsLayer layer) : layer(layer), dependencies() {} 82 VmsLayer layer; 83 std::vector<VmsLayer> dependencies; 84 }; 85 86 // A VmsOffers refers to a list of layers that can be published by the publisher 87 // with the specified publisher ID. 88 struct VmsOffers { VmsOffersVmsOffers89 VmsOffers(int publisher_id, std::vector<VmsLayerOffering> offerings) 90 : publisher_id(publisher_id), offerings(offerings) {} 91 int publisher_id; 92 std::vector<VmsLayerOffering> offerings; 93 }; 94 95 // A VmsSubscriptionsState is delivered in response to a 96 // VmsMessageType.SUBSCRIPTIONS_REQUEST or on the first SUBSCRIBE or last 97 // UNSUBSCRIBE for a layer. It indicates which layers or associated_layers are 98 // currently being subscribed to in the system. 99 struct VmsSubscriptionsState { 100 int sequence_number; 101 std::vector<VmsLayer> layers; 102 std::vector<VmsAssociatedLayer> associated_layers; 103 }; 104 105 struct VmsAvailabilityState { 106 int sequence_number; 107 std::vector<VmsAssociatedLayer> associated_layers; 108 }; 109 110 // An enum to represent the result of parsing START_SESSION message from the VMS service. 111 enum VmsSessionStatus { 112 // When a new session is received, the client should acknowledge it with the correct 113 // IDs in the START_SESSION message. 114 kNewServerSession, 115 // When an acknowledgement it received, the client can start using the connection. 116 kAckToCurrentSession, 117 // Invalid message with either invalid format or unexpected data. 118 kInvalidMessage 119 }; 120 121 // Creates an empty base VMS message with some pre-populated default fields. 122 std::unique_ptr<VehiclePropValue> createBaseVmsMessage(size_t message_size); 123 124 // Creates a VehiclePropValue containing a message of type 125 // VmsMessageType.SUBSCRIBE, specifying to the VMS service 126 // which layer to subscribe to. 127 std::unique_ptr<VehiclePropValue> createSubscribeMessage(const VmsLayer& layer); 128 129 // Creates a VehiclePropValue containing a message of type 130 // VmsMessageType.SUBSCRIBE_TO_PUBLISHER, specifying to the VMS service 131 // which layer and publisher_id to subscribe to. 132 std::unique_ptr<VehiclePropValue> createSubscribeToPublisherMessage( 133 const VmsLayerAndPublisher& layer); 134 135 // Creates a VehiclePropValue containing a message of type 136 // VmsMessageType.UNSUBSCRIBE, specifying to the VMS service 137 // which layer to unsubscribe from. 138 std::unique_ptr<VehiclePropValue> createUnsubscribeMessage(const VmsLayer& layer); 139 140 // Creates a VehiclePropValue containing a message of type 141 // VmsMessageType.UNSUBSCRIBE_TO_PUBLISHER, specifying to the VMS service 142 // which layer and publisher_id to unsubscribe from. 143 std::unique_ptr<VehiclePropValue> createUnsubscribeToPublisherMessage( 144 const VmsLayerAndPublisher& layer); 145 146 // Creates a VehiclePropValue containing a message of type 147 // VmsMessageType.OFFERING, specifying to the VMS service which layers are being 148 // offered and their dependencies, if any. 149 std::unique_ptr<VehiclePropValue> createOfferingMessage(const VmsOffers& offers); 150 151 // Creates a VehiclePropValue containing a message of type 152 // VmsMessageType.AVAILABILITY_REQUEST. 153 std::unique_ptr<VehiclePropValue> createAvailabilityRequest(); 154 155 // Creates a VehiclePropValue containing a message of type 156 // VmsMessageType.AVAILABILITY_REQUEST. 157 std::unique_ptr<VehiclePropValue> createSubscriptionsRequest(); 158 159 // Creates a VehiclePropValue containing a message of type VmsMessageType.DATA. 160 // Returns a nullptr if the vms_packet string in bytes is empty or if the layer_publisher 161 // information in VmsLayerAndPublisher format is missing the later or publisher 162 // information. 163 // 164 // For example, to build a VehiclePropValue message containing a proto, the caller 165 // should first convert the proto to a byte string (vms_packet) using the 166 // SerializeToString proto API. Then, it use this interface to build the VehicleProperty 167 // by passing publisher and layer information (layer_publisher) and the vms_packet. 168 std::unique_ptr<VehiclePropValue> createDataMessageWithLayerPublisherInfo( 169 const VmsLayerAndPublisher& layer_publisher, const std::string& vms_packet); 170 171 // Creates a VehiclePropValue containing a message of type 172 // VmsMessageType.PUBLISHER_ID_REQUEST with the given publisher information. 173 // Returns a nullptr if the input is empty. 174 std::unique_ptr<VehiclePropValue> createPublisherIdRequest( 175 const std::string& vms_provider_description); 176 177 // Creates a VehiclePropValue message of type VmsMessageType.START_SESSION. 178 std::unique_ptr<VehiclePropValue> createStartSessionMessage(const int service_id, 179 const int client_id); 180 181 // Returns true if the VehiclePropValue pointed to by value contains a valid Vms 182 // message, i.e. the VehicleProperty, VehicleArea, and VmsMessageType are all 183 // valid. Note: If the VmsMessageType enum is extended, this function will 184 // return false for any new message types added. 185 bool isValidVmsMessage(const VehiclePropValue& value); 186 187 // Returns the message type. Expects that the VehiclePropValue contains a valid 188 // Vms message, as verified by isValidVmsMessage. 189 VmsMessageType parseMessageType(const VehiclePropValue& value); 190 191 // Constructs a string byte array from a message of type VmsMessageType.DATA. 192 // Returns an empty string if the message type doesn't match or if the 193 // VehiclePropValue does not contain a byte array. 194 // 195 // A proto message can then be constructed by passing the result of this 196 // function to ParseFromString. 197 std::string parseData(const VehiclePropValue& value); 198 199 // Returns the publisher ID by parsing the VehiclePropValue containing the ID. 200 // Returns null if the message is invalid. 201 int32_t parsePublisherIdResponse(const VehiclePropValue& publisher_id_response); 202 203 // Returns true if the new sequence number is greater than the last seen 204 // sequence number. 205 bool isSequenceNumberNewer(const VehiclePropValue& subscription_change, 206 const int last_seen_sequence_number); 207 208 // Returns sequence number of the message. 209 int32_t getSequenceNumberForSubscriptionsState(const VehiclePropValue& subscription_change); 210 211 // Takes a subscription change message and returns the layers that have active 212 // subscriptions of the layers that are offered by your HAL client/publisher. 213 // 214 // A publisher can use this function when receiving a subscription change message 215 // to determine which layers to publish data on. 216 // The caller of this function can optionally decide to not consume these layers 217 // if the subscription change has the sequence number less than the last seen 218 // sequence number. 219 std::vector<VmsLayer> getSubscribedLayers(const VehiclePropValue& subscription_change, 220 const VmsOffers& offers); 221 222 // Takes an availability change message and returns true if the parsed message implies that 223 // the service has newly started or restarted. 224 // If the message has a sequence number 0, it means that the service 225 // has newly started or restarted. 226 bool hasServiceNewlyStarted(const VehiclePropValue& availability_change); 227 228 // Takes a start session message, current service ID, current client ID; and returns the type/status 229 // of the message. It also populates the new service ID with the correct value. 230 VmsSessionStatus parseStartSessionMessage(const VehiclePropValue& start_session, 231 const int current_service_id, const int current_client_id, 232 int* new_service_id); 233 234 } // namespace vms 235 } // namespace V2_0 236 } // namespace vehicle 237 } // namespace automotive 238 } // namespace hardware 239 } // namespace android 240 241 #endif // android_hardware_automotive_vehicle_V2_0_VmsUtils_H_ 242