1 // Copyright 2022 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "util/os_utils.h"
16 
17 #include <fcntl.h>
18 #include <stdio.h>
19 #include <unistd.h>
20 #if defined(_WIN32)
21 #include <windows.h>
22 #endif
23 
24 #include <memory>
25 #include <string>
26 
27 #include "util/filesystem.h"
28 #include "util/ini_file.h"
29 #include "util/log.h"
30 
31 namespace netsim {
32 namespace osutils {
33 namespace {
34 
35 constexpr uint16_t DEFAULT_INSTANCE = 0;
36 constexpr uint32_t DEFAULT_HCI_PORT = 6402;
37 
38 struct DiscoveryDir {
39   const char *root_env;
40   const char *subdir;
41 };
42 
43 DiscoveryDir discovery{
44 #if defined(_WIN32)
45     "LOCALAPPDATA", "Temp"
46 #elif defined(__linux__)
47     "XDG_RUNTIME_DIR", ""
48 #elif defined(__APPLE__)
49     "HOME", "Library/Caches/TemporaryItems"
50 #else
51 #error This platform is not supported.
52 #endif
53 };
54 
55 }  // namespace
56 
GetDiscoveryDirectory()57 std::string GetDiscoveryDirectory() {
58   // $TMPDIR is the temp directory on buildbots.
59   const char *test_env_p = std::getenv("TMPDIR");
60   if (test_env_p && *test_env_p) {
61     return std::string(test_env_p);
62   }
63   const char *env_p = std::getenv(discovery.root_env);
64   if (!env_p) {
65     BtsLogWarn("No discovery env for %s, using tmp/", discovery.root_env);
66     env_p = "/tmp";
67   }
68   return std::string(env_p) + netsim::filesystem::slash + discovery.subdir;
69 }
70 
GetNetsimIniFilepath(uint16_t instance_num)71 std::string GetNetsimIniFilepath(uint16_t instance_num) {
72   auto discovery_dir = GetDiscoveryDirectory();
73   // Check if directory has a trailing slash.
74   if (discovery_dir.back() != netsim::filesystem::slash.back())
75     discovery_dir.append(netsim::filesystem::slash);
76   auto filename = (instance_num == 1)
77                       ? "netsim.ini"
78                       : "netsim_" + std::to_string(instance_num) + ".ini";
79   discovery_dir.append(filename);
80   return discovery_dir;
81 }
82 
GetServerAddress(uint16_t instance_num)83 std::optional<std::string> GetServerAddress(uint16_t instance_num) {
84   auto filepath = GetNetsimIniFilepath(instance_num);
85   if (!netsim::filesystem::exists(filepath)) {
86     BtsLogWarn("Unable to find netsim ini file: %s", filepath.c_str());
87     return std::nullopt;
88   }
89   if (!netsim::filesystem::is_regular_file(filepath)) {
90     BtsLogError("Not a regular file: %s", filepath.c_str());
91     return std::nullopt;
92   }
93   IniFile iniFile(filepath);
94   iniFile.Read();
95   return iniFile.Get("grpc.port");
96 }
97 
98 }  // namespace osutils
99 }  // namespace netsim
100