]> pilppa.org Git - libplpbus.git/blob - src/plpbus/BusClient.cc
75583fe4cd9ffaf008830944d825403348eebff4
[libplpbus.git] / src / plpbus / BusClient.cc
1 /*
2  * BusClient.cc
3  *
4  *  Created on: Jun 7, 2010
5  *      Author: lamikr
6  */
7
8 #include <malloc.h>
9 #include <plp/log.h>
10 #include <plp/retval.h>
11
12 #include "BusClient.hh"
13 #include "ClientServerCommon.hh"
14 #include "BusMessageInternal.hh"
15 #include "RequestResponseBus.hh"
16
17 using namespace std;
18 using namespace plpbus;
19 using namespace plpbus_orb;
20
21 class OrbClientImpl : public virtual POA_plpbus_orb::OrbClient {
22         private:
23                 IClientListener *listener;
24         public:
25                 OrbClientImpl(IClientListener *listener_param)  {
26                         listener        = listener_param;
27                 }
28                 virtual ~OrbClientImpl() {}
29
30                 virtual void receive_event_message(const char *event_param) {
31                         if (listener != NULL) {
32                                 listener->event_received(event_param);
33                         }
34                 }
35
36                 virtual void receive_event_dataitem_sequence(const ::plpbus_orb::DataItemSequence& event_param) {
37                         BusMessageInternal      *bus_msg;
38
39                         if (listener != NULL) {
40                                 bus_msg = new BusMessageInternal(event_param);
41                                 listener->event_received(bus_msg);
42                         }
43                 }
44
45                 virtual void receive_response_message(const char *msg_rsp_param) {
46                         if (listener != NULL) {
47                                 listener->response_received(msg_rsp_param);
48                         }
49                 }
50
51                 virtual void receive_response_dataitem_sequence(const ::plpbus_orb::DataItemSequence& msg_rsp_param) {
52                         const BusMessageInternal        *bus_msg;
53
54                         if (listener != NULL) {
55                                 bus_msg = new BusMessageInternal(msg_rsp_param);
56                                 listener->response_received(bus_msg);
57                                 delete(bus_msg);
58                         }
59                 }
60 };
61
62 BusClient::BusClient()
63 {
64         log_debug("created\n");;
65         _orb            = NULL;
66         _poa            = NULL;
67 }
68
69 BusClient::~BusClient()
70 {
71         if (_poa != NULL) {
72                 //_poa->destroy(true, true);
73         }
74         if (_orb != NULL) {
75                 _orb->destroy();
76                 _orb    = NULL;
77         }
78         log_debug("destroyed\n");
79 }
80
81 int BusClient::init(const char *server_name) {
82         int                     argc;
83         char                    **argv;
84         CORBA::Object_var       server_obj;
85         int                     ret_val;
86
87         argc    = 0;
88         argv    = NULL;
89         ret_val = PLP_ERR;
90         log_info("CORBA client init() started\n");
91         _orb    = CORBA::ORB_init(argc, argv);
92         if (CORBA::is_nil(_orb) == false) {
93                 log_debug("ORB_init() done, finding server: %s\n", server_name);
94                 server_obj      = find_server_object_by_name(_orb,
95                                                         CONST_CONTEXT_NAME__PLPBUS,
96                                                         CONST_CONTEXT_KIND__PLPBUS,
97                                                         server_name,
98                                                         CONST_CONTEXT_NAME__PLPBUS);
99                 if (CORBA::is_nil(server_obj) == false) {
100                         _server         = plpbus_orb::OrbServer::_narrow(server_obj);
101                         if (CORBA::is_nil(_server) == false) {
102                                 log_info("CORBA service found: %s", server_name);
103                                 ret_val = PLP_OK;
104                         }
105                 }
106                 else {
107                         log_error("Could not find CORBA service: %s\n", server_name);
108                 }
109         }
110         else {
111                 log_error("Could not init CORBA client\n");
112         }
113         return ret_val;
114 }
115
116 int BusClient::add_client_listener(IClientListener *listener_param) {
117         log_debug("add_client_listener() started\n");
118         if (_poa == NULL) {
119                 OrbClientImpl                   *client_cb;
120                 PortableServer::ObjectId_var    oid;
121
122                 _poa            = create_poa(_orb);
123                 client_cb       = new OrbClientImpl(listener_param);
124                 oid             = _poa->activate_object(client_cb);
125                 _client         = client_cb->_this();
126                 client_cb->_remove_ref();
127                 _server->add_event_listener(_client, "event_message", CONST_DEFAULT_EVENT_INTERVAL);
128         }
129         log_debug("add_client_listener() done\n");
130         return 0;
131 }
132
133 int BusClient::send_message_and_request_response(const char *msg_req_param) {
134         _server->send_message_and_request_response(_client, msg_req_param);
135         return 0;
136 }
137
138 int BusClient::send_message_and_wait_response(const char *msg_req_param, char **msg_rsp_param) {
139         CORBA::Long     ret_val;
140         char            *rsp;
141
142         rsp             = _server->send_message_and_wait_response(msg_req_param, ret_val);
143         *msg_rsp_param  = strdup(rsp);
144         CORBA::string_free(rsp);
145         return ret_val;
146 }
147
148 int BusClient::send_message_and_request_response(const BusMessage *msg_req_param) {
149         DataItemSequence        *seq;
150
151         seq     = (DataItemSequence *)msg_req_param->_dataItemSeq;
152         _server->send_dataitem_message_and_request_response(_client, *seq);
153         return 0;
154 }
155
156 int BusClient::send_message_and_wait_response(const BusMessage *msg_req_param, BusMessage **msg_rsp_param) {
157         DataItemSequence        *seq_rsp;
158         DataItemSequence        *seq;
159
160         seq_rsp = NULL;
161         seq     = (DataItemSequence *)msg_req_param->_dataItemSeq;
162         _server->send_dataitem_message_and_wait_response(*seq, seq_rsp);
163         *msg_rsp_param  = new BusMessageInternal(*seq_rsp);
164         return 0;
165 }
166
167 void BusClient::request_shutdown() {
168         if (CORBA::is_nil(_server) == false) {
169                 _server->shutdown();
170         }
171 }
172
173 PortableServer::POA_var BusClient::create_poa(CORBA::ORB_var orb) {
174         PortableServer::POA_var         ret_val;
175         CORBA::Object_var               poa_obj;
176         CORBA::PolicyList               policy_list;
177         CORBA::Any                      policyVal;
178         PortableServer::POAManager_var  poa_man;
179         PortableServer::POA_var         rootpoa;
180
181         ret_val = NULL;
182         poa_obj = orb->resolve_initial_references(CONST_ROOT_POA_NAME);
183         if (poa_obj != NULL) {
184                 rootpoa = PortableServer::POA::_narrow(poa_obj);
185                 if (rootpoa != NULL) {
186                         poa_man = rootpoa->the_POAManager();
187                         if (poa_man != NULL) {
188                                 poa_man->activate();
189                                 // bidirectional policy
190                                 policy_list.length(1);
191                                 policyVal       <<= BiDirPolicy::BOTH;
192                                 policy_list[0] = orb->create_policy(BiDirPolicy::BIDIRECTIONAL_POLICY_TYPE, policyVal);
193                                 ret_val = rootpoa->create_POA(CONST_ROOT_POA_BIDIR_POLICY_NAME,
194                                                         poa_man,
195                                                         policy_list);
196                         }
197                 }
198         }
199         else {
200                 cerr << "Failed to create RootPOA." << endl;
201         }
202         return ret_val;
203 }
204
205 CosNaming::NamingContext_var BusClient::get_name_service_context(CORBA::ORB_var orb_param,
206                                                                 const char *nameservice_name_param) {
207         CORBA::Object_var               ns_obj;
208         CosNaming::NamingContext_var    ret_val;
209
210         ret_val = NULL;
211         try {
212                 ns_obj  = orb_param->resolve_initial_references(nameservice_name_param);
213                 if (CORBA::is_nil(ns_obj) == false) {
214                         // narrow the object reference
215                         ret_val = CosNaming::NamingContext::_narrow(ns_obj);
216                 }
217         }
218         catch (CORBA::ORB::InvalidName&) {
219                 // This should not happen!
220                 cerr << "Could not find name service." << endl;
221         }
222         catch(CORBA::TRANSIENT& ex) {
223                 cerr << "Could not find name service, verify that name service is running. " << endl;
224         }
225         catch (CORBA::NO_RESOURCES&) {
226                 cerr << "Could not find name service, verify that name service is running. " << endl;
227         }
228         catch(CORBA::SystemException& ex) {
229                 cerr << "Could not find name service, unknown reason. " << endl;
230         }
231         return ret_val;
232 }
233
234 CORBA::Object_var BusClient::find_server_object_by_name(CORBA::ORB_var orb_param,
235                                                         const char *leaf_name_param,
236                                                         const char *leaf_kind_param,
237                                                         const char *service_name_param,
238                                                         const char *service_kind_param)
239 {
240         CORBA::Object_var               ret_val;
241         CosNaming::NamingContext_var    ns_root_context;
242         CosNaming::Name                 service_data;
243         char *n;
244
245         ret_val = CORBA::Object::_nil();
246         n       = strdup(CONST_NAME_SERVICE_NAME);
247         ns_root_context = get_name_service_context(orb_param, n);
248         free(n);
249         if (CORBA::is_nil(ns_root_context) == false) {
250                 // define search criteria
251                 service_data.length(2);
252                 service_data[0].id   = leaf_name_param;
253                 service_data[0].kind = leaf_kind_param;
254                 service_data[1].id   = service_name_param;
255                 service_data[1].kind = service_kind_param;
256                 try {
257                         ret_val = ns_root_context->resolve(service_data);
258                 }
259                 catch(CosNaming::NamingContext::NotFound& ex) {
260                         log_error("Could not find service from the name server.\n");
261                 }
262                 catch(CORBA::TRANSIENT& ex) {
263                         log_error("Could not find service from the name server.\n");
264                 }
265                 catch(CORBA::SystemException& ex) {
266                         log_error("Could not find service from the name server, unknown error.\n");
267                 }
268         }
269         else {
270                 log_error("Could not find naming service.\n");
271         }
272         return ret_val;
273 }