Python-API: Support for zero-length arrays from caller to VPP. (Previously only VPP to caller was supported.)

Change-Id: Id660caeb780f3b26cc091467291463980f485178
Signed-off-by: Ole Troan <ot@cisco.com>
This commit is contained in:
Ole Troan
2016-04-25 12:36:02 +02:00
parent 8a1a19b8b6
commit fc6cf287c4

View File

@ -36,6 +36,9 @@ format_struct = {'u8': 'B',
'vl_api_ip4_fib_counter_t' : 'IBQQ', 'vl_api_ip4_fib_counter_t' : 'IBQQ',
'vl_api_ip6_fib_counter_t' : 'QQBQQ', 'vl_api_ip6_fib_counter_t' : 'QQBQQ',
}; };
#
# NB: If new types are introduced in vpe.api, these must be updated.
#
type_size = {'u8': 1, type_size = {'u8': 1,
'u16' : 2, 'u16' : 2,
'u32' : 4, 'u32' : 4,
@ -47,17 +50,13 @@ type_size = {'u8': 1,
}; };
def get_args(t): def get_args(t):
args = None argslist = []
for i in t: for i in t:
arg = i[1] argslist.append(i[1].replace('_',''))
arg = arg.replace('_','') return argslist
if args == None:
args = arg
continue
args = args + ', ' + arg
return args
def get_pack(t): def get_pack(t):
zeroarray = False
bytecount = 0 bytecount = 0
pack = '>' pack = '>'
tup = u'' tup = u''
@ -67,8 +66,10 @@ def get_pack(t):
if len(i) is 3: if len(i) is 3:
size = type_size[i[0]] size = type_size[i[0]]
bytecount += size * int(i[2]) bytecount += size * int(i[2])
# Check if we have a zero length array
if i[2] == '0': if i[2] == '0':
tup += 'msg[' + str(bytecount) + ':],' tup += 'msg[' + str(bytecount) + ':],'
zeroarray = True
continue continue
if size == 1: if size == 1:
n = i[2] * size n = i[2] * size
@ -82,7 +83,7 @@ def get_pack(t):
bytecount += type_size[i[0]] bytecount += type_size[i[0]]
pack += format_struct[i[0]] pack += format_struct[i[0]]
tup += 'tr[' + str(j) + '],' tup += 'tr[' + str(j) + '],'
return pack, bytecount, tup return pack, bytecount, tup, zeroarray
def get_reply_func(f): def get_reply_func(f):
if f['name']+'_reply' in func_name: if f['name']+'_reply' in func_name:
@ -115,8 +116,9 @@ def get_definitions():
func_name = {} func_name = {}
i = 1 i = 1
for a in cfg.vppapidef: for a in cfg.vppapidef:
pack, packlen, tup = get_pack(a[1:]) pack, packlen, tup, zeroarray = get_pack(a[1:])
func_name[a[0]] = dict([('name', a[0]), ('args', get_args(a[4:])), ('full_args', get_args(a[1:])), ('pack', pack), ('packlen', packlen), ('tup', tup)]) func_name[a[0]] = dict([('name', a[0]), ('pack', pack), ('packlen', packlen), ('tup', tup), ('args', get_args(a[1:])),
('zeroarray', zeroarray)])
func_list.append(func_name[a[0]]) # Indexed by name func_list.append(func_name[a[0]]) # Indexed by name
return func_list, func_name return func_list, func_name
@ -137,14 +139,13 @@ void pneum_set_handlers(void) {
''' '''
# #
# XXX:Deal with empty arrays
# Print array with a hash of 'decode' and 'multipart' # Print array with a hash of 'decode' and 'multipart'
# Simplify to do only decode for now. And deduce multipart from _dump? # Simplify to do only decode for now. And deduce multipart from _dump?
# #
def decode_function_print(name, args, pack, packlen, tup): def decode_function_print(name, args, pack, packlen, tup):
print(u'def ' + name + u'_decode(msg):') print(u'def ' + name + u'_decode(msg):')
print(u" n = namedtuple('" + name + "', '" + args + "')" + print(u" n = namedtuple('" + name + "', '" + ', '.join(args) + "')" +
''' '''
if not n: if not n:
return None return None
@ -157,12 +158,11 @@ def decode_function_print(name, args, pack, packlen, tup):
return r return r
''') ''')
def function_print(name, id, args, pack, multipart): def function_print(name, id, args, pack, multipart, zeroarray):
if not args: if len(args) < 4:
args = ""
print "def", name + "(async = False):" print "def", name + "(async = False):"
else: else:
print "def", name + "(" + args + ",async = False):" print "def", name + "(" + ', '.join(args[3:]) + ", async = False):"
print " global waiting_for_reply" print " global waiting_for_reply"
print " context = get_context(" + id + ")" print " context = get_context(" + id + ")"
@ -176,7 +176,10 @@ def function_print(name, id, args, pack, multipart):
if multipart == True: if multipart == True:
print " results[context]['m'] = True" print " results[context]['m'] = True"
print " vpp_api.write(pack('" + pack + "', " + id + ", 0, context, " + args + "))" if zeroarray == True:
print " vpp_api.write(pack('" + pack + "', " + id + ", 0, context, " + ', '.join(args[3:-1]) + ") + " + args[-1] + ")"
else:
print " vpp_api.write(pack('" + pack + "', " + id + ", 0, context, " + ', '.join(args[3:]) + "))"
if multipart == True: if multipart == True:
print " vpp_api.write(pack('>HII', VL_API_CONTROL_PING, 0, context))" print " vpp_api.write(pack('>HII', VL_API_CONTROL_PING, 0, context))"
@ -201,6 +204,9 @@ def api_table_print (name, msg_id):
print '''#!/usr/bin/env python3 print '''#!/usr/bin/env python3
#
# AUTO-GENERATED FILE. PLEASE DO NOT EDIT.
#
import sys, time, threading, signal, os, logging import sys, time, threading, signal, os, logging
from struct import * from struct import *
from collections import namedtuple from collections import namedtuple
@ -312,7 +318,7 @@ pp = pprint.PrettyPrinter(indent=4)
# #
for f in func_list: for f in func_list:
#if f['name'].find('_reply') > 0 or f['name'].find('_details') > 0: #if f['name'].find('_reply') > 0 or f['name'].find('_details') > 0:
decode_function_print(f['name'], f['full_args'], f['pack'], f['packlen'], f['tup']) decode_function_print(f['name'], f['args'], f['pack'], f['packlen'], f['tup'])
#r = get_reply_func(f) #r = get_reply_func(f)
#if not r: #if not r:
@ -327,7 +333,7 @@ for f in func_list:
else: else:
f['multipart'] = False f['multipart'] = False
msg_id_in = 'VL_API_' + f['name'].upper() msg_id_in = 'VL_API_' + f['name'].upper()
function_print(f['name'], msg_id_in, f['args'], f['pack'], f['multipart']) function_print(f['name'], msg_id_in, f['args'], f['pack'], f['multipart'], f['zeroarray'])
print "api_func_table = [0] * 10000" print "api_func_table = [0] * 10000"