Python API: Preparation for RPM/DEB packaging.
[vpp.git] / vpp-api / python / vpp_papi / vpp_papi.py
index 6a7a358..42ddcdc 100644 (file)
 #
 from __future__ import print_function
 
-import signal, logging, os, sys
+import signal, os, sys
 from struct import *
 
-scriptdir = os.path.dirname(os.path.realpath(__file__))
-sys.path.append(scriptdir)
 import vpp_api
 from vpp_api_base import *
 
 # Import API definitions. The core VPE API is imported into main namespace
 import memclnt
+
+# Cheating a bit, importing it into this namespace as well as a module.
+import vpe
 from vpe import *
-vpe = sys.modules['vpe']
+
+def eprint(*args, **kwargs):
+    print(*args, file=sys.stderr, **kwargs)
 
 def msg_handler(msg):
     if not msg:
-        logging.warning('vpp_api.read failed')
+        eprint('vpp_api.read failed')
         return
 
     id = unpack('>H', msg[0:2])
-    logging.debug('Received message', id[0])
     if id[0] == memclnt.VL_API_RX_THREAD_EXIT:
-        logging.info("We got told to leave")
         return;
 
     #
     # Decode message and returns a tuple.
     #
-    logging.debug('api_func', api_func_table[id[0]])
-    r = api_func_table[id[0]](msg)
-    if not r:
-        logging.warning('Message decode failed', id[0])
-        return
+    try:
+        r = api_func_table[id[0]](msg)
+    except:
+        eprint('Message decode failed', id[0], api_func_table[id[0]])
+        raise
 
     if 'context' in r._asdict():
         if r.context > 0:
@@ -66,12 +67,12 @@ def msg_handler(msg):
     #
     # Collect results until control ping
     #
-    if id[0] == vpe.VL_API_CONTROL_PING_REPLY:
+    if id[0] == VL_API_CONTROL_PING_REPLY:
         results_event_set(context)
         waiting_for_reply_clear()
         return
     if not is_results_context(context):
-        logging.warning('Not expecting results for this context', context)
+        eprint('Not expecting results for this context', context)
         return
     if is_results_more(context):
         results_append(context, r)
@@ -81,22 +82,29 @@ def msg_handler(msg):
     results_event_set(context)
     waiting_for_reply_clear()
 
+def handler(signum, frame):
+    print('Signal handler called with signal', signum)
+    raise IOError("Couldn't connect to VPP!")
+
 def connect(name):
+    # Set the signal handler
+    signal.signal(signal.SIGALRM, handler)
+
     signal.alarm(3) # 3 second
     rv = vpp_api.connect(name, msg_handler)
     signal.alarm(0)
-    logging.info("Connect:", rv)
 
     #
     # Assign message id space for plugins
     #
-    plugin_map_plugins()
-
+    try:
+        plugin_map_plugins()
+    except:
+        return -1
     return rv
 
 def disconnect():
     rv = vpp_api.disconnect()
-    logging.info("Disconnected")
     return rv
 
 def register_event_callback(callback):
@@ -107,6 +115,7 @@ def plugin_name_to_id(plugin, name_to_id_table, base):
         m = globals()[plugin]
     except KeyError:
         m = sys.modules[plugin]
+
     for name in name_to_id_table:
         setattr(m, name, name_to_id_table[name] + base)
 
@@ -121,12 +130,10 @@ def plugin_map_plugins():
         #
         version = plugins[p]['version']
         name = p + '_' + format(version, '08x')
-        r = memclnt.get_first_msg_id(name.encode('ascii'))
-
-        ## TODO: Add error handling
+        r = memclnt.get_first_msg_id(name)
         if r.retval != 0:
-            print('Failed getting first msg id for:', p)
-            continue
+            eprint('Failed getting first msg id for:', p, r, name)
+            raise
 
         # Set base
         base = r.first_msg_id
@@ -135,8 +142,12 @@ def plugin_map_plugins():
         plugins[p]['base'] = base
         func_table = plugins[p]['func_table']
         i = r.first_msg_id
+        # Insert doesn't extend the table
+        if i + len(func_table) > len(api_func_table):
+            fill = [None] * (i + len(func_table) - len(api_func_table))
+            api_func_table.extend(fill)
         for entry in func_table:
-            api_func_table.insert(i, entry)
+            api_func_table[i] = entry
             i += 1
         plugin_name_to_id(p, plugins[p]['name_to_id_table'], base)
 
@@ -145,6 +156,8 @@ def plugin_map_plugins():
 #
 memclnt.msg_id_base_set(1)
 plugins['memclnt']['base'] = 1
+
+# vpe
 msg_id_base_set(len(plugins['memclnt']['func_table']) + 1)
 plugins['vpe']['base'] = len(plugins['memclnt']['func_table']) + 1
 api_func_table = []
@@ -152,4 +165,4 @@ api_func_table.append(None)
 api_func_table[1:] = plugins['memclnt']['func_table'] + plugins['vpe']['func_table']
 plugin_name_to_id('memclnt', plugins['memclnt']['name_to_id_table'], 1)
 plugin_name_to_id('vpe', plugins['vpe']['name_to_id_table'], plugins['vpe']['base'])
-#logging.basicConfig(level=logging.DEBUG)
+plugin_name_to_id(__name__, plugins['vpe']['name_to_id_table'], plugins['vpe']['base'])