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 #include "VmsUtils.h"
18 
19 #include <common/include/vhal_v2_0/VehicleUtils.h>
20 
21 namespace android {
22 namespace hardware {
23 namespace automotive {
24 namespace vehicle {
25 namespace V2_0 {
26 namespace vms {
27 
28 static constexpr int kMessageIndex = toInt(VmsBaseMessageIntegerValuesIndex::MESSAGE_TYPE);
29 static constexpr int kMessageTypeSize = 1;
30 static constexpr int kPublisherIdSize = 1;
31 static constexpr int kLayerNumberSize = 1;
32 static constexpr int kLayerSize = 3;
33 static constexpr int kLayerAndPublisherSize = 4;
34 static constexpr int kSessionIdsSize = 2;
35 static constexpr int kPublisherIdIndex =
36         toInt(VmsPublisherInformationIntegerValuesIndex::PUBLISHER_ID);
37 static constexpr int kSubscriptionStateSequenceNumberIndex =
38         toInt(VmsSubscriptionsStateIntegerValuesIndex::SEQUENCE_NUMBER);
39 static constexpr int kAvailabilitySequenceNumberIndex =
40         toInt(VmsAvailabilityStateIntegerValuesIndex::SEQUENCE_NUMBER);
41 
42 // TODO(aditin): We should extend the VmsMessageType enum to include a first and
43 // last, which would prevent breakages in this API. However, for all of the
44 // functions in this module, we only need to guarantee that the message type is
45 // between SUBSCRIBE and START_SESSION.
46 static constexpr int kFirstMessageType = toInt(VmsMessageType::SUBSCRIBE);
47 static constexpr int kLastMessageType = toInt(VmsMessageType::START_SESSION);
48 
createBaseVmsMessage(size_t message_size)49 std::unique_ptr<VehiclePropValue> createBaseVmsMessage(size_t message_size) {
50     auto result = createVehiclePropValue(VehiclePropertyType::INT32, message_size);
51     result->prop = toInt(VehicleProperty::VEHICLE_MAP_SERVICE);
52     result->areaId = toInt(VehicleArea::GLOBAL);
53     return result;
54 }
55 
createSubscribeMessage(const VmsLayer & layer)56 std::unique_ptr<VehiclePropValue> createSubscribeMessage(const VmsLayer& layer) {
57     auto result = createBaseVmsMessage(kMessageTypeSize + kLayerSize);
58     result->value.int32Values = hidl_vec<int32_t>{toInt(VmsMessageType::SUBSCRIBE), layer.type,
59                                                   layer.subtype, layer.version};
60     return result;
61 }
62 
createSubscribeToPublisherMessage(const VmsLayerAndPublisher & layer_publisher)63 std::unique_ptr<VehiclePropValue> createSubscribeToPublisherMessage(
64     const VmsLayerAndPublisher& layer_publisher) {
65     auto result = createBaseVmsMessage(kMessageTypeSize + kLayerAndPublisherSize);
66     result->value.int32Values = hidl_vec<int32_t>{
67         toInt(VmsMessageType::SUBSCRIBE_TO_PUBLISHER), layer_publisher.layer.type,
68         layer_publisher.layer.subtype, layer_publisher.layer.version, layer_publisher.publisher_id};
69     return result;
70 }
71 
createUnsubscribeMessage(const VmsLayer & layer)72 std::unique_ptr<VehiclePropValue> createUnsubscribeMessage(const VmsLayer& layer) {
73     auto result = createBaseVmsMessage(kMessageTypeSize + kLayerSize);
74     result->value.int32Values = hidl_vec<int32_t>{toInt(VmsMessageType::UNSUBSCRIBE), layer.type,
75                                                   layer.subtype, layer.version};
76     return result;
77 }
78 
createUnsubscribeToPublisherMessage(const VmsLayerAndPublisher & layer_publisher)79 std::unique_ptr<VehiclePropValue> createUnsubscribeToPublisherMessage(
80     const VmsLayerAndPublisher& layer_publisher) {
81     auto result = createBaseVmsMessage(kMessageTypeSize + kLayerAndPublisherSize);
82     result->value.int32Values = hidl_vec<int32_t>{
83         toInt(VmsMessageType::UNSUBSCRIBE_TO_PUBLISHER), layer_publisher.layer.type,
84         layer_publisher.layer.subtype, layer_publisher.layer.version, layer_publisher.publisher_id};
85     return result;
86 }
87 
createOfferingMessage(const VmsOffers & offers)88 std::unique_ptr<VehiclePropValue> createOfferingMessage(const VmsOffers& offers) {
89     int message_size = kMessageTypeSize + kPublisherIdSize + kLayerNumberSize;
90     for (const auto& offer : offers.offerings) {
91         message_size += kLayerSize + kLayerNumberSize + (offer.dependencies.size() * kLayerSize);
92     }
93     auto result = createBaseVmsMessage(message_size);
94 
95     std::vector<int32_t> offerings = {toInt(VmsMessageType::OFFERING), offers.publisher_id,
96                                       static_cast<int>(offers.offerings.size())};
97     for (const auto& offer : offers.offerings) {
98         std::vector<int32_t> layer_vector = {offer.layer.type, offer.layer.subtype,
99                                              offer.layer.version,
100                                              static_cast<int32_t>(offer.dependencies.size())};
101         for (const auto& dependency : offer.dependencies) {
102             std::vector<int32_t> dependency_layer = {dependency.type, dependency.subtype,
103                                                      dependency.version};
104             layer_vector.insert(layer_vector.end(), dependency_layer.begin(),
105                                 dependency_layer.end());
106         }
107         offerings.insert(offerings.end(), layer_vector.begin(), layer_vector.end());
108     }
109     result->value.int32Values = offerings;
110     return result;
111 }
112 
createAvailabilityRequest()113 std::unique_ptr<VehiclePropValue> createAvailabilityRequest() {
114     auto result = createBaseVmsMessage(kMessageTypeSize);
115     result->value.int32Values = hidl_vec<int32_t>{
116         toInt(VmsMessageType::AVAILABILITY_REQUEST),
117     };
118     return result;
119 }
120 
createSubscriptionsRequest()121 std::unique_ptr<VehiclePropValue> createSubscriptionsRequest() {
122     auto result = createBaseVmsMessage(kMessageTypeSize);
123     result->value.int32Values = hidl_vec<int32_t>{
124         toInt(VmsMessageType::SUBSCRIPTIONS_REQUEST),
125     };
126     return result;
127 }
128 
createDataMessageWithLayerPublisherInfo(const VmsLayerAndPublisher & layer_publisher,const std::string & vms_packet)129 std::unique_ptr<VehiclePropValue> createDataMessageWithLayerPublisherInfo(
130         const VmsLayerAndPublisher& layer_publisher, const std::string& vms_packet) {
131     auto result = createBaseVmsMessage(kMessageTypeSize + kLayerAndPublisherSize);
132     result->value.int32Values = hidl_vec<int32_t>{
133             toInt(VmsMessageType::DATA), layer_publisher.layer.type, layer_publisher.layer.subtype,
134             layer_publisher.layer.version, layer_publisher.publisher_id};
135     result->value.bytes = std::vector<uint8_t>(vms_packet.begin(), vms_packet.end());
136     return result;
137 }
138 
createPublisherIdRequest(const std::string & vms_provider_description)139 std::unique_ptr<VehiclePropValue> createPublisherIdRequest(
140         const std::string& vms_provider_description) {
141     auto result = createBaseVmsMessage(kMessageTypeSize);
142     result->value.int32Values = hidl_vec<int32_t>{
143             toInt(VmsMessageType::PUBLISHER_ID_REQUEST),
144     };
145     result->value.bytes =
146             std::vector<uint8_t>(vms_provider_description.begin(), vms_provider_description.end());
147     return result;
148 }
149 
createStartSessionMessage(const int service_id,const int client_id)150 std::unique_ptr<VehiclePropValue> createStartSessionMessage(const int service_id,
151                                                             const int client_id) {
152     auto result = createBaseVmsMessage(kMessageTypeSize + kSessionIdsSize);
153     result->value.int32Values = hidl_vec<int32_t>{
154             toInt(VmsMessageType::START_SESSION),
155             service_id,
156             client_id,
157     };
158     return result;
159 }
160 
isValidVmsProperty(const VehiclePropValue & value)161 bool isValidVmsProperty(const VehiclePropValue& value) {
162     return (value.prop == toInt(VehicleProperty::VEHICLE_MAP_SERVICE));
163 }
164 
isValidVmsMessageType(const VehiclePropValue & value)165 bool isValidVmsMessageType(const VehiclePropValue& value) {
166     return (value.value.int32Values.size() > 0 &&
167             value.value.int32Values[kMessageIndex] >= kFirstMessageType &&
168             value.value.int32Values[kMessageIndex] <= kLastMessageType);
169 }
170 
isValidVmsMessage(const VehiclePropValue & value)171 bool isValidVmsMessage(const VehiclePropValue& value) {
172     return (isValidVmsProperty(value) && isValidVmsMessageType(value));
173 }
174 
parseMessageType(const VehiclePropValue & value)175 VmsMessageType parseMessageType(const VehiclePropValue& value) {
176     return static_cast<VmsMessageType>(value.value.int32Values[kMessageIndex]);
177 }
178 
parseData(const VehiclePropValue & value)179 std::string parseData(const VehiclePropValue& value) {
180     if (isValidVmsMessage(value) && parseMessageType(value) == VmsMessageType::DATA &&
181         value.value.bytes.size() > 0) {
182         return std::string(value.value.bytes.begin(), value.value.bytes.end());
183     } else {
184         return std::string();
185     }
186 }
187 
parsePublisherIdResponse(const VehiclePropValue & publisher_id_response)188 int32_t parsePublisherIdResponse(const VehiclePropValue& publisher_id_response) {
189     if (isValidVmsMessage(publisher_id_response) &&
190         parseMessageType(publisher_id_response) == VmsMessageType::PUBLISHER_ID_RESPONSE &&
191         publisher_id_response.value.int32Values.size() > kPublisherIdIndex) {
192         return publisher_id_response.value.int32Values[kPublisherIdIndex];
193     }
194     return -1;
195 }
196 
isSequenceNumberNewer(const VehiclePropValue & subscriptions_state,const int last_seen_sequence_number)197 bool isSequenceNumberNewer(const VehiclePropValue& subscriptions_state,
198                            const int last_seen_sequence_number) {
199     return (isValidVmsMessage(subscriptions_state) &&
200             (parseMessageType(subscriptions_state) == VmsMessageType::SUBSCRIPTIONS_CHANGE ||
201              parseMessageType(subscriptions_state) == VmsMessageType::SUBSCRIPTIONS_RESPONSE) &&
202             subscriptions_state.value.int32Values.size() > kSubscriptionStateSequenceNumberIndex &&
203             subscriptions_state.value.int32Values[kSubscriptionStateSequenceNumberIndex] >
204                     last_seen_sequence_number);
205 }
206 
getSequenceNumberForSubscriptionsState(const VehiclePropValue & subscriptions_state)207 int32_t getSequenceNumberForSubscriptionsState(const VehiclePropValue& subscriptions_state) {
208     if (isValidVmsMessage(subscriptions_state) &&
209         (parseMessageType(subscriptions_state) == VmsMessageType::SUBSCRIPTIONS_CHANGE ||
210          parseMessageType(subscriptions_state) == VmsMessageType::SUBSCRIPTIONS_RESPONSE) &&
211         subscriptions_state.value.int32Values.size() > kSubscriptionStateSequenceNumberIndex) {
212         return subscriptions_state.value.int32Values[kSubscriptionStateSequenceNumberIndex];
213     }
214     return -1;
215 }
216 
getSubscribedLayers(const VehiclePropValue & subscriptions_state,const VmsOffers & offers)217 std::vector<VmsLayer> getSubscribedLayers(const VehiclePropValue& subscriptions_state,
218                                           const VmsOffers& offers) {
219     if (isValidVmsMessage(subscriptions_state) &&
220         (parseMessageType(subscriptions_state) == VmsMessageType::SUBSCRIPTIONS_CHANGE ||
221          parseMessageType(subscriptions_state) == VmsMessageType::SUBSCRIPTIONS_RESPONSE) &&
222         subscriptions_state.value.int32Values.size() >
223                 toInt(VmsSubscriptionsStateIntegerValuesIndex::NUMBER_OF_LAYERS)) {
224         int subscriptions_state_int_size = subscriptions_state.value.int32Values.size();
225         std::unordered_set<VmsLayer, VmsLayer::VmsLayerHashFunction> offered_layers;
226         for (const auto& offer : offers.offerings) {
227             offered_layers.insert(offer.layer);
228         }
229         std::vector<VmsLayer> subscribed_layers;
230 
231         int current_index = toInt(VmsSubscriptionsStateIntegerValuesIndex::SUBSCRIPTIONS_START);
232 
233         // Add all subscribed layers which are offered by the current publisher.
234         const int32_t num_of_layers = subscriptions_state.value.int32Values[toInt(
235                 VmsSubscriptionsStateIntegerValuesIndex::NUMBER_OF_LAYERS)];
236         for (int i = 0; i < num_of_layers; i++) {
237             if (subscriptions_state_int_size < current_index + kLayerSize) {
238                 return {};
239             }
240             VmsLayer layer = VmsLayer(subscriptions_state.value.int32Values[current_index],
241                                       subscriptions_state.value.int32Values[current_index + 1],
242                                       subscriptions_state.value.int32Values[current_index + 2]);
243             if (offered_layers.find(layer) != offered_layers.end()) {
244                 subscribed_layers.push_back(std::move(layer));
245             }
246             current_index += kLayerSize;
247         }
248 
249         // Add all subscribed associated layers which are offered by the current publisher.
250         // For this, we need to check if the associated layer has a publisher ID which is
251         // same as that of the current publisher.
252         if (subscriptions_state_int_size >
253             toInt(VmsSubscriptionsStateIntegerValuesIndex::NUMBER_OF_ASSOCIATED_LAYERS)) {
254             const int32_t num_of_associated_layers = subscriptions_state.value.int32Values[toInt(
255                     VmsSubscriptionsStateIntegerValuesIndex::NUMBER_OF_ASSOCIATED_LAYERS)];
256 
257             for (int i = 0; i < num_of_associated_layers; i++) {
258                 if (subscriptions_state_int_size < current_index + kLayerSize) {
259                     return {};
260                 }
261                 VmsLayer layer = VmsLayer(subscriptions_state.value.int32Values[current_index],
262                                           subscriptions_state.value.int32Values[current_index + 1],
263                                           subscriptions_state.value.int32Values[current_index + 2]);
264                 current_index += kLayerSize;
265                 if (offered_layers.find(layer) != offered_layers.end() &&
266                     subscriptions_state_int_size > current_index) {
267                     int32_t num_of_publisher_ids =
268                             subscriptions_state.value.int32Values[current_index];
269                     current_index++;
270                     for (int j = 0; j < num_of_publisher_ids; j++) {
271                         if (subscriptions_state_int_size > current_index &&
272                             subscriptions_state.value.int32Values[current_index] ==
273                                     offers.publisher_id) {
274                             subscribed_layers.push_back(std::move(layer));
275                         }
276                         current_index++;
277                     }
278                 }
279             }
280         }
281         return subscribed_layers;
282     }
283     return {};
284 }
285 
hasServiceNewlyStarted(const VehiclePropValue & availability_change)286 bool hasServiceNewlyStarted(const VehiclePropValue& availability_change) {
287     return (isValidVmsMessage(availability_change) &&
288             parseMessageType(availability_change) == VmsMessageType::AVAILABILITY_CHANGE &&
289             availability_change.value.int32Values.size() > kAvailabilitySequenceNumberIndex &&
290             availability_change.value.int32Values[kAvailabilitySequenceNumberIndex] == 0);
291 }
292 
parseStartSessionMessage(const VehiclePropValue & start_session,const int current_service_id,const int current_client_id,int * new_service_id)293 VmsSessionStatus parseStartSessionMessage(const VehiclePropValue& start_session,
294                                           const int current_service_id, const int current_client_id,
295                                           int* new_service_id) {
296     if (isValidVmsMessage(start_session) &&
297         parseMessageType(start_session) == VmsMessageType::START_SESSION &&
298         start_session.value.int32Values.size() == kSessionIdsSize + 1) {
299         *new_service_id = start_session.value.int32Values[1];
300         const int new_client_id = start_session.value.int32Values[2];
301         if (new_client_id != current_client_id) {
302             // If the new_client_id = -1, it means the service has newly started.
303             // But if it is not -1 and is different than the current client ID, then
304             // it means that the service did not have the correct client ID. In
305             // both these cases, the client should acknowledge with a START_SESSION
306             // message containing the correct client ID. So here, the status is returned as
307             // kNewServerSession.
308             return VmsSessionStatus::kNewServerSession;
309         } else {
310             // kAckToCurrentSession is returned if the new client ID is same as the current one.
311             return VmsSessionStatus::kAckToCurrentSession;
312         }
313     }
314     // If the message is invalid then persist the old service ID.
315     *new_service_id = current_service_id;
316     return VmsSessionStatus::kInvalidMessage;
317 }
318 
isAvailabilitySequenceNumberNewer(const VehiclePropValue & availability_state,const int last_seen_availability_sequence_number)319 bool isAvailabilitySequenceNumberNewer(const VehiclePropValue& availability_state,
320                                        const int last_seen_availability_sequence_number) {
321     return (isValidVmsMessage(availability_state) &&
322             (parseMessageType(availability_state) == VmsMessageType::AVAILABILITY_CHANGE ||
323              parseMessageType(availability_state) == VmsMessageType::AVAILABILITY_RESPONSE) &&
324             availability_state.value.int32Values.size() > kAvailabilitySequenceNumberIndex &&
325             availability_state.value.int32Values[kAvailabilitySequenceNumberIndex] >
326                     last_seen_availability_sequence_number);
327 }
328 
getSequenceNumberForAvailabilityState(const VehiclePropValue & availability_state)329 int32_t getSequenceNumberForAvailabilityState(const VehiclePropValue& availability_state) {
330     if (isValidVmsMessage(availability_state) &&
331         (parseMessageType(availability_state) == VmsMessageType::AVAILABILITY_CHANGE ||
332          parseMessageType(availability_state) == VmsMessageType::AVAILABILITY_RESPONSE) &&
333         availability_state.value.int32Values.size() > kAvailabilitySequenceNumberIndex) {
334         return availability_state.value.int32Values[kAvailabilitySequenceNumberIndex];
335     }
336     return -1;
337 }
338 
getAvailableLayers(const VehiclePropValue & availability_state)339 std::vector<VmsAssociatedLayer> getAvailableLayers(const VehiclePropValue& availability_state) {
340     if (isValidVmsMessage(availability_state) &&
341         (parseMessageType(availability_state) == VmsMessageType::AVAILABILITY_CHANGE ||
342          parseMessageType(availability_state) == VmsMessageType::AVAILABILITY_RESPONSE) &&
343         availability_state.value.int32Values.size() >
344                 toInt(VmsAvailabilityStateIntegerValuesIndex::NUMBER_OF_ASSOCIATED_LAYERS)) {
345         int availability_state_int_size = availability_state.value.int32Values.size();
346         const int32_t num_of_associated_layers = availability_state.value.int32Values[toInt(
347                 VmsAvailabilityStateIntegerValuesIndex::NUMBER_OF_ASSOCIATED_LAYERS)];
348         int current_index = toInt(VmsAvailabilityStateIntegerValuesIndex::LAYERS_START);
349         std::vector<VmsAssociatedLayer> available_layers;
350         for (int i = 0; i < num_of_associated_layers; i++) {
351             if (availability_state_int_size < current_index + kLayerSize) {
352                 return {};
353             }
354             VmsLayer layer = VmsLayer(availability_state.value.int32Values[current_index],
355                                       availability_state.value.int32Values[current_index + 1],
356                                       availability_state.value.int32Values[current_index + 2]);
357             current_index += kLayerSize;
358             std::vector<int> publisher_ids;
359             if (availability_state_int_size > current_index) {
360                 int32_t num_of_publisher_ids = availability_state.value.int32Values[current_index];
361                 current_index++;
362                 for (int j = 0; j < num_of_publisher_ids; j++) {
363                     if (availability_state_int_size > current_index) {
364                         publisher_ids.push_back(
365                                 availability_state.value.int32Values[current_index]);
366                         current_index++;
367                     }
368                 }
369             }
370             available_layers.emplace_back(layer, std::move(publisher_ids));
371         }
372         return available_layers;
373     }
374     return {};
375 }
376 
377 }  // namespace vms
378 }  // namespace V2_0
379 }  // namespace vehicle
380 }  // namespace automotive
381 }  // namespace hardware
382 }  // namespace android
383