#
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:
#
# 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)
results_event_set(context)
waiting_for_reply_clear()
-def connect(name):
+def handler(signum, frame):
+ print('Signal handler called with signal', signum)
+ raise IOError("Couldn't connect to VPP!")
+
+def connect(name, chroot_prefix = None):
+ # Set the signal handler
+ signal.signal(signal.SIGALRM, handler)
+
signal.alarm(3) # 3 second
- rv = vpp_api.connect(name, msg_handler)
+ if not chroot_prefix:
+ rv = vpp_api.connect(name, msg_handler)
+ else:
+ rv = vpp_api.connect(name, msg_handler, chroot_prefix)
+
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):
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)
#
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
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)
#
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 = []
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'])