X-Git-Url: https://gerrit.fd.io/r/gitweb?p=vpp.git;a=blobdiff_plain;f=src%2Ftools%2Fvppapigen%2Fvppapigen_c.py;h=ae47625a474b5f830fe0bc5f94d047c300cc6bfc;hp=4369dd86690d66d037d26c4b1bec72f518b98f27;hb=36217e3ca;hpb=df87f8092f5b6b54eef0d5acf3c27c2e398a401a diff --git a/src/tools/vppapigen/vppapigen_c.py b/src/tools/vppapigen/vppapigen_c.py index 4369dd86690..ae47625a474 100644 --- a/src/tools/vppapigen/vppapigen_c.py +++ b/src/tools/vppapigen/vppapigen_c.py @@ -32,6 +32,7 @@ import shutil process_imports = False + ############################################################################### class ToJSON(): '''Class to generate functions converting from VPP binary API to JSON.''' @@ -65,16 +66,17 @@ class ToJSON(): write('#ifndef included_{}_api_tojson_h\n'.format(self.module)) write('#define included_{}_api_tojson_h\n'.format(self.module)) write('#include \n\n') - write('#include \n\n') + write('#include \n\n') + if self.module == 'interface_types': + write('#define vl_printfun\n') + write('#include \n\n') def footer(self): '''Output the bottom boilerplate.''' write = self.stream.write write('#endif\n') - def get_json_func(self, t): - '''Given the type, returns the function to use to create a - cJSON object''' + def get_base_type(self, t): vt_type = None try: vt = self.types_hash[t] @@ -82,6 +84,12 @@ class ToJSON(): vt_type = vt.alias['type'] except KeyError: vt = t + return vt, vt_type + + def get_json_func(self, t): + '''Given the type, returns the function to use to create a + cJSON object''' + vt, vt_type = self.get_base_type(t) if t in self.is_number or vt_type in self.is_number: return 'cJSON_AddNumberToObject', '', False @@ -89,7 +97,7 @@ class ToJSON(): return 'cJSON_AddBoolToObject', '', False # Lookup type name check if it's enum - if vt.type == 'Enum': + if vt.type == 'Enum' or vt.type == 'EnumFlag': return '{t}_tojson'.format(t=t), '', True return '{t}_tojson'.format(t=t), '&', True @@ -100,6 +108,9 @@ class ToJSON(): return 'cJSON_CreateNumber', '' if t == 'bool': return 'cJSON_CreateBool', '' + vt, vt_type = self.get_base_type(t) + if vt.type == 'Enum' or vt.type == 'EnumFlag': + return '{t}_tojson'.format(t=t), '' return '{t}_tojson'.format(t=t), '&' def print_string(self, o): @@ -187,6 +198,21 @@ class ToJSON(): _dispatch['Enum'] = print_enum + def print_enum_flag(self, o): + '''Create cJSON object (string) for VPP API enum''' + write = self.stream.write + write('static inline cJSON *vl_api_{name}_t_tojson ' + '(vl_api_{name}_t a) {{\n'.format(name=o.name)) + write(' cJSON *array = cJSON_CreateArray();\n') + + for b in o.block: + write(' if (a & {})\n'.format(b[0])) + write(' cJSON_AddItemToArray(array, cJSON_CreateString("{}"));\n'.format(b[0])) + write(' return array;\n') + write('}\n') + + _dispatch['EnumFlag'] = print_enum_flag + def print_typedef(self, o): '''Create cJSON (dictionary) object from VPP API typedef''' write = self.stream.write @@ -208,6 +234,8 @@ class ToJSON(): write(' cJSON *o = cJSON_CreateObject();\n') write(' cJSON_AddStringToObject(o, "_msgname", "{}");\n' .format(o.name)) + write(' cJSON_AddStringToObject(o, "_crc", "{crc:08x}");\n' + .format(crc=o.crc)) for t in o.block: self._dispatch[t.type](self, t) @@ -289,7 +317,8 @@ class FromJSON(): write('#ifndef included_{}_api_fromjson_h\n'.format(self.module)) write('#define included_{}_api_fromjson_h\n'.format(self.module)) write('#include \n\n') - write('#include \n\n') + write('#include \n\n') + write('#pragma GCC diagnostic ignored "-Wunused-label"\n') def is_base_type(self, t): '''Check if a type is one of the VPP API base types''' @@ -308,14 +337,15 @@ class FromJSON(): '''Convert JSON string to vl_api_string_t''' write = self.stream.write - msgvar = "a" if toplevel else "mp" + msgvar = "a" if toplevel else "*mp" msgsize = "l" if toplevel else "*len" if o.modern_vla: write(' char *p = cJSON_GetStringValue(item);\n') write(' size_t plen = strlen(p);\n') - write(' {msgvar} = realloc({msgvar}, {msgsize} + plen);\n' + write(' {msgvar} = cJSON_realloc({msgvar}, {msgsize} + plen, {msgsize});\n' .format(msgvar=msgvar, msgsize=msgsize)) + write(' if ({msgvar} == 0) goto error;\n'.format(msgvar=msgvar)) write(' vl_api_c_string_to_api_string(p, (void *){msgvar} + ' '{msgsize} - sizeof(vl_api_string_t));\n' .format(msgvar=msgvar, msgsize=msgsize)) @@ -328,25 +358,21 @@ class FromJSON(): def print_field(self, o, toplevel=False): '''Called for every field in a typedef or define.''' write = self.stream.write - write(' // start field {}\n'.format(o.fieldname)) if o.fieldname in self.noprint_fields: return is_bt = self.is_base_type(o.fieldtype) t = 'vl_api_{}'.format(o.fieldtype) if is_bt else o.fieldtype - msgvar = "a" if toplevel else "mp" + msgvar = "(void **)&a" if toplevel else "mp" msgsize = "&l" if toplevel else "len" if is_bt: write(' vl_api_{t}_fromjson(item, &a->{n});\n' .format(t=o.fieldtype, n=o.fieldname)) else: - write(' {msgvar} = {t}_fromjson({msgvar}, ' - '{msgsize}, item, &a->{n});\n' + write(' if ({t}_fromjson({msgvar}, ' + '{msgsize}, item, &a->{n}) < 0) goto error;\n' .format(t=t, n=o.fieldname, msgvar=msgvar, msgsize=msgsize)) - write(' if (!{msgvar}) return 0;\n'.format(msgvar=msgvar)) - - write(' // end field {}\n'.format(o.fieldname)) _dispatch['Field'] = print_field @@ -359,7 +385,7 @@ class FromJSON(): int i; cJSON *array = cJSON_GetObjectItem(o, "{n}"); int size = cJSON_GetArraySize(array); - if (size != {lfield}) return 0; + if (size != {lfield}) goto error; for (i = 0; i < size; i++) {{ cJSON *e = cJSON_GetArrayItem(array, i); {call} @@ -372,8 +398,8 @@ class FromJSON(): cJSON *array = cJSON_GetObjectItem(o, "{n}"); int size = cJSON_GetArraySize(array); {lfield} = size; - {msgvar} = realloc({msgvar}, {msgsize} + sizeof({t}) * size); - {t} *d = (void *){msgvar} + {msgsize}; + {realloc} = cJSON_realloc({realloc}, {msgsize} + sizeof({t}) * size, {msgsize}); + {t} *d = (void *){realloc} + {msgsize}; {msgsize} += sizeof({t}) * size; for (i = 0; i < size; i++) {{ cJSON *e = cJSON_GetArrayItem(array, i); @@ -387,25 +413,26 @@ class FromJSON(): return lfield = 'a->' + o.lengthfield if o.lengthfield else o.length - msgvar = "a" if toplevel else "mp" + msgvar = "(void **)&a" if toplevel else "mp" + realloc = "a" if toplevel else "*mp" msgsize = "l" if toplevel else "*len" if o.fieldtype == 'u8': if o.lengthfield: write(' s = u8string_fromjson(o, "{}");\n' .format(o.fieldname)) - write(' if (!s) return 0;\n') + write(' if (!s) goto error;\n') write(' {} = vec_len(s);\n'.format(lfield)) - write(' {msgvar} = realloc({msgvar}, {msgsize} + ' - 'vec_len(s));\n'.format(msgvar=msgvar, msgsize=msgsize)) - write(' memcpy((void *){msgvar} + {msgsize}, s, ' - 'vec_len(s));\n'.format(msgvar=msgvar, msgsize=msgsize)) + write(' {realloc} = cJSON_realloc({realloc}, {msgsize} + ' + 'vec_len(s), {msgsize});\n'.format(msgvar=msgvar, msgsize=msgsize, realloc=realloc)) + write(' memcpy((void *){realloc} + {msgsize}, s, ' + 'vec_len(s));\n'.format(realloc=realloc, msgsize=msgsize)) write(' {msgsize} += vec_len(s);\n'.format(msgsize=msgsize)) write(' vec_free(s);\n') else: - write(' u8string_fromjson2(o, "{n}", a->{n});\n' + write(' if (u8string_fromjson2(o, "{n}", a->{n}) < 0) goto error;\n' .format(n=o.fieldname)) return @@ -416,26 +443,27 @@ class FromJSON(): call = ('vl_api_{t}_fromjson(e, &d[i]);' .format(t=o.fieldtype)) else: - call = ('{t}_fromjson({msgvar}, len, e, &d[i]); ' + call = ('if ({t}_fromjson({msgvar}, len, e, &d[i]) < 0) goto error; ' .format(t=o.fieldtype, msgvar=msgvar)) write(forloop_vla.format(lfield=lfield, t=o.fieldtype, n=o.fieldname, call=call, - msgvar=msgvar, + realloc=realloc, msgsize=msgsize)) else: if is_bt: call = ('vl_api_{t}_fromjson(e, &a->{n}[i]);' .format(t=t, n=o.fieldname)) else: - call = ('a = {}_fromjson({}, len, e, &a->{}[i]);' + call = ('if ({}_fromjson({}, len, e, &a->{}[i]) < 0) goto error;' .format(t, msgvar, o.fieldname)) write(forloop.format(lfield=lfield, t=t, n=o.fieldname, call=call, msgvar=msgvar, + realloc=realloc, msgsize=msgsize)) _dispatch['Array'] = print_array @@ -443,23 +471,45 @@ class FromJSON(): def print_enum(self, o): '''Convert to JSON enum(string) to VPP API enum (int)''' write = self.stream.write - write('static inline void *vl_api_{n}_t_fromjson ' - '(void *mp, int *len, cJSON *o, vl_api_{n}_t *a) {{\n' + write('static inline int vl_api_{n}_t_fromjson' + '(void **mp, int *len, cJSON *o, vl_api_{n}_t *a) {{\n' .format(n=o.name)) write(' char *p = cJSON_GetStringValue(o);\n') for b in o.block: - write(' if (strcmp(p, "{}") == 0) {{*a = {}; return mp;}}\n' + write(' if (strcmp(p, "{}") == 0) {{*a = {}; return 0;}}\n' .format(b[0], b[1])) - write(' return 0;\n') + write(' *a = 0;\n') + write(' return -1;\n') write('}\n') _dispatch['Enum'] = print_enum + def print_enum_flag(self, o): + '''Convert to JSON enum(string) to VPP API enum (int)''' + write = self.stream.write + write('static inline int vl_api_{n}_t_fromjson ' + '(void **mp, int *len, cJSON *o, vl_api_{n}_t *a) {{\n' + .format(n=o.name)) + write(' int i;\n') + write(' *a = 0;\n') + write(' for (i = 0; i < cJSON_GetArraySize(o); i++) {\n') + write(' cJSON *e = cJSON_GetArrayItem(o, i);\n') + write(' char *p = cJSON_GetStringValue(e);\n') + write(' if (!p) return -1;\n') + for b in o.block: + write(' if (strcmp(p, "{}") == 0) *a |= {};\n' + .format(b[0], b[1])) + write(' }\n') + write(' return 0;\n') + write('}\n') + + _dispatch['EnumFlag'] = print_enum_flag + def print_typedef(self, o): '''Convert from JSON object to VPP API binary representation''' write = self.stream.write - write('static inline void *vl_api_{name}_t_fromjson (void *mp, ' + write('static inline int vl_api_{name}_t_fromjson (void **mp, ' 'int *len, cJSON *o, vl_api_{name}_t *a) {{\n' .format(name=o.name)) write(' cJSON *item __attribute__ ((unused));\n') @@ -467,20 +517,21 @@ class FromJSON(): for t in o.block: if t.type == 'Field' and t.is_lengthfield: continue - write(' item = cJSON_GetObjectItem(o, "{}");\n' + write('\n item = cJSON_GetObjectItem(o, "{}");\n' .format(t.fieldname)) - write(' if (!item) return 0;\n') - + write(' if (!item) goto error;\n') self._dispatch[t.type](self, t) - write(' return mp;\n') + write('\n return 0;\n') + write('\n error:\n') + write(' return -1;\n') write('}\n') def print_union(self, o): '''Convert JSON object to VPP API binary union''' write = self.stream.write - write('static inline void *vl_api_{name}_t_fromjson (void *mp, ' + write('static inline int vl_api_{name}_t_fromjson (void **mp, ' 'int *len, cJSON *o, vl_api_{name}_t *a) {{\n' .format(name=o.name)) write(' cJSON *item __attribute__ ((unused));\n') @@ -493,36 +544,42 @@ class FromJSON(): write(' if (item) {\n') self._dispatch[t.type](self, t) write(' };\n') - write(' return mp;\n') + write('\n return 0;\n') + write('\n error:\n') + write(' return -1;\n') write('}\n') def print_define(self, o): '''Convert JSON object to VPP API message''' write = self.stream.write + error = 0 write('static inline vl_api_{name}_t *vl_api_{name}_t_fromjson ' '(cJSON *o, int *len) {{\n'.format(name=o.name)) write(' cJSON *item __attribute__ ((unused));\n') write(' u8 *s __attribute__ ((unused));\n') write(' int l = sizeof(vl_api_{}_t);\n'.format(o.name)) - write(' vl_api_{}_t *a = malloc(l);\n'.format(o.name)) + write(' vl_api_{}_t *a = cJSON_malloc(l);\n'.format(o.name)) + write('\n') for t in o.block: if t.fieldname in self.noprint_fields: continue if t.type == 'Field' and t.is_lengthfield: continue - write(' // processing {}: {} {}\n' - .format(o.name, t.fieldtype, t.fieldname)) - write(' item = cJSON_GetObjectItem(o, "{}");\n' .format(t.fieldname)) - write(' if (!item) return 0;\n') + write(' if (!item) goto error;\n') + error += 1 self._dispatch[t.type](self, t, toplevel=True) write('\n') - write('\n') write(' *len = l;\n') write(' return a;\n') + + if error: + write('\n error:\n') + write(' cJSON_free(a);\n') + write(' return 0;\n') write('}\n') def print_using(self, o): @@ -533,7 +590,7 @@ class FromJSON(): return t = o.using - write('static inline void *vl_api_{name}_t_fromjson (void *mp, ' + write('static inline int vl_api_{name}_t_fromjson (void **mp, ' 'int *len, cJSON *o, vl_api_{name}_t *a) {{\n' .format(name=o.name)) if 'length' in o.alias: @@ -546,7 +603,7 @@ class FromJSON(): write(' vl_api_{t}_fromjson(o, ({t} *)a);\n' .format(t=t.fieldtype)) - write(' return mp;\n') + write(' return 0;\n') write('}\n') _dispatch['Typedef'] = print_typedef @@ -845,6 +902,7 @@ class Printfun(): write(' }\n') _dispatch['Enum'] = print_enum + _dispatch['EnumFlag'] = print_enum def print_obj(self, o, stream): '''Entry point''' @@ -875,10 +933,13 @@ def printfun(objs, stream, modulename): #define _uword_cast long #endif +#include "{module}.api_tojson.h" +#include "{module}.api_fromjson.h" + ''' signature = '''\ -static inline void *vl_api_{name}_t_print (vl_api_{name}_t *a, void *handle) +static inline void *vl_api_{name}_t_print{suffix} (vl_api_{name}_t *a, void *handle) {{ u8 *s = 0; u32 indent __attribute__((unused)) = 2; @@ -893,7 +954,7 @@ static inline void *vl_api_{name}_t_print (vl_api_{name}_t *a, void *handle) if t.manual_print: write("/***** manual: vl_api_%s_t_print *****/\n\n" % t.name) continue - write(signature.format(name=t.name)) + write(signature.format(name=t.name, suffix='')) write(' /* Message definition: vl_api_{}_t: */\n'.format(t.name)) write(" s = format(s, \"vl_api_%s_t:\");\n" % t.name) for o in t.block: @@ -904,6 +965,16 @@ static inline void *vl_api_{name}_t_print (vl_api_{name}_t *a, void *handle) write(' return handle;\n') write('}\n\n') + write(signature.format(name=t.name, suffix='_json')) + write(' cJSON * o = vl_api_{}_t_tojson(a);\n'.format(t.name)) + write(' (void)s;\n'); + write(' char *out = cJSON_Print(o);\n') + write(' vl_print(handle, out);\n'); + write(' cJSON_Delete(o);\n') + write(' cJSON_free(out);\n'); + write(' return handle;\n') + write('}\n\n'); + write("\n#endif") write("\n#endif /* vl_printfun */\n") @@ -935,7 +1006,7 @@ static inline u8 *format_vl_api_{name}_t (u8 *s, va_list * args) ''' for t in objs: - if t.__class__.__name__ == 'Enum': + if t.__class__.__name__ == 'Enum' or t.__class__.__name__ == 'EnumFlag': write(signature.format(name=t.name)) pp.print_enum(t.block, stream) write(' return s;\n') @@ -1001,7 +1072,7 @@ def endianfun_array(o): ''' output = '' - if o.fieldtype == 'u8' or o.fieldtype == 'string': + if o.fieldtype == 'u8' or o.fieldtype == 'string' or o.fieldtype == 'bool': output += ' /* a->{n} = a->{n} (no-op) */\n'.format(n=o.fieldname) else: lfield = 'a->' + o.lengthfield if o.lengthfield else o.length @@ -1071,7 +1142,7 @@ static inline void vl_api_{name}_t_endian (vl_api_{name}_t *a) ''' for t in objs: - if t.__class__.__name__ == 'Enum': + if t.__class__.__name__ == 'Enum' or t.__class__.__name__ == 'EnumFlag' : output += signature.format(name=t.name) if t.enumtype in ENDIAN_STRINGS: output += (' *a = {}(*a);\n' @@ -1157,7 +1228,7 @@ def generate_include_counters(s, stream): write(' {}_N_ERROR\n'.format(csetname.upper())) write('}} vl_counter_{}_enum_t;\n'.format(csetname)) - write('extern vl_counter_t {}_error_counters[];\n'.format(csetname)) + write('extern vlib_error_desc_t {}_error_counters[];\n'.format(csetname)) def generate_include_types(s, module, stream): @@ -1191,7 +1262,7 @@ def generate_include_types(s, module, stream): (o.alias['type'], o.name, o.alias['length'])) else: write('typedef %s vl_api_%s_t;\n' % (o.alias['type'], o.name)) - elif tname == 'Enum': + elif tname == 'Enum' or tname == 'EnumFlag': if o.enumtype == 'u32': write("typedef enum {\n") else: @@ -1291,8 +1362,14 @@ def generate_c_boilerplate(services, defines, counters, file_crc, ' .cleanup = vl_noop_handler,\n' ' .endian = vl_api_{n}_t_endian,\n' ' .print = vl_api_{n}_t_print,\n' - ' .is_autoendian = 0}};\n' - .format(n=s.caller, ID=s.caller.upper())) + ' .traced = 1,\n' + ' .replay = 1,\n' + ' .print_json = vl_api_{n}_t_print_json,\n' + ' .tojson = vl_api_{n}_t_tojson,\n' + ' .fromjson = vl_api_{n}_t_fromjson,\n' + ' .is_autoendian = {auto}}};\n' + .format(n=s.caller, ID=s.caller.upper(), + auto=d.autoendian)) write(' vl_msg_api_config (&c);\n') try: d = define_hash[s.reply] @@ -1303,8 +1380,14 @@ def generate_c_boilerplate(services, defines, counters, file_crc, ' .cleanup = vl_noop_handler,\n' ' .endian = vl_api_{n}_t_endian,\n' ' .print = vl_api_{n}_t_print,\n' - ' .is_autoendian = 0}};\n' - .format(n=s.reply, ID=s.reply.upper())) + ' .traced = 1,\n' + ' .replay = 1,\n' + ' .print_json = vl_api_{n}_t_print_json,\n' + ' .tojson = vl_api_{n}_t_tojson,\n' + ' .fromjson = vl_api_{n}_t_fromjson,\n' + ' .is_autoendian = {auto}}};\n' + .format(n=s.reply, ID=s.reply.upper(), + auto=d.autoendian)) write(' vl_msg_api_config (&c);\n') except KeyError: pass @@ -1318,7 +1401,7 @@ def generate_c_boilerplate(services, defines, counters, file_crc, for cnt in counters: csetname = cnt.name - write('vl_counter_t {}_error_counters[] = {{\n'.format(csetname)) + write('vlib_error_desc_t {}_error_counters[] = {{\n'.format(csetname)) for c in cnt.block: write(' {\n') write(' .name = "{}",\n'.format(c['name'])) @@ -1398,7 +1481,10 @@ def generate_c_test_boilerplate(services, defines, file_crc, module, plugin, ' vl_noop_handler,\n' ' vl_api_{n}_t_endian, ' ' vl_api_{n}_t_print,\n' - ' sizeof(vl_api_{n}_t), 1);\n' + ' sizeof(vl_api_{n}_t), 1,\n' + ' vl_api_{n}_t_print_json,\n' + ' vl_api_{n}_t_tojson,\n' + ' vl_api_{n}_t_fromjson);\n' .format(n=s.reply, ID=s.reply.upper())) write(' hash_set_mem (vam->function_by_name, "{n}", api_{n});\n' .format(n=s.caller)) @@ -1417,15 +1503,14 @@ def generate_c_test_boilerplate(services, defines, file_crc, module, plugin, ' vl_noop_handler,\n' ' vl_api_{n}_t_endian, ' ' vl_api_{n}_t_print,\n' - ' sizeof(vl_api_{n}_t), 1);\n' + ' sizeof(vl_api_{n}_t), 1,\n' + ' vl_api_{n}_t_print_json,\n' + ' vl_api_{n}_t_tojson,\n' + ' vl_api_{n}_t_fromjson);\n' .format(n=e, ID=e.upper())) write('}\n') - if plugin: - write('clib_error_t * vat_plugin_register (vat_main_t *vam)\n') - else: - write('clib_error_t * vat_{}_plugin_register (vat_main_t *vam)\n' - .format(module)) + write('clib_error_t * vat_plugin_register (vat_main_t *vam)\n') write('{\n') write(' {n}_test_main_t * mainp = &{n}_test_main;\n'.format(n=module)) write(' mainp->vat_main = vam;\n') @@ -1473,12 +1558,13 @@ api_{n} (cJSON *o) mp->_vl_msg_id = vac_get_msg_index(VL_API_{N}_CRC); vl_api_{n}_t_endian(mp); vac_write((char *)mp, len); - free(mp); + cJSON_free(mp); /* Read reply */ char *p; int l; vac_read(&p, &l, 5); // XXX: Fix timeout + if (p == 0 || l == 0) return 0; // XXX Will fail in case of event received. Do loop if (ntohs(*((u16 *)p)) != vac_get_msg_index(VL_API_{R}_CRC)) {{ fprintf(stderr, "Mismatched reply\\n"); @@ -1505,7 +1591,7 @@ api_{n} (cJSON *o) mp->_vl_msg_id = msg_id; vl_api_{n}_t_endian(mp); vac_write((char *)mp, len); - free(mp); + cJSON_free(mp); vat2_control_ping(123); // FIX CONTEXT cJSON *reply = cJSON_CreateArray(); @@ -1518,6 +1604,10 @@ api_{n} (cJSON *o) char *p; int l; vac_read(&p, &l, 5); // XXX: Fix timeout + if (p == 0 || l == 0) {{ + cJSON_free(reply); + return 0; + }} /* Message can be one of [_details, control_ping_reply * or unrelated event] @@ -1528,6 +1618,10 @@ api_{n} (cJSON *o) }} if (reply_msg_id == details_msg_id) {{ + if (l < sizeof(vl_api_{r}_t)) {{ + cJSON_free(reply); + return 0; + }} vl_api_{r}_t *rmp = (vl_api_{r}_t *)p; vl_api_{r}_t_endian(rmp); cJSON_AddItemToArray(reply, vl_api_{r}_t_tojson(rmp)); @@ -1553,7 +1647,7 @@ api_{n} (cJSON *o) vl_api_{n}_t_endian(mp); vac_write((char *)mp, len); - free(mp); + cJSON_free(mp); cJSON *reply = cJSON_CreateArray(); @@ -1619,7 +1713,9 @@ def generate_c_test2_boilerplate(services, defines, module, stream): #include #define vl_typedefs /* define message structures */ -#include +#include +#include +#include #undef vl_typedefs #include "{module}.api_enum.h" @@ -1649,13 +1745,16 @@ def generate_c_test2_boilerplate(services, defines, module, stream): continue c_test_api_service(s, s.stream, stream) - write('void vat2_register_function(char *, cJSON * (*)(cJSON *));\n') + write('void vat2_register_function(char *, cJSON * (*)(cJSON *), cJSON * (*)(void *), u32);\n') # write('__attribute__((constructor))') write('clib_error_t *\n') write('vat2_register_plugin (void) {\n') for s in services: - write(' vat2_register_function("{n}", api_{n});\n' - .format(n=s.caller)) + if s.reply not in define_hash: + continue + crc = define_hash[s.caller].crc + write(' vat2_register_function("{n}", api_{n}, (cJSON * (*)(void *))vl_api_{n}_t_tojson, 0x{crc:08x});\n' + .format(n=s.caller, crc=crc)) write(' return 0;\n') write('}\n')