1 /*
2  * Copyright (C) 2022 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 <android-base/logging.h>
18 #include <common/libs/fs/shared_buf.h>
19 #include <gflags/gflags.h>
20 #include <host/libs/config/logging.h>
21 #include "host/libs/config/cuttlefish_config.h"
22 
23 #include "host/libs/location/GnssClient.h"
24 #include "host/libs/location/GpxParser.h"
25 #include "host/libs/location/KmlParser.h"
26 
27 DEFINE_int32(instance_num, 1, "Which instance to read the configs from");
28 DEFINE_double(delay, 1.0, "delay interval between different coordinates");
29 
30 DEFINE_string(format, "", "supported file format, either kml or gpx");
31 DEFINE_string(file_path, "", "path to input file location {Kml or gpx} format");
32 
33 const char* kUsageMessage = R""""(gps locations import commandline utility
34 
35 Usage: cvd_import_locations [option] command [args...]
36 
37 arguments:
38 
39   --format=[format_string]
40     input file format for cvd_import_locations
41         "gpx" for gpx input data file
42         "kml" for kml input data file
43 
44   --file_path=[path]
45     gps locations input file path
46     if path is not specified, error will be reported
47 
48   --delay=[delay_value]
49     delay between different gps locations ( double , default value is 1.0 second)
50 
51   --instance_num=[integer_value]
52     running instance number , starts from 1 ( integer , default value is 1)
53 
54 examples:
55 
56     cvd_import_locations --format="gpx" --file_path="input.gpx"
57     cvd_import_locations --format="kml" --file_path="input.kml"
58 
59     cvd_import_locations --format="gpx" --file_path="input.gpx" --delay=.5
60     cvd_import_locations --format="kml" --file_path="input.kml" --delay=.5
61 
62     cvd_import_locations --format="gpx" --file_path="input.gpx" --delay=.5 --instance_num=2
63 
64 )"""";
65 namespace cuttlefish {
66 namespace {
67 
ImportLocationsCvdMain(int argc,char ** argv)68 int ImportLocationsCvdMain(int argc, char** argv) {
69   ::android::base::InitLogging(argv, android::base::StderrLogger);
70   google::ParseCommandLineFlags(&argc, &argv, true);
71 
72   auto config = CuttlefishConfig::Get();
73   if (!config) {
74     LOG(ERROR) << "Failed to obtain config object";
75     return 1;
76   }
77   std::set<std::string> supportedFormat = {"gpx", "GPX", "kml", "KML"};
78 
79   if (supportedFormat.count(FLAGS_format) == 0) {
80     LOG(ERROR) << "Unsupported parsing format" << std::endl;
81     return 1;
82   }
83   LOG(INFO) << FLAGS_format << " Supported format" << std::endl;
84   auto instance = config->ForInstance(FLAGS_instance_num);
85   auto server_port = instance.gnss_grpc_proxy_server_port();
86   std::string socket_name =
87       std::string("localhost:") + std::to_string(server_port);
88   GnssClient gpsclient(
89       grpc::CreateChannel(socket_name, grpc::InsecureChannelCredentials()));
90 
91   GpsFixArray coordinates;
92   std::string error;
93   bool isOk = false;
94 
95   LOG(INFO) << "Server port: " << server_port << " socket: " << socket_name
96             << std::endl;
97   if (FLAGS_format == "gpx" || FLAGS_format == "GPX") {
98     isOk =
99         GpxParser::parseFile(FLAGS_file_path.c_str(), &coordinates, &error);
100   } else if (FLAGS_format == "kml" || FLAGS_format == "KML") {
101     isOk =
102         KmlParser::parseFile(FLAGS_file_path.c_str(), &coordinates, &error);
103   }
104 
105   LOG(INFO) << "Number of parsed points: " << coordinates.size() << std::endl;
106 
107   if (!isOk) {
108     LOG(ERROR) << " Parsing Error: " << error << std::endl;
109     return 1;
110   }
111 
112   int delay = (int)(1000 * FLAGS_delay);
113   auto status = gpsclient.SendGpsLocations(delay,coordinates);
114   CHECK(status.ok()) << "Failed to send gps location data \n";
115   if (!status.ok()) {
116     return 1;
117   }
118   std::this_thread::sleep_for(std::chrono::milliseconds(delay));
119   return 0;
120 }
121 
122 }  // namespace
123 }  // namespace cuttlefish
124 
main(int argc,char ** argv)125 int main(int argc, char** argv) {
126   gflags::SetUsageMessage(kUsageMessage);
127   return cuttlefish::ImportLocationsCvdMain(argc, argv);
128 }