Fawkes API  Fawkes Development Version
blackboard.cpp
00001 
00002 /***************************************************************************
00003  *  blackboard.h - External predicates to remotely access the Fawkes
00004  *                 blackboard
00005  *
00006  *  Created: Wed Mar 09 17:10:54 2011
00007  *  Copyright  2011  Daniel Beck
00008  *
00009  ****************************************************************************/
00010 
00011 /*  This program is free software; you can redistribute it and/or modify
00012  *  it under the terms of the GNU General Public License as published by
00013  *  the Free Software Foundation; either version 2 of the License, or
00014  *  (at your option) any later version.
00015  *
00016  *  This program is distributed in the hope that it will be useful,
00017  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019  *  GNU Library General Public License for more details.
00020  *
00021  *  Read the full text in the LICENSE.GPL file in the doc directory.
00022  */
00023 
00024 #include "blackboard.h"
00025 
00026 #include <blackboard/remote.h>
00027 
00028 #include <eclipseclass.h>
00029 
00030 #include <vector>
00031 
00032 #include <cstdio>
00033 #include <cstring>
00034 #include <cstdlib>
00035 
00036 /** @class fawkes::EclExternalBlackBoard
00037  * Wrapper class for using the blackboard in the implementation of the external
00038  * predicates.
00039  * @author Daniel Beck
00040  */
00041 namespace fawkes
00042 {
00043 class EclExternalBlackBoard
00044 {
00045 public:
00046   /** Constructor. */
00047   EclExternalBlackBoard() : m_blackboard( 0 ) {}
00048   /** Destructor. */
00049   ~EclExternalBlackBoard() {
00050     for ( std::vector< Interface* >::iterator iit = m_interfaces.begin();
00051           iit != m_interfaces.end();
00052           ++iit )
00053     { m_blackboard->close( *iit ); }
00054     delete m_blackboard;
00055   }
00056 
00057   /** Open remote blackboard connection.
00058    * @param host the host running Fawkes
00059    */
00060   void connect( const char* host )
00061   {
00062     m_blackboard = new RemoteBlackBoard( host, 1910 );
00063   }
00064 
00065   /** Query connection status.
00066    * @return true if connected; false otherwise
00067    */
00068   bool connected()
00069   {
00070     return m_blackboard ? true : false;
00071   }
00072 
00073   /** Disconnect remote blackboard connection. */
00074   void disconnect()
00075   {
00076     for ( std::vector< Interface* >::iterator iit = m_interfaces.begin();
00077           iit != m_interfaces.end();
00078           ++iit )
00079     { m_blackboard->close( *iit ); }
00080     delete m_blackboard;
00081     m_blackboard = 0;
00082   }
00083 
00084   /** Access the BlackBoard instance.
00085    * @return the blackboard instance
00086    */
00087   BlackBoard* instance()
00088   {
00089     return m_blackboard;
00090   }
00091 
00092   /** Obtain the list of opened interfaces.
00093    * @return list of opened interfaces
00094    */
00095   std::vector< Interface* >& interfaces()
00096   {
00097     return m_interfaces;
00098   }
00099 
00100 private:
00101   BlackBoard*                m_blackboard;
00102   std::vector< Interface* >  m_interfaces;
00103 };
00104 
00105 }
00106 
00107 using namespace std;
00108 using namespace fawkes;
00109 
00110 EclExternalBlackBoard g_blackboard;
00111 
00112 bool process_message_args(Message* msg, EC_word arg_list);
00113 
00114 int
00115 p_connect_to_blackboard()
00116 {
00117   if ( g_blackboard.connected() )
00118   {
00119     printf( "p_connect_to_blackboard(): already connected\n" );
00120     return EC_fail;
00121   }
00122 
00123   // get hostname
00124   char* hostname;
00125 
00126   if ( EC_succeed != EC_arg( 1 ).is_string( &hostname ) )
00127   {
00128     printf( "p_connect_to_blackboard(): first argument is not a string\n" );
00129     return EC_fail;
00130   }
00131 
00132   try
00133   {
00134     g_blackboard.connect( hostname );
00135   }
00136   catch ( Exception& e )
00137   {
00138     e.print_trace();
00139     return EC_fail;
00140   }
00141 
00142   return EC_succeed;
00143 }
00144 
00145 
00146 int
00147 p_disconnect_from_blackboard()
00148 {
00149   if ( !g_blackboard.connected() )
00150   {
00151     printf( "p_disconnect_from_blackboard(): not connected\n" );
00152     return EC_fail;
00153   }
00154 
00155   g_blackboard.disconnect();
00156 
00157   return EC_succeed;
00158 }
00159 
00160 
00161 int
00162 p_is_alive()
00163 {
00164   if ( !g_blackboard.connected() )
00165   {
00166     printf( "p_is_alive(): not connected\n" );
00167     return EC_fail;
00168   }
00169 
00170   if ( g_blackboard.instance()->is_alive() )
00171   { return EC_succeed; }
00172   else
00173   { return EC_fail; }
00174 }
00175 
00176 
00177 int
00178 p_open_interface()
00179 {
00180   if ( !g_blackboard.connected() )
00181   {
00182     printf("p_open_interface(): not connected\n" );
00183     return EC_fail;
00184   }
00185 
00186   EC_atom mode;
00187   char* interface_type;
00188   char* interface_id;
00189 
00190   if ( EC_succeed != EC_arg( 1 ).is_atom( &mode) )
00191   {
00192     printf( "p_open_interface(): no mode given\n" );
00193     return EC_fail;
00194   }
00195 
00196   if ( EC_succeed != EC_arg( 2 ).is_string( &interface_type ) )
00197   {
00198     printf( "p_open_interface(): no type given\n" );
00199     return EC_fail;
00200   }
00201 
00202   if ( EC_succeed != EC_arg ( 3 ).is_string( &interface_id ) )
00203   {
00204     printf( "p_open_interface(): no id given\n" );
00205     return EC_fail;
00206   }
00207 
00208   try
00209   {
00210     Interface* iface;
00211 
00212     if ( 0 == strcmp( "w", mode.name() ) )
00213     { iface = g_blackboard.instance()->open_for_writing( interface_type, interface_id ); }
00214     else
00215     { iface = g_blackboard.instance()->open_for_reading( interface_type, interface_id ); }
00216 
00217     g_blackboard.interfaces().push_back( iface );
00218   }
00219   catch (Exception& e)
00220   {
00221     e.print_trace();
00222     return EC_fail;
00223   }
00224 
00225   return EC_succeed;
00226 }
00227 
00228 
00229 int
00230 p_close_interface()
00231 {
00232   if ( !g_blackboard.connected() )
00233   {
00234     printf("p_close_interface(): not connected\n" );
00235     return EC_fail;
00236   }
00237 
00238   // char* interface_type;
00239   char* interface_id;
00240 
00241   if ( EC_succeed != EC_arg( 1 ).is_string( &interface_id ) )
00242   {
00243     printf( "p_close_interface(): no id given\n" );
00244     return EC_fail;
00245   }
00246 
00247   bool iface_found = false;
00248 
00249   for ( vector< Interface* >::iterator it = g_blackboard.interfaces().begin();
00250         it != g_blackboard.interfaces().end();
00251         ++it )
00252   {
00253     if ( 0 == strcmp( (*it)->id(), interface_id ) )
00254 
00255     {
00256       iface_found = true;
00257       g_blackboard.instance()->close( *it );
00258       g_blackboard.interfaces().erase( it );
00259       break;
00260     }
00261   }
00262 
00263   if ( iface_found )
00264   { return EC_succeed; }
00265   else
00266   { return EC_fail; }
00267 }
00268 
00269 
00270 int
00271 p_has_writer()
00272 {
00273   char* interface_id;
00274 
00275   if ( EC_succeed != EC_arg( 1 ).is_string( &interface_id ) )
00276   {
00277     printf( "p_has_writer(): no id given\n" );
00278     return EC_fail;
00279   }
00280 
00281   for ( vector< Interface* >::iterator it = g_blackboard.interfaces().begin();
00282         it != g_blackboard.interfaces().end();
00283         ++it )
00284   {
00285     if ( 0 == strcmp( (*it)->id(), interface_id ) )
00286     {
00287       if ( (*it)->has_writer() )
00288       { return EC_succeed; }
00289       else
00290       { return EC_fail; }
00291 
00292       break;
00293     }
00294   }
00295 
00296   return EC_fail;
00297 }
00298 
00299 
00300 int
00301 p_instance_serial()
00302 {
00303   if ( !g_blackboard.connected() )
00304   {
00305     printf( "p_instance_serial(): not connected to blackboard\n" );
00306     return EC_fail;
00307   }
00308 
00309   char* interface_id;
00310   if ( EC_succeed != EC_arg( 1 ).is_string( &interface_id ) )
00311   {
00312     printf( "p_instance_serial(): no interface id given\n" );
00313     return EC_fail;
00314   }
00315 
00316   for ( vector< Interface* >::iterator iit = g_blackboard.interfaces().begin();
00317         iit != g_blackboard.interfaces().end();
00318         ++iit )
00319   {
00320     if ( 0 == strcmp( (*iit)->id(), interface_id ) )
00321     {
00322       if ( EC_succeed != EC_arg( 2 ).unify( (*iit)->serial() ) )
00323       {
00324         printf( "p_instance_serial(): could not bind return value\n" );
00325         return EC_fail;
00326       }
00327 
00328       return EC_succeed;
00329     }
00330   }
00331 
00332   return EC_fail;
00333 }
00334 
00335 
00336 int
00337 p_read_interfaces()
00338 {
00339   for ( vector< Interface* >::iterator it = g_blackboard.interfaces().begin();
00340         it != g_blackboard.interfaces().end();
00341         ++it )
00342   {
00343     (*it)->read();
00344   }
00345 
00346   return EC_succeed;
00347 }
00348 
00349 int
00350 p_write_interfaces()
00351 {
00352   for ( vector< Interface* >::iterator it = g_blackboard.interfaces().begin();
00353         it != g_blackboard.interfaces().end();
00354         ++it )
00355   {
00356     if ( (*it)->is_writer() )
00357     { (*it)->write(); }
00358   }
00359 
00360   return EC_succeed;
00361 }
00362 
00363 int
00364 p_read_from_interface()
00365 {
00366   char* interface_id;
00367   char* field;
00368 
00369   if ( EC_succeed != EC_arg( 1 ).is_string( &interface_id ) )
00370   {
00371     printf( "p_read_from_interface(): no interface id given\n" );
00372     return EC_fail;
00373   }
00374 
00375   if ( EC_succeed != EC_arg( 2 ).is_string( &field ) )
00376   {
00377     printf( "p_read_from_interface(): no field given\n" );
00378     return EC_fail;
00379   }
00380 
00381   vector< Interface* >::iterator it;
00382   for ( it = g_blackboard.interfaces().begin();
00383         it != g_blackboard.interfaces().end();
00384         ++it )
00385   {
00386     if ( 0 == strcmp( interface_id, (*it)->id() ) )
00387     {
00388       InterfaceFieldIterator fit;
00389       for ( fit = (*it)->fields();
00390             fit != (*it)->fields_end();
00391             ++fit )
00392       {
00393         if ( 0 == strcmp( field, fit.get_name() ) )
00394         {
00395           switch ( fit.get_type() ) {
00396           case IFT_BOOL:
00397             if ( fit.get_bool() )
00398             {
00399               if ( EC_succeed != EC_arg( 3 ).unify( EC_atom( (char*) "true" ) ) )
00400               {
00401                 printf( "p_read_from_interface(): could not bind return value\n" );
00402                 return EC_fail;
00403               }
00404             }
00405             else
00406             {
00407               if ( EC_succeed != EC_arg( 3 ).unify( EC_atom( (char*) "false" ) ) )
00408               {
00409                 printf( "p_read_from_interface(): could not bind return value\n" );
00410                 return EC_fail;
00411               }
00412             }
00413              
00414             break;
00415             
00416           case IFT_INT8:
00417             if ( EC_succeed != EC_arg( 3 ).unify( EC_word( (long) fit.get_int8() ) ) )
00418             {
00419               printf( "p_read_from_interface(): could not bind return value\n" );
00420               return EC_fail;
00421             }
00422             
00423             break;
00424             
00425           case IFT_UINT8:
00426             if ( EC_succeed != EC_arg( 3 ).unify( EC_word( (long) fit.get_uint8() ) ) )
00427             {
00428               printf( "p_read_from_interface(): could not bind return value\n" );
00429               return EC_fail;
00430             }
00431             
00432             break;
00433             
00434           case IFT_INT16:
00435             if ( EC_succeed != EC_arg( 3 ).unify( EC_word( (long) fit.get_int16() ) ) )
00436             {
00437               printf( "p_read_from_interface(): could not bind return value\n" );
00438               return EC_fail;
00439             }
00440             
00441             break;
00442             
00443           case IFT_UINT16:
00444             if ( EC_succeed != EC_arg( 3 ).unify( EC_word( (long) fit.get_uint16() ) ) )
00445             {
00446               printf( "p_read_from_interface(): could not bind return value\n" );
00447               return EC_fail;
00448             }
00449             
00450             break;
00451             
00452           case IFT_INT32:
00453             if ( EC_succeed != EC_arg( 3 ).unify( EC_word( (long) fit.get_int32() ) ) )
00454             {
00455               printf( "bb_read_interface/3: could not bind value\n" );
00456               return EC_fail;
00457             }
00458             
00459             break;
00460             
00461           case IFT_UINT32:
00462             if ( EC_succeed != EC_arg( 3 ).unify( EC_word( (long) fit.get_uint32() ) ) )
00463             {
00464               printf( "p_read_from_interface(): could not bind return value\n" );
00465               return EC_fail;
00466             }
00467             
00468             break;
00469             
00470           case IFT_INT64:
00471             if ( EC_succeed != EC_arg( 3 ).unify( EC_word( (long) fit.get_int64() ) ) )
00472             {
00473               printf( "p_read_from_interface(): could not bind return value\n" );
00474               return EC_fail;
00475             }
00476             
00477             break;
00478             
00479           case IFT_UINT64:
00480             if ( EC_succeed != EC_arg( 3 ).unify( EC_word( (long) fit.get_uint64() ) ) )
00481             {
00482               printf( "p_read_from_interface(): could not bind return value\n" );
00483               return EC_fail;
00484             }
00485             
00486             break;
00487             
00488           case IFT_FLOAT:
00489             if ( EC_succeed != EC_arg( 3 ).unify( EC_word( (double) fit.get_float() ) ) )
00490             {
00491               printf( "p_read_from_interface(): could not bind return value\n" );
00492               return EC_fail;
00493             }
00494             
00495             break;
00496 
00497           case IFT_STRING:
00498             if ( EC_succeed != EC_arg( 3 ).unify( EC_word( fit.get_string() ) ) )
00499             {
00500               printf( "p_read_from_interface(): could not bind return value\n" );
00501               return EC_fail;
00502             }
00503             
00504             break;
00505             
00506           case IFT_BYTE:
00507             printf( "p_read_from_interface(): NOT YET IMPLEMENTED\n" );
00508             break;
00509 
00510           case IFT_ENUM:
00511             if ( EC_succeed != EC_arg( 3 ).unify( fit.get_value_string() ) )
00512             {
00513               printf( "p_read_from_interface(): could not bind return value\n" );
00514               return EC_fail;
00515             }
00516 
00517           default:
00518             break;
00519           }
00520 
00521           break;
00522         }
00523 
00524       }
00525 
00526       if ( fit == (*it)->fields_end() )
00527       {
00528         printf( "p_read_from_interface(): interface %s has no field %s\n",
00529                 interface_id, field );
00530         
00531         return EC_fail;
00532       }
00533 
00534       break;
00535     }
00536   }
00537 
00538   if ( it == g_blackboard.interfaces().end() )
00539   {
00540     printf( "p_read_from_interface(): no interface with id %s found\n",
00541             interface_id );
00542     
00543     return EC_fail;
00544   }
00545 
00546   return EC_succeed;
00547 }
00548 
00549 int
00550 p_write_to_interface()
00551 {
00552   char* interface_id;
00553   char* field;
00554 
00555   if ( EC_succeed != EC_arg( 1 ).is_string( &interface_id ) )
00556   {
00557     printf( "p_write_to_interface(): no interface id given\n" );
00558     return EC_fail;
00559   }
00560 
00561   if ( EC_succeed != EC_arg( 2 ).is_string( &field ) )
00562   {
00563     printf( "p_write_to_interface(): no field given\n" );
00564     return EC_fail;
00565   }
00566 
00567   vector< Interface* >::iterator it;
00568   for ( it = g_blackboard.interfaces().begin();
00569         it != g_blackboard.interfaces().end();
00570         ++it )
00571   {
00572     if ( 0 == strcmp( interface_id, (*it)->id() ) )
00573     {
00574       if ( !(*it)->is_writer() )
00575       {
00576         printf( "p_write_to_interface(): not a writer\n" );
00577         return EC_fail;
00578       }
00579 
00580       InterfaceFieldIterator fit;
00581       for ( fit = (*it)->fields();
00582             fit != (*it)->fields_end();
00583             ++fit )
00584       {
00585         if ( 0 == strcmp( field, fit.get_name() ) )
00586         {
00587           switch ( fit.get_type() ) {
00588           case IFT_BOOL:
00589             {
00590               EC_atom val;
00591               if ( EC_succeed != EC_arg( 3 ).is_atom( &val ) )
00592               {
00593                 printf( "p_write_to_interface(): no value_given\n" );
00594                 return EC_fail;
00595               }
00596 
00597               if ( 0 == strcmp( "true", val.name() ) )
00598               { fit.set_bool( true ); }
00599               else if ( 0 == strcmp( "false", val.name() ) )
00600               { fit.set_bool( false ); }
00601               else
00602               {
00603                 printf( "p_write_to_interface(): boolean value neither true nor false\n" );
00604                 return EC_fail;
00605               }
00606             }
00607 
00608             break;
00609             
00610           case IFT_INT8:
00611             {
00612               long val;
00613               if ( EC_succeed != EC_arg( 3 ).is_long( &val ) )
00614               {
00615                 printf( "p_write_to_interface(): no value given\n" );
00616                 return EC_fail;
00617               }
00618 
00619               fit.set_int8( (int8_t) val );
00620             }
00621 
00622             break;
00623             
00624           case IFT_UINT8:
00625             {
00626               long val;
00627               if ( EC_succeed != EC_arg( 3 ).is_long( &val ) )
00628               {
00629                 printf( "p_write_to_interface(): no value given\n" );
00630                 return EC_fail;
00631               }
00632 
00633               fit.set_uint8( (uint8_t) val );
00634             }
00635 
00636             break;
00637             
00638           case IFT_INT16:
00639             {
00640               long val;
00641               if ( EC_succeed != EC_arg( 3 ).is_long( &val ) )
00642               {
00643                 printf( "p_write_to_interface(): no value given\n" );
00644                 return EC_fail;
00645               }
00646 
00647               fit.set_int16( (int16_t) val );
00648             }
00649 
00650             break;
00651             
00652           case IFT_UINT16:
00653             {
00654               long val;
00655               if ( EC_succeed != EC_arg( 3 ).is_long( &val ) )
00656               {
00657                 printf( "p_write_to_interface(): no value given\n" );
00658                 return EC_fail;
00659               }
00660 
00661               fit.set_uint16( (uint16_t) val );
00662             }
00663 
00664             break;
00665             
00666           case IFT_INT32:
00667             {
00668               long val;
00669               if ( EC_succeed != EC_arg( 3 ).is_long( &val ) )
00670               {
00671                 printf( "p_write_to_interface(): no value given\n" );
00672                 return EC_fail;
00673               }
00674 
00675               fit.set_int32( (int32_t) val );
00676             }
00677             
00678             break;
00679             
00680           case IFT_UINT32:
00681             {
00682               long val;
00683               if ( EC_succeed != EC_arg( 3 ).is_long( &val ) )
00684               {
00685                 printf( "p_write_to_interface(): no value given\n" );
00686                 return EC_fail;
00687               }
00688 
00689               fit.set_uint32( (uint32_t) val );
00690             }
00691             
00692             break;
00693             
00694           case IFT_INT64:
00695             {
00696               long val;
00697               if ( EC_succeed != EC_arg( 3 ).is_long( &val ) )
00698               {
00699                 printf( "p_write_to_interface(): no value given\n" );
00700                 return EC_fail;
00701               }
00702 
00703               fit.set_int64( (int64_t) val );
00704             }
00705             
00706             break;
00707             
00708           case IFT_UINT64:
00709             {
00710               long val;
00711               if ( EC_succeed != EC_arg( 3 ).is_long( &val ) )
00712               {
00713                 printf( "p_write_to_interface(): no value given\n" );
00714                 return EC_fail;
00715               }
00716 
00717               fit.set_uint64( (uint64_t) val );
00718             }
00719             
00720             break;
00721             
00722           case IFT_FLOAT:
00723             {
00724               double val;
00725               if ( EC_succeed != EC_arg( 3 ).is_double( &val ) )
00726               {
00727                 printf( "p_write_to_interface(): no value given\n" );
00728                 return EC_fail;
00729               }
00730 
00731               fit.set_float( (float) val );
00732             }
00733             
00734             break;
00735             
00736           case IFT_STRING:
00737             {
00738               char* val;
00739               if ( EC_succeed != EC_arg( 3 ).is_string( &val ) )
00740               {
00741                 printf( "p_write_to_interface(): no value given\n" );
00742                 return EC_fail;
00743               }
00744 
00745               fit.set_string( val );
00746             }
00747             
00748             break;
00749             
00750           case IFT_BYTE:
00751           case IFT_ENUM:
00752             printf( "p_write_to_interface(): NOT YET IMPLEMENTET\n" );
00753             break;
00754 
00755           default:
00756             break;
00757           }
00758 
00759           break;
00760         }
00761 
00762       }
00763 
00764       if ( fit == (*it)->fields_end() )
00765       {
00766         printf( "p_write_to_interface(): interface %s has no field %s\n",
00767                 interface_id, field );
00768         
00769         return EC_fail;
00770       }
00771 
00772       break;
00773     }
00774   }
00775 
00776   if ( it == g_blackboard.interfaces().end() )
00777   {
00778     printf( "p_write_to_interface(): no interface with id %s found\n",
00779             interface_id );
00780     
00781     return EC_fail;
00782   }
00783 
00784   return EC_succeed;
00785   
00786 }
00787 
00788 
00789 int
00790 p_send_message()
00791 {
00792   char* interface_id;
00793   char* message_type;
00794 
00795   if ( EC_succeed != EC_arg( 1 ).is_string( &interface_id ) )
00796   {
00797     printf( "p_send_message(): no interface id given\n" );
00798     return EC_fail;
00799   }
00800 
00801   if ( EC_succeed != EC_arg( 2 ).is_string( &message_type ) )
00802   {
00803     printf( "p_send_message(): no message type given\n" );
00804     return EC_fail;
00805   }
00806 
00807   vector< Interface* >::iterator it;
00808   for ( it = g_blackboard.interfaces().begin();
00809         it != g_blackboard.interfaces().end();
00810         ++it )
00811   {
00812     if ( 0 == strcmp( interface_id, (*it)->id() ) )
00813     {
00814       if ( (*it)->is_writer() )
00815       {
00816         printf( "p_send_message(): interface with id %s is a writer\n", interface_id );
00817         return EC_fail;
00818       }
00819 
00820       try
00821       {
00822         Message* msg = (*it)->create_message( message_type );
00823 
00824         EC_word head;
00825         EC_word tail;
00826         if ( EC_succeed == EC_arg( 3 ).is_list( head, tail ) )
00827         {
00828           if ( !process_message_args(msg, ::list(head, tail)) )
00829           {
00830             return EC_fail;
00831           };
00832         }
00833 
00834         (*it)->msgq_enqueue( msg );
00835       }
00836       catch (Exception& e)
00837       {
00838         e.print_trace();
00839         return EC_fail;
00840       }
00841 
00842       break;
00843     }
00844   }
00845 
00846   if ( it == g_blackboard.interfaces().end() )
00847   {
00848     printf( "p_send_message(): no interface with name %s\n", interface_id );
00849     return EC_fail;
00850   }
00851 
00852   return EC_succeed;
00853 }
00854 
00855 
00856 int
00857 p_recv_messages()
00858 {
00859   char* interface_id;
00860 
00861   if ( EC_succeed != EC_arg( 1 ).is_string( &interface_id ) )
00862   {
00863     printf( "p_recv_messages(): no interface id given\n" );
00864     return EC_fail;
00865   }
00866 
00867   vector< Interface* >::iterator it;
00868 
00869   for ( it  = g_blackboard.interfaces().begin();
00870         it != g_blackboard.interfaces().end();
00871         ++it )
00872   {
00873     if ( 0 == strcmp( interface_id, (*it)->id() ) )
00874     {
00875       EC_word msg_list = nil();
00876 
00877       while ( !(*it)->msgq_empty() )
00878       {
00879         Message* msg = (*it)->msgq_first();
00880 
00881         // construct list of key-value pairs: [[field1, val1], [field2, val2], ...]
00882         EC_word args = nil();
00883         for ( InterfaceFieldIterator fit = msg->fields();
00884               fit != msg->fields_end();
00885               ++fit )
00886         {
00887           EC_word value;
00888 
00889           switch ( fit.get_type() )
00890           {
00891           case IFT_BOOL:
00892             if ( fit.get_bool() )
00893             { value = EC_atom( (char*) "true" ); }
00894             else
00895             { value = EC_atom( (char*) "false" ); }
00896 
00897             break;
00898 
00899           case IFT_INT8:
00900             value = EC_word( (long) fit.get_int8() );
00901             break;
00902 
00903           case IFT_UINT8:
00904             value = EC_word( (long) fit.get_uint8() );
00905             break;
00906 
00907           case IFT_INT16:
00908             value = EC_word( (long) fit.get_int16() );
00909             break;
00910 
00911           case IFT_UINT16:
00912             value = EC_word( (long) fit.get_uint16() );
00913             break;
00914 
00915           case IFT_INT32:
00916             value = EC_word( (long) fit.get_int32() );
00917             break;
00918 
00919           case IFT_UINT32:
00920             value = EC_word( (long) fit.get_uint32() );
00921             break;
00922 
00923           case IFT_INT64:
00924             value = EC_word( (long) fit.get_int64() );
00925             break;
00926 
00927           case IFT_UINT64:
00928             value = EC_word( (long) fit.get_uint64() );
00929             break;
00930 
00931           case IFT_FLOAT:
00932             value = EC_word( (double) fit.get_float() );
00933             break;
00934 
00935           case IFT_STRING:
00936             value = EC_word( fit.get_string() );
00937             break;
00938 
00939           case IFT_BYTE:
00940           case IFT_ENUM:
00941             printf( "p_recv_messages(): NOT YET IMPLEMENTED\n" );
00942             break;
00943 
00944           default:
00945             printf( "p_recv_messages(): unknown field type\n" );
00946           }
00947 
00948           EC_word field = ::list( EC_word( fit.get_name() ),
00949                                   ::list( value, nil() ) );
00950           args = ::list(field, args);
00951         }
00952 
00953         // construct list of messages: [[MsgType, [[Key1, Val1], ...]], ... ]
00954         msg_list = ::list( ::list( EC_word( msg->type() ),
00955                                    ::list(args, nil() ) ),
00956                            msg_list );
00957 
00958         (*it)->msgq_pop();
00959       }
00960 
00961       if ( EC_succeed != EC_arg( 2 ).unify( msg_list ) )
00962       {
00963         printf( "p_recv_messages(): could not bind return value\n" );
00964         return EC_fail;
00965       }
00966 
00967       break;
00968     }
00969   }
00970 
00971   if ( it == g_blackboard.interfaces().end() )
00972   {
00973     printf( "p_recv_messages(): no interface with id %s found\n", interface_id );
00974     return EC_fail;
00975   }
00976 
00977   return EC_succeed;
00978 }
00979 
00980 
00981 bool
00982 process_message_args(Message* msg, EC_word arg_list)
00983 {
00984   EC_word head;
00985   EC_word tail;
00986 
00987   for ( ; EC_succeed == arg_list.is_list(head, tail) ; arg_list = tail )
00988   {
00989     // [field, value]
00990     EC_word field;
00991     EC_word value;
00992     EC_word t1;
00993     EC_word t2;
00994 
00995     if ( EC_succeed != head.is_list( field, t1 ) ||
00996          EC_succeed != t1.is_list( value, t2 )        )
00997     {
00998       printf( "p_send_messge(): could not parse argument list\n" );
00999       return false;
01000     }
01001 
01002     char* field_name;
01003     if ( EC_succeed != field.is_string( &field_name ) )
01004     {
01005       printf( "p_send_message(): malformed argument list\n" );
01006       return false;
01007     }
01008 
01009     InterfaceFieldIterator fit;
01010     for ( fit = msg->fields();
01011           fit != msg->fields_end();
01012           ++fit )
01013     {
01014       if ( 0 == strcmp( fit.get_name(), field_name ) )
01015       {
01016         switch( fit.get_type() )
01017         {
01018         case IFT_BOOL:
01019           {
01020             EC_atom val;
01021             if ( EC_succeed != value.is_atom( &val ) )
01022             {
01023               printf( "p_send_message(): no value_given (bool)\n" );
01024               return false;
01025             }
01026 
01027             if ( 0 == strcmp( "true", val.name() ) )
01028             { fit.set_bool( true ); }
01029             else if ( 0 == strcmp( "false", val.name() ) )
01030             { fit.set_bool( false ); }
01031             else
01032             {
01033               printf( "p_send_message(): boolean value neither true nor false\n" );
01034               return false;
01035             }
01036           }
01037 
01038           break;
01039 
01040         case IFT_INT8:
01041           {
01042             long val;
01043             if ( EC_succeed != value.is_long( &val ) )
01044             {
01045               printf( "p_send_message(): no value given (int8)\n" );
01046               return false;
01047             }
01048 
01049             fit.set_int8( (int8_t) val );
01050           }
01051 
01052           break;
01053 
01054         case IFT_UINT8:
01055           {
01056             long val;
01057             if ( EC_succeed != value.is_long( &val ) )
01058             {
01059               printf( "p_send_message(): no value given (uint8)\n" );
01060               return false;
01061             }
01062 
01063             fit.set_uint8( (uint8_t) val );
01064           }
01065 
01066           break;
01067 
01068         case IFT_INT16:
01069           {
01070             long val;
01071             if ( EC_succeed != value.is_long( &val ) )
01072             {
01073               printf( "p_send_message(): no value given (int16)\n" );
01074               return false;
01075             }
01076 
01077             fit.set_int16( (int16_t) val );
01078           }
01079 
01080           break;
01081 
01082         case IFT_UINT16:
01083           {
01084             long val;
01085             if ( EC_succeed != value.is_long( &val ) )
01086             {
01087               printf( "p_send_message(): no value given (uint16)\n" );
01088               return false;
01089             }
01090 
01091             fit.set_uint16( (uint16_t) val );
01092           }
01093 
01094           break;
01095 
01096         case IFT_INT32:
01097           {
01098             long val;
01099             if ( EC_succeed != value.is_long( &val ) )
01100             {
01101               printf( "p_send_message(): no value given (int32)\n" );
01102               return false;
01103             }
01104 
01105             fit.set_int32( (int32_t) val );
01106           }
01107 
01108           break;
01109 
01110         case IFT_UINT32:
01111           {
01112             long val;
01113             if ( EC_succeed != value.is_long( &val ) )
01114             {
01115               printf( "p_send_message(): no value given (uint32)\n" );
01116               return false;
01117             }
01118 
01119             fit.set_uint32( (uint32_t) val );
01120           }
01121 
01122           break;
01123 
01124         case IFT_INT64:
01125           {
01126             long val;
01127             if ( EC_succeed != value.is_long( &val ) )
01128             {
01129               printf( "p_send_message(): no value given (int64)\n" );
01130               return false;
01131             }
01132 
01133             fit.set_int64( (int64_t) val );
01134           }
01135 
01136           break;
01137 
01138         case IFT_UINT64:
01139           {
01140             long val;
01141             if ( EC_succeed != value.is_long( &val ) )
01142             {
01143               printf( "p_send_message(): no value given (uint64)\n" );
01144               return false;
01145             }
01146 
01147             fit.set_uint64( (uint64_t) val );
01148           }
01149 
01150           break;
01151 
01152         case IFT_FLOAT:
01153           {
01154             double val;
01155             if ( EC_succeed != value.is_double( &val ) )
01156             {
01157               printf( "p_send_message(): no value given (float)\n" );
01158               return false;
01159             }
01160 
01161             fit.set_float( (float) val );
01162           }
01163 
01164           break;
01165 
01166         case IFT_STRING:
01167           {
01168             char* val;
01169             if ( EC_succeed != value.is_string( &val ) )
01170             {
01171               printf( "p_send_message(): no value given (string)\n" );
01172               return false;
01173             }
01174 
01175             fit.set_string( val );
01176           }
01177 
01178           break;
01179 
01180         case IFT_BYTE:
01181         case IFT_ENUM:
01182           printf( "p_send_message(): NOT YET IMPLEMENTET\n" );
01183           break;
01184 
01185         default:
01186           break;
01187         }
01188 
01189         break;
01190       }
01191     }
01192 
01193     if ( fit == msg->fields_end() )
01194     {
01195       printf( "p_send_message(): message has no field with name %s\n",
01196               field_name );
01197       return false;
01198     }
01199   }
01200 
01201   return true;
01202 }