Fawkes API  Fawkes Development Version
mod_protobuf.cpp
1 
2 /***************************************************************************
3  * mod_protobuf.cpp - OpenPRS protobuf communication module
4  *
5  * Created: Tue Sep 02 16:23:43 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.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU Library General Public License for more details.
18  *
19  * Read the full text in the LICENSE.GPL file in the doc directory.
20  */
21 
22 #include "oprs_protobuf.h"
23 
24 #include <core/exception.h>
25 #include <plugins/openprs/mod_utils.h>
26 
27 #include <lisp-list_f-pub.h>
28 #include <oprs-array_f-pub.h>
29 #include <oprs-type_f-pub.h>
30 #include <oprs_f-pub.h>
31 #include <slistPack_f.h>
32 
33 using namespace oprs_protobuf;
34 
35 extern "C" void finalize();
36 
37 #define ASSERT_PB \
38  do { \
39  if (!g_oprs_pb) { \
40  fprintf(stderr, "Error: pb-setup has not been called\n"); \
41  ACTION_FAIL(); \
42  } \
43  } while (0);
44 
45 #define ASSERT_B_PB \
46  do { \
47  if (!g_oprs_pb) { \
48  fprintf(stderr, "Error: pb-setup has not been called\n"); \
49  return true; \
50  } \
51  } while (0);
52 
53 // Global variables
54 OpenPRSProtobuf *g_oprs_pb = NULL;
55 
56 extern "C" Term *
57 action_pb_setup(TermList terms)
58 {
59  int terms_len = sl_slist_length(terms);
60  if (terms_len != 1) {
61  fprintf(stderr,
62  "Error[pb-setup]: invalid number of "
63  "arguments: req 1, got %i\n",
64  terms_len);
65  ACTION_FAIL();
66  }
67 
68  Term *proto_paths = (Term *)get_list_pos(terms, 1);
69  if (proto_paths->type != LISP_LIST) {
70  fprintf(stderr, "Error[pb-setup]: proto paths type is not a LISP_LIST\n");
71  ACTION_FAIL();
72  }
73 
74  size_t num_paths = 0;
75  for (L_List p_l = proto_paths->u.l_list; p_l; p_l = l_cdr(p_l)) {
76  Term *t = l_car(p_l);
77  if (t->type != STRING) {
78  fprintf(stderr, "Error[pb-setup]: at least one proto path is not of type STRING\n");
79  ACTION_FAIL();
80  }
81  num_paths += 1;
82  }
83 
84  std::vector<std::string> ppaths(num_paths);
85  size_t i = 0;
86  for (L_List p_l = proto_paths->u.l_list; p_l; p_l = l_cdr(p_l)) {
87  Term *t = l_car(p_l);
88  ppaths[i++] = t->u.string;
89  }
90 
91  for (size_t i = 0; i < ppaths.size(); ++i) {
92  std::string::size_type pos;
93  if ((pos = ppaths[i].find("@BASEDIR@")) != std::string::npos) {
94  ppaths[i].replace(pos, 9, BASEDIR);
95  }
96  if ((pos = ppaths[i].find("@FAWKES_BASEDIR@")) != std::string::npos) {
97  ppaths[i].replace(pos, 16, FAWKES_BASEDIR);
98  }
99  if ((pos = ppaths[i].find("@RESDIR@")) != std::string::npos) {
100  ppaths[i].replace(pos, 8, RESDIR);
101  }
102  if ((pos = ppaths[i].find("@CONFDIR@")) != std::string::npos) {
103  ppaths[i].replace(pos, 9, CONFDIR);
104  }
105  if (ppaths[i][ppaths.size() - 1] != '/') {
106  ppaths[i] += "/";
107  }
108  }
109 
110  delete g_oprs_pb;
111  g_oprs_pb = new OpenPRSProtobuf(ppaths);
112 
113  ACTION_FINAL();
114 }
115 
116 extern "C" Term *
117 func_pb_create(TermList terms)
118 {
119  ASSERT_PB;
120 
121  Term *type;
122 
123  ACTION_ASSERT_ARG_LENGTH("pb-create", terms, 1);
124  ACTION_SET_AND_ASSERT_ARG_TYPE("pb-create", type, terms, 1, STRING);
125 
126  try {
127  std::shared_ptr<google::protobuf::Message> *msg = g_oprs_pb->oprs_create_msg(type->u.string);
128 
129  Term *res = MAKE_OBJECT(Term);
130  res->type = U_POINTER;
131  res->u.u_pointer = msg;
132  return res;
133  } catch (std::runtime_error &e) {
134  fprintf(stderr, "Cannot create message of type %s: %s", type->u.string, e.what());
135  return build_nil();
136  }
137 }
138 
139 extern "C" Term *
140 action_pb_client_connect(TermList terms)
141 {
142  ASSERT_PB;
143 
144  Term *host, *port;
145  ACTION_ASSERT_ARG_LENGTH("pb-client-connect", terms, 2);
146  ACTION_SET_AND_ASSERT_ARG_TYPE("pb-client-connect", host, terms, 1, STRING);
147  ACTION_SET_AND_ASSERT_ARG_TYPE("pb-client-connect", port, terms, 2, LONG_LONG);
148 
149  if (port->u.llintval < 0 || port->u.llintval > 65535) {
150  fprintf(stderr, "Error[pb-client-connect]: invalid port %lli\n", port->u.llintval);
151  ACTION_FAIL();
152  }
153 
154  return g_oprs_pb->oprs_pb_client_connect(host->u.string, port->u.llintval);
155 }
156 
157 extern "C" Term *
158 action_pb_enable_server(TermList terms)
159 {
160  ASSERT_PB;
161 
162  Term *port;
163  ACTION_ASSERT_ARG_LENGTH("pb-enable-server", terms, 1);
164  ACTION_SET_AND_ASSERT_ARG_TYPE("pb-enable-server", port, terms, 1, LONG_LONG);
165 
166  if (port->u.llintval < 0 || port->u.llintval > 65535) {
167  fprintf(stderr, "Error[pb-enable-server]: invalid port %lli\n", port->u.llintval);
168  ACTION_FAIL();
169  }
170 
171  try {
172  g_oprs_pb->oprs_pb_enable_server(port->u.llintval);
173  ACTION_FINAL();
174  } catch (fawkes::Exception &e) {
175  fprintf(stderr, "Error[pb-enable-server]: %s\n", e.what_no_backtrace());
176  ACTION_FAIL();
177  }
178 }
179 
180 extern "C" Term *
181 action_pb_disable_server(TermList terms)
182 {
183  ASSERT_PB;
184 
185  ACTION_ASSERT_ARG_LENGTH("pb-disable-server", terms, 0);
186 
187  try {
188  g_oprs_pb->oprs_pb_disable_server();
189  ACTION_FINAL();
190  } catch (fawkes::Exception &e) {
191  fprintf(stderr, "Error[pb-disable-server]: %s\n", e.what_no_backtrace());
192  ACTION_FAIL();
193  }
194 }
195 
196 extern "C" Term *
197 action_pb_peer_create(TermList terms)
198 {
199  ASSERT_PB;
200 
201  Term *host, *port;
202  ACTION_ASSERT_ARG_LENGTH("pb-peer-create", terms, 2);
203  ACTION_SET_AND_ASSERT_ARG_TYPE("pb-peer-create", host, terms, 1, STRING);
204  ACTION_SET_AND_ASSERT_ARG_TYPE("pb-peer-create", port, terms, 2, LONG_LONG);
205 
206  if (port->u.llintval < 0 || port->u.llintval > 65535) {
207  fprintf(stderr, "Error[pb-peer-create]: invalid port %lli\n", port->u.llintval);
208  ACTION_FAIL();
209  }
210 
211  return g_oprs_pb->oprs_pb_peer_create(host->u.string, port->u.llintval);
212 }
213 
214 extern "C" Term *
215 action_pb_peer_create_local(TermList terms)
216 {
217  ASSERT_PB;
218 
219  Term *host, *send_port, *recv_port;
220  ACTION_ASSERT_ARG_LENGTH("pb-peer-create-local", terms, 3);
221  ACTION_SET_AND_ASSERT_ARG_TYPE("pb-peer-create-local", host, terms, 1, STRING);
222  ACTION_SET_AND_ASSERT_ARG_TYPE("pb-peer-create-local", send_port, terms, 2, LONG_LONG);
223  ACTION_SET_AND_ASSERT_ARG_TYPE("pb-peer-create-local", recv_port, terms, 3, LONG_LONG);
224 
225  if (send_port->u.llintval < 0 || send_port->u.llintval > 65535) {
226  fprintf(stderr, "Error[pb-peer-create-local]: invalid send port %lli\n", send_port->u.llintval);
227  ACTION_FAIL();
228  }
229  if (recv_port->u.llintval < 0 || recv_port->u.llintval > 65535) {
230  fprintf(stderr, "Error[pb-peer-create-local]: invalid recv port %lli\n", recv_port->u.llintval);
231  ACTION_FAIL();
232  }
233 
234  return g_oprs_pb->oprs_pb_peer_create_local(host->u.string,
235  send_port->u.llintval,
236  recv_port->u.llintval);
237 }
238 
239 extern "C" Term *
240 action_pb_peer_create_crypto(TermList terms)
241 {
242  ASSERT_PB;
243 
244  Term *host, *port, *crypto_key, *cipher;
245  ACTION_ASSERT_ARG_LENGTH("pb-peer-create-local", terms, 4);
246  ACTION_SET_AND_ASSERT_ARG_TYPE("pb-peer-create-crypto", host, terms, 1, STRING);
247  ACTION_SET_AND_ASSERT_ARG_TYPE("pb-peer-create-crypto", port, terms, 2, LONG_LONG);
248  ACTION_SET_AND_ASSERT_ARG_TYPE("pb-peer-create-crypto", crypto_key, terms, 3, STRING);
249  ACTION_SET_AND_ASSERT_ARG_TYPE("pb-peer-create-crypto", cipher, terms, 4, STRING);
250 
251  if (port->u.llintval < 0 || port->u.llintval > 65535) {
252  fprintf(stderr, "Error[pb-peer-create-local]: invalid port %lli\n", port->u.llintval);
253  ACTION_FAIL();
254  }
255 
256  return g_oprs_pb->oprs_pb_peer_create_crypto(host->u.string,
257  port->u.llintval,
258  crypto_key->u.string,
259  cipher->u.string);
260 }
261 
262 extern "C" Term *
263 action_pb_peer_create_local_crypto(TermList terms)
264 {
265  ASSERT_PB;
266 
267  Term *host, *send_port, *recv_port, *crypto_key, *cipher;
268  ACTION_ASSERT_ARG_LENGTH("pb-peer-create-local-crypto", terms, 5);
269  ACTION_SET_AND_ASSERT_ARG_TYPE("pb-peer-create-local-crypto", host, terms, 1, STRING);
270  ACTION_SET_AND_ASSERT_ARG_TYPE("pb-peer-create-local-crypto", send_port, terms, 2, LONG_LONG);
271  ACTION_SET_AND_ASSERT_ARG_TYPE("pb-peer-create-local-crypto", recv_port, terms, 3, LONG_LONG);
272  ACTION_SET_AND_ASSERT_ARG_TYPE("pb-peer-create-local-crypto", crypto_key, terms, 4, STRING);
273  ACTION_SET_AND_ASSERT_ARG_TYPE("pb-peer-create-local-crypto", cipher, terms, 5, STRING);
274 
275  if (send_port->u.llintval < 0 || send_port->u.llintval > 65535) {
276  fprintf(stderr, "Error[pb-peer-create-local]: invalid send port %lli\n", send_port->u.llintval);
277  ACTION_FAIL();
278  }
279  if (recv_port->u.llintval < 0 || recv_port->u.llintval > 65535) {
280  fprintf(stderr, "Error[pb-peer-create-local]: invalid recv port %lli\n", recv_port->u.llintval);
281  ACTION_FAIL();
282  }
283 
284  printf("Creating local peer. %s:%lli %lli %s %s\n",
285  host->u.string,
286  send_port->u.llintval,
287  recv_port->u.llintval,
288  crypto_key->u.string,
289  cipher->u.string);
290  return g_oprs_pb->oprs_pb_peer_create_local_crypto(host->u.string,
291  send_port->u.llintval,
292  recv_port->u.llintval,
293  crypto_key->u.string,
294  cipher->u.string);
295 }
296 
297 extern "C" Term *
298 action_pb_peer_setup_crypto(TermList terms)
299 {
300  ASSERT_PB;
301 
302  Term *peer_id, *crypto_key, *cipher;
303  ACTION_ASSERT_ARG_LENGTH("pb-peer-setup-crypto", terms, 4);
304  ACTION_SET_AND_ASSERT_ARG_TYPE("pb-peer-setup-crypto", peer_id, terms, 1, LONG_LONG);
305  ACTION_SET_AND_ASSERT_ARG_TYPE("pb-peer-setup-crypto", crypto_key, terms, 2, STRING);
306  ACTION_SET_AND_ASSERT_ARG_TYPE("pb-peer-setup-crypto", cipher, terms, 3, STRING);
307 
308  try {
309  g_oprs_pb->oprs_pb_peer_setup_crypto(peer_id->u.llintval,
310  crypto_key->u.string,
311  cipher->u.string);
312  ACTION_FINAL();
313  } catch (fawkes::Exception &e) {
314  fprintf(stderr, "Error[pb-peer-setup-crypto]: %s\n", e.what_no_backtrace());
315  ACTION_FAIL();
316  }
317 }
318 
319 extern "C" PBoolean
320 pred_pb_events_pending(TermList terms)
321 {
322  ASSERT_B_PB;
323 
324  return g_oprs_pb->oprs_pb_events_pending();
325 }
326 
327 extern "C" Term *
328 action_pb_process(TermList terms)
329 {
330  ASSERT_PB;
331 
332  try {
333  g_oprs_pb->oprs_pb_process();
334  ACTION_FINAL();
335  } catch (fawkes::Exception &e) {
336  fprintf(stderr, "Error[pb-process]: %s\n", e.what_no_backtrace());
337  ACTION_FAIL();
338  }
339 }
340 
341 #define PB_FIELD_ACCESSOR_FUNC(func_name, print_name) \
342  extern "C" Term *func_pb_##func_name(TermList terms) \
343  { \
344  ASSERT_PB; \
345  \
346  Term *msg, *field_name; \
347  ACTION_ASSERT_ARG_LENGTH(print_name, terms, 2); \
348  ACTION_SET_AND_ASSERT_ARG_TYPE(print_name, msg, terms, 1, U_POINTER); \
349  ACTION_SET_AND_ASSERT_ARG_TYPE(print_name, field_name, terms, 2, STRING); \
350  \
351  return g_oprs_pb->oprs_pb_##func_name(msg->u.u_pointer, field_name->u.string); \
352  }
353 
354 #define PB_FIELD_ACCESSOR_PRED(func_name, print_name) \
355  extern "C" PBoolean pred_pb_##func_name(TermList terms) \
356  { \
357  ASSERT_B_PB; \
358  \
359  Term *msg, *field_name; \
360  ACTION_ASSERT_B_ARG_LENGTH(print_name, terms, 2); \
361  ACTION_SET_AND_ASSERT_B_ARG_TYPE(print_name, msg, terms, 1, U_POINTER); \
362  ACTION_SET_AND_ASSERT_B_ARG_TYPE(print_name, field_name, terms, 2, STRING); \
363  \
364  return g_oprs_pb->oprs_pb_##func_name(msg->u.u_pointer, field_name->u.string); \
365  }
366 
367 #define PB_MESSAGE_FUNC(func_name, print_name) \
368  extern "C" Term *func_pb_##func_name(TermList terms) \
369  { \
370  ASSERT_PB; \
371  \
372  Term *msg; \
373  ACTION_ASSERT_ARG_LENGTH(print_name, terms, 1); \
374  ACTION_SET_AND_ASSERT_ARG_TYPE(print_name, msg, terms, 1, U_POINTER); \
375  \
376  return g_oprs_pb->oprs_pb_##func_name(msg->u.u_pointer); \
377  }
378 
379 #define PB_MESSAGE_ACTION(func_name, print_name) \
380  extern "C" Term *action_pb_##func_name(TermList terms) \
381  { \
382  ASSERT_PB; \
383  \
384  Term *msg; \
385  ACTION_ASSERT_ARG_LENGTH(print_name, terms, 1); \
386  ACTION_SET_AND_ASSERT_ARG_TYPE(print_name, msg, terms, 1, U_POINTER); \
387  \
388  return g_oprs_pb->oprs_pb_##func_name(msg->u.u_pointer); \
389  }
390 
391 #define PB_CLIENT_MESSAGE_ACTION(func_name, print_name) \
392  extern "C" Term *action_pb_##func_name(TermList terms) \
393  { \
394  ASSERT_PB; \
395  \
396  Term *client_id, *msg; \
397  ACTION_ASSERT_ARG_LENGTH(print_name, terms, 2); \
398  ACTION_SET_AND_ASSERT_ARG_TYPE(print_name, client_id, terms, 1, LONG_LONG); \
399  ACTION_SET_AND_ASSERT_ARG_TYPE(print_name, msg, terms, 2, U_POINTER); \
400  \
401  try { \
402  g_oprs_pb->oprs_pb_##func_name(client_id->u.llintval, msg->u.u_pointer); \
403  ACTION_FINAL(); \
404  } catch (fawkes::Exception & e) { \
405  fprintf(stderr, "Error[%s]: %s\n", print_name, e.what_no_backtrace()); \
406  ACTION_FAIL(); \
407  } \
408  }
409 
410 #define PB_FIELD_SET_ACTION(func_name, print_name) \
411  extern "C" Term *action_pb_##func_name(TermList terms) \
412  { \
413  ASSERT_PB; \
414  \
415  Term *msg, *field_name, *value; \
416  ACTION_ASSERT_ARG_LENGTH(print_name, terms, 3); \
417  ACTION_SET_AND_ASSERT_ARG_TYPE(print_name, msg, terms, 1, U_POINTER); \
418  ACTION_SET_AND_ASSERT_ARG_TYPE(print_name, field_name, terms, 2, STRING); \
419  value = (Term *)get_list_pos(terms, 3); \
420  \
421  try { \
422  g_oprs_pb->oprs_pb_##func_name(msg->u.u_pointer, field_name->u.string, value); \
423  ACTION_FINAL(); \
424  } catch (fawkes::Exception & e) { \
425  fprintf(stderr, "Error[%s]: %s\n", print_name, e.what_no_backtrace()); \
426  ACTION_FAIL(); \
427  } \
428  }
429 
430 #define PB_CLIENT_ID_ACTION(func_name, print_name) \
431  extern "C" Term *action_pb_##func_name(TermList terms) \
432  { \
433  ASSERT_PB; \
434  \
435  Term *client_id; \
436  ACTION_ASSERT_ARG_LENGTH(print_name, terms, 1); \
437  ACTION_SET_AND_ASSERT_ARG_TYPE(print_name, client_id, terms, 1, LONG_LONG); \
438  \
439  try { \
440  g_oprs_pb->oprs_pb_##func_name(client_id->u.llintval); \
441  ACTION_FINAL(); \
442  } catch (fawkes::Exception & e) { \
443  fprintf(stderr, \
444  "Error[pb-client-connect]: failed on " \
445  "client %lli\n", \
446  client_id->u.llintval); \
447  ACTION_FAIL(); \
448  } \
449  }
450 
451 PB_FIELD_ACCESSOR_FUNC(field_value, "pb-field-value")
452 PB_FIELD_ACCESSOR_FUNC(field_type, "pb-field-type")
453 PB_FIELD_ACCESSOR_FUNC(field_label, "pb-field-label")
454 PB_FIELD_ACCESSOR_FUNC(field_list, "pb-field-list")
455 
456 PB_FIELD_ACCESSOR_PRED(has_field, "pb-has-field")
457 PB_FIELD_ACCESSOR_PRED(field_is_list, "pb-field-is-list")
458 
459 PB_MESSAGE_FUNC(field_names, "pb-field-names")
460 PB_MESSAGE_FUNC(ref, "pb-ref")
461 PB_MESSAGE_ACTION(destroy, "pb-destroy")
462 PB_CLIENT_MESSAGE_ACTION(send, "pb-send")
463 PB_CLIENT_MESSAGE_ACTION(broadcast, "pb-broadcast")
464 
465 PB_FIELD_SET_ACTION(set_field, "pb-set-field")
466 PB_FIELD_SET_ACTION(add_list, "pb-add-list")
467 
468 PB_CLIENT_ID_ACTION(disconnect, "pb-disconnect")
469 PB_CLIENT_ID_ACTION(peer_destroy, "pb-peer-destroy")
470 
471 /** Entry function for the OpenPRS module. */
472 extern "C" void
473 init()
474 {
475  printf("*** LOADING mod_protobuf\n");
476  printf("Make sure your kernel calls pb-setup!\n");
477 
478  make_and_declare_action("pb-setup", action_pb_setup, 1);
479  make_and_declare_action("pb-process", action_pb_process, 0);
480  make_and_declare_action("pb-destroy", action_pb_destroy, 1);
481  make_and_declare_action("pb-set-field", action_pb_set_field, 3);
482  make_and_declare_action("pb-add-list", action_pb_add_list, 3);
483  make_and_declare_action("pb-disconnect", action_pb_disconnect, 1);
484  make_and_declare_action("pb-peer-destroy", action_pb_peer_destroy, 1);
485  make_and_declare_action("pb-send", action_pb_send, 2);
486  make_and_declare_action("pb-broadcast", action_pb_broadcast, 2);
487  make_and_declare_action("pb-client-connect", action_pb_client_connect, 2);
488  make_and_declare_action("pb-enable-server", action_pb_enable_server, 1);
489  make_and_declare_action("pb-disable-server", action_pb_enable_server, 1);
490  make_and_declare_action("pb-peer-create", action_pb_peer_create, 2);
491  make_and_declare_action("pb-peer-create-local", action_pb_peer_create_local, 3);
492  make_and_declare_action("pb-peer-create-crypto", action_pb_peer_create_crypto, 4);
493  make_and_declare_action("pb-peer-create-local-crypto", action_pb_peer_create_local_crypto, 5);
494  make_and_declare_action("pb-peer-setup-crypto", action_pb_peer_setup_crypto, 3);
495 
496  make_and_declare_eval_funct("pb-create", func_pb_create, 1);
497  make_and_declare_eval_funct("pb-field-names", func_pb_field_names, 1);
498  make_and_declare_eval_funct("pb-ref", func_pb_ref, 1);
499  make_and_declare_eval_funct("pb-field-value", func_pb_field_value, 2);
500  make_and_declare_eval_funct("pb-field-type", func_pb_field_type, 2);
501  make_and_declare_eval_funct("pb-field-label", func_pb_field_label, 2);
502  make_and_declare_eval_funct("pb-field-list", func_pb_field_list, 2);
503 
504  make_and_declare_eval_pred("pb-has-field", pred_pb_has_field, 2, TRUE);
505  make_and_declare_eval_pred("pb-is-list", pred_pb_field_is_list, 2, TRUE);
506  make_and_declare_eval_pred("pb-events-pending", pred_pb_events_pending, 0, TRUE);
507 
508  add_user_end_kernel_hook(finalize);
509 }
510 
511 /** Finalization function for the OpenPRS module. */
512 extern "C" void
513 finalize()
514 {
515  printf("*** DESTROYING mod_protobuf\n");
516  delete g_oprs_pb;
517  g_oprs_pb = NULL;
518 }
Base class for exceptions in Fawkes.
Definition: exception.h:36
virtual const char * what_no_backtrace() const noexcept
Get primary string (does not implicitly print the back trace).
Definition: exception.cpp:663
OpenPRS protobuf integration class.
Definition: oprs_protobuf.h:58
Term * oprs_pb_peer_create_local_crypto(const std::string &host, int send_port, int recv_port, const std::string &crypto_key="", const std::string &cipher="")
Enable protobuf peer.
Term * oprs_pb_peer_create_local(const std::string &host, int send_port, int recv_port)
Enable protobuf peer.
Term * oprs_pb_peer_create_crypto(const std::string &host, int port, const std::string &crypto_key="", const std::string &cipher="")
Enable protobuf peer.
std::shared_ptr< google::protobuf::Message > * oprs_create_msg(std::string full_name)
Create a new message of given type.
void oprs_pb_process()
Process all pending events.
bool oprs_pb_events_pending()
Check if there are pending events.
void oprs_pb_disable_server()
Disable protobuf stream server.
void oprs_pb_enable_server(int port)
Enable protobuf stream server.
Term * oprs_pb_client_connect(std::string host, int port)
Connect as a client to the given server.
Term * oprs_pb_peer_create(const std::string &host, int port)
Enable protobuf peer.
void oprs_pb_peer_setup_crypto(long int peer_id, const std::string &crypto_key, const std::string &cipher)
Setup crypto for peer.