Python API: Re-adding rudimentary variable length array pack support. 57/2557/3
authorOle Troan <ot@cisco.com>
Tue, 30 Aug 2016 19:03:51 +0000 (21:03 +0200)
committerDave Wallace <dwallacelf@gmail.com>
Tue, 13 Sep 2016 01:38:14 +0000 (01:38 +0000)
Fixed bug in message-id mapping with non-consequtive APIs.

Change-Id: Icd6073e4655f7ce5432816861ae58915e5b336af
Signed-off-by: Ole Troan <ot@cisco.com>
vpp-api/python/tests/test_modules.py
vpp-api/python/vpp_papi/vpp_papi.py
vppapigen/pyvppapigen.py

index f3066b2..48df175 100755 (executable)
@@ -14,4 +14,7 @@ print('R:', r)
 r = snat.snat_interface_add_del_feature(1, 1, 1)
 print('R:', r)
 
+list_name = 'foobar'
+r = pot.pot_profile_add(0, 1, 123, 123, 0, 12, 0, 23, len(list_name), list_name)
+print('R:', r)
 vpp_papi.disconnect()
index 144151c..174e61d 100644 (file)
@@ -17,7 +17,7 @@
 #
 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__))
@@ -30,25 +30,26 @@ import memclnt
 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:
@@ -71,7 +72,7 @@ def msg_handler(msg):
         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)
@@ -85,7 +86,6 @@ def connect(name):
     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
@@ -96,7 +96,6 @@ def connect(name):
 
 def disconnect():
     rv = vpp_api.disconnect()
-    logging.info("Disconnected")
     return rv
 
 # CLI convenience wrapper
@@ -128,10 +127,9 @@ 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
+        ## TODO: Add error handling / raise exception
         if r.retval != 0:
-            print('Failed getting first msg id for:', p)
+            eprint('Failed getting first msg id for:', p)
             continue
 
         # Set base
@@ -141,8 +139,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)
 
@@ -158,4 +160,3 @@ 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)
index e216169..c215d15 100755 (executable)
@@ -68,7 +68,7 @@ def get_pack(f):
     bytecount = 0
     pack = ''
     elements = 1
-    if len(f) is 3 or len(f) is 4:  # TODO: add support for variable length arrays (VPP-162)
+    if len(f) is 3 or len(f) is 4:
         size = type_size[f[0]]
         bytecount += size * int(f[2])
         # Check if we have a zero length array
@@ -146,14 +146,26 @@ def encode_print(name, id, t):
     if multipart == True:
         print(u"    results_more_set(context)")
 
-    ### TODO deal with zeroarray!!!
-    #if zeroarray == True:
-    #    print(u"    vpp_api.write(pack('" + pack + "', " + id + ", 0, context, " + ', '.join(args[3:-1]) + ") + " + args[-1] + ")")
-    #else:
-    print(u"    vpp_api.write(pack('" + pack + "', base + " + id + ", 0, context, " + ', '.join(args[3:]) + "))")
+    pack = '>'
+    start = 0
+    end = 0
+    offset = 0
+    t = list(t)
+    i = 0
+
+    while t:
+        t, i, pack, offset, array = get_normal_pack(t, i, pack, offset)
+        if array:
+            print(u"    vpp_api.write(pack('" + pack + "', base + " +
+                  id + ", 0, context, " + ', '.join(args[3:-1]) + ") + "
+                  + args[-1] + ")")
+        else:
+            print(u"    vpp_api.write(pack('" + pack + "', base + " + id +
+                  ", 0, context, " + ', '.join(args[3:]) + "))")
 
     if multipart == True:
-        print(u"    vpp_api.write(pack('>HII', VL_API_CONTROL_PING, 0, context))")
+        print(
+            u"    vpp_api.write(pack('>HII', VL_API_CONTROL_PING, 0, context))")
 
     print('''
     if not async: