3 * \brief SmartDeviceLink main application sources
4 * Copyright (c) 2013, Ford Motor Company
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
10 * Redistributions of source code must retain the above copyright notice, this
11 * list of conditions and the following disclaimer.
13 * Redistributions in binary form must reproduce the above copyright notice,
14 * this list of conditions and the following
15 * disclaimer in the documentation and/or other materials provided with the
18 * Neither the name of the Ford Motor Company nor the names of its contributors
19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
26 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 * POSSIBILITY OF SUCH DAMAGE.
43 #include <iostream> // cpplint: Streams are highly discouraged.
44 #include <fstream> // cpplint: Streams are highly discouraged.
46 // ----------------------------------------------------------------------------
48 #include "./life_cycle.h"
50 #include "utils/signals.h"
51 #include "config_profile/profile.h"
53 #if defined(EXTENDED_MEDIA_MODE)
57 #include "media_manager/media_manager_impl.h"
58 // ----------------------------------------------------------------------------
59 // Third-Party includes
60 #include "networking.h" // cpplint: Include the directory when naming .h files
62 // ----------------------------------------------------------------------------
66 const char kBrowser[] = "/usr/bin/chromium-browser";
67 const char kBrowserName[] = "chromium-browser";
68 const char kBrowserParams[] = "--auth-schemes=basic,digest,ntlm";
69 const char kLocalHostAddress[] = "127.0.0.1";
70 const char kApplicationVersion[] = "SDL_RB_3.3";
73 bool Execute(std::string command, const char * const *) {
74 log4cxx::LoggerPtr logger = log4cxx::LoggerPtr(
75 log4cxx::Logger::getLogger("appMain"));
76 if (system(command.c_str()) == -1) {
77 LOG4CXX_INFO(logger, "Can't start HMI!");
83 bool Execute(std::string file, const char * const * argv) {
84 log4cxx::LoggerPtr logger = log4cxx::LoggerPtr(
85 log4cxx::Logger::getLogger("appMain"));
86 // Create a child process.
87 pid_t pid_hmi = fork();
91 LOG4CXX_INFO(logger, "fork() failed!");
94 case 0: { // Child process
95 int32_t fd_dev0 = open("/dev/null", O_RDWR, S_IWRITE);
97 LOG4CXX_WARN(logger, "Open dev0 failed!");
100 // close input/output file descriptors.
102 close(STDOUT_FILENO);
103 close(STDERR_FILENO);
105 // move input/output to /dev/null.
106 dup2(fd_dev0, STDIN_FILENO);
107 dup2(fd_dev0, STDOUT_FILENO);
108 dup2(fd_dev0, STDERR_FILENO);
110 // Execute the program.
111 if (execvp(file.c_str(), const_cast<char* const *>(argv)) == -1) {
112 LOG4CXX_ERROR_WITH_ERRNO(logger, "execvp() failed! Can't start HMI!");
118 default: { /* Parent process */
119 LOG4CXX_INFO(logger, "Process created with pid " << pid_hmi);
128 * Initialize HTML based HMI.
129 * @return true if success otherwise false.
132 log4cxx::LoggerPtr logger = log4cxx::LoggerPtr(
133 log4cxx::Logger::getLogger("appMain"));
136 if (stat("hmi_link", &sb) == -1) {
137 LOG4CXX_INFO(logger, "File with HMI link doesn't exist!");
141 std::ifstream file_str;
142 file_str.open("hmi_link");
144 if (!file_str.is_open()) {
145 LOG4CXX_INFO(logger, "File with HMI link was not opened!");
149 file_str.seekg(0, std::ios::end);
150 int32_t length = file_str.tellg();
151 file_str.seekg(0, std::ios::beg);
153 std::string hmi_link;
154 std::getline(file_str, hmi_link);
158 "Input string:" << hmi_link << " length = " << hmi_link.size());
161 if (stat(hmi_link.c_str(), &sb) == -1) {
162 LOG4CXX_INFO(logger, "HMI index.html doesn't exist!");
166 std::string kBin = kBrowser;
167 const char* const kParams[4] = {kBrowserName, kBrowserParams,
168 hmi_link.c_str(), NULL};
170 return Execute(kBin, kParams);
176 * Initialize HTML based HMI.
177 * @return true if success otherwise false.
180 log4cxx::LoggerPtr logger = log4cxx::LoggerPtr(
181 log4cxx::Logger::getLogger("appMain"));
182 std::string kStartHmi = "./start_hmi.sh";
184 if (stat(kStartHmi.c_str(), &sb) == -1) {
185 LOG4CXX_INFO(logger, "HMI start script doesn't exist!");
189 return Execute(kStartHmi, NULL);
196 * \brief Entry point of the program.
197 * \param argc number of argument
198 * \param argv array of arguments
199 * \return EXIT_SUCCESS or EXIT_FAILURE
201 int32_t main(int32_t argc, char** argv) {
203 // --------------------------------------------------------------------------
204 // Logger initialization
206 log4cxx::LoggerPtr logger = log4cxx::LoggerPtr(
207 log4cxx::Logger::getLogger("appMain"));
208 log4cxx::PropertyConfigurator::configure("log4cxx.properties");
210 threads::Thread::SetNameForId(threads::Thread::CurrentId(), "MainThread");
212 LOG4CXX_INFO(logger, "Application started!");
213 LOG4CXX_INFO(logger, "Application version " << kApplicationVersion);
215 // Initialize gstreamer. Needed to activate debug from the command line.
216 #if defined(EXTENDED_MEDIA_MODE)
217 gst_init(&argc, &argv);
220 // --------------------------------------------------------------------------
221 // Components initialization
222 if ((argc > 1)&&(0 != argv)) {
223 profile::Profile::instance()->config_file_name(argv[1]);
225 profile::Profile::instance()->config_file_name("smartDeviceLink.ini");
228 main_namespace::LifeCycle::instance()->StartComponents();
230 // --------------------------------------------------------------------------
231 // Third-Party components initialization.
233 if (!main_namespace::LifeCycle::instance()->InitMessageSystem()) {
234 main_namespace::LifeCycle::instance()->StopComponents();
235 // without this line log4cxx threads continue using some instances destroyed by exit()
236 log4cxx::Logger::getRootLogger()->closeNestedAppenders();
239 LOG4CXX_INFO(logger, "InitMessageBroker successful");
241 if (profile::Profile::instance()->launch_hmi()) {
242 if (profile::Profile::instance()->server_address() ==
243 std::string(kLocalHostAddress)) {
244 LOG4CXX_INFO(logger, "Start HMI on localhost");
248 main_namespace::LifeCycle::instance()->StopComponents();
249 // without this line log4cxx threads continue using some instances destroyed by exit()
250 log4cxx::Logger::getRootLogger()->closeNestedAppenders();
253 LOG4CXX_INFO(logger, "InitHmi successful");
254 #endif // #ifndef NO_HMI
257 // --------------------------------------------------------------------------
259 utils::SubscribeToTerminateSignal(
260 &main_namespace::LifeCycle::StopComponentsOnSignal);