• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #if defined(_WIN32)
16 #include <msvc-getopt.h>
17 #else
18 #include <getopt.h>
19 #endif
20 
21 #if defined(__linux__)
22 #include <execinfo.h>
23 #include <signal.h>
24 #include <unistd.h>
25 
26 #include <cstdio>
27 #endif
28 
29 #ifndef NETSIM_ANDROID_EMULATOR
30 #include "backend/fd_startup.h"
31 #endif
32 #include "core/server.h"
33 #include "frontend/frontend_client_stub.h"
34 #include "hci/bluetooth_facade.h"
35 #include "netsim-cxx/src/lib.rs.h"
36 
37 // Wireless network simulator for android (and other) emulated devices.
38 
39 #if defined(__linux__)
40 // Signal handler to print backtraces and then terminate the program.
SignalHandler(int sig)41 void SignalHandler(int sig) {
42   size_t buffer_size = 20;  // Number of entries in that array.
43   void *buffer[buffer_size];
44 
45   auto size = backtrace(buffer, buffer_size);
46   fprintf(stderr,
47           "netsim error: interrupt by signal %d. Obtained %d stack frames:\n",
48           sig, size);
49   backtrace_symbols_fd(buffer, size, STDERR_FILENO);
50   exit(sig);
51 }
52 #endif
53 
ArgError(char * argv[],int c)54 void ArgError(char *argv[], int c) {
55   std::cerr << argv[0] << ": invalid option -- " << (char)c << "\n";
56   std::cerr << "Try `" << argv[0] << " --help' for more information.\n";
57 }
58 
main(int argc,char * argv[])59 int main(int argc, char *argv[]) {
60 #if defined(__linux__)
61   signal(SIGSEGV, SignalHandler);
62 #endif
63   const char *kShortOpt = "s:dg";
64   const option kLongOptions[] = {
65       {"rootcanal_default_commands_file", required_argument, 0, 'c'},
66       {"rootcanal_controller_properties_file", required_argument, 0, 'p'},
67   };
68 
69   bool debug = false;
70   bool grpc_startup = false;
71   std::string fd_startup_str;
72   std::string rootcanal_default_commands_file;
73   std::string rootcanal_controller_properties_file;
74 
75   int c;
76 
77   while ((c = getopt_long(argc, argv, kShortOpt, kLongOptions, nullptr)) !=
78          -1) {
79     switch (c) {
80 #ifdef NETSIM_ANDROID_EMULATOR
81       case 'g':
82         grpc_startup = true;
83         break;
84 #else
85       case 's':
86         fd_startup_str = std::string(optarg);
87         break;
88 #endif
89       case 'd':
90         debug = true;
91         break;
92 
93       case 'c':
94         rootcanal_default_commands_file = std::string(optarg);
95         break;
96 
97       case 'p':
98         rootcanal_controller_properties_file = std::string(optarg);
99         break;
100 
101       default:
102         ArgError(argv, c);
103         return (-2);
104     }
105   }
106 
107   // Daemon mode -- start radio managers
108   if (!fd_startup_str.empty() || grpc_startup) {
109     netsim::hci::facade::Start();
110   }
111 
112 #ifdef NETSIM_ANDROID_EMULATOR
113   // get netsim daemon, starting if it doesn't exist
114   // Create a frontend grpc client to check if a netsimd is already running.
115   auto frontend_stub = netsim::frontend::NewFrontendClient();
116   if (frontend_stub == nullptr) {
117     // starts netsim in vhci connection mode
118     netsim::server::Run();
119   }
120 #else
121   if (!fd_startup_str.empty()) {
122     netsim::RunFdTransport(fd_startup_str);
123     netsim::server::Run();
124     return -1;
125   }
126 #endif
127 
128   return (0);
129 }
130