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
32namespace 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. */
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
55void
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,
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
111void
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 */
134void
135OpenPRSAspectIniFin::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 */
157void
159{
160 kernel_timeout_sec_ = timeout_sec;
161}
162
163} // end namespace fawkes
Aspect initializer/finalizer base class.
Definition: inifin.h:34
Thread cannot be finalized.
Base class for exceptions in Fawkes.
Definition: exception.h:36
LockPtr<> is a reference-counting shared lockable smartpointer.
Definition: lockptr.h:55
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.
void set_kernel_timeout(float timeout_sec)
Set timeout for kernel creation.
virtual void init(Thread *thread)
Initialize thread.
virtual void finalize(Thread *thread)
Finalize thread.
OpenPRS kernel creation and communication aspect.
Definition: openprs.h:39
LockPtr< OpenPRSComm > openprs
OpenPRS kernel communication wrapper.
Definition: openprs.h:56
const Mode openprs_kernel_mode
The kernel mode, can be OPRS or XOPRS (with graphical interface).
Definition: openprs.h:58
@ XOPRS
graphical mode
Definition: openprs.h:46
const std::string openprs_local_name
The local message passer name for communication.
Definition: openprs.h:59
const std::string openprs_kernel_name
The name of the kernel created for this thread.
Definition: openprs.h:57
OpenPRS communication wrapper.
Definition: openprs_comm.h:38
void transmit_command_f(const std::string &recipient, const char *format,...)
Transmit a command to an OpenPRS kernel.
Proxy for the OpenPRS server communication.
Proxy for the OpenPRS server communication.
bool has_kernel(const std::string &kernel_name)
Check if a kernel connected to the proxy.
Thread class encapsulation of pthreads.
Definition: thread.h:46
const char * name() const
Get name of thread.
Definition: thread.h:100
A class for handling time.
Definition: time.h:93
Time & stamp()
Set this time to the current time.
Definition: time.cpp:704
Fawkes library namespace.