Fawkes API  Fawkes Development Version
openprs_inifin.cpp
1 
2 /***************************************************************************
3  * openprs_inifin.cpp - Fawkes OpenPRSAspect initializer/finalizer
4  *
5  * Created: Mon Aug 18 15:32:20 2014
6  * Copyright 2014 Tim Niemueller [www.niemueller.de]
7  ****************************************************************************/
8 
9 /* This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version. A runtime exception applies to
13  * this software (see LICENSE.GPL_WRE file mentioned below for details).
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU Library General Public License for more details.
19  *
20  * Read the full text in the LICENSE.GPL_WRE file in the doc directory.
21  */
22 
23 #include <core/threading/thread_finalizer.h>
24 #include <plugins/openprs/aspect/openprs_inifin.h>
25 #include <plugins/openprs/aspect/openprs_kernel_manager.h>
26 #include <plugins/openprs/utils/openprs_comm.h>
27 #include <plugins/openprs/utils/openprs_server_proxy.h>
28 #include <utils/time/time.h>
29 
30 #include <unistd.h>
31 
32 namespace fawkes {
33 
34 /** @class OpenPRSAspectIniFin <plugins/openprs/aspect/openprs_inifin.h>
35  * OpenPRSAspect initializer/finalizer.
36  * This initializer/finalizer will provide the OpenPRS node handle to
37  * threads with the OpenPRSAspect.
38  * @author Tim Niemueller
39  */
40 
41 /** Constructor. */
42 OpenPRSAspectIniFin::OpenPRSAspectIniFin() : AspectIniFin("OpenPRSAspect")
43 {
44  openprs_comm_ = NULL;
45  // conservative default, better wait a little longer than fail
46  kernel_timeout_sec_ = 30.;
47 }
48 
49 /** Destructor. */
51 {
52  delete openprs_comm_;
53 }
54 
55 void
57 {
58  OpenPRSAspect *openprs_thread;
59  openprs_thread = dynamic_cast<OpenPRSAspect *>(thread);
60  if (openprs_thread == NULL) {
61  throw CannotInitializeThreadException("Thread '%s' claims to have the "
62  "OpenPRSAspect, but RTTI says it "
63  "has not. ",
64  thread->name());
65  }
66 
67  openprs_kernel_mgr_->create_kernel(openprs_thread->openprs_kernel_name,
68  openprs_thread->openprs_kernel_mode == OpenPRSAspect::XOPRS,
69  openprs_thread->openprs_data_paths_,
70  openprs_thread->openprs_gdb_delay_);
71 
72  try {
73  openprs_thread->openprs = new OpenPRSComm(openprs_thread->openprs_local_name.c_str(),
74  openprs_kernel_mgr_->mp_host().c_str(),
75  openprs_kernel_mgr_->mp_port(),
76  openprs_server_proxy_);
77  } catch (Exception &e) {
78  openprs_kernel_mgr_->destroy_kernel(openprs_thread->openprs_kernel_name);
79  throw;
80  }
81 
82  fawkes::Time now, start;
83  while (!openprs_server_proxy_->has_kernel(openprs_thread->openprs_kernel_name)) {
84  now.stamp();
85  if ((now - &start) > kernel_timeout_sec_) {
86  openprs_kernel_mgr_->destroy_kernel(openprs_thread->openprs_kernel_name);
87  throw Exception("OpenPRSAspect: timeout waiting for kernel startup");
88  }
89  usleep(100000);
90  }
91 
92  openprs_comm_->transmit_command_f(openprs_thread->openprs_kernel_name,
93  "add (! (= @@FAWKES_MOD_DIR \"%s\"))",
94  OPENPRS_MOD_DIR);
95  openprs_comm_->transmit_command_f(openprs_thread->openprs_kernel_name,
96  "add (! (= @@FAWKES_HOST \"%s\"))",
97  fawkes_host_.c_str());
98  openprs_comm_->transmit_command_f(openprs_thread->openprs_kernel_name,
99  "add (! (= @@FAWKES_PORT \"%u\"))",
100  fawkes_port_);
101  openprs_comm_->transmit_command_f(openprs_thread->openprs_kernel_name,
102  "declare symbol %s",
103  openprs_thread->openprs_local_name.c_str());
104  openprs_comm_->transmit_command_f(openprs_thread->openprs_kernel_name,
105  "add (! (= @@FAWKES_MP_NAME %s))",
106  openprs_thread->openprs_local_name.c_str());
107 
108  usleep(200000);
109 }
110 
111 void
112 OpenPRSAspectIniFin::finalize(Thread *thread)
113 {
114  OpenPRSAspect *openprs_thread;
115  openprs_thread = dynamic_cast<OpenPRSAspect *>(thread);
116  if (openprs_thread == NULL) {
117  throw CannotFinalizeThreadException("Thread '%s' claims to have the "
118  "OpenPRSAspect, but RTTI says it "
119  "has not. ",
120  thread->name());
121  }
122 
123  openprs_kernel_mgr_->destroy_kernel(openprs_thread->openprs_kernel_name);
124  openprs_thread->finalize_OpenPRSAspect();
125 }
126 
127 /** Prepare OpenPRS aspect initializer.
128  * @param fawkes_host Hostname where Fawkes is running
129  * @param fawkes_port TCP port where Fawkes listens on
130  * @param openprs_kernel_mgr OpenPRS kernel manager
131  * @param openprs_server_proxy OpenPRS server proxy
132  * @param openprs_mp_proxy OpenPRS Message Passer proxy
133  */
134 void
135 OpenPRSAspectIniFin::prepare(const std::string & fawkes_host,
136  unsigned short fawkes_port,
137  LockPtr<OpenPRSKernelManager> &openprs_kernel_mgr,
138  OpenPRSServerProxy * openprs_server_proxy,
139  OpenPRSMessagePasserProxy * openprs_mp_proxy)
140 {
141  fawkes_host_ = fawkes_host;
142  fawkes_port_ = fawkes_port;
143  openprs_kernel_mgr_ = openprs_kernel_mgr;
144  openprs_server_proxy_ = openprs_server_proxy;
145  openprs_mp_proxy_ = openprs_mp_proxy;
146 
147  openprs_comm_ = new OpenPRSComm("OpenPRSAspect",
148  openprs_kernel_mgr_->mp_host().c_str(),
149  openprs_kernel_mgr_->mp_port(),
150  openprs_server_proxy_);
151 }
152 
153 /** Set timeout for kernel creation.
154  * @param timeout_sec timeout in seconds after which kernel creation
155  * is assumed to have failed.
156  */
157 void
159 {
160  kernel_timeout_sec_ = timeout_sec;
161 }
162 
163 } // end namespace fawkes
fawkes::OpenPRSAspect::openprs_kernel_mode
const Mode openprs_kernel_mode
Definition: openprs.h:62
fawkes::OpenPRSComm
Definition: openprs_comm.h:40
fawkes::OpenPRSAspect
Definition: openprs.h:42
fawkes::OpenPRSAspect::openprs_local_name
const std::string openprs_local_name
Definition: openprs.h:63
fawkes::CannotInitializeThreadException
Definition: thread_initializer.h:37
fawkes::OpenPRSMessagePasserProxy
Definition: openprs_mp_proxy.h:40
fawkes::Thread::name
const char * name() const
Definition: thread.h:99
fawkes::OpenPRSAspectIniFin::finalize
virtual void finalize(Thread *thread)
Definition: openprs_inifin.cpp:115
fawkes::OpenPRSAspect::openprs
LockPtr< OpenPRSComm > openprs
Definition: openprs.h:60
fawkes::OpenPRSAspect::openprs_kernel_name
const std::string openprs_kernel_name
Definition: openprs.h:61
fawkes::OpenPRSComm::transmit_command_f
void transmit_command_f(const std::string &recipient, const char *format,...)
Transmit a command to an OpenPRS kernel.
Definition: openprs_comm.cpp:254
fawkes
fawkes::OpenPRSAspect::XOPRS
graphical mode
Definition: openprs.h:50
fawkes::OpenPRSAspectIniFin::prepare
void prepare(const std::string &fawkes_host, unsigned short fawkes_port, LockPtr< OpenPRSKernelManager > &openprs_kernel_mgr, OpenPRSServerProxy *openprs_server_proxy, OpenPRSMessagePasserProxy *openprs_mp_proxy)
Prepare OpenPRS aspect initializer.
Definition: openprs_inifin.cpp:138
fawkes::OpenPRSAspectIniFin::set_kernel_timeout
void set_kernel_timeout(float timeout_sec)
Set timeout for kernel creation.
Definition: openprs_inifin.cpp:161
fawkes::OpenPRSAspectIniFin::~OpenPRSAspectIniFin
~OpenPRSAspectIniFin()
Destructor.
Definition: openprs_inifin.cpp:53
fawkes::Time
Definition: time.h:96
fawkes::Thread
Definition: thread.h:44
fawkes::OpenPRSAspectIniFin::init
virtual void init(Thread *thread)
Definition: openprs_inifin.cpp:59
fawkes::Time::stamp
Time & stamp()
Set this time to the current time.
Definition: time.cpp:709
fawkes::OpenPRSServerProxy::has_kernel
bool has_kernel(const std::string &kernel_name)
Check if a kernel connected to the proxy.
Definition: openprs_server_proxy.cpp:85
fawkes::CannotFinalizeThreadException
Definition: thread_finalizer.h:37
fawkes::OpenPRSServerProxy
Definition: openprs_server_proxy.h:41
fawkes::OpenPRSAspectIniFin::OpenPRSAspectIniFin
OpenPRSAspectIniFin()
Constructor.
Definition: openprs_inifin.cpp:45