Fawkes API  Fawkes Development Version
blackboard.cpp
1 
2 /***************************************************************************
3  * blackboard.h - External predicates to remotely access the Fawkes
4  * blackboard
5  *
6  * Created: Wed Mar 09 17:10:54 2011
7  * Copyright 2011 Daniel Beck
8  * 2014 Tim Niemueller
9  ****************************************************************************/
10 
11 /* This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or
14  * (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU Library General Public License for more details.
20  *
21  * Read the full text in the LICENSE.GPL file in the doc directory.
22  */
23 
24 #include "blackboard.h"
25 
26 
27 #include <eclipseclass.h>
28 
29 
30 #include <cstring>
31 #include <cstdlib>
32 
33 namespace fawkes{
34 /** @class fawkes::EclExternalBlackBoard
35  * Wrapper class for using the blackboard in the implementation of the external
36  * predicates.
37  * @author Daniel Beck
38  */
39 
40 BlackBoard* EclExternalBlackBoard::m_blackboard = NULL;
41 EclExternalBlackBoard* EclExternalBlackBoard::m_instance = NULL;
42 
43  /** Constructor. */
44  EclExternalBlackBoard::EclExternalBlackBoard()
45  {
46  if (m_instance != NULL) {
47  throw Exception("There is already an instance of type "
48  "EclExternalBlackBoard instantiated");
49  }
50  m_own_blackboard = true;
51  }
52 
53  /** Constructor. */
54  EclExternalBlackBoard::EclExternalBlackBoard(BlackBoard* blackboard)
55  {
56  if (m_instance != NULL) {
57  throw Exception("There is already an instance of type "
58  "EclExternalBlackBoard instantiated");
59  }
60  m_blackboard = blackboard;
61  m_own_blackboard = false;
62  }
63 
64  /** Destructor. */
66  {
67  for (std::map<std::string, Interface *>::iterator iit = m_interfaces.begin();
68  iit != m_interfaces.end(); ++iit) {
69  m_blackboard->close(iit->second);
70  }
71  if (m_own_blackboard) {
72  delete m_blackboard;
73  }
74  }
75 
76  /** Creates the initial EclExternalBlackBoard object
77  * @param bb pointer to the BlackBoard to be used
78  */
80  {
81  m_instance = new EclExternalBlackBoard(bb);
82  }
83 
84  /** Delete the current EclExternalBlackBoard instance and set it to NULL */
86  {
87  if (m_instance) {
88  delete m_instance;
89  }
90  m_instance = NULL;
91  }
92 
93 
94  /** Get the EclExternalBlackBoard instance.
95  * @return the instance
96  */
98  {
99  if (!m_instance) {
100  throw Exception("EclExternalBlackBoard::instance(): "
101  "No instance of type EclExternalBlackBoard instantiated");
102  }
103 
104  return m_instance;
105  }
106 
107 
108  /** Open remote blackboard connection.
109  * @param host the host running Fawkes
110  * @param port the host's port to connect to
111  */
112  void EclExternalBlackBoard::connect(const char* host, const long port)
113  {
114  if (m_blackboard && m_own_blackboard) {
115  delete m_blackboard;
116  }
117  m_blackboard = new RemoteBlackBoard(host, port);
118  }
119 
120 
121  /** Query connection status.
122  * @return true if connected; false otherwise
123  */
125  {
126  return m_blackboard ? true : false;
127  }
128 
129  /** Disconnect remote blackboard connection. */
131  {
132  for (std::map<std::string, Interface *>::iterator iit = m_interfaces.begin();
133  iit != m_interfaces.end();
134  ++iit)
135  { m_blackboard->close(iit->second); }
136  if (m_own_blackboard) {
137  delete m_blackboard;
138  }
139  m_blackboard = 0;
140  }
141 
142  /** Access the BlackBoard instance.
143  * @return the blackboard instance
144  */
146  {
147  if (!m_blackboard)
148  { throw Exception("No instance of type BlackBoard instantiated"); }
149 
150  return m_blackboard;
151  }
152 
153  /** Obtain the list of opened interfaces.
154  * @return list of opened interfaces
155  */
156  std::map<std::string, Interface *>& EclExternalBlackBoard::interfaces()
157  {
158  return m_interfaces;
159  }
160 
161 }
162 
163 using namespace fawkes;
164 
165 
166 bool process_message_args(Message* msg, EC_word arg_list);
167 
168 int
169 p_bb_connect_to_remote_blackboard()
170 {
172  {
173  fprintf(stderr, "p_bb_connect_to_remote_blackboard(): already connected\n");
174  return EC_fail;
175  }
176 
177  // get hostname
178  char* hostname;
179 
180  if (EC_succeed != EC_arg(1).is_string(&hostname))
181  {
182  fprintf(stderr, "p_bb_connect_to_remote_blackboard(): first argument is not a string\n");
183  return EC_fail;
184  }
185 
186  long port;
187  if (EC_succeed != EC_arg(2).is_long(&port))
188  {
189  return EC_fail;
190  }
191 
192  try
193  {
194  EclExternalBlackBoard::instance()->connect(hostname, port);
195  }
196  catch (Exception& e)
197  {
198  fprintf(stderr, "p_bb_connect_to_remote_blacboard() failed: %s\n", e.what_no_backtrace());
199  return EC_fail;
200  }
201 
202  return EC_succeed;
203 }
204 
205 
206 int
207 p_bb_disconnect_from_blackboard()
208 {
210  {
211  fprintf(stderr, "p_bb_disconnect_from_blackboard(): not connected\n");
212  return EC_fail;
213  }
214 
216 
217  return EC_succeed;
218 }
219 
220 
221 int
222 p_bb_is_alive()
223 {
225  {
226  fprintf(stderr, "p_bb_is_alive(): not connected\n");
227  return EC_fail;
228  }
229 
231  { return EC_succeed; }
232  else
233  { return EC_fail; }
234 }
235 
236 int
237 p_bb_is_connected()
238 {
240  return EC_succeed;
241  }else{
242  return EC_fail;
243  }
244 }
245 
246 int
247 p_bb_open_interface()
248 {
250  {
251  fprintf(stderr, "p_bb_open_interface(): not connected\n");
252  return EC_fail;
253  }
254 
255  EC_atom mode;
256  char* interface_type;
257  char* interface_id;
258 
259  if (EC_succeed != EC_arg(1).is_atom(&mode))
260  {
261  fprintf(stderr, "p_bb_open_interface(): no mode given\n");
262  return EC_fail;
263  }
264 
265  if (EC_succeed != EC_arg(2).is_string(&interface_type))
266  {
267  fprintf(stderr, "p_bb_open_interface(): no type given\n");
268  return EC_fail;
269  }
270 
271  if (EC_succeed != EC_arg (3).is_string(&interface_id))
272  {
273  fprintf(stderr, "p_bb_open_interface(): no id given\n");
274  return EC_fail;
275  }
276 
277  std::map<std::string, Interface *> &interfaces =
279 
280  std::string uid = std::string(interface_type) + "::" + interface_id;
281  if (interfaces.find(uid) == interfaces.end()) {
282  try {
283  Interface* iface;
284 
285  if (0 == strcmp("w", mode.name()))
286  {
288  blackboard_instance()->open_for_writing(interface_type, interface_id);
289  } else {
291  blackboard_instance()->open_for_reading(interface_type, interface_id);
292  }
293 
294  interfaces[iface->uid()] = iface;
295  } catch (Exception& e) {
296  fprintf(stderr, "p_bb_open_interface() failed: %s\n", e.what_no_backtrace());
297  return EC_fail;
298  }
299  }
300 
301  if (interfaces.find(uid) == interfaces.end()) {
302  return EC_fail;
303  }
304 
305  return EC_succeed;
306 }
307 
308 
309 int
310 p_bb_close_interface()
311 {
313  {
314  fprintf(stderr, "p_bb_close_interface(): not connected\n");
315  return EC_fail;
316  }
317 
318  // char* interface_type;
319  char* uid;
320 
321  if (EC_succeed != EC_arg(1).is_string(&uid))
322  {
323  fprintf(stderr, "p_bb_close_interface(): no id given\n");
324  return EC_fail;
325  }
326 
327  std::map<std::string, Interface *> &interfaces =
329 
330  if (interfaces.find(uid) != interfaces.end()) {
333  }
334 
335  return EC_succeed;
336 }
337 
338 
339 int
340 p_bb_has_writer()
341 {
342  char* uid;
343 
344  if (EC_succeed != EC_arg(1).is_string(&uid)) {
345  fprintf(stderr, "p_bb_has_writer(): no uid given\n");
346  return EC_fail;
347  }
348 
349  std::map<std::string, Interface *> &interfaces =
351 
352  if (interfaces.find(uid) != interfaces.end()) {
353  return interfaces[uid]->has_writer() ? EC_succeed : EC_fail;
354  }
355 
356  return EC_fail;
357 }
358 
359 
360 int
361 p_bb_instance_serial()
362 {
364  {
365  fprintf(stderr, "p_bb_instance_serial(): not connected to blackboard\n");
366  return EC_fail;
367  }
368 
369  char* uid;
370  if (EC_succeed != EC_arg(1).is_string(&uid))
371  {
372  fprintf(stderr, "p_bb_instance_serial(): no interface uid given\n");
373  return EC_fail;
374  }
375 
376  std::map<std::string, Interface *> &interfaces =
378 
379  if (interfaces.find(uid) != interfaces.end()) {
380 
381  if (EC_succeed != EC_arg(2).unify(interfaces[uid]->serial())) {
382  fprintf(stderr, "p_bb_instance_serial(): could not bind return value\n");
383  return EC_fail;
384  } else {
385  return EC_succeed;
386  }
387  }
388 
389  return EC_fail;
390 }
391 
392 
393 int
394 p_bb_read_interfaces()
395 {
396  for (std::map<std::string, Interface *>::iterator it = EclExternalBlackBoard::instance()->interfaces().begin();
398  ++it)
399  {
400  it->second->read();
401  }
402 
403  return EC_succeed;
404 }
405 
406 int
407 p_bb_read_interface()
408 {
409  char *uid;
410  if (EC_succeed != EC_arg(1).is_string(&uid))
411  {
412  fprintf(stderr, "p_read_interface(): no interface UID given\n");
413  return EC_fail;
414  }
415 
416  std::map<std::string, Interface *> &interfaces =
418 
419  if (interfaces.find(uid) == interfaces.end()) {
420  fprintf(stderr, "p_bb_read_interface: interface %s has not been opened\n", uid);
421  return EC_fail;
422  }
423 
424  interfaces[uid]->read();
425 
426  return EC_succeed;
427 }
428 
429 int
430 p_bb_write_interfaces()
431 {
432  for (std::map<std::string, Interface *>::iterator it = EclExternalBlackBoard::instance()->interfaces().begin();
434  ++it)
435  {
436  if (it->second->is_writer()) { it->second->write(); }
437  }
438 
439  return EC_succeed;
440 }
441 
442 int
443 p_bb_write_interface()
444 {
445  char *uid;
446  if (EC_succeed != EC_arg(1).is_string(&uid))
447  {
448  fprintf(stderr, "p_read_interface(): no interface UID given\n");
449  return EC_fail;
450  }
451 
452  std::map<std::string, Interface *> &interfaces =
454 
455  if (interfaces.find(uid) == interfaces.end()) {
456  fprintf(stderr, "p_bb_read_interface: interface %s has not been opened\n", uid);
457  return EC_fail;
458  }
459 
460  if (! interfaces[uid]->is_writer()) {
461  fprintf(stderr, "p_bb_set(): interface %s not a writer\n", uid);
462  return EC_fail;
463  }
464 
465  interfaces[uid]->write();
466  return EC_succeed;
467 }
468 
469 int
470 p_bb_interface_changed()
471 {
472  char *uid;
473  if (EC_succeed != EC_arg(1).is_string(&uid))
474  {
475  fprintf(stderr, "p_interface_changed(): no interface UID given\n");
476  return EC_fail;
477  }
478 
479  std::map<std::string, Interface *> &interfaces =
481 
482  if (interfaces.find(uid) == interfaces.end()) {
483  fprintf(stderr, "p_bb_interface_changed: interface %s has not been opened\n", uid);
484  return EC_fail;
485  }
486 
487  return interfaces[uid]->changed() ? EC_succeed : EC_fail;
488 }
489 
490 
491 int
492 p_bb_get()
493 {
494  char* uid;
495  char* field;
496 
497  if (EC_succeed != EC_arg(1).is_string(&uid))
498  {
499  fprintf(stderr, "p_bb_get(): no interface uid given\n");
500  return EC_fail;
501  }
502 
503  if (EC_succeed != EC_arg(2).is_string(&field))
504  {
505  fprintf(stderr, "p_bb_get(): no field given\n");
506  return EC_fail;
507  }
508 
509  std::map<std::string, Interface *> &interfaces =
511 
512  if (interfaces.find(uid) != interfaces.end()) {
513  Interface *iface = interfaces[uid];
514 
516  for (fit = iface->fields(); fit != iface->fields_end(); ++fit) {
517  if (0 == strcmp(field, fit.get_name())) {
518  switch (fit.get_type()) {
519  case IFT_BOOL:
520  if (fit.get_bool()) {
521  if (EC_succeed != EC_arg(3).unify(EC_atom((char*) "true"))) {
522  fprintf(stderr, "p_bb_get(): could not bind return value\n");
523  return EC_fail;
524  }
525  } else {
526  if (EC_succeed != EC_arg(3).unify(EC_atom((char*) "false"))) {
527  fprintf(stderr, "p_bb_get(): could not bind return value\n");
528  return EC_fail;
529  }
530  }
531  break;
532 
533  case IFT_INT8:
534  if (EC_succeed != EC_arg(3).unify(EC_word((long) fit.get_int8()))) {
535  fprintf(stderr, "p_bb_get(): could not bind return value\n");
536  return EC_fail;
537  }
538  break;
539 
540  case IFT_UINT8:
541  if (EC_succeed != EC_arg(3).unify(EC_word((long) fit.get_uint8()))) {
542  fprintf(stderr, "p_bb_get(): could not bind return value\n");
543  return EC_fail;
544  }
545  break;
546 
547  case IFT_INT16:
548  if (EC_succeed != EC_arg(3).unify(EC_word((long) fit.get_int16()))) {
549  fprintf(stderr, "p_bb_get(): could not bind return value\n");
550  return EC_fail;
551  }
552  break;
553 
554  case IFT_UINT16:
555  if (EC_succeed != EC_arg(3).unify(EC_word((long) fit.get_uint16()))) {
556  fprintf(stderr, "p_bb_get(): could not bind return value\n");
557  return EC_fail;
558  }
559  break;
560 
561  case IFT_INT32:
562  if (EC_succeed != EC_arg(3).unify(EC_word((long) fit.get_int32()))) {
563  fprintf(stderr, "p_bb_get: could not bind value\n");
564  return EC_fail;
565  }
566  break;
567 
568  case IFT_UINT32:
569  if (EC_succeed != EC_arg(3).unify(EC_word((long) fit.get_uint32()))) {
570  fprintf(stderr, "p_bb_get(): could not bind return value\n");
571  return EC_fail;
572  }
573  break;
574 
575  case IFT_INT64:
576  if (EC_succeed != EC_arg(3).unify(EC_word((long) fit.get_int64()))) {
577  fprintf(stderr, "p_bb_get(): could not bind return value\n");
578  return EC_fail;
579  }
580  break;
581 
582  case IFT_UINT64:
583  if (EC_succeed != EC_arg(3).unify(EC_word((long) fit.get_uint64()))) {
584  fprintf(stderr, "p_bb_get(): could not bind return value\n");
585  return EC_fail;
586  }
587  break;
588 
589  case IFT_FLOAT:
590  if (fit.get_length() > 1) {
591  EC_word res = nil();
592  float* f_array = fit.get_floats();
593  for (int i=fit.get_length() - 1; i >= 0; --i)
594  res = list(EC_word(f_array[i]), res);
595  if (EC_succeed != EC_arg(3).unify(res)) {
596  fprintf(stderr, "p_bb_get(): could not bind return value\n");
597  return EC_fail;
598  }
599  } else {
600  if (EC_succeed != EC_arg(3).unify(EC_word((double) fit.get_float()))) {
601  fprintf(stderr, "p_bb_get(): could not bind return value\n");
602  return EC_fail;
603  }
604  }
605  break;
606 
607  case IFT_DOUBLE:
608  if (fit.get_length() > 1) {
609  EC_word res = nil();
610  double* double_array = fit.get_doubles();
611  for (int i=fit.get_length() - 1; i >= 0; --i)
612  res = list(EC_word(double_array[i]), res);
613  if (EC_succeed != EC_arg(3).unify(res)) {
614  fprintf(stderr, "p_bb_get(): could not bind return value\n");
615  return EC_fail;
616  }
617  } else {
618  if (EC_succeed != EC_arg(3).unify(EC_word((double) fit.get_double()))) {
619  fprintf(stderr, "p_bb_get(): could not bind return value\n");
620  return EC_fail;
621  }
622  }
623  break;
624 
625  case IFT_STRING:
626  if (EC_succeed != EC_arg(3).unify(EC_word(fit.get_string()))) {
627  fprintf(stderr, "p_bb_get(): could not bind return value\n");
628  return EC_fail;
629  }
630  break;
631 
632  case IFT_BYTE:
633  if (fit.get_length() > 1)
634  {
635  EC_word res = nil();
636  uint8_t* array = fit.get_bytes();
637  for (int i=fit.get_length()-1; i>= 0; i--)
638  res = list( EC_word( (long) array[i]), res);
639  if ( EC_succeed != EC_arg( 3 ).unify( res ) )
640  {
641  printf( "p_bb_get(): could not bind return value\n" );
642  return EC_fail;
643  }
644  } else
645  {
646  if ( EC_succeed != EC_arg( 3 ).unify( EC_word( (long) fit.get_byte() ) ) )
647  {
648  printf( "p_bb_get(): could not bind return value\n" );
649  return EC_fail;
650  }
651  }
652  break;
653 
654  case IFT_ENUM:
655  if (EC_succeed != EC_arg(3).unify(fit.get_value_string())) {
656  fprintf(stderr, "p_bb_get(): could not bind return value\n");
657  return EC_fail;
658  }
659  break;
660 
661  default:
662  fprintf(stderr, "p_bb_get(): could not find type of interface! Type: %s (%d)", fit.get_typename(), fit.get_type());
663  break;
664  }
665  break;
666  }
667  }
668 
669  if (fit == iface->fields_end()) {
670  fprintf(stderr, "p_bb_get(): interface %s has no field %s\n", uid, field);
671  return EC_fail;
672  }
673 
674  } else {
675  fprintf(stderr, "p_bb_get(): no interface with id %s found\n", uid);
676  return EC_fail;
677  }
678 
679  return EC_succeed;
680 }
681 
682 
683 int
684 p_bb_set()
685 {
686  char* uid;
687  char* field;
688 
689  if (EC_succeed != EC_arg(1).is_string(&uid)) {
690  fprintf(stderr, "p_bb_set(): no interface id given\n");
691  return EC_fail;
692  }
693 
694  if (EC_succeed != EC_arg(2).is_string(&field)) {
695  fprintf(stderr, "p_bb_set(): no field given\n");
696  return EC_fail;
697  }
698 
699  std::map<std::string, Interface *> &interfaces =
701 
702  if (interfaces.find(uid) != interfaces.end()) {
703  Interface *iface = interfaces[uid];
704 
705  if (!iface->is_writer()) {
706  fprintf(stderr, "p_bb_set(): interface %s not a writer\n", uid);
707  return EC_fail;
708  }
709 
711  for (fit = iface->fields(); fit != iface->fields_end(); ++fit) {
712  if (0 == strcmp(field, fit.get_name())) {
713  switch (fit.get_type()) {
714  case IFT_BOOL:
715  {
716  EC_atom val;
717  if (EC_succeed != EC_arg(3).is_atom(&val)) {
718  fprintf(stderr, "p_bb_set(): no value_given\n");
719  return EC_fail;
720  }
721 
722  if (0 == strcmp("true", val.name()))
723  { fit.set_bool(true); }
724  else if (0 == strcmp("false", val.name()))
725  { fit.set_bool(false); }
726  else
727  {
728  fprintf(stderr, "p_bb_set(): boolean value neither true nor false\n");
729  return EC_fail;
730  }
731  }
732  break;
733 
734  case IFT_INT8:
735  {
736  long val;
737  if (EC_succeed != EC_arg(3).is_long(&val))
738  {
739  fprintf(stderr, "p_bb_set(): no value given\n");
740  return EC_fail;
741  }
742 
743  fit.set_int8((int8_t) val);
744  }
745  break;
746 
747  case IFT_UINT8:
748  {
749  long val;
750  if (EC_succeed != EC_arg(3).is_long(&val))
751  {
752  fprintf(stderr, "p_bb_set(): no value given\n");
753  return EC_fail;
754  }
755 
756  fit.set_uint8((uint8_t) val);
757  }
758  break;
759 
760  case IFT_INT16:
761  {
762  long val;
763  if (EC_succeed != EC_arg(3).is_long(&val))
764  {
765  fprintf(stderr, "p_bb_set(): no value given\n");
766  return EC_fail;
767  }
768 
769  fit.set_int16((int16_t) val);
770  }
771  break;
772 
773  case IFT_UINT16:
774  {
775  long val;
776  if (EC_succeed != EC_arg(3).is_long(&val))
777  {
778  fprintf(stderr, "p_bb_set(): no value given\n");
779  return EC_fail;
780  }
781 
782  fit.set_uint16((uint16_t) val);
783  }
784  break;
785 
786  case IFT_INT32:
787  {
788  long val;
789  if (EC_succeed != EC_arg(3).is_long(&val))
790  {
791  fprintf(stderr, "p_bb_set(): no value given\n");
792  return EC_fail;
793  }
794 
795  fit.set_int32((int32_t) val);
796  }
797  break;
798 
799  case IFT_UINT32:
800  {
801  long val;
802  if (EC_succeed != EC_arg(3).is_long(&val))
803  {
804  fprintf(stderr, "p_bb_set(): no value given\n");
805  return EC_fail;
806  }
807 
808  fit.set_uint32((uint32_t) val);
809  }
810  break;
811 
812  case IFT_INT64:
813  {
814  long val;
815  if (EC_succeed != EC_arg(3).is_long(&val))
816  {
817  fprintf(stderr, "p_bb_set(): no value given\n");
818  return EC_fail;
819  }
820 
821  fit.set_int64((int64_t) val);
822  }
823  break;
824 
825  case IFT_UINT64:
826  {
827  long val;
828  if (EC_succeed != EC_arg(3).is_long(&val))
829  {
830  fprintf(stderr, "p_bb_set(): no value given\n");
831  return EC_fail;
832  }
833 
834  fit.set_uint64((uint64_t) val);
835  }
836  break;
837 
838  case IFT_FLOAT:
839  {
840  double val;
841  if (EC_succeed != EC_arg(3).is_double(&val))
842  {
843  fprintf(stderr, "p_bb_set(): no value given\n");
844  return EC_fail;
845  }
846 
847  fit.set_float((float) val);
848  }
849  break;
850 
851  case IFT_STRING:
852  {
853  char* val;
854  if (EC_succeed != EC_arg(3).is_string(&val))
855  {
856  fprintf(stderr, "p_bb_set(): no value given\n");
857  return EC_fail;
858  }
859 
860  fit.set_string(val);
861  }
862  break;
863 
864  case IFT_BYTE:
865  case IFT_ENUM:
866  fprintf(stderr, "p_bb_set(): NOT YET IMPLEMENTET\n");
867  break;
868 
869  default:
870  break;
871  }
872  break;
873  }
874  }
875 
876  if (fit == iface->fields_end()) {
877  fprintf(stderr, "p_bb_set(): interface %s has no field %s\n", uid, field);
878  return EC_fail;
879  }
880 
881  } else {
882  fprintf(stderr, "p_bb_set(): no interface with id %s found\n", uid);
883 
884  return EC_fail;
885  }
886 
887  return EC_succeed;
888 }
889 
890 
891 int
892 p_bb_send_message()
893 {
894  char* uid;
895  char* message_type;
896 
897  if (EC_succeed != EC_arg(1).is_string(&uid)) {
898  fprintf(stderr, "p_bb_send_message(): no interface id given\n");
899  return EC_fail;
900  }
901 
902  if (EC_succeed != EC_arg(2).is_string(&message_type))
903  {
904  fprintf(stderr, "p_bb_send_message(): no message type given\n");
905  return EC_fail;
906  }
907 
908  std::map<std::string, Interface *> &interfaces =
910 
911  if (interfaces.find(uid) != interfaces.end()) {
912  Interface *iface = interfaces[uid];
913 
914  if (iface->is_writer()) {
915  fprintf(stderr, "p_bb_send_message(): interface with uid %s is a writer\n", uid);
916  return EC_fail;
917  }
918 
919  try {
920  Message* msg = iface->create_message(message_type);
921 
922  EC_word head;
923  EC_word tail;
924  if (EC_succeed == EC_arg(3).is_list(head, tail)) {
925  if (!process_message_args(msg, ::list(head, tail))) {
926  return EC_fail;
927  };
928  }
929 
930  msg->ref();
931  try {
932  (iface)->msgq_enqueue( msg );
933  // return the msgID as 4th argument
934  EC_arg( 4 ).unify((int)(msg->id()));
935  msg->unref();
936  } catch (Exception &e) {
937  msg->unref();
938  e.print_trace();
939  return EC_fail;
940  }
941 
942  } catch (Exception& e) {
943  fprintf(stderr, "p_bb_send_message() failed: %s\n", e.what_no_backtrace());
944  return EC_fail;
945  }
946  } else {
947  fprintf(stderr, "p_bb_send_message(): no interface with name %s\n", uid);
948  return EC_fail;
949  }
950 
951  return EC_succeed;
952 }
953 
954 
955 int
956 p_bb_recv_messages()
957 {
958  char* uid;
959 
960  if (EC_succeed != EC_arg(1).is_string(&uid)) {
961  fprintf(stderr, "p_bb_recv_messages(): no interface uid given\n");
962  return EC_fail;
963  }
964 
965  std::map<std::string, Interface *> &interfaces =
967 
968  if (interfaces.find(uid) != interfaces.end()) {
969  Interface *iface = interfaces[uid];
970 
971  if (! iface->is_writer()) {
972  fprintf(stderr, "p_bb_recv_messages(): interface with uid %s is not a writer\n", uid);
973  return EC_fail;
974  }
975 
976  EC_word msg_list = nil();
977 
978  while (!iface->msgq_empty()) {
979  Message* msg = iface->msgq_first();
980 
981  // construct list of key-value pairs: [[field1, val1], [field2, val2], ...]
982  EC_word args = nil();
983  for (InterfaceFieldIterator fit = msg->fields(); fit != msg->fields_end(); ++fit) {
984  EC_word value;
985 
986  switch (fit.get_type()) {
987  case IFT_BOOL:
988  if (fit.get_bool())
989  { value = EC_atom((char*) "true"); }
990  else
991  { value = EC_atom((char*) "false"); }
992 
993  break;
994 
995  case IFT_INT8:
996  value = EC_word((long) fit.get_int8());
997  break;
998 
999  case IFT_UINT8:
1000  value = EC_word((long) fit.get_uint8());
1001  break;
1002 
1003  case IFT_INT16:
1004  value = EC_word((long) fit.get_int16());
1005  break;
1006 
1007  case IFT_UINT16:
1008  value = EC_word((long) fit.get_uint16());
1009  break;
1010 
1011  case IFT_INT32:
1012  value = EC_word((long) fit.get_int32());
1013  break;
1014 
1015  case IFT_UINT32:
1016  value = EC_word((long) fit.get_uint32());
1017  break;
1018 
1019  case IFT_INT64:
1020  value = EC_word((long) fit.get_int64());
1021  break;
1022 
1023  case IFT_UINT64:
1024  value = EC_word((long) fit.get_uint64());
1025  break;
1026 
1027  case IFT_FLOAT:
1028  value = EC_word((double) fit.get_float());
1029  break;
1030 
1031  case IFT_STRING:
1032  value = EC_word(fit.get_string());
1033  break;
1034 
1035  case IFT_BYTE:
1036  case IFT_ENUM:
1037  fprintf(stderr, "p_bb_recv_messages(): NOT YET IMPLEMENTED\n");
1038  break;
1039 
1040  default:
1041  fprintf(stderr, "p_bb_recv_messages(): unknown field type\n");
1042  }
1043 
1044  EC_word field = ::list(EC_word(fit.get_name()),
1045  ::list(value, nil()));
1046  args = ::list(field, args);
1047  }
1048 
1049  // construct list of messages: [[MsgType, [[Key1, Val1], ...]], ... ]
1050  msg_list = ::list(::list(EC_word(msg->type()),
1051  ::list(args, nil())),
1052  msg_list);
1053 
1054  iface->msgq_pop();
1055  }
1056 
1057  if (EC_succeed != EC_arg(2).unify(msg_list)) {
1058  fprintf(stderr, "p_bb_recv_messages(): could not bind return value\n");
1059  return EC_fail;
1060  }
1061 
1062  } else {
1063  fprintf(stderr, "p_bb_recv_messages(): no interface with id %s found\n", uid);
1064  return EC_fail;
1065  }
1066 
1067  return EC_succeed;
1068 }
1069 
1070 
1071 bool
1072 process_message_args(Message* msg, EC_word arg_list)
1073 {
1074  EC_word head;
1075  EC_word tail;
1076 
1077  for (; EC_succeed == arg_list.is_list(head, tail) ; arg_list = tail)
1078  {
1079  // [field, value]
1080  EC_word field;
1081  EC_word value;
1082  EC_word t1;
1083  EC_word t2;
1084 
1085  if (EC_succeed != head.is_list(field, t1) ||
1086  EC_succeed != t1.is_list(value, t2) )
1087  {
1088  fprintf(stderr, "p_bb_send_messge(): could not parse argument list\n");
1089  return false;
1090  }
1091 
1092  char* field_name;
1093  if (EC_succeed != field.is_string(&field_name))
1094  {
1095  fprintf(stderr, "p_bb_send_message(): malformed argument list\n");
1096  return false;
1097  }
1098 
1100  for (fit = msg->fields();
1101  fit != msg->fields_end();
1102  ++fit)
1103  {
1104  if (0 == strcmp(fit.get_name(), field_name))
1105  {
1106  switch(fit.get_type())
1107  {
1108  case IFT_BOOL:
1109  {
1110  EC_atom val;
1111  if (EC_succeed != value.is_atom(&val))
1112  {
1113  fprintf(stderr, "p_bb_send_message(): no value_given (bool)\n");
1114  return false;
1115  }
1116 
1117  if (0 == strcmp("true", val.name()))
1118  { fit.set_bool(true); }
1119  else if (0 == strcmp("false", val.name()))
1120  { fit.set_bool(false); }
1121  else
1122  {
1123  fprintf(stderr, "p_bb_send_message(): boolean value neither true nor false\n");
1124  return false;
1125  }
1126  }
1127 
1128  break;
1129 
1130  case IFT_INT8:
1131  {
1132  long val;
1133  if (EC_succeed != value.is_long(&val))
1134  {
1135  fprintf(stderr, "p_bb_send_message(): no value given (int8)\n");
1136  return false;
1137  }
1138 
1139  fit.set_int8((int8_t) val);
1140  }
1141 
1142  break;
1143 
1144  case IFT_UINT8:
1145  {
1146  long val;
1147  if (EC_succeed != value.is_long(&val))
1148  {
1149  fprintf(stderr, "p_bb_send_message(): no value given (uint8)\n");
1150  return false;
1151  }
1152 
1153  fit.set_uint8((uint8_t) val);
1154  }
1155 
1156  break;
1157 
1158  case IFT_INT16:
1159  {
1160  long val;
1161  if (EC_succeed != value.is_long(&val))
1162  {
1163  fprintf(stderr, "p_bb_send_message(): no value given (int16)\n");
1164  return false;
1165  }
1166 
1167  fit.set_int16((int16_t) val);
1168  }
1169 
1170  break;
1171 
1172  case IFT_UINT16:
1173  {
1174  long val;
1175  if (EC_succeed != value.is_long(&val))
1176  {
1177  fprintf(stderr, "p_bb_send_message(): no value given (uint16)\n");
1178  return false;
1179  }
1180 
1181  fit.set_uint16((uint16_t) val);
1182  }
1183 
1184  break;
1185 
1186  case IFT_INT32:
1187  {
1188  long val;
1189  if (EC_succeed != value.is_long(&val))
1190  {
1191  fprintf(stderr, "p_bb_send_message(): no value given (int32)\n");
1192  return false;
1193  }
1194 
1195  fit.set_int32((int32_t) val);
1196  }
1197 
1198  break;
1199 
1200  case IFT_UINT32:
1201  {
1202  long val;
1203  if (EC_succeed != value.is_long(&val))
1204  {
1205  fprintf(stderr, "p_bb_send_message(): no value given (uint32)\n");
1206  return false;
1207  }
1208 
1209  fit.set_uint32((uint32_t) val);
1210  }
1211 
1212  break;
1213 
1214  case IFT_INT64:
1215  {
1216  long val;
1217  if (EC_succeed != value.is_long(&val))
1218  {
1219  fprintf(stderr, "p_bb_send_message(): no value given (int64)\n");
1220  return false;
1221  }
1222 
1223  fit.set_int64((int64_t) val);
1224  }
1225 
1226  break;
1227 
1228  case IFT_UINT64:
1229  {
1230  long val;
1231  if (EC_succeed != value.is_long(&val))
1232  {
1233  fprintf(stderr, "p_bb_send_message(): no value given (uint64)\n");
1234  return false;
1235  }
1236 
1237  fit.set_uint64((uint64_t) val);
1238  }
1239 
1240  break;
1241 
1242  case IFT_FLOAT:
1243  {
1244  double val;
1245  if (EC_succeed != value.is_double(&val))
1246  {
1247  fprintf(stderr, "p_bb_send_message(): no value given (float)\n");
1248  return false;
1249  }
1250 
1251  fit.set_float((float) val);
1252  }
1253 
1254  break;
1255 
1256  case IFT_STRING:
1257  {
1258  char* val;
1259  if (EC_succeed != value.is_string(&val))
1260  {
1261  fprintf(stderr, "p_bb_send_message(): no value given (string)\n");
1262  return false;
1263  }
1264 
1265  fit.set_string(val);
1266  }
1267 
1268  break;
1269 
1270  case IFT_BYTE:
1271  case IFT_ENUM:
1272  fprintf(stderr, "p_bb_send_message(): NOT YET IMPLEMENTET\n");
1273  break;
1274 
1275  default:
1276  break;
1277  }
1278 
1279  break;
1280  }
1281  }
1282 
1283  if (fit == msg->fields_end())
1284  {
1285  fprintf(stderr, "p_bb_send_message(): message has no field with name %s\n",
1286  field_name);
1287  return false;
1288  }
1289  }
1290 
1291  return true;
1292 }
64 bit integer field
Definition: types.h:43
Interface field iterator.
void set_int64(int64_t i, unsigned int index=0)
Set value of current field as integer.
Base class for all messages passed through interfaces in Fawkes BlackBoard.
Definition: message.h:44
unsigned int id() const
Get message ID.
Definition: message.cpp:197
uint8_t * get_bytes() const
Get value of current field as byte array.
uint16_t get_uint16(unsigned int index=0) const
Get value of current field as unsigned integer.
void set_float(float f, unsigned int index=0)
Set value of current field as float.
bool msgq_empty()
Check if queue is empty.
Definition: interface.cpp:1048
const char * get_typename() const
Get type of current field as string.
void unref()
Decrement reference count and conditionally delete this instance.
Definition: refcount.cpp:99
double get_double(unsigned int index=0) const
Get value of current field as double.
void set_bool(bool b, unsigned int index=0)
Set value of current field as bool.
void set_int16(int16_t i, unsigned int index=0)
Set value of current field as integer.
Fawkes library namespace.
bool get_bool(unsigned int index=0) const
Get value of current field as bool.
8 bit unsigned integer field
Definition: types.h:38
void set_uint16(uint16_t i, unsigned int index=0)
Set value of current field as unsigned integer.
float * get_floats() const
Get value of current field as float array.
16 bit unsigned integer field
Definition: types.h:40
void set_int8(int8_t i, unsigned int index=0)
Set value of current field as integer.
interface_fieldtype_t get_type() const
Get type of current field.
std::map< std::string, Interface * > & interfaces()
Obtain the list of opened interfaces.
Definition: blackboard.cpp:156
void set_uint8(uint8_t i, unsigned int index=0)
Set value of current field as unsigned integer.
string field
Definition: types.h:47
byte field, alias for uint8
Definition: types.h:48
static BlackBoard * blackboard_instance()
Access the BlackBoard instance.
Definition: blackboard.cpp:145
const char * get_value_string(const char *array_sep=", ")
Get value of current field as string.
float get_float(unsigned int index=0) const
Get value of current field as float.
virtual Message * create_message(const char *type) const =0
Create message based on type name.
Base class for all Fawkes BlackBoard interfaces.
Definition: interface.h:79
InterfaceFieldIterator fields_end()
Invalid iterator.
Definition: message.cpp:398
16 bit integer field
Definition: types.h:39
static void cleanup_instance()
Delete the current EclExternalBlackBoard instance and set it to NULL.
Definition: blackboard.cpp:85
uint8_t get_byte(unsigned int index=0) const
Get value of current field as byte.
void set_int32(int32_t i, unsigned int index=0)
Set value of current field as integer.
static void create_initial_object(BlackBoard *bb)
Creates the initial EclExternalBlackBoard object.
Definition: blackboard.cpp:79
static EclExternalBlackBoard * instance()
Get the EclExternalBlackBoard instance.
Definition: blackboard.cpp:97
int16_t get_int16(unsigned int index=0) const
Get value of current field as integer.
void msgq_pop()
Erase first message from queue.
Definition: interface.cpp:1193
int8_t get_int8(unsigned int index=0) const
Get value of current field as integer.
Base class for exceptions in Fawkes.
Definition: exception.h:36
Message * msgq_first()
Get the first message from the message queue.
Definition: interface.cpp:1180
void disconnect()
Disconnect remote blackboard connection.
Definition: blackboard.cpp:130
const char * get_name() const
Get name of current field.
uint8_t get_uint8(unsigned int index=0) const
Get value of current field as unsigned integer.
void ref()
Increment reference count.
Definition: refcount.cpp:70
double * get_doubles() const
Get value of current field as double array.
Wrapper class for using the blackboard in the implementation of the external predicates.
Definition: blackboard.h:39
~EclExternalBlackBoard()
Destructor.
Definition: blackboard.cpp:65
const char * uid() const
Get unique identifier of interface.
Definition: interface.cpp:687
virtual const char * what_no_backtrace() const
Get primary string (does not implicitly print the back trace).
Definition: exception.cpp:686
void set_string(const char *s)
Set value of current field as string.
uint64_t get_uint64(unsigned int index=0) const
Get value of current field as unsigned integer.
64 bit unsigned integer field
Definition: types.h:44
const char * get_string() const
Get value of current field as string.
InterfaceFieldIterator fields()
Get iterator over all fields of this interface instance.
Definition: message.cpp:388
bool connected()
Query connection status.
Definition: blackboard.cpp:124
void set_uint32(uint32_t i, unsigned int index=0)
Set value of current field as unsigned integer.
uint32_t get_uint32(unsigned int index=0) const
Get value of current field as unsigned integer.
float field
Definition: types.h:45
size_t get_length() const
Get length of current field.
bool is_writer() const
Check if this is a writing instance.
Definition: interface.cpp:440
void print_trace()
Prints trace to stderr.
Definition: exception.cpp:619
32 bit integer field
Definition: types.h:41
InterfaceFieldIterator fields_end()
Invalid iterator.
Definition: interface.cpp:1218
Remote BlackBoard.
Definition: remote.h:48
void connect(const char *host, long port)
Open remote blackboard connection.
Definition: blackboard.cpp:112
virtual Interface * open_for_reading(const char *interface_type, const char *identifier, const char *owner=NULL)=0
Open interface for reading.
void set_uint64(uint64_t i, unsigned int index=0)
Set value of current field as unsigned integer.
The BlackBoard abstract class.
Definition: blackboard.h:48
InterfaceFieldIterator fields()
Get iterator over all fields of this interface instance.
Definition: interface.cpp:1208
boolean field
Definition: types.h:36
int32_t get_int32(unsigned int index=0) const
Get value of current field as integer.
virtual Interface * open_for_writing(const char *interface_type, const char *identifier, const char *owner=NULL)=0
Open interface for writing.
const char * type() const
Get message type.
Definition: message.cpp:378
32 bit unsigned integer field
Definition: types.h:42
field with interface specific enum type
Definition: types.h:49
8 bit integer field
Definition: types.h:37
double field
Definition: types.h:46
virtual void close(Interface *interface)=0
Close interface.
int64_t get_int64(unsigned int index=0) const
Get value of current field as integer.