// auto-generated by Georg Sauthoff's eti2wireshark.py

/* packet-eti.c
 * Routines for EOBI dissection
 * Copyright 2021, Georg Sauthoff <mail@gms.tf>
 *
 * Wireshark - Network traffic analyzer
 * By Gerald Combs <gerald@wireshark.org>
 * Copyright 1998 Gerald Combs
 *
 * SPDX-License-Identifier: GPL-2.0-or-later
 */

/*
 * The Enhanced Order Book Interface 10.0 (EOBI) is an electronic trading protocol
 * that is used by a few exchanges (Eurex, Xetra, ...).
 *
 * It's a Length-Tag based protocol consisting of mostly fix sized
 * request/response messages.
 *
 * Links:
 * https://en.wikipedia.org/wiki/List_of_electronic_trading_protocols#Europe
 * https://github.com/gsauthof/python-eti#protocol-descriptions
 * https://github.com/gsauthof/python-eti#protocol-introduction
 *
 */

#include <config.h>


#include <epan/packet.h>   // Should be first Wireshark include (other than config.h)
#include "packet-udp.h"    // udp_dissect_pdus()
#include <epan/expert.h>   // expert info

#include <inttypes.h>
#include <stdio.h>         // snprintf()


/* Prototypes */
/* (Required to prevent [-Wmissing-prototypes] warnings */
void proto_reg_handoff_eobi(void);
void proto_register_eobi(void);

static dissector_handle_t eobi_handle;

static int proto_eobi = -1;
static expert_field ei_eobi_counter_overflow = EI_INIT;
static expert_field ei_eobi_invalid_template = EI_INIT;
static expert_field ei_eobi_invalid_length = EI_INIT;
static expert_field ei_eobi_missing = EI_INIT;
static expert_field ei_eobi_overused = EI_INIT;

static int hf_eobi[] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 };
static int hf_eobi_dscp_exec_summary = -1;
static int hf_eobi_dscp_improved = -1;
static int hf_eobi_dscp_widened = -1;
enum Field_Handle_Index {
      AGGRESSORSIDE_FH_IDX
    , AGGRESSORTIME_FH_IDX
    , ALGORITHMICTRADEINDICATOR_FH_IDX
    , APPLSEQNUM_FH_IDX
    , APPLSEQRESETINDICATOR_FH_IDX
    , BIDORDTYPE_FH_IDX
    , BIDPX_FH_IDX
    , BIDSIZE_FH_IDX
    , BODYLEN_FH_IDX
    , COMPLETIONINDICATOR_FH_IDX
    , CROSSREQUESTTYPE_FH_IDX
    , DSCP_FH_IDX
    , DISPLAYQTY_FH_IDX
    , EXECID_FH_IDX
    , FASTMARKETINDICATOR_FH_IDX
    , HIGHPX_FH_IDX
    , IMBALANCEQTY_FH_IDX
    , IMPLIEDMARKETINDICATOR_FH_IDX
    , INPUTSOURCE_FH_IDX
    , INSTRUMENTSCOPEPRODUCTCOMPLEX_FH_IDX
    , LASTFRAGMENT_FH_IDX
    , LASTMSGSEQNUMPROCESSED_FH_IDX
    , LASTPX_FH_IDX
    , LASTQTY_FH_IDX
    , LASTUPDATETIME_FH_IDX
    , LEGPRICE_FH_IDX
    , LEGRATIOMULTIPLIER_FH_IDX
    , LEGRATIOQTY_FH_IDX
    , LEGSECURITYID_FH_IDX
    , LEGSECURITYTYPE_FH_IDX
    , LEGSIDE_FH_IDX
    , LEGSYMBOL_FH_IDX
    , LOWPX_FH_IDX
    , MDENTRYPX_FH_IDX
    , MDENTRYSIZE_FH_IDX
    , MDENTRYTYPE_FH_IDX
    , MARKETCONDITION_FH_IDX
    , MARKETSEGMENTID_FH_IDX
    , MASSMARKETCONDITION_FH_IDX
    , MASSSOLDOUTINDICATOR_FH_IDX
    , MATCHSUBTYPE_FH_IDX
    , MATCHTYPE_FH_IDX
    , MSGSEQNUM_FH_IDX
    , NOLEGS_FH_IDX
    , NOMDENTRIES_FH_IDX
    , NORELATEDSYM_FH_IDX
    , NUMBEROFBUYORDERS_FH_IDX
    , NUMBEROFSELLORDERS_FH_IDX
    , OFFERORDTYPE_FH_IDX
    , OFFERPX_FH_IDX
    , OFFERSIZE_FH_IDX
    , ORDTYPE_FH_IDX
    , PARTITIONID_FH_IDX
    , POTENTIALSECURITYTRADINGEVENT_FH_IDX
    , PREVDISPLAYQTY_FH_IDX
    , PREVPRICE_FH_IDX
    , PRICE_FH_IDX
    , PRODUCTCOMPLEX_FH_IDX
    , REQUESTTIME_FH_IDX
    , RESTINGCXLQTY_FH_IDX
    , RESTINGHIDDENQTY_FH_IDX
    , SECURITYID_FH_IDX
    , SECURITYMASSSTATUS_FH_IDX
    , SECURITYMASSTRADINGEVENT_FH_IDX
    , SECURITYMASSTRADINGSTATUS_FH_IDX
    , SECURITYSTATUS_FH_IDX
    , SECURITYSUBTYPE_FH_IDX
    , SECURITYTRADINGEVENT_FH_IDX
    , SECURITYTRADINGSTATUS_FH_IDX
    , SIDE_FH_IDX
    , SOLDOUTINDICATOR_FH_IDX
    , TEMPLATEID_FH_IDX
    , TOTNOORDERS_FH_IDX
    , TRADSESSTATUS_FH_IDX
    , TRADECONDITION_FH_IDX
    , TRADINGSESSIONID_FH_IDX
    , TRADINGSESSIONSUBID_FH_IDX
    , TRANSACTTIME_FH_IDX
    , TRDMATCHID_FH_IDX
    , TRDREGTSEXECUTIONTIME_FH_IDX
    , TRDREGTSPREVTIMEPRIORITY_FH_IDX
    , TRDREGTSTIMEIN_FH_IDX
    , TRDREGTSTIMEPRIORITY_FH_IDX
};
static const value_string template_id_vals[] = { // TemplateID
    { 13001, "Heartbeat" },
    { 13002, "Unknown" },
    { 13003, "Unknown" },
    { 13004, "Unknown" },
    { 13005, "PacketHeader" },
    { 13006, "Unknown" },
    { 13007, "Unknown" },
    { 13008, "Unknown" },
    { 13009, "Unknown" },
    { 13010, "Unknown" },
    { 13011, "Unknown" },
    { 13012, "Unknown" },
    { 13013, "Unknown" },
    { 13014, "Unknown" },
    { 13015, "Unknown" },
    { 13016, "Unknown" },
    { 13017, "Unknown" },
    { 13018, "Unknown" },
    { 13019, "Unknown" },
    { 13020, "Unknown" },
    { 13021, "Unknown" },
    { 13022, "Unknown" },
    { 13023, "Unknown" },
    { 13024, "Unknown" },
    { 13025, "Unknown" },
    { 13026, "Unknown" },
    { 13027, "Unknown" },
    { 13028, "Unknown" },
    { 13029, "Unknown" },
    { 13030, "Unknown" },
    { 13031, "Unknown" },
    { 13032, "Unknown" },
    { 13033, "Unknown" },
    { 13034, "Unknown" },
    { 13035, "Unknown" },
    { 13036, "Unknown" },
    { 13037, "Unknown" },
    { 13038, "Unknown" },
    { 13039, "Unknown" },
    { 13040, "Unknown" },
    { 13041, "Unknown" },
    { 13042, "Unknown" },
    { 13043, "Unknown" },
    { 13044, "Unknown" },
    { 13045, "Unknown" },
    { 13046, "Unknown" },
    { 13047, "Unknown" },
    { 13048, "Unknown" },
    { 13049, "Unknown" },
    { 13050, "Unknown" },
    { 13051, "Unknown" },
    { 13052, "Unknown" },
    { 13053, "Unknown" },
    { 13054, "Unknown" },
    { 13055, "Unknown" },
    { 13056, "Unknown" },
    { 13057, "Unknown" },
    { 13058, "Unknown" },
    { 13059, "Unknown" },
    { 13060, "Unknown" },
    { 13061, "Unknown" },
    { 13062, "Unknown" },
    { 13063, "Unknown" },
    { 13064, "Unknown" },
    { 13065, "Unknown" },
    { 13066, "Unknown" },
    { 13067, "Unknown" },
    { 13068, "Unknown" },
    { 13069, "Unknown" },
    { 13070, "Unknown" },
    { 13071, "Unknown" },
    { 13072, "Unknown" },
    { 13073, "Unknown" },
    { 13074, "Unknown" },
    { 13075, "Unknown" },
    { 13076, "Unknown" },
    { 13077, "Unknown" },
    { 13078, "Unknown" },
    { 13079, "Unknown" },
    { 13080, "Unknown" },
    { 13081, "Unknown" },
    { 13082, "Unknown" },
    { 13083, "Unknown" },
    { 13084, "Unknown" },
    { 13085, "Unknown" },
    { 13086, "Unknown" },
    { 13087, "Unknown" },
    { 13088, "Unknown" },
    { 13089, "Unknown" },
    { 13090, "Unknown" },
    { 13091, "Unknown" },
    { 13092, "Unknown" },
    { 13093, "Unknown" },
    { 13094, "Unknown" },
    { 13095, "Unknown" },
    { 13096, "Unknown" },
    { 13097, "Unknown" },
    { 13098, "Unknown" },
    { 13099, "Unknown" },
    { 13100, "OrderAdd" },
    { 13101, "OrderModify" },
    { 13102, "OrderDelete" },
    { 13103, "OrderMassDelete" },
    { 13104, "FullOrderExecution" },
    { 13105, "PartialOrderExecution" },
    { 13106, "OrderModifySamePrio" },
    { 13107, "Unknown" },
    { 13108, "Unknown" },
    { 13109, "Unknown" },
    { 13110, "Unknown" },
    { 13111, "Unknown" },
    { 13112, "Unknown" },
    { 13113, "Unknown" },
    { 13114, "Unknown" },
    { 13115, "Unknown" },
    { 13116, "Unknown" },
    { 13117, "Unknown" },
    { 13118, "Unknown" },
    { 13119, "Unknown" },
    { 13120, "Unknown" },
    { 13121, "Unknown" },
    { 13122, "Unknown" },
    { 13123, "Unknown" },
    { 13124, "Unknown" },
    { 13125, "Unknown" },
    { 13126, "Unknown" },
    { 13127, "Unknown" },
    { 13128, "Unknown" },
    { 13129, "Unknown" },
    { 13130, "Unknown" },
    { 13131, "Unknown" },
    { 13132, "Unknown" },
    { 13133, "Unknown" },
    { 13134, "Unknown" },
    { 13135, "Unknown" },
    { 13136, "Unknown" },
    { 13137, "Unknown" },
    { 13138, "Unknown" },
    { 13139, "Unknown" },
    { 13140, "Unknown" },
    { 13141, "Unknown" },
    { 13142, "Unknown" },
    { 13143, "Unknown" },
    { 13144, "Unknown" },
    { 13145, "Unknown" },
    { 13146, "Unknown" },
    { 13147, "Unknown" },
    { 13148, "Unknown" },
    { 13149, "Unknown" },
    { 13150, "Unknown" },
    { 13151, "Unknown" },
    { 13152, "Unknown" },
    { 13153, "Unknown" },
    { 13154, "Unknown" },
    { 13155, "Unknown" },
    { 13156, "Unknown" },
    { 13157, "Unknown" },
    { 13158, "Unknown" },
    { 13159, "Unknown" },
    { 13160, "Unknown" },
    { 13161, "Unknown" },
    { 13162, "Unknown" },
    { 13163, "Unknown" },
    { 13164, "Unknown" },
    { 13165, "Unknown" },
    { 13166, "Unknown" },
    { 13167, "Unknown" },
    { 13168, "Unknown" },
    { 13169, "Unknown" },
    { 13170, "Unknown" },
    { 13171, "Unknown" },
    { 13172, "Unknown" },
    { 13173, "Unknown" },
    { 13174, "Unknown" },
    { 13175, "Unknown" },
    { 13176, "Unknown" },
    { 13177, "Unknown" },
    { 13178, "Unknown" },
    { 13179, "Unknown" },
    { 13180, "Unknown" },
    { 13181, "Unknown" },
    { 13182, "Unknown" },
    { 13183, "Unknown" },
    { 13184, "Unknown" },
    { 13185, "Unknown" },
    { 13186, "Unknown" },
    { 13187, "Unknown" },
    { 13188, "Unknown" },
    { 13189, "Unknown" },
    { 13190, "Unknown" },
    { 13191, "Unknown" },
    { 13192, "Unknown" },
    { 13193, "Unknown" },
    { 13194, "Unknown" },
    { 13195, "Unknown" },
    { 13196, "Unknown" },
    { 13197, "Unknown" },
    { 13198, "Unknown" },
    { 13199, "Unknown" },
    { 13200, "TradeReversal" },
    { 13201, "TradeReport" },
    { 13202, "ExecutionSummary" },
    { 13203, "Unknown" },
    { 13204, "Unknown" },
    { 13205, "Unknown" },
    { 13206, "Unknown" },
    { 13207, "Unknown" },
    { 13208, "Unknown" },
    { 13209, "Unknown" },
    { 13210, "Unknown" },
    { 13211, "Unknown" },
    { 13212, "Unknown" },
    { 13213, "Unknown" },
    { 13214, "Unknown" },
    { 13215, "Unknown" },
    { 13216, "Unknown" },
    { 13217, "Unknown" },
    { 13218, "Unknown" },
    { 13219, "Unknown" },
    { 13220, "Unknown" },
    { 13221, "Unknown" },
    { 13222, "Unknown" },
    { 13223, "Unknown" },
    { 13224, "Unknown" },
    { 13225, "Unknown" },
    { 13226, "Unknown" },
    { 13227, "Unknown" },
    { 13228, "Unknown" },
    { 13229, "Unknown" },
    { 13230, "Unknown" },
    { 13231, "Unknown" },
    { 13232, "Unknown" },
    { 13233, "Unknown" },
    { 13234, "Unknown" },
    { 13235, "Unknown" },
    { 13236, "Unknown" },
    { 13237, "Unknown" },
    { 13238, "Unknown" },
    { 13239, "Unknown" },
    { 13240, "Unknown" },
    { 13241, "Unknown" },
    { 13242, "Unknown" },
    { 13243, "Unknown" },
    { 13244, "Unknown" },
    { 13245, "Unknown" },
    { 13246, "Unknown" },
    { 13247, "Unknown" },
    { 13248, "Unknown" },
    { 13249, "Unknown" },
    { 13250, "Unknown" },
    { 13251, "Unknown" },
    { 13252, "Unknown" },
    { 13253, "Unknown" },
    { 13254, "Unknown" },
    { 13255, "Unknown" },
    { 13256, "Unknown" },
    { 13257, "Unknown" },
    { 13258, "Unknown" },
    { 13259, "Unknown" },
    { 13260, "Unknown" },
    { 13261, "Unknown" },
    { 13262, "Unknown" },
    { 13263, "Unknown" },
    { 13264, "Unknown" },
    { 13265, "Unknown" },
    { 13266, "Unknown" },
    { 13267, "Unknown" },
    { 13268, "Unknown" },
    { 13269, "Unknown" },
    { 13270, "Unknown" },
    { 13271, "Unknown" },
    { 13272, "Unknown" },
    { 13273, "Unknown" },
    { 13274, "Unknown" },
    { 13275, "Unknown" },
    { 13276, "Unknown" },
    { 13277, "Unknown" },
    { 13278, "Unknown" },
    { 13279, "Unknown" },
    { 13280, "Unknown" },
    { 13281, "Unknown" },
    { 13282, "Unknown" },
    { 13283, "Unknown" },
    { 13284, "Unknown" },
    { 13285, "Unknown" },
    { 13286, "Unknown" },
    { 13287, "Unknown" },
    { 13288, "Unknown" },
    { 13289, "Unknown" },
    { 13290, "Unknown" },
    { 13291, "Unknown" },
    { 13292, "Unknown" },
    { 13293, "Unknown" },
    { 13294, "Unknown" },
    { 13295, "Unknown" },
    { 13296, "Unknown" },
    { 13297, "Unknown" },
    { 13298, "Unknown" },
    { 13299, "Unknown" },
    { 13300, "ProductStateChange" },
    { 13301, "InstrumentStateChange" },
    { 13302, "MassInstrumentStateChange" },
    { 13303, "Unknown" },
    { 13304, "Unknown" },
    { 13305, "Unknown" },
    { 13306, "Unknown" },
    { 13307, "Unknown" },
    { 13308, "Unknown" },
    { 13309, "Unknown" },
    { 13310, "Unknown" },
    { 13311, "Unknown" },
    { 13312, "Unknown" },
    { 13313, "Unknown" },
    { 13314, "Unknown" },
    { 13315, "Unknown" },
    { 13316, "Unknown" },
    { 13317, "Unknown" },
    { 13318, "Unknown" },
    { 13319, "Unknown" },
    { 13320, "Unknown" },
    { 13321, "Unknown" },
    { 13322, "Unknown" },
    { 13323, "Unknown" },
    { 13324, "Unknown" },
    { 13325, "Unknown" },
    { 13326, "Unknown" },
    { 13327, "Unknown" },
    { 13328, "Unknown" },
    { 13329, "Unknown" },
    { 13330, "Unknown" },
    { 13331, "Unknown" },
    { 13332, "Unknown" },
    { 13333, "Unknown" },
    { 13334, "Unknown" },
    { 13335, "Unknown" },
    { 13336, "Unknown" },
    { 13337, "Unknown" },
    { 13338, "Unknown" },
    { 13339, "Unknown" },
    { 13340, "Unknown" },
    { 13341, "Unknown" },
    { 13342, "Unknown" },
    { 13343, "Unknown" },
    { 13344, "Unknown" },
    { 13345, "Unknown" },
    { 13346, "Unknown" },
    { 13347, "Unknown" },
    { 13348, "Unknown" },
    { 13349, "Unknown" },
    { 13350, "Unknown" },
    { 13351, "Unknown" },
    { 13352, "Unknown" },
    { 13353, "Unknown" },
    { 13354, "Unknown" },
    { 13355, "Unknown" },
    { 13356, "Unknown" },
    { 13357, "Unknown" },
    { 13358, "Unknown" },
    { 13359, "Unknown" },
    { 13360, "Unknown" },
    { 13361, "Unknown" },
    { 13362, "Unknown" },
    { 13363, "Unknown" },
    { 13364, "Unknown" },
    { 13365, "Unknown" },
    { 13366, "Unknown" },
    { 13367, "Unknown" },
    { 13368, "Unknown" },
    { 13369, "Unknown" },
    { 13370, "Unknown" },
    { 13371, "Unknown" },
    { 13372, "Unknown" },
    { 13373, "Unknown" },
    { 13374, "Unknown" },
    { 13375, "Unknown" },
    { 13376, "Unknown" },
    { 13377, "Unknown" },
    { 13378, "Unknown" },
    { 13379, "Unknown" },
    { 13380, "Unknown" },
    { 13381, "Unknown" },
    { 13382, "Unknown" },
    { 13383, "Unknown" },
    { 13384, "Unknown" },
    { 13385, "Unknown" },
    { 13386, "Unknown" },
    { 13387, "Unknown" },
    { 13388, "Unknown" },
    { 13389, "Unknown" },
    { 13390, "Unknown" },
    { 13391, "Unknown" },
    { 13392, "Unknown" },
    { 13393, "Unknown" },
    { 13394, "Unknown" },
    { 13395, "Unknown" },
    { 13396, "Unknown" },
    { 13397, "Unknown" },
    { 13398, "Unknown" },
    { 13399, "Unknown" },
    { 13400, "AddComplexInstrument" },
    { 13401, "Unknown" },
    { 13402, "Unknown" },
    { 13403, "Unknown" },
    { 13404, "Unknown" },
    { 13405, "Unknown" },
    { 13406, "Unknown" },
    { 13407, "Unknown" },
    { 13408, "Unknown" },
    { 13409, "Unknown" },
    { 13410, "Unknown" },
    { 13411, "Unknown" },
    { 13412, "Unknown" },
    { 13413, "Unknown" },
    { 13414, "Unknown" },
    { 13415, "Unknown" },
    { 13416, "Unknown" },
    { 13417, "Unknown" },
    { 13418, "Unknown" },
    { 13419, "Unknown" },
    { 13420, "Unknown" },
    { 13421, "Unknown" },
    { 13422, "Unknown" },
    { 13423, "Unknown" },
    { 13424, "Unknown" },
    { 13425, "Unknown" },
    { 13426, "Unknown" },
    { 13427, "Unknown" },
    { 13428, "Unknown" },
    { 13429, "Unknown" },
    { 13430, "Unknown" },
    { 13431, "Unknown" },
    { 13432, "Unknown" },
    { 13433, "Unknown" },
    { 13434, "Unknown" },
    { 13435, "Unknown" },
    { 13436, "Unknown" },
    { 13437, "Unknown" },
    { 13438, "Unknown" },
    { 13439, "Unknown" },
    { 13440, "Unknown" },
    { 13441, "Unknown" },
    { 13442, "Unknown" },
    { 13443, "Unknown" },
    { 13444, "Unknown" },
    { 13445, "Unknown" },
    { 13446, "Unknown" },
    { 13447, "Unknown" },
    { 13448, "Unknown" },
    { 13449, "Unknown" },
    { 13450, "Unknown" },
    { 13451, "Unknown" },
    { 13452, "Unknown" },
    { 13453, "Unknown" },
    { 13454, "Unknown" },
    { 13455, "Unknown" },
    { 13456, "Unknown" },
    { 13457, "Unknown" },
    { 13458, "Unknown" },
    { 13459, "Unknown" },
    { 13460, "Unknown" },
    { 13461, "Unknown" },
    { 13462, "Unknown" },
    { 13463, "Unknown" },
    { 13464, "Unknown" },
    { 13465, "Unknown" },
    { 13466, "Unknown" },
    { 13467, "Unknown" },
    { 13468, "Unknown" },
    { 13469, "Unknown" },
    { 13470, "Unknown" },
    { 13471, "Unknown" },
    { 13472, "Unknown" },
    { 13473, "Unknown" },
    { 13474, "Unknown" },
    { 13475, "Unknown" },
    { 13476, "Unknown" },
    { 13477, "Unknown" },
    { 13478, "Unknown" },
    { 13479, "Unknown" },
    { 13480, "Unknown" },
    { 13481, "Unknown" },
    { 13482, "Unknown" },
    { 13483, "Unknown" },
    { 13484, "Unknown" },
    { 13485, "Unknown" },
    { 13486, "Unknown" },
    { 13487, "Unknown" },
    { 13488, "Unknown" },
    { 13489, "Unknown" },
    { 13490, "Unknown" },
    { 13491, "Unknown" },
    { 13492, "Unknown" },
    { 13493, "Unknown" },
    { 13494, "Unknown" },
    { 13495, "Unknown" },
    { 13496, "Unknown" },
    { 13497, "Unknown" },
    { 13498, "Unknown" },
    { 13499, "Unknown" },
    { 13500, "AuctionBBO" },
    { 13501, "AuctionClearingPrice" },
    { 13502, "CrossRequest" },
    { 13503, "QuoteRequest" },
    { 13504, "TopOfBook" },
    { 13505, "Unknown" },
    { 13506, "Unknown" },
    { 13507, "Unknown" },
    { 13508, "Unknown" },
    { 13509, "Unknown" },
    { 13510, "Unknown" },
    { 13511, "Unknown" },
    { 13512, "Unknown" },
    { 13513, "Unknown" },
    { 13514, "Unknown" },
    { 13515, "Unknown" },
    { 13516, "Unknown" },
    { 13517, "Unknown" },
    { 13518, "Unknown" },
    { 13519, "Unknown" },
    { 13520, "Unknown" },
    { 13521, "Unknown" },
    { 13522, "Unknown" },
    { 13523, "Unknown" },
    { 13524, "Unknown" },
    { 13525, "Unknown" },
    { 13526, "Unknown" },
    { 13527, "Unknown" },
    { 13528, "Unknown" },
    { 13529, "Unknown" },
    { 13530, "Unknown" },
    { 13531, "Unknown" },
    { 13532, "Unknown" },
    { 13533, "Unknown" },
    { 13534, "Unknown" },
    { 13535, "Unknown" },
    { 13536, "Unknown" },
    { 13537, "Unknown" },
    { 13538, "Unknown" },
    { 13539, "Unknown" },
    { 13540, "Unknown" },
    { 13541, "Unknown" },
    { 13542, "Unknown" },
    { 13543, "Unknown" },
    { 13544, "Unknown" },
    { 13545, "Unknown" },
    { 13546, "Unknown" },
    { 13547, "Unknown" },
    { 13548, "Unknown" },
    { 13549, "Unknown" },
    { 13550, "Unknown" },
    { 13551, "Unknown" },
    { 13552, "Unknown" },
    { 13553, "Unknown" },
    { 13554, "Unknown" },
    { 13555, "Unknown" },
    { 13556, "Unknown" },
    { 13557, "Unknown" },
    { 13558, "Unknown" },
    { 13559, "Unknown" },
    { 13560, "Unknown" },
    { 13561, "Unknown" },
    { 13562, "Unknown" },
    { 13563, "Unknown" },
    { 13564, "Unknown" },
    { 13565, "Unknown" },
    { 13566, "Unknown" },
    { 13567, "Unknown" },
    { 13568, "Unknown" },
    { 13569, "Unknown" },
    { 13570, "Unknown" },
    { 13571, "Unknown" },
    { 13572, "Unknown" },
    { 13573, "Unknown" },
    { 13574, "Unknown" },
    { 13575, "Unknown" },
    { 13576, "Unknown" },
    { 13577, "Unknown" },
    { 13578, "Unknown" },
    { 13579, "Unknown" },
    { 13580, "Unknown" },
    { 13581, "Unknown" },
    { 13582, "Unknown" },
    { 13583, "Unknown" },
    { 13584, "Unknown" },
    { 13585, "Unknown" },
    { 13586, "Unknown" },
    { 13587, "Unknown" },
    { 13588, "Unknown" },
    { 13589, "Unknown" },
    { 13590, "Unknown" },
    { 13591, "Unknown" },
    { 13592, "Unknown" },
    { 13593, "Unknown" },
    { 13594, "Unknown" },
    { 13595, "Unknown" },
    { 13596, "Unknown" },
    { 13597, "Unknown" },
    { 13598, "Unknown" },
    { 13599, "Unknown" },
    { 13600, "ProductSummary" },
    { 13601, "InstrumentSummary" },
    { 13602, "SnapshotOrder" },
    { 0, NULL }
};
static value_string_ext template_id_vals_ext = VALUE_STRING_EXT_INIT(template_id_vals);
static const value_string aggressor_side_vals[] = { // AggressorSide
    { 1, "Buy" },
    { 2, "Sell" },
    { 0xFF, "NO_VALUE" },
    { 0, NULL }
};
static const value_string algorithmic_trade_indicator_vals[] = { // AlgorithmicTradeIndicator
    { 1, "AlgorithmicTrade" },
    { 0xFF, "NO_VALUE" },
    { 0, NULL }
};
static const value_string appl_seq_reset_indicator_vals[] = { // ApplSeqResetIndicator
    { 0, "NoReset" },
    { 1, "Reset" },
    { 0xFF, "NO_VALUE" },
    { 0, NULL }
};
static const value_string bid_ord_type_vals[] = { // BidOrdType
    { 1, "Market" },
    { 0xFF, "NO_VALUE" },
    { 0, NULL }
};
static const value_string completion_indicator_vals[] = { // CompletionIndicator
    { 0, "Incomplete" },
    { 1, "Complete" },
    { 0xFF, "NO_VALUE" },
    { 0, NULL }
};
static const value_string cross_request_type_vals[] = { // CrossRequestType
    { 1, "CrossAnnouncement" },
    { 2, "LiquidityImprovementCross" },
    { 0xFF, "NO_VALUE" },
    { 0, NULL }
};
static const value_string fast_market_indicator_vals[] = { // FastMarketIndicator
    { 0, "No" },
    { 1, "Yes" },
    { 0xFF, "NO_VALUE" },
    { 0, NULL }
};
static const value_string implied_market_indicator_vals[] = { // ImpliedMarketIndicator
    { 0, "NotImplied" },
    { 3, "ImpliedInOut" },
    { 0xFF, "NO_VALUE" },
    { 0, NULL }
};
static const value_string input_source_vals[] = { // InputSource
    { 1, "CLIPClientBroker" },
    { 0xFF, "NO_VALUE" },
    { 0, NULL }
};
static const value_string instrument_scope_product_complex_vals[] = { // InstrumentScopeProductComplex
    { 1, "SimpleInstrument" },
    { 2, "StandardOptionStrategy" },
    { 3, "NonStandardOptionStrategy" },
    { 4, "VolatilityStrategy" },
    { 5, "FuturesSpread" },
    { 6, "InterProductSpread" },
    { 7, "StandardFuturesStrategy" },
    { 8, "PackAndBundle" },
    { 9, "Strip" },
    { 0xFF, "NO_VALUE" },
    { 0, NULL }
};
static value_string_ext instrument_scope_product_complex_vals_ext = VALUE_STRING_EXT_INIT(instrument_scope_product_complex_vals);
static const value_string last_fragment_vals[] = { // LastFragment
    { 0, "N" },
    { 1, "Y" },
    { 0xFF, "NO_VALUE" },
    { 0, NULL }
};
static const value_string leg_security_type_vals[] = { // LegSecurityType
    { 1, "LegSecurityMultiLeg" },
    { 2, "LegSecurityUnderlyingLeg" },
    { 0xFF, "NO_VALUE" },
    { 0, NULL }
};
// LegSide aliased by AggressorSide
static const value_string mdentry_type_vals[] = { // MDEntryType
    { 2, "Trade" },
    { 4, "OpeningPrice" },
    { 5, "ClosingPrice" },
    { 7, "HighPrice" },
    { 8, "LowPrice" },
    { 66, "TradeVolume" },
    { 101, "PreviousClosingPrice" },
    { 200, "OpeningAuction" },
    { 201, "IntradayAuction" },
    { 202, "CircuitBreakerAuction" },
    { 203, "ClosingAuction" },
    { 204, "IPOAuction" },
    { 0xFF, "NO_VALUE" },
    { 0, NULL }
};
static value_string_ext mdentry_type_vals_ext = VALUE_STRING_EXT_INIT(mdentry_type_vals);
static const value_string market_condition_vals[] = { // MarketCondition
    { 0, "Normal" },
    { 1, "Stressed" },
    { 0xFF, "NO_VALUE" },
    { 0, NULL }
};
// MassMarketCondition aliased by MarketCondition
static const value_string mass_sold_out_indicator_vals[] = { // MassSoldOutIndicator
    { 1, "SoldOut" },
    { 0xFF, "NO_VALUE" },
    { 0, NULL }
};
static const value_string match_sub_type_vals[] = { // MatchSubType
    { 1, "OpeningAuction" },
    { 2, "ClosingAuction" },
    { 3, "IntradayAuction" },
    { 4, "CircuitBreakerAuction" },
    { 5, "IPOAuction" },
    { 0xFF, "NO_VALUE" },
    { 0, NULL }
};
static const value_string match_type_vals[] = { // MatchType
    { 3, "ConfirmedTradeReport" },
    { 5, "CrossAuction" },
    { 7, "CallAuction" },
    { 13, "LiquidityImprovementCross" },
    { 14, "ContinuousAuction" },
    { 0xFF, "NO_VALUE" },
    { 0, NULL }
};
// OfferOrdType aliased by BidOrdType
// OrdType aliased by BidOrdType
static const value_string potential_security_trading_event_vals[] = { // PotentialSecurityTradingEvent
    { 0, "None" },
    { 10, "PriceVolatilityAuctionIsExtended" },
    { 0xFF, "NO_VALUE" },
    { 0, NULL }
};
// ProductComplex aliased by InstrumentScopeProductComplex
static const value_string security_mass_status_vals[] = { // SecurityMassStatus
    { 1, "Active" },
    { 2, "Inactive" },
    { 4, "Expired" },
    { 6, "KnockedOut" },
    { 7, "KnockOutRevoked" },
    { 9, "Suspended" },
    { 11, "PendingDeletion" },
    { 12, "KnockedOutAndSuspended" },
    { 0xFF, "NO_VALUE" },
    { 0, NULL }
};
static value_string_ext security_mass_status_vals_ext = VALUE_STRING_EXT_INIT(security_mass_status_vals);
static const value_string security_mass_trading_event_vals[] = { // SecurityMassTradingEvent
    { 10, "PriceVolatilityAuctionIsExtended" },
    { 11, "PriceVolatilityAuctionIsExtendedAgain" },
    { 0xFF, "NO_VALUE" },
    { 0, NULL }
};
static const value_string security_mass_trading_status_vals[] = { // SecurityMassTradingStatus
    { 2, "TradingHalt" },
    { 7, "MarketImbalanceBuy" },
    { 8, "MarketImbalanceSell" },
    { 200, "Closed" },
    { 201, "Restricted" },
    { 202, "Book" },
    { 203, "Continuous" },
    { 204, "OpeningAuction" },
    { 205, "OpeningAuctionFreeze" },
    { 206, "IntradayAuction" },
    { 207, "IntradayAuctionFreeze" },
    { 208, "CircuitBreakerAuction" },
    { 209, "CircuitBreakerAuctionFreeze" },
    { 210, "ClosingAuction" },
    { 211, "ClosingAuctionFreeze" },
    { 212, "IPOAuction" },
    { 213, "IPOAuctionFreeze" },
    { 214, "PreCall" },
    { 215, "Call" },
    { 216, "Freeze" },
    { 217, "TradeAtClose" },
    { 0xFF, "NO_VALUE" },
    { 0, NULL }
};
static value_string_ext security_mass_trading_status_vals_ext = VALUE_STRING_EXT_INIT(security_mass_trading_status_vals);
// SecurityStatus aliased by SecurityMassStatus
// SecurityTradingEvent aliased by SecurityMassTradingEvent
// SecurityTradingStatus aliased by SecurityMassTradingStatus
// Side aliased by AggressorSide
// SoldOutIndicator aliased by MassSoldOutIndicator
static const value_string trad_ses_status_vals[] = { // TradSesStatus
    { 1, "Halted" },
    { 2, "Open" },
    { 3, "Closed" },
    { 0xFF, "NO_VALUE" },
    { 0, NULL }
};
static const value_string trade_condition_vals[] = { // TradeCondition
    { 1, "ImpliedTrade" },
    { 107, "OutOfSequence" },
    { 155, "MidpointPrice" },
    { 156, "TradingOnTermsOfIssue" },
    { 596, "SpecialAuction" },
    { 624, "TradeAtClose" },
    { 0xFFFF, "NO_VALUE" },
    { 0, NULL }
};
static const value_string trading_session_id_vals[] = { // TradingSessionID
    { 1, "Day" },
    { 3, "Morning" },
    { 5, "Evening" },
    { 6, "AfterHours" },
    { 7, "Holiday" },
    { 0xFF, "NO_VALUE" },
    { 0, NULL }
};
static const value_string trading_session_sub_id_vals[] = { // TradingSessionSubID
    { 1, "PreTrading" },
    { 3, "Continuous" },
    { 4, "Closing" },
    { 5, "PostTrading" },
    { 7, "Quiescent" },
    { 0xFF, "NO_VALUE" },
    { 0, NULL }
};

enum ETI_Type {
    ETI_EOF,
    ETI_PADDING,
    ETI_UINT,
    ETI_INT,
    ETI_UINT_ENUM,
    ETI_INT_ENUM,
    ETI_COUNTER,
    ETI_FIXED_POINT,
    ETI_TIMESTAMP_NS,
    ETI_CHAR,
    ETI_STRING,
    ETI_VAR_STRING,
    ETI_STRUCT,
    ETI_VAR_STRUCT,
    ETI_DSCP
};

struct ETI_Field {
    uint8_t  type;
    uint8_t  counter_off;      // offset into counter array
                               // if ETI_COUNTER => storage
                               // if ETI_VAR_STRING or ETI_VAR_STRUCT => load
                               // to get length or repeat count
                               // if ETI_FIXED_POINT: #fractional digits
    uint16_t size;             // or offset into struct_names if ETI_STRUCT/ETI_VAR_STRUCT
    uint16_t field_handle_idx; // or index into fields array if ETI_STRUCT/ETI_VAR_STRUT
    uint16_t ett_idx;          // index into ett array if ETI_STRUCT/ETI_VAR_STRUCT
                               // or max value if ETI_COUNTER
};

static gint ett_eobi[] = { -1, -1, -1, -1, -1, -1, -1 };
static gint ett_eobi_dscp = -1;
/* This method dissects fully reassembled messages */
static int
dissect_eobi_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
{
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "EOBI");
    col_clear(pinfo->cinfo, COL_INFO);
    guint16 templateid = tvb_get_letohs(tvb, 2);
    const char *template_str = val_to_str_ext(templateid, &template_id_vals_ext, "Unknown EOBI template: 0x%04x");
    col_add_fstr(pinfo->cinfo, COL_INFO, "%s", template_str);

    /* create display subtree for the protocol */
    proto_item *ti = proto_tree_add_item(tree, proto_eobi, tvb, 0, -1, ENC_NA);
    guint32 bodylen= tvb_get_letohs(tvb, 0);
    proto_item_append_text(ti, ", %s (%" PRIu16 "), BodyLen: %u", template_str, templateid, bodylen);
    proto_tree *root = proto_item_add_subtree(ti, ett_eobi[0]);

    static const char struct_names[] = "InstrmtLegGrp\0MDInstrumentEntryGrp\0MDTradeEntryGrp\0MessageHeader\0OrderDetails\0SecMassStatGrp";
    static const struct ETI_Field fields[] = {
        // InstrmtLegGrpComp@0
          { ETI_INT, 0, 4, LEGSYMBOL_FH_IDX, 0 }
        , { ETI_PADDING, 0, 4, 0, 0 }
        , { ETI_INT, 0, 8, LEGSECURITYID_FH_IDX, 0 }
        , { ETI_FIXED_POINT, 8, 8, LEGPRICE_FH_IDX, 0 }
        , { ETI_INT, 0, 4, LEGRATIOQTY_FH_IDX, 0 }
        , { ETI_UINT_ENUM, 0, 1, LEGSECURITYTYPE_FH_IDX, 0 }
        , { ETI_UINT_ENUM, 0, 1, LEGSIDE_FH_IDX, 0 }
        , { ETI_PADDING, 0, 2, 0, 0 }
        , { ETI_EOF, 0, 0, 0, 0 }
        // MDInstrumentEntryGrpComp@9
        , { ETI_FIXED_POINT, 8, 8, MDENTRYPX_FH_IDX, 0 }
        , { ETI_FIXED_POINT, 4, 8, MDENTRYSIZE_FH_IDX, 0 }
        , { ETI_UINT_ENUM, 0, 1, MDENTRYTYPE_FH_IDX, 0 }
        , { ETI_PADDING, 0, 1, 0, 0 }
        , { ETI_UINT_ENUM, 0, 2, TRADECONDITION_FH_IDX, 0 }
        , { ETI_PADDING, 0, 4, 0, 0 }
        , { ETI_EOF, 0, 0, 0, 0 }
        // MDTradeEntryGrpComp@16
        , { ETI_FIXED_POINT, 8, 8, MDENTRYPX_FH_IDX, 0 }
        , { ETI_FIXED_POINT, 4, 8, MDENTRYSIZE_FH_IDX, 0 }
        , { ETI_UINT_ENUM, 0, 1, MDENTRYTYPE_FH_IDX, 0 }
        , { ETI_PADDING, 0, 7, 0, 0 }
        , { ETI_EOF, 0, 0, 0, 0 }
        // MessageHeaderComp@21
        , { ETI_UINT, 0, 2, BODYLEN_FH_IDX, 0 }
        , { ETI_UINT, 0, 2, TEMPLATEID_FH_IDX, 0 }
        , { ETI_UINT, 0, 4, MSGSEQNUM_FH_IDX, 0 }
        , { ETI_EOF, 0, 0, 0, 0 }
        // OrderDetailsComp@25
        , { ETI_TIMESTAMP_NS, 0, 8, TRDREGTSTIMEPRIORITY_FH_IDX, 0 }
        , { ETI_FIXED_POINT, 4, 8, DISPLAYQTY_FH_IDX, 0 }
        , { ETI_UINT_ENUM, 0, 1, SIDE_FH_IDX, 0 }
        , { ETI_UINT_ENUM, 0, 1, ORDTYPE_FH_IDX, 0 }
        , { ETI_PADDING, 0, 6, 0, 0 }
        , { ETI_FIXED_POINT, 8, 8, PRICE_FH_IDX, 0 }
        , { ETI_EOF, 0, 0, 0, 0 }
        // SecMassStatGrpComp@32
        , { ETI_INT, 0, 8, SECURITYID_FH_IDX, 0 }
        , { ETI_FIXED_POINT, 8, 8, HIGHPX_FH_IDX, 0 }
        , { ETI_FIXED_POINT, 8, 8, LOWPX_FH_IDX, 0 }
        , { ETI_UINT_ENUM, 0, 1, SECURITYSTATUS_FH_IDX, 0 }
        , { ETI_UINT_ENUM, 0, 1, SECURITYTRADINGSTATUS_FH_IDX, 0 }
        , { ETI_UINT_ENUM, 0, 1, MARKETCONDITION_FH_IDX, 0 }
        , { ETI_UINT_ENUM, 0, 1, SECURITYTRADINGEVENT_FH_IDX, 0 }
        , { ETI_UINT_ENUM, 0, 1, SOLDOUTINDICATOR_FH_IDX, 0 }
        , { ETI_PADDING, 0, 3, 0, 0 }
        , { ETI_EOF, 0, 0, 0, 0 }
        // AddComplexInstrument@42
        , { ETI_STRUCT, 0, 51, 21, 4 } // MessageHeader
        , { ETI_INT, 0, 8, SECURITYID_FH_IDX, 0 }
        , { ETI_TIMESTAMP_NS, 0, 8, TRANSACTTIME_FH_IDX, 0 }
        , { ETI_INT, 0, 4, SECURITYSUBTYPE_FH_IDX, 0 }
        , { ETI_UINT_ENUM, 0, 1, PRODUCTCOMPLEX_FH_IDX, 0 }
        , { ETI_UINT_ENUM, 0, 1, IMPLIEDMARKETINDICATOR_FH_IDX, 0 }
        , { ETI_PADDING, 0, 2, 0, 0 }
        , { ETI_UINT, 0, 4, LEGRATIOMULTIPLIER_FH_IDX, 0 }
        , { ETI_COUNTER, 0, 1, NOLEGS_FH_IDX, 20 } // <- counter@0
        , { ETI_PADDING, 0, 3, 0, 0 }
        , { ETI_VAR_STRUCT, 0, 0, 0, 1 } // InstrmtLegGrp
        , { ETI_EOF, 0, 0, 0, 0 }
        // AuctionBBO@54
        , { ETI_STRUCT, 0, 51, 21, 4 } // MessageHeader
        , { ETI_TIMESTAMP_NS, 0, 8, TRANSACTTIME_FH_IDX, 0 }
        , { ETI_INT, 0, 8, SECURITYID_FH_IDX, 0 }
        , { ETI_FIXED_POINT, 8, 8, BIDPX_FH_IDX, 0 }
        , { ETI_FIXED_POINT, 8, 8, OFFERPX_FH_IDX, 0 }
        , { ETI_FIXED_POINT, 4, 8, BIDSIZE_FH_IDX, 0 }
        , { ETI_FIXED_POINT, 4, 8, OFFERSIZE_FH_IDX, 0 }
        , { ETI_UINT_ENUM, 0, 1, POTENTIALSECURITYTRADINGEVENT_FH_IDX, 0 }
        , { ETI_UINT_ENUM, 0, 1, BIDORDTYPE_FH_IDX, 0 }
        , { ETI_UINT_ENUM, 0, 1, OFFERORDTYPE_FH_IDX, 0 }
        , { ETI_PADDING, 0, 5, 0, 0 }
        , { ETI_EOF, 0, 0, 0, 0 }
        // AuctionClearingPrice@66
        , { ETI_STRUCT, 0, 51, 21, 4 } // MessageHeader
        , { ETI_TIMESTAMP_NS, 0, 8, TRANSACTTIME_FH_IDX, 0 }
        , { ETI_INT, 0, 8, SECURITYID_FH_IDX, 0 }
        , { ETI_FIXED_POINT, 8, 8, LASTPX_FH_IDX, 0 }
        , { ETI_FIXED_POINT, 4, 8, LASTQTY_FH_IDX, 0 }
        , { ETI_FIXED_POINT, 4, 8, IMBALANCEQTY_FH_IDX, 0 }
        , { ETI_UINT_ENUM, 0, 1, SECURITYTRADINGSTATUS_FH_IDX, 0 }
        , { ETI_UINT_ENUM, 0, 1, POTENTIALSECURITYTRADINGEVENT_FH_IDX, 0 }
        , { ETI_PADDING, 0, 6, 0, 0 }
        , { ETI_EOF, 0, 0, 0, 0 }
        // CrossRequest@76
        , { ETI_STRUCT, 0, 51, 21, 4 } // MessageHeader
        , { ETI_INT, 0, 8, SECURITYID_FH_IDX, 0 }
        , { ETI_FIXED_POINT, 8, 8, LASTPX_FH_IDX, 0 }
        , { ETI_FIXED_POINT, 4, 8, LASTQTY_FH_IDX, 0 }
        , { ETI_UINT_ENUM, 0, 1, SIDE_FH_IDX, 0 }
        , { ETI_UINT_ENUM, 0, 1, CROSSREQUESTTYPE_FH_IDX, 0 }
        , { ETI_UINT_ENUM, 0, 1, INPUTSOURCE_FH_IDX, 0 }
        , { ETI_PADDING, 0, 5, 0, 0 }
        , { ETI_TIMESTAMP_NS, 0, 8, TRANSACTTIME_FH_IDX, 0 }
        , { ETI_EOF, 0, 0, 0, 0 }
        // ExecutionSummary@86
        , { ETI_STRUCT, 0, 51, 21, 4 } // MessageHeader
        , { ETI_INT, 0, 8, SECURITYID_FH_IDX, 0 }
        , { ETI_TIMESTAMP_NS, 0, 8, AGGRESSORTIME_FH_IDX, 0 }
        , { ETI_TIMESTAMP_NS, 0, 8, REQUESTTIME_FH_IDX, 0 }
        , { ETI_TIMESTAMP_NS, 0, 8, EXECID_FH_IDX, 0 }
        , { ETI_FIXED_POINT, 4, 8, LASTQTY_FH_IDX, 0 }
        , { ETI_UINT_ENUM, 0, 1, AGGRESSORSIDE_FH_IDX, 0 }
        , { ETI_PADDING, 0, 1, 0, 0 }
        , { ETI_UINT_ENUM, 0, 2, TRADECONDITION_FH_IDX, 0 }
        , { ETI_PADDING, 0, 4, 0, 0 }
        , { ETI_FIXED_POINT, 8, 8, LASTPX_FH_IDX, 0 }
        , { ETI_FIXED_POINT, 4, 8, RESTINGHIDDENQTY_FH_IDX, 0 }
        , { ETI_FIXED_POINT, 4, 8, RESTINGCXLQTY_FH_IDX, 0 }
        , { ETI_EOF, 0, 0, 0, 0 }
        // FullOrderExecution@100
        , { ETI_STRUCT, 0, 51, 21, 4 } // MessageHeader
        , { ETI_UINT_ENUM, 0, 1, SIDE_FH_IDX, 0 }
        , { ETI_UINT_ENUM, 0, 1, ORDTYPE_FH_IDX, 0 }
        , { ETI_UINT_ENUM, 0, 1, ALGORITHMICTRADEINDICATOR_FH_IDX, 0 }
        , { ETI_PADDING, 0, 1, 0, 0 }
        , { ETI_UINT, 0, 4, TRDMATCHID_FH_IDX, 0 }
        , { ETI_FIXED_POINT, 8, 8, PRICE_FH_IDX, 0 }
        , { ETI_TIMESTAMP_NS, 0, 8, TRDREGTSTIMEPRIORITY_FH_IDX, 0 }
        , { ETI_INT, 0, 8, SECURITYID_FH_IDX, 0 }
        , { ETI_FIXED_POINT, 4, 8, LASTQTY_FH_IDX, 0 }
        , { ETI_FIXED_POINT, 8, 8, LASTPX_FH_IDX, 0 }
        , { ETI_EOF, 0, 0, 0, 0 }
        // Heartbeat@112
        , { ETI_STRUCT, 0, 51, 21, 4 } // MessageHeader
        , { ETI_UINT, 0, 4, LASTMSGSEQNUMPROCESSED_FH_IDX, 0 }
        , { ETI_PADDING, 0, 4, 0, 0 }
        , { ETI_EOF, 0, 0, 0, 0 }
        // InstrumentStateChange@116
        , { ETI_STRUCT, 0, 51, 21, 4 } // MessageHeader
        , { ETI_INT, 0, 8, SECURITYID_FH_IDX, 0 }
        , { ETI_UINT_ENUM, 0, 1, SECURITYSTATUS_FH_IDX, 0 }
        , { ETI_UINT_ENUM, 0, 1, SECURITYTRADINGSTATUS_FH_IDX, 0 }
        , { ETI_UINT_ENUM, 0, 1, MARKETCONDITION_FH_IDX, 0 }
        , { ETI_UINT_ENUM, 0, 1, FASTMARKETINDICATOR_FH_IDX, 0 }
        , { ETI_UINT_ENUM, 0, 1, SECURITYTRADINGEVENT_FH_IDX, 0 }
        , { ETI_UINT_ENUM, 0, 1, SOLDOUTINDICATOR_FH_IDX, 0 }
        , { ETI_PADDING, 0, 2, 0, 0 }
        , { ETI_FIXED_POINT, 8, 8, HIGHPX_FH_IDX, 0 }
        , { ETI_FIXED_POINT, 8, 8, LOWPX_FH_IDX, 0 }
        , { ETI_TIMESTAMP_NS, 0, 8, TRANSACTTIME_FH_IDX, 0 }
        , { ETI_EOF, 0, 0, 0, 0 }
        // InstrumentSummary@129
        , { ETI_STRUCT, 0, 51, 21, 4 } // MessageHeader
        , { ETI_INT, 0, 8, SECURITYID_FH_IDX, 0 }
        , { ETI_TIMESTAMP_NS, 0, 8, LASTUPDATETIME_FH_IDX, 0 }
        , { ETI_TIMESTAMP_NS, 0, 8, TRDREGTSEXECUTIONTIME_FH_IDX, 0 }
        , { ETI_COUNTER, 0, 2, TOTNOORDERS_FH_IDX, 65534 } // <- counter@0
        , { ETI_UINT_ENUM, 0, 1, SECURITYSTATUS_FH_IDX, 0 }
        , { ETI_UINT_ENUM, 0, 1, SECURITYTRADINGSTATUS_FH_IDX, 0 }
        , { ETI_UINT_ENUM, 0, 1, MARKETCONDITION_FH_IDX, 0 }
        , { ETI_UINT_ENUM, 0, 1, FASTMARKETINDICATOR_FH_IDX, 0 }
        , { ETI_UINT_ENUM, 0, 1, SECURITYTRADINGEVENT_FH_IDX, 0 }
        , { ETI_UINT_ENUM, 0, 1, SOLDOUTINDICATOR_FH_IDX, 0 }
        , { ETI_FIXED_POINT, 8, 8, HIGHPX_FH_IDX, 0 }
        , { ETI_FIXED_POINT, 8, 8, LOWPX_FH_IDX, 0 }
        , { ETI_UINT_ENUM, 0, 1, PRODUCTCOMPLEX_FH_IDX, 0 }
        , { ETI_COUNTER, 1, 1, NOMDENTRIES_FH_IDX, 15 } // <- counter@1
        , { ETI_PADDING, 0, 6, 0, 0 }
        , { ETI_VAR_STRUCT, 1, 14, 9, 2 } // MDInstrumentEntryGrp
        , { ETI_EOF, 0, 0, 0, 0 }
        // MassInstrumentStateChange@147
        , { ETI_STRUCT, 0, 51, 21, 4 } // MessageHeader
        , { ETI_UINT_ENUM, 0, 1, INSTRUMENTSCOPEPRODUCTCOMPLEX_FH_IDX, 0 }
        , { ETI_UINT_ENUM, 0, 1, SECURITYMASSSTATUS_FH_IDX, 0 }
        , { ETI_UINT_ENUM, 0, 1, SECURITYMASSTRADINGSTATUS_FH_IDX, 0 }
        , { ETI_UINT_ENUM, 0, 1, MASSMARKETCONDITION_FH_IDX, 0 }
        , { ETI_UINT_ENUM, 0, 1, FASTMARKETINDICATOR_FH_IDX, 0 }
        , { ETI_UINT_ENUM, 0, 1, SECURITYMASSTRADINGEVENT_FH_IDX, 0 }
        , { ETI_UINT_ENUM, 0, 1, MASSSOLDOUTINDICATOR_FH_IDX, 0 }
        , { ETI_PADDING, 0, 1, 0, 0 }
        , { ETI_TIMESTAMP_NS, 0, 8, TRANSACTTIME_FH_IDX, 0 }
        , { ETI_UINT_ENUM, 0, 1, LASTFRAGMENT_FH_IDX, 0 }
        , { ETI_COUNTER, 0, 1, NORELATEDSYM_FH_IDX, 24 } // <- counter@0
        , { ETI_PADDING, 0, 6, 0, 0 }
        , { ETI_VAR_STRUCT, 0, 78, 32, 6 } // SecMassStatGrp
        , { ETI_EOF, 0, 0, 0, 0 }
        // OrderAdd@162
        , { ETI_STRUCT, 0, 51, 21, 4 } // MessageHeader
        , { ETI_TIMESTAMP_NS, 0, 8, TRDREGTSTIMEIN_FH_IDX, 0 }
        , { ETI_INT, 0, 8, SECURITYID_FH_IDX, 0 }
        , { ETI_STRUCT, 0, 65, 25, 5 } // OrderDetails
        , { ETI_EOF, 0, 0, 0, 0 }
        // OrderDelete@167
        , { ETI_STRUCT, 0, 51, 21, 4 } // MessageHeader
        , { ETI_TIMESTAMP_NS, 0, 8, TRDREGTSTIMEIN_FH_IDX, 0 }
        , { ETI_TIMESTAMP_NS, 0, 8, TRANSACTTIME_FH_IDX, 0 }
        , { ETI_INT, 0, 8, SECURITYID_FH_IDX, 0 }
        , { ETI_STRUCT, 0, 65, 25, 5 } // OrderDetails
        , { ETI_EOF, 0, 0, 0, 0 }
        // OrderMassDelete@173
        , { ETI_STRUCT, 0, 51, 21, 4 } // MessageHeader
        , { ETI_INT, 0, 8, SECURITYID_FH_IDX, 0 }
        , { ETI_TIMESTAMP_NS, 0, 8, TRANSACTTIME_FH_IDX, 0 }
        , { ETI_EOF, 0, 0, 0, 0 }
        // OrderModify@177
        , { ETI_STRUCT, 0, 51, 21, 4 } // MessageHeader
        , { ETI_TIMESTAMP_NS, 0, 8, TRDREGTSTIMEIN_FH_IDX, 0 }
        , { ETI_TIMESTAMP_NS, 0, 8, TRDREGTSPREVTIMEPRIORITY_FH_IDX, 0 }
        , { ETI_FIXED_POINT, 8, 8, PREVPRICE_FH_IDX, 0 }
        , { ETI_FIXED_POINT, 4, 8, PREVDISPLAYQTY_FH_IDX, 0 }
        , { ETI_INT, 0, 8, SECURITYID_FH_IDX, 0 }
        , { ETI_STRUCT, 0, 65, 25, 5 } // OrderDetails
        , { ETI_EOF, 0, 0, 0, 0 }
        // OrderModifySamePrio@185
        , { ETI_STRUCT, 0, 51, 21, 4 } // MessageHeader
        , { ETI_TIMESTAMP_NS, 0, 8, TRDREGTSTIMEIN_FH_IDX, 0 }
        , { ETI_TIMESTAMP_NS, 0, 8, TRANSACTTIME_FH_IDX, 0 }
        , { ETI_FIXED_POINT, 4, 8, PREVDISPLAYQTY_FH_IDX, 0 }
        , { ETI_INT, 0, 8, SECURITYID_FH_IDX, 0 }
        , { ETI_STRUCT, 0, 65, 25, 5 } // OrderDetails
        , { ETI_EOF, 0, 0, 0, 0 }
        // PacketHeader@192
        , { ETI_STRUCT, 0, 51, 21, 4 } // MessageHeader
        , { ETI_UINT, 0, 4, APPLSEQNUM_FH_IDX, 0 }
        , { ETI_INT, 0, 4, MARKETSEGMENTID_FH_IDX, 0 }
        , { ETI_UINT, 0, 1, PARTITIONID_FH_IDX, 0 }
        , { ETI_UINT_ENUM, 0, 1, COMPLETIONINDICATOR_FH_IDX, 0 }
        , { ETI_UINT_ENUM, 0, 1, APPLSEQRESETINDICATOR_FH_IDX, 0 }
        , { ETI_DSCP, 0, 1, DSCP_FH_IDX, 0 }
        , { ETI_PADDING, 0, 4, 0, 0 }
        , { ETI_TIMESTAMP_NS, 0, 8, TRANSACTTIME_FH_IDX, 0 }
        , { ETI_EOF, 0, 0, 0, 0 }
        // PartialOrderExecution@202
        , { ETI_STRUCT, 0, 51, 21, 4 } // MessageHeader
        , { ETI_UINT_ENUM, 0, 1, SIDE_FH_IDX, 0 }
        , { ETI_UINT_ENUM, 0, 1, ORDTYPE_FH_IDX, 0 }
        , { ETI_UINT_ENUM, 0, 1, ALGORITHMICTRADEINDICATOR_FH_IDX, 0 }
        , { ETI_PADDING, 0, 1, 0, 0 }
        , { ETI_UINT, 0, 4, TRDMATCHID_FH_IDX, 0 }
        , { ETI_FIXED_POINT, 8, 8, PRICE_FH_IDX, 0 }
        , { ETI_TIMESTAMP_NS, 0, 8, TRDREGTSTIMEPRIORITY_FH_IDX, 0 }
        , { ETI_INT, 0, 8, SECURITYID_FH_IDX, 0 }
        , { ETI_FIXED_POINT, 4, 8, LASTQTY_FH_IDX, 0 }
        , { ETI_FIXED_POINT, 8, 8, LASTPX_FH_IDX, 0 }
        , { ETI_EOF, 0, 0, 0, 0 }
        // ProductStateChange@214
        , { ETI_STRUCT, 0, 51, 21, 4 } // MessageHeader
        , { ETI_UINT_ENUM, 0, 1, TRADINGSESSIONID_FH_IDX, 0 }
        , { ETI_UINT_ENUM, 0, 1, TRADINGSESSIONSUBID_FH_IDX, 0 }
        , { ETI_UINT_ENUM, 0, 1, TRADSESSTATUS_FH_IDX, 0 }
        , { ETI_UINT_ENUM, 0, 1, MARKETCONDITION_FH_IDX, 0 }
        , { ETI_UINT_ENUM, 0, 1, FASTMARKETINDICATOR_FH_IDX, 0 }
        , { ETI_PADDING, 0, 3, 0, 0 }
        , { ETI_TIMESTAMP_NS, 0, 8, TRANSACTTIME_FH_IDX, 0 }
        , { ETI_EOF, 0, 0, 0, 0 }
        // ProductSummary@223
        , { ETI_STRUCT, 0, 51, 21, 4 } // MessageHeader
        , { ETI_UINT, 0, 4, LASTMSGSEQNUMPROCESSED_FH_IDX, 0 }
        , { ETI_UINT_ENUM, 0, 1, TRADINGSESSIONID_FH_IDX, 0 }
        , { ETI_UINT_ENUM, 0, 1, TRADINGSESSIONSUBID_FH_IDX, 0 }
        , { ETI_UINT_ENUM, 0, 1, TRADSESSTATUS_FH_IDX, 0 }
        , { ETI_UINT_ENUM, 0, 1, MARKETCONDITION_FH_IDX, 0 }
        , { ETI_UINT_ENUM, 0, 1, FASTMARKETINDICATOR_FH_IDX, 0 }
        , { ETI_PADDING, 0, 7, 0, 0 }
        , { ETI_EOF, 0, 0, 0, 0 }
        // QuoteRequest@232
        , { ETI_STRUCT, 0, 51, 21, 4 } // MessageHeader
        , { ETI_INT, 0, 8, SECURITYID_FH_IDX, 0 }
        , { ETI_FIXED_POINT, 4, 8, LASTQTY_FH_IDX, 0 }
        , { ETI_UINT_ENUM, 0, 1, SIDE_FH_IDX, 0 }
        , { ETI_PADDING, 0, 7, 0, 0 }
        , { ETI_TIMESTAMP_NS, 0, 8, TRANSACTTIME_FH_IDX, 0 }
        , { ETI_EOF, 0, 0, 0, 0 }
        // SnapshotOrder@239
        , { ETI_STRUCT, 0, 51, 21, 4 } // MessageHeader
        , { ETI_STRUCT, 0, 65, 25, 5 } // OrderDetails
        , { ETI_EOF, 0, 0, 0, 0 }
        // TopOfBook@242
        , { ETI_STRUCT, 0, 51, 21, 4 } // MessageHeader
        , { ETI_TIMESTAMP_NS, 0, 8, TRANSACTTIME_FH_IDX, 0 }
        , { ETI_INT, 0, 8, SECURITYID_FH_IDX, 0 }
        , { ETI_FIXED_POINT, 8, 8, BIDPX_FH_IDX, 0 }
        , { ETI_FIXED_POINT, 8, 8, OFFERPX_FH_IDX, 0 }
        , { ETI_FIXED_POINT, 4, 8, BIDSIZE_FH_IDX, 0 }
        , { ETI_FIXED_POINT, 4, 8, OFFERSIZE_FH_IDX, 0 }
        , { ETI_UINT, 0, 2, NUMBEROFBUYORDERS_FH_IDX, 0 }
        , { ETI_UINT, 0, 2, NUMBEROFSELLORDERS_FH_IDX, 0 }
        , { ETI_PADDING, 0, 4, 0, 0 }
        , { ETI_EOF, 0, 0, 0, 0 }
        // TradeReport@253
        , { ETI_STRUCT, 0, 51, 21, 4 } // MessageHeader
        , { ETI_INT, 0, 8, SECURITYID_FH_IDX, 0 }
        , { ETI_TIMESTAMP_NS, 0, 8, TRANSACTTIME_FH_IDX, 0 }
        , { ETI_FIXED_POINT, 4, 8, LASTQTY_FH_IDX, 0 }
        , { ETI_FIXED_POINT, 8, 8, LASTPX_FH_IDX, 0 }
        , { ETI_UINT, 0, 4, TRDMATCHID_FH_IDX, 0 }
        , { ETI_UINT_ENUM, 0, 1, MATCHTYPE_FH_IDX, 0 }
        , { ETI_UINT_ENUM, 0, 1, MATCHSUBTYPE_FH_IDX, 0 }
        , { ETI_UINT_ENUM, 0, 1, ALGORITHMICTRADEINDICATOR_FH_IDX, 0 }
        , { ETI_PADDING, 0, 1, 0, 0 }
        , { ETI_UINT_ENUM, 0, 2, TRADECONDITION_FH_IDX, 0 }
        , { ETI_PADDING, 0, 6, 0, 0 }
        , { ETI_EOF, 0, 0, 0, 0 }
        // TradeReversal@266
        , { ETI_STRUCT, 0, 51, 21, 4 } // MessageHeader
        , { ETI_INT, 0, 8, SECURITYID_FH_IDX, 0 }
        , { ETI_TIMESTAMP_NS, 0, 8, TRANSACTTIME_FH_IDX, 0 }
        , { ETI_FIXED_POINT, 4, 8, LASTQTY_FH_IDX, 0 }
        , { ETI_FIXED_POINT, 8, 8, LASTPX_FH_IDX, 0 }
        , { ETI_TIMESTAMP_NS, 0, 8, TRDREGTSEXECUTIONTIME_FH_IDX, 0 }
        , { ETI_UINT, 0, 4, TRDMATCHID_FH_IDX, 0 }
        , { ETI_UINT_ENUM, 0, 2, TRADECONDITION_FH_IDX, 0 }
        , { ETI_PADDING, 0, 2, 0, 0 }
        , { ETI_COUNTER, 0, 1, NOMDENTRIES_FH_IDX, 15 } // <- counter@0
        , { ETI_PADDING, 0, 7, 0, 0 }
        , { ETI_VAR_STRUCT, 0, 35, 16, 3 } // MDTradeEntryGrp
        , { ETI_EOF, 0, 0, 0, 0 }
    };
    static const int16_t tid2fidx[] = {
          112 /* Heartbeat */
        , -1
        , -1
        , -1
        , 192 /* PacketHeader */
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , 162 /* OrderAdd */
        , 177 /* OrderModify */
        , 167 /* OrderDelete */
        , 173 /* OrderMassDelete */
        , 100 /* FullOrderExecution */
        , 202 /* PartialOrderExecution */
        , 185 /* OrderModifySamePrio */
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , 266 /* TradeReversal */
        , 253 /* TradeReport */
        , 86 /* ExecutionSummary */
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , 214 /* ProductStateChange */
        , 116 /* InstrumentStateChange */
        , 147 /* MassInstrumentStateChange */
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , 42 /* AddComplexInstrument */
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , 54 /* AuctionBBO */
        , 66 /* AuctionClearingPrice */
        , 76 /* CrossRequest */
        , 232 /* QuoteRequest */
        , 242 /* TopOfBook */
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , 223 /* ProductSummary */
        , 129 /* InstrumentSummary */
        , 239 /* SnapshotOrder */
    };
    static const uint32_t tid2size[] = {
          16 /* Heartbeat */
        , 0
        , 0
        , 0
        , 32 /* PacketHeader */
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 56 /* OrderAdd */
        , 80 /* OrderModify */
        , 64 /* OrderDelete */
        , 24 /* OrderMassDelete */
        , 56 /* FullOrderExecution */
        , 56 /* PartialOrderExecution */
        , 72 /* OrderModifySamePrio */
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 424 /* TradeReversal */
        , 56 /* TradeReport */
        , 80 /* ExecutionSummary */
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 24 /* ProductStateChange */
        , 48 /* InstrumentStateChange */
        , 800 /* MassInstrumentStateChange */
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 680 /* AddComplexInstrument */
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 64 /* AuctionBBO */
        , 56 /* AuctionClearingPrice */
        , 48 /* CrossRequest */
        , 40 /* QuoteRequest */
        , 64 /* TopOfBook */
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 0
        , 24 /* ProductSummary */
        , 424 /* InstrumentSummary */
        , 40 /* SnapshotOrder */
    };
    static const unsigned char usages[] = {
        // AddComplexInstrument
        //// MessageHeaderComp
          0 // BodyLen#0
        , 0 // TemplateID#1
        , 0 // MsgSeqNum#2
        ///
        , 0 // SecurityID#3
        , 0 // TransactTime#4
        , 1 // SecuritySubType#5
        , 0 // ProductComplex#6
        , 0 // ImpliedMarketIndicator#7
        , 1 // LegRatioMultiplier#8
        , 0 // NoLegs#9
        //// InstrmtLegGrpComp
        , 0 // LegSymbol#10
        , 0 // LegSecurityID#11
        , 1 // LegPrice#12
        , 0 // LegRatioQty#13
        , 0 // LegSecurityType#14
        , 0 // LegSide#15
        ///
        // AuctionBBO
        //// MessageHeaderComp
        , 0 // BodyLen#16
        , 0 // TemplateID#17
        , 0 // MsgSeqNum#18
        ///
        , 0 // TransactTime#19
        , 0 // SecurityID#20
        , 1 // BidPx#21
        , 1 // OfferPx#22
        , 1 // BidSize#23
        , 1 // OfferSize#24
        , 1 // PotentialSecurityTradingEvent#25
        , 1 // BidOrdType#26
        , 1 // OfferOrdType#27
        // AuctionClearingPrice
        //// MessageHeaderComp
        , 0 // BodyLen#28
        , 0 // TemplateID#29
        , 0 // MsgSeqNum#30
        ///
        , 0 // TransactTime#31
        , 0 // SecurityID#32
        , 0 // LastPx#33
        , 1 // LastQty#34
        , 1 // ImbalanceQty#35
        , 1 // SecurityTradingStatus#36
        , 1 // PotentialSecurityTradingEvent#37
        // CrossRequest
        //// MessageHeaderComp
        , 0 // BodyLen#38
        , 0 // TemplateID#39
        , 0 // MsgSeqNum#40
        ///
        , 0 // SecurityID#41
        , 1 // LastPx#42
        , 1 // LastQty#43
        , 1 // Side#44
        , 0 // CrossRequestType#45
        , 1 // InputSource#46
        , 0 // TransactTime#47
        // ExecutionSummary
        //// MessageHeaderComp
        , 0 // BodyLen#48
        , 0 // TemplateID#49
        , 0 // MsgSeqNum#50
        ///
        , 0 // SecurityID#51
        , 1 // AggressorTime#52
        , 1 // RequestTime#53
        , 0 // ExecID#54
        , 0 // LastQty#55
        , 0 // AggressorSide#56
        , 1 // TradeCondition#57
        , 0 // LastPx#58
        , 1 // RestingHiddenQty#59
        , 0 // RestingCxlQty#60
        // FullOrderExecution
        //// MessageHeaderComp
        , 0 // BodyLen#61
        , 0 // TemplateID#62
        , 0 // MsgSeqNum#63
        ///
        , 0 // Side#64
        , 1 // OrdType#65
        , 1 // AlgorithmicTradeIndicator#66
        , 0 // TrdMatchID#67
        , 1 // Price#68
        , 0 // TrdRegTSTimePriority#69
        , 0 // SecurityID#70
        , 0 // LastQty#71
        , 0 // LastPx#72
        // Heartbeat
        //// MessageHeaderComp
        , 0 // BodyLen#73
        , 0 // TemplateID#74
        , 2 // MsgSeqNum#75
        ///
        , 0 // LastMsgSeqNumProcessed#76
        // InstrumentStateChange
        //// MessageHeaderComp
        , 0 // BodyLen#77
        , 0 // TemplateID#78
        , 0 // MsgSeqNum#79
        ///
        , 0 // SecurityID#80
        , 0 // SecurityStatus#81
        , 0 // SecurityTradingStatus#82
        , 0 // MarketCondition#83
        , 0 // FastMarketIndicator#84
        , 1 // SecurityTradingEvent#85
        , 1 // SoldOutIndicator#86
        , 1 // HighPx#87
        , 1 // LowPx#88
        , 0 // TransactTime#89
        // InstrumentSummary
        //// MessageHeaderComp
        , 0 // BodyLen#90
        , 0 // TemplateID#91
        , 0 // MsgSeqNum#92
        ///
        , 0 // SecurityID#93
        , 0 // LastUpdateTime#94
        , 1 // TrdRegTSExecutionTime#95
        , 0 // TotNoOrders#96
        , 0 // SecurityStatus#97
        , 0 // SecurityTradingStatus#98
        , 0 // MarketCondition#99
        , 0 // FastMarketIndicator#100
        , 1 // SecurityTradingEvent#101
        , 1 // SoldOutIndicator#102
        , 1 // HighPx#103
        , 1 // LowPx#104
        , 0 // ProductComplex#105
        , 0 // NoMDEntries#106
        //// MDInstrumentEntryGrpComp
        , 1 // MDEntryPx#107
        , 1 // MDEntrySize#108
        , 0 // MDEntryType#109
        , 1 // TradeCondition#110
        ///
        // MassInstrumentStateChange
        //// MessageHeaderComp
        , 0 // BodyLen#111
        , 0 // TemplateID#112
        , 0 // MsgSeqNum#113
        ///
        , 0 // InstrumentScopeProductComplex#114
        , 0 // SecurityMassStatus#115
        , 0 // SecurityMassTradingStatus#116
        , 0 // MassMarketCondition#117
        , 0 // FastMarketIndicator#118
        , 1 // SecurityMassTradingEvent#119
        , 1 // MassSoldOutIndicator#120
        , 0 // TransactTime#121
        , 0 // LastFragment#122
        , 0 // NoRelatedSym#123
        //// SecMassStatGrpComp
        , 0 // SecurityID#124
        , 1 // HighPx#125
        , 1 // LowPx#126
        , 0 // SecurityStatus#127
        , 0 // SecurityTradingStatus#128
        , 0 // MarketCondition#129
        , 1 // SecurityTradingEvent#130
        , 1 // SoldOutIndicator#131
        ///
        // OrderAdd
        //// MessageHeaderComp
        , 0 // BodyLen#132
        , 0 // TemplateID#133
        , 0 // MsgSeqNum#134
        ///
        , 1 // TrdRegTSTimeIn#135
        , 0 // SecurityID#136
        //// OrderDetailsComp
        , 0 // TrdRegTSTimePriority#137
        , 0 // DisplayQty#138
        , 0 // Side#139
        , 1 // OrdType#140
        , 1 // Price#141
        ///
        // OrderDelete
        //// MessageHeaderComp
        , 0 // BodyLen#142
        , 0 // TemplateID#143
        , 0 // MsgSeqNum#144
        ///
        , 1 // TrdRegTSTimeIn#145
        , 0 // TransactTime#146
        , 0 // SecurityID#147
        //// OrderDetailsComp
        , 0 // TrdRegTSTimePriority#148
        , 0 // DisplayQty#149
        , 0 // Side#150
        , 1 // OrdType#151
        , 1 // Price#152
        ///
        // OrderMassDelete
        //// MessageHeaderComp
        , 0 // BodyLen#153
        , 0 // TemplateID#154
        , 0 // MsgSeqNum#155
        ///
        , 0 // SecurityID#156
        , 0 // TransactTime#157
        // OrderModify
        //// MessageHeaderComp
        , 0 // BodyLen#158
        , 0 // TemplateID#159
        , 0 // MsgSeqNum#160
        ///
        , 0 // TrdRegTSTimeIn#161
        , 0 // TrdRegTSPrevTimePriority#162
        , 1 // PrevPrice#163
        , 0 // PrevDisplayQty#164
        , 0 // SecurityID#165
        //// OrderDetailsComp
        , 0 // TrdRegTSTimePriority#166
        , 0 // DisplayQty#167
        , 0 // Side#168
        , 1 // OrdType#169
        , 1 // Price#170
        ///
        // OrderModifySamePrio
        //// MessageHeaderComp
        , 0 // BodyLen#171
        , 0 // TemplateID#172
        , 0 // MsgSeqNum#173
        ///
        , 0 // TrdRegTSTimeIn#174
        , 0 // TransactTime#175
        , 0 // PrevDisplayQty#176
        , 0 // SecurityID#177
        //// OrderDetailsComp
        , 0 // TrdRegTSTimePriority#178
        , 0 // DisplayQty#179
        , 0 // Side#180
        , 1 // OrdType#181
        , 1 // Price#182
        ///
        // PacketHeader
        //// MessageHeaderComp
        , 0 // BodyLen#183
        , 0 // TemplateID#184
        , 2 // MsgSeqNum#185
        ///
        , 0 // ApplSeqNum#186
        , 0 // MarketSegmentID#187
        , 0 // PartitionID#188
        , 0 // CompletionIndicator#189
        , 0 // ApplSeqResetIndicator#190
        , 1 // DSCP#191
        , 0 // TransactTime#192
        // PartialOrderExecution
        //// MessageHeaderComp
        , 0 // BodyLen#193
        , 0 // TemplateID#194
        , 0 // MsgSeqNum#195
        ///
        , 0 // Side#196
        , 1 // OrdType#197
        , 1 // AlgorithmicTradeIndicator#198
        , 0 // TrdMatchID#199
        , 1 // Price#200
        , 0 // TrdRegTSTimePriority#201
        , 0 // SecurityID#202
        , 0 // LastQty#203
        , 0 // LastPx#204
        // ProductStateChange
        //// MessageHeaderComp
        , 0 // BodyLen#205
        , 0 // TemplateID#206
        , 0 // MsgSeqNum#207
        ///
        , 0 // TradingSessionID#208
        , 0 // TradingSessionSubID#209
        , 0 // TradSesStatus#210
        , 1 // MarketCondition#211
        , 0 // FastMarketIndicator#212
        , 0 // TransactTime#213
        // ProductSummary
        //// MessageHeaderComp
        , 0 // BodyLen#214
        , 0 // TemplateID#215
        , 0 // MsgSeqNum#216
        ///
        , 0 // LastMsgSeqNumProcessed#217
        , 1 // TradingSessionID#218
        , 1 // TradingSessionSubID#219
        , 1 // TradSesStatus#220
        , 1 // MarketCondition#221
        , 0 // FastMarketIndicator#222
        // QuoteRequest
        //// MessageHeaderComp
        , 0 // BodyLen#223
        , 0 // TemplateID#224
        , 0 // MsgSeqNum#225
        ///
        , 0 // SecurityID#226
        , 1 // LastQty#227
        , 1 // Side#228
        , 0 // TransactTime#229
        // SnapshotOrder
        //// MessageHeaderComp
        , 0 // BodyLen#230
        , 0 // TemplateID#231
        , 0 // MsgSeqNum#232
        ///
        //// OrderDetailsComp
        , 0 // TrdRegTSTimePriority#233
        , 0 // DisplayQty#234
        , 0 // Side#235
        , 1 // OrdType#236
        , 1 // Price#237
        ///
        // TopOfBook
        //// MessageHeaderComp
        , 0 // BodyLen#238
        , 0 // TemplateID#239
        , 0 // MsgSeqNum#240
        ///
        , 0 // TransactTime#241
        , 0 // SecurityID#242
        , 1 // BidPx#243
        , 1 // OfferPx#244
        , 1 // BidSize#245
        , 1 // OfferSize#246
        , 1 // NumberOfBuyOrders#247
        , 1 // NumberOfSellOrders#248
        // TradeReport
        //// MessageHeaderComp
        , 0 // BodyLen#249
        , 0 // TemplateID#250
        , 0 // MsgSeqNum#251
        ///
        , 0 // SecurityID#252
        , 0 // TransactTime#253
        , 0 // LastQty#254
        , 0 // LastPx#255
        , 1 // TrdMatchID#256
        , 1 // MatchType#257
        , 1 // MatchSubType#258
        , 1 // AlgorithmicTradeIndicator#259
        , 1 // TradeCondition#260
        // TradeReversal
        //// MessageHeaderComp
        , 0 // BodyLen#261
        , 0 // TemplateID#262
        , 0 // MsgSeqNum#263
        ///
        , 0 // SecurityID#264
        , 0 // TransactTime#265
        , 0 // LastQty#266
        , 0 // LastPx#267
        , 1 // TrdRegTSExecutionTime#268
        , 0 // TrdMatchID#269
        , 1 // TradeCondition#270
        , 0 // NoMDEntries#271
        //// MDTradeEntryGrpComp
        , 1 // MDEntryPx#272
        , 1 // MDEntrySize#273
        , 0 // MDEntryType#274
        ///
        , 0 // filler
    };
    static const int16_t tid2uidx[] = {
        73 /* Heartbeat */
        , -1
        , -1
        , -1
        , 183 /* PacketHeader */
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , 132 /* OrderAdd */
        , 158 /* OrderModify */
        , 142 /* OrderDelete */
        , 153 /* OrderMassDelete */
        , 61 /* FullOrderExecution */
        , 193 /* PartialOrderExecution */
        , 171 /* OrderModifySamePrio */
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , 261 /* TradeReversal */
        , 249 /* TradeReport */
        , 48 /* ExecutionSummary */
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , 205 /* ProductStateChange */
        , 77 /* InstrumentStateChange */
        , 111 /* MassInstrumentStateChange */
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , 0 /* AddComplexInstrument */
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , 16 /* AuctionBBO */
        , 28 /* AuctionClearingPrice */
        , 38 /* CrossRequest */
        , 223 /* QuoteRequest */
        , 238 /* TopOfBook */
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , -1
        , 214 /* ProductSummary */
        , 90 /* InstrumentSummary */
        , 230 /* SnapshotOrder */
    };
    static int * const dscp_bits[] = {
        &hf_eobi_dscp_exec_summary,
        &hf_eobi_dscp_improved,
        &hf_eobi_dscp_widened,
        NULL
    };
    if (templateid < 13001 || templateid > 13602) {
        proto_tree_add_expert_format(root, pinfo, &ei_eobi_invalid_template, tvb, 2, 4,
            "Template ID out of range: %" PRIu16, templateid);
        return tvb_captured_length(tvb);
    }
    int fidx = tid2fidx[templateid - 13001];
    if (fidx == -1) {
        proto_tree_add_expert_format(root, pinfo, &ei_eobi_invalid_template, tvb, 2, 4,
            "Unallocated Template ID: %" PRIu16, templateid);
        return tvb_captured_length(tvb);
    }
    if (bodylen != tid2size[templateid - 13001]) {
        proto_tree_add_expert_format(root, pinfo, &ei_eobi_invalid_length, tvb, 0, 2,
                "Unexpected BodyLen value of %" PRIu32 ", expected:  %" PRIu32, bodylen, tid2size[templateid - 13001]);
    }
    int uidx = tid2uidx[templateid - 13001];
    DISSECTOR_ASSERT_CMPINT(uidx, >=, 0);
    DISSECTOR_ASSERT_CMPUINT(((size_t)uidx), <, (sizeof usages / sizeof usages[0]));

    int old_fidx = 0;
    int old_uidx = 0;
    unsigned top = 1;
    unsigned counter[8] = {0};
    unsigned off = 0;
    unsigned struct_off = 0;
    unsigned repeats = 0;
    proto_tree *t = root;
    while (top) {
        DISSECTOR_ASSERT_CMPINT(fidx, >=, 0);
        DISSECTOR_ASSERT_CMPUINT(((size_t)fidx), <, (sizeof fields / sizeof fields[0]));
        DISSECTOR_ASSERT_CMPINT(uidx, >=, 0);
        DISSECTOR_ASSERT_CMPUINT(((size_t)uidx), <, (sizeof usages / sizeof usages[0]));

        switch (fields[fidx].type) {
            case ETI_EOF:
                DISSECTOR_ASSERT_CMPUINT(top, >=, 1);
                DISSECTOR_ASSERT_CMPUINT(top, <=, 2);
                if (t != root)
                    proto_item_set_len(t, off - struct_off);
                if (repeats) {
                    --repeats;
                    fidx = fields[old_fidx].field_handle_idx;
                    uidx = old_uidx;
                    t = proto_tree_add_subtree(root, tvb, off, -1, ett_eobi[fields[old_fidx].ett_idx], NULL, &struct_names[fields[old_fidx].size]);
                    struct_off = off;
                } else {
                    fidx = old_fidx + 1;
                    t = root;
                    --top;
                }
                break;
            case ETI_VAR_STRUCT:
            case ETI_STRUCT:
                DISSECTOR_ASSERT_CMPUINT(fields[fidx].counter_off, <, sizeof counter / sizeof counter[0]);
                repeats = fields[fidx].type == ETI_VAR_STRUCT ? counter[fields[fidx].counter_off] : 1;
                if (repeats) {
                    --repeats;
                    t = proto_tree_add_subtree(root, tvb, off, -1, ett_eobi[fields[fidx].ett_idx], NULL, &struct_names[fields[fidx].size]);
                    struct_off = off;
                    old_fidx = fidx;
                    old_uidx = uidx;
                    fidx = fields[fidx].field_handle_idx;
                    DISSECTOR_ASSERT_CMPUINT(top, ==, 1);
                    ++top;
                } else {
                    ++fidx;
                }
                break;
            case ETI_PADDING:
                off += fields[fidx].size;
                ++fidx;
                break;
            case ETI_CHAR:
                proto_tree_add_item(t, hf_eobi[fields[fidx].field_handle_idx], tvb, off, fields[fidx].size, ENC_ASCII);
                off += fields[fidx].size;
                ++fidx;
                ++uidx;
                break;
            case ETI_STRING:
                {
                    guint8 c = tvb_get_guint8(tvb, off);
                    if (c)
                        proto_tree_add_item(t, hf_eobi[fields[fidx].field_handle_idx], tvb, off, fields[fidx].size, ENC_ASCII);
                    else {
                        proto_item *e = proto_tree_add_string(t, hf_eobi[fields[fidx].field_handle_idx], tvb, off, fields[fidx].size, "NO_VALUE ('0x00...')");
                        if (!usages[uidx])
                            expert_add_info_format(pinfo, e, &ei_eobi_missing, "required value is missing");
                    }
                }
                off += fields[fidx].size;
                ++fidx;
                ++uidx;
                break;
            case ETI_VAR_STRING:
                DISSECTOR_ASSERT_CMPUINT(fields[fidx].counter_off, <, sizeof counter / sizeof counter[0]);
                proto_tree_add_item(t, hf_eobi[fields[fidx].field_handle_idx], tvb, off, counter[fields[fidx].counter_off], ENC_ASCII);
                off += counter[fields[fidx].counter_off];
                ++fidx;
                ++uidx;
                break;
            case ETI_COUNTER:
                DISSECTOR_ASSERT_CMPUINT(fields[fidx].counter_off, <, sizeof counter / sizeof counter[0]);
                DISSECTOR_ASSERT_CMPUINT(fields[fidx].size, <=, 2);
                {
                    switch (fields[fidx].size) {
                        case 1:
                            {
                                guint8 x = tvb_get_guint8(tvb, off);
                                if (x == UINT8_MAX) {
                                    proto_tree_add_uint_format_value(t, hf_eobi[fields[fidx].field_handle_idx], tvb, off, fields[fidx].size, x, "NO_VALUE (0xff)");
                                    counter[fields[fidx].counter_off] = 0;
                                } else {
                                    proto_item *e = proto_tree_add_uint_format_value(t, hf_eobi[fields[fidx].field_handle_idx], tvb, off, fields[fidx].size, x, "%" PRIu8, x);
                                    if (x > fields[fidx].ett_idx) {
                                        counter[fields[fidx].counter_off] = fields[fidx].ett_idx;
                                        expert_add_info_format(pinfo, e, &ei_eobi_counter_overflow, "Counter overflow: %" PRIu8 " > %" PRIu16, x, fields[fidx].ett_idx);
                                    } else {
                                        counter[fields[fidx].counter_off] = x;
                                    }
                                }
                            }
                            break;
                        case 2:
                            {
                                guint16 x = tvb_get_letohs(tvb, off);
                                if (x == UINT16_MAX) {
                                    proto_tree_add_uint_format_value(t, hf_eobi[fields[fidx].field_handle_idx], tvb, off, fields[fidx].size, x, "NO_VALUE (0xffff)");
                                    counter[fields[fidx].counter_off] = 0;
                                } else {
                                    proto_item *e = proto_tree_add_uint_format_value(t, hf_eobi[fields[fidx].field_handle_idx], tvb, off, fields[fidx].size, x, "%" PRIu16, x);
                                    if (x > fields[fidx].ett_idx) {
                                        counter[fields[fidx].counter_off] = fields[fidx].ett_idx;
                                        expert_add_info_format(pinfo, e, &ei_eobi_counter_overflow, "Counter overflow: %" PRIu16 " > %" PRIu16, x, fields[fidx].ett_idx);
                                    } else {
                                        counter[fields[fidx].counter_off] = x;
                                    }
                                }
                            }
                            break;
                    }
                }
                off += fields[fidx].size;
                ++fidx;
                ++uidx;
                break;
            case ETI_UINT:
                switch (fields[fidx].size) {
                    case 1:
                        {
                            guint8 x = tvb_get_guint8(tvb, off);
                            if (x == UINT8_MAX) {
                                proto_item *e = proto_tree_add_uint_format_value(t, hf_eobi[fields[fidx].field_handle_idx], tvb, off, fields[fidx].size, x, "NO_VALUE (0xff)");
                                if (!usages[uidx])
                                    expert_add_info_format(pinfo, e, &ei_eobi_missing, "required value is missing");
                            } else {
                                proto_item *e = proto_tree_add_uint_format_value(t, hf_eobi[fields[fidx].field_handle_idx], tvb, off, fields[fidx].size, x, "%" PRIu8, x);
                                if (usages[uidx] == 2)
                                    expert_add_info_format(pinfo, e, &ei_eobi_overused, "unused value is set");
                            }
                        }
                        break;
                    case 2:
                        {
                            guint16 x = tvb_get_letohs(tvb, off);
                            if (x == UINT16_MAX) {
                                proto_item *e = proto_tree_add_uint_format_value(t, hf_eobi[fields[fidx].field_handle_idx], tvb, off, fields[fidx].size, x, "NO_VALUE (0xffff)");
                                if (!usages[uidx])
                                    expert_add_info_format(pinfo, e, &ei_eobi_missing, "required value is missing");
                            } else {
                                proto_item *e = proto_tree_add_uint_format_value(t, hf_eobi[fields[fidx].field_handle_idx], tvb, off, fields[fidx].size, x, "%" PRIu16, x);
                                if (usages[uidx] == 2)
                                    expert_add_info_format(pinfo, e, &ei_eobi_overused, "unused value is set");
                            }
                        }
                        break;
                    case 4:
                        {
                            guint32 x = tvb_get_letohl(tvb, off);
                            if (x == UINT32_MAX) {
                                proto_item *e = proto_tree_add_uint_format_value(t, hf_eobi[fields[fidx].field_handle_idx], tvb, off, fields[fidx].size, x, "NO_VALUE (0xffffffff)");
                                if (!usages[uidx])
                                    expert_add_info_format(pinfo, e, &ei_eobi_missing, "required value is missing");
                            } else {
                                proto_item *e = proto_tree_add_uint_format_value(t, hf_eobi[fields[fidx].field_handle_idx], tvb, off, fields[fidx].size, x, "%" PRIu32, x);
                                if (usages[uidx] == 2)
                                    expert_add_info_format(pinfo, e, &ei_eobi_overused, "unused value is set");
                            }
                        }
                        break;
                    case 8:
                        {
                            guint64 x = tvb_get_letoh64(tvb, off);
                            if (x == UINT64_MAX) {
                                proto_item *e = proto_tree_add_uint64_format_value(t, hf_eobi[fields[fidx].field_handle_idx], tvb, off, fields[fidx].size, x, "NO_VALUE (0xffffffffffffffff)");
                                if (!usages[uidx])
                                    expert_add_info_format(pinfo, e, &ei_eobi_missing, "required value is missing");
                            } else {
                                proto_item *e = proto_tree_add_uint64_format_value(t, hf_eobi[fields[fidx].field_handle_idx], tvb, off, fields[fidx].size, x, "%" PRIu64, x);
                                if (usages[uidx] == 2)
                                    expert_add_info_format(pinfo, e, &ei_eobi_overused, "unused value is set");
                            }
                        }
                        break;
                }
                off += fields[fidx].size;
                ++fidx;
                ++uidx;
                break;
            case ETI_INT:
                switch (fields[fidx].size) {
                    case 1:
                        {
                            gint8 x = tvb_get_gint8(tvb, off);
                            if (x == INT8_MIN) {
                                proto_item *e = proto_tree_add_int_format_value(t, hf_eobi[fields[fidx].field_handle_idx], tvb, off, fields[fidx].size, x, "NO_VALUE (0x80)");
                                if (!usages[uidx])
                                    expert_add_info_format(pinfo, e, &ei_eobi_missing, "required value is missing");
                            } else {
                                proto_item *e = proto_tree_add_int_format_value(t, hf_eobi[fields[fidx].field_handle_idx], tvb, off, fields[fidx].size, x, "%" PRIi8, x);
                                if (usages[uidx] == 2)
                                    expert_add_info_format(pinfo, e, &ei_eobi_overused, "unused value is set");
                            }
                        }
                        break;
                    case 2:
                        {
                            gint16 x = tvb_get_letohis(tvb, off);
                            if (x == INT16_MIN) {
                                proto_item *e = proto_tree_add_int_format_value(t, hf_eobi[fields[fidx].field_handle_idx], tvb, off, fields[fidx].size, x, "NO_VALUE (0x8000)");
                                if (!usages[uidx])
                                    expert_add_info_format(pinfo, e, &ei_eobi_missing, "required value is missing");
                            } else {
                                proto_item *e = proto_tree_add_int_format_value(t, hf_eobi[fields[fidx].field_handle_idx], tvb, off, fields[fidx].size, x, "%" PRIi16, x);
                                if (usages[uidx] == 2)
                                    expert_add_info_format(pinfo, e, &ei_eobi_overused, "unused value is set");
                            }
                        }
                        break;
                    case 4:
                        {
                            gint32 x = tvb_get_letohil(tvb, off);
                            if (x == INT32_MIN) {
                                proto_item *e = proto_tree_add_int_format_value(t, hf_eobi[fields[fidx].field_handle_idx], tvb, off, fields[fidx].size, x, "NO_VALUE (0x80000000)");
                                if (!usages[uidx])
                                    expert_add_info_format(pinfo, e, &ei_eobi_missing, "required value is missing");
                            } else {
                                proto_item *e = proto_tree_add_int_format_value(t, hf_eobi[fields[fidx].field_handle_idx], tvb, off, fields[fidx].size, x, "%" PRIi32, x);
                                if (usages[uidx] == 2)
                                    expert_add_info_format(pinfo, e, &ei_eobi_overused, "unused value is set");
                            }
                        }
                        break;
                    case 8:
                        {
                            gint64 x = tvb_get_letohi64(tvb, off);
                            if (x == INT64_MIN) {
                                proto_item *e = proto_tree_add_int64_format_value(t, hf_eobi[fields[fidx].field_handle_idx], tvb, off, fields[fidx].size, x, "NO_VALUE (0x8000000000000000)");
                                if (!usages[uidx])
                                    expert_add_info_format(pinfo, e, &ei_eobi_missing, "required value is missing");
                            } else {
                                proto_item *e = proto_tree_add_int64_format_value(t, hf_eobi[fields[fidx].field_handle_idx], tvb, off, fields[fidx].size, x, "%" PRIi64, x);
                                if (usages[uidx] == 2)
                                    expert_add_info_format(pinfo, e, &ei_eobi_overused, "unused value is set");
                            }
                        }
                        break;
                }
                off += fields[fidx].size;
                ++fidx;
                ++uidx;
                break;
            case ETI_UINT_ENUM:
            case ETI_INT_ENUM:
                proto_tree_add_item(t, hf_eobi[fields[fidx].field_handle_idx], tvb, off, fields[fidx].size, ENC_LITTLE_ENDIAN);
                off += fields[fidx].size;
                ++fidx;
                ++uidx;
                break;
            case ETI_FIXED_POINT:
                DISSECTOR_ASSERT_CMPUINT(fields[fidx].size, ==, 8);
                DISSECTOR_ASSERT_CMPUINT(fields[fidx].counter_off, >, 0);
                DISSECTOR_ASSERT_CMPUINT(fields[fidx].counter_off, <=, 16);
                {
                    gint64 x = tvb_get_letohi64(tvb, off);
                    if (x == INT64_MIN) {
                        proto_item *e = proto_tree_add_int64_format_value(t, hf_eobi[fields[fidx].field_handle_idx], tvb, off, fields[fidx].size, x, "NO_VALUE (0x8000000000000000)");
                        if (!usages[uidx])
                            expert_add_info_format(pinfo, e, &ei_eobi_missing, "required value is missing");
                    } else {
                        unsigned slack = fields[fidx].counter_off + 1;
                        if (x < 0)
                            slack += 1;
                        char s[21];
                        int n = snprintf(s, sizeof s, "%0*" PRIi64, slack, x);
                        DISSECTOR_ASSERT_CMPUINT(n, >, 0);
                        unsigned k = n - fields[fidx].counter_off;
                        proto_tree_add_int64_format_value(t, hf_eobi[fields[fidx].field_handle_idx], tvb, off, fields[fidx].size, x, "%.*s.%s", k, s, s + k);
                    }
                }
                off += fields[fidx].size;
                ++fidx;
                ++uidx;
                break;
            case ETI_TIMESTAMP_NS:
                DISSECTOR_ASSERT_CMPUINT(fields[fidx].size, ==, 8);
                proto_tree_add_item(t, hf_eobi[fields[fidx].field_handle_idx], tvb, off, fields[fidx].size, ENC_LITTLE_ENDIAN | ENC_TIME_NSECS);
                off += fields[fidx].size;
                ++fidx;
                ++uidx;
                break;
            case ETI_DSCP:
                DISSECTOR_ASSERT_CMPUINT(fields[fidx].size, ==, 1);
                proto_tree_add_bitmask(t, tvb, off, hf_eobi[fields[fidx].field_handle_idx], ett_eobi_dscp, dscp_bits, ENC_LITTLE_ENDIAN);
                off += fields[fidx].size;
                ++fidx;
                ++uidx;
                break;
        }
    }

    return tvb_captured_length(tvb);
}

/* determine PDU length of protocol EOBI */
static guint
get_eobi_message_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset, void *data _U_)
{
    return (guint)tvb_get_letohs(tvb, offset);
}

static int
dissect_eobi(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        void *data)
{
    return udp_dissect_pdus(tvb, pinfo, tree, 4, NULL,
            get_eobi_message_len, dissect_eobi_message, data);
}

void
proto_register_eobi(void)
{
    static hf_register_info hf[] ={
          { &hf_eobi[AGGRESSORSIDE_FH_IDX],
              { "AggressorSide", "eobi.aggressorside",
                FT_UINT8, BASE_DEC, VALS(aggressor_side_vals), 0x0,
                NULL, HFILL }
          }
        , { &hf_eobi[AGGRESSORTIME_FH_IDX],
              { "AggressorTime", "eobi.aggressortime",
                FT_ABSOLUTE_TIME, ABSOLUTE_TIME_UTC, NULL, 0x0,
                NULL, HFILL }
          }
        , { &hf_eobi[ALGORITHMICTRADEINDICATOR_FH_IDX],
              { "AlgorithmicTradeIndicator", "eobi.algorithmictradeindicator",
                FT_UINT8, BASE_DEC, VALS(algorithmic_trade_indicator_vals), 0x0,
                NULL, HFILL }
          }
        , { &hf_eobi[APPLSEQNUM_FH_IDX],
              { "ApplSeqNum", "eobi.applseqnum",
                FT_UINT32, BASE_DEC, NULL, 0x0,
                NULL, HFILL }
          }
        , { &hf_eobi[APPLSEQRESETINDICATOR_FH_IDX],
              { "ApplSeqResetIndicator", "eobi.applseqresetindicator",
                FT_UINT8, BASE_DEC, VALS(appl_seq_reset_indicator_vals), 0x0,
                NULL, HFILL }
          }
        , { &hf_eobi[BIDORDTYPE_FH_IDX],
              { "BidOrdType", "eobi.bidordtype",
                FT_UINT8, BASE_DEC, VALS(bid_ord_type_vals), 0x0,
                NULL, HFILL }
          }
        , { &hf_eobi[BIDPX_FH_IDX],
              { "BidPx", "eobi.bidpx",
                FT_INT64, BASE_DEC, NULL, 0x0,
                NULL, HFILL }
          }
        , { &hf_eobi[BIDSIZE_FH_IDX],
              { "BidSize", "eobi.bidsize",
                FT_INT64, BASE_DEC, NULL, 0x0,
                NULL, HFILL }
          }
        , { &hf_eobi[BODYLEN_FH_IDX],
              { "BodyLen", "eobi.bodylen",
                FT_UINT16, BASE_DEC, NULL, 0x0,
                NULL, HFILL }
          }
        , { &hf_eobi[COMPLETIONINDICATOR_FH_IDX],
              { "CompletionIndicator", "eobi.completionindicator",
                FT_UINT8, BASE_DEC, VALS(completion_indicator_vals), 0x0,
                NULL, HFILL }
          }
        , { &hf_eobi[CROSSREQUESTTYPE_FH_IDX],
              { "CrossRequestType", "eobi.crossrequesttype",
                FT_UINT8, BASE_DEC, VALS(cross_request_type_vals), 0x0,
                NULL, HFILL }
          }
        , { &hf_eobi[DSCP_FH_IDX],
              { "DSCP", "eobi.dscp",
                FT_UINT8, BASE_HEX, NULL, 0x0,
                NULL, HFILL }
          }
        , { &hf_eobi[DISPLAYQTY_FH_IDX],
              { "DisplayQty", "eobi.displayqty",
                FT_INT64, BASE_DEC, NULL, 0x0,
                NULL, HFILL }
          }
        , { &hf_eobi[EXECID_FH_IDX],
              { "ExecID", "eobi.execid",
                FT_ABSOLUTE_TIME, ABSOLUTE_TIME_UTC, NULL, 0x0,
                NULL, HFILL }
          }
        , { &hf_eobi[FASTMARKETINDICATOR_FH_IDX],
              { "FastMarketIndicator", "eobi.fastmarketindicator",
                FT_UINT8, BASE_DEC, VALS(fast_market_indicator_vals), 0x0,
                NULL, HFILL }
          }
        , { &hf_eobi[HIGHPX_FH_IDX],
              { "HighPx", "eobi.highpx",
                FT_INT64, BASE_DEC, NULL, 0x0,
                NULL, HFILL }
          }
        , { &hf_eobi[IMBALANCEQTY_FH_IDX],
              { "ImbalanceQty", "eobi.imbalanceqty",
                FT_INT64, BASE_DEC, NULL, 0x0,
                NULL, HFILL }
          }
        , { &hf_eobi[IMPLIEDMARKETINDICATOR_FH_IDX],
              { "ImpliedMarketIndicator", "eobi.impliedmarketindicator",
                FT_UINT8, BASE_DEC, VALS(implied_market_indicator_vals), 0x0,
                NULL, HFILL }
          }
        , { &hf_eobi[INPUTSOURCE_FH_IDX],
              { "InputSource", "eobi.inputsource",
                FT_UINT8, BASE_DEC, VALS(input_source_vals), 0x0,
                NULL, HFILL }
          }
        , { &hf_eobi[INSTRUMENTSCOPEPRODUCTCOMPLEX_FH_IDX],
              { "InstrumentScopeProductComplex", "eobi.instrumentscopeproductcomplex",
                FT_UINT8, BASE_DEC| BASE_EXT_STRING, &instrument_scope_product_complex_vals_ext, 0x0,
                NULL, HFILL }
          }
        , { &hf_eobi[LASTFRAGMENT_FH_IDX],
              { "LastFragment", "eobi.lastfragment",
                FT_UINT8, BASE_DEC, VALS(last_fragment_vals), 0x0,
                NULL, HFILL }
          }
        , { &hf_eobi[LASTMSGSEQNUMPROCESSED_FH_IDX],
              { "LastMsgSeqNumProcessed", "eobi.lastmsgseqnumprocessed",
                FT_UINT32, BASE_DEC, NULL, 0x0,
                NULL, HFILL }
          }
        , { &hf_eobi[LASTPX_FH_IDX],
              { "LastPx", "eobi.lastpx",
                FT_INT64, BASE_DEC, NULL, 0x0,
                NULL, HFILL }
          }
        , { &hf_eobi[LASTQTY_FH_IDX],
              { "LastQty", "eobi.lastqty",
                FT_INT64, BASE_DEC, NULL, 0x0,
                NULL, HFILL }
          }
        , { &hf_eobi[LASTUPDATETIME_FH_IDX],
              { "LastUpdateTime", "eobi.lastupdatetime",
                FT_ABSOLUTE_TIME, ABSOLUTE_TIME_UTC, NULL, 0x0,
                NULL, HFILL }
          }
        , { &hf_eobi[LEGPRICE_FH_IDX],
              { "LegPrice", "eobi.legprice",
                FT_INT64, BASE_DEC, NULL, 0x0,
                NULL, HFILL }
          }
        , { &hf_eobi[LEGRATIOMULTIPLIER_FH_IDX],
              { "LegRatioMultiplier", "eobi.legratiomultiplier",
                FT_UINT32, BASE_DEC, NULL, 0x0,
                NULL, HFILL }
          }
        , { &hf_eobi[LEGRATIOQTY_FH_IDX],
              { "LegRatioQty", "eobi.legratioqty",
                FT_INT32, BASE_DEC, NULL, 0x0,
                NULL, HFILL }
          }
        , { &hf_eobi[LEGSECURITYID_FH_IDX],
              { "LegSecurityID", "eobi.legsecurityid",
                FT_INT64, BASE_DEC, NULL, 0x0,
                NULL, HFILL }
          }
        , { &hf_eobi[LEGSECURITYTYPE_FH_IDX],
              { "LegSecurityType", "eobi.legsecuritytype",
                FT_UINT8, BASE_DEC, VALS(leg_security_type_vals), 0x0,
                NULL, HFILL }
          }
        , { &hf_eobi[LEGSIDE_FH_IDX],
              { "LegSide", "eobi.legside",
                FT_UINT8, BASE_DEC, VALS(aggressor_side_vals), 0x0,
                NULL, HFILL }
          }
        , { &hf_eobi[LEGSYMBOL_FH_IDX],
              { "LegSymbol", "eobi.legsymbol",
                FT_INT32, BASE_DEC, NULL, 0x0,
                NULL, HFILL }
          }
        , { &hf_eobi[LOWPX_FH_IDX],
              { "LowPx", "eobi.lowpx",
                FT_INT64, BASE_DEC, NULL, 0x0,
                NULL, HFILL }
          }
        , { &hf_eobi[MDENTRYPX_FH_IDX],
              { "MDEntryPx", "eobi.mdentrypx",
                FT_INT64, BASE_DEC, NULL, 0x0,
                NULL, HFILL }
          }
        , { &hf_eobi[MDENTRYSIZE_FH_IDX],
              { "MDEntrySize", "eobi.mdentrysize",
                FT_INT64, BASE_DEC, NULL, 0x0,
                NULL, HFILL }
          }
        , { &hf_eobi[MDENTRYTYPE_FH_IDX],
              { "MDEntryType", "eobi.mdentrytype",
                FT_UINT8, BASE_DEC| BASE_EXT_STRING, &mdentry_type_vals_ext, 0x0,
                NULL, HFILL }
          }
        , { &hf_eobi[MARKETCONDITION_FH_IDX],
              { "MarketCondition", "eobi.marketcondition",
                FT_UINT8, BASE_DEC, VALS(market_condition_vals), 0x0,
                NULL, HFILL }
          }
        , { &hf_eobi[MARKETSEGMENTID_FH_IDX],
              { "MarketSegmentID", "eobi.marketsegmentid",
                FT_INT32, BASE_DEC, NULL, 0x0,
                NULL, HFILL }
          }
        , { &hf_eobi[MASSMARKETCONDITION_FH_IDX],
              { "MassMarketCondition", "eobi.massmarketcondition",
                FT_UINT8, BASE_DEC, VALS(market_condition_vals), 0x0,
                NULL, HFILL }
          }
        , { &hf_eobi[MASSSOLDOUTINDICATOR_FH_IDX],
              { "MassSoldOutIndicator", "eobi.masssoldoutindicator",
                FT_UINT8, BASE_DEC, VALS(mass_sold_out_indicator_vals), 0x0,
                NULL, HFILL }
          }
        , { &hf_eobi[MATCHSUBTYPE_FH_IDX],
              { "MatchSubType", "eobi.matchsubtype",
                FT_UINT8, BASE_DEC, VALS(match_sub_type_vals), 0x0,
                NULL, HFILL }
          }
        , { &hf_eobi[MATCHTYPE_FH_IDX],
              { "MatchType", "eobi.matchtype",
                FT_UINT8, BASE_DEC, VALS(match_type_vals), 0x0,
                NULL, HFILL }
          }
        , { &hf_eobi[MSGSEQNUM_FH_IDX],
              { "MsgSeqNum", "eobi.msgseqnum",
                FT_UINT32, BASE_DEC, NULL, 0x0,
                NULL, HFILL }
          }
        , { &hf_eobi[NOLEGS_FH_IDX],
              { "NoLegs", "eobi.nolegs",
                FT_UINT8, BASE_DEC, NULL, 0x0,
                NULL, HFILL }
          }
        , { &hf_eobi[NOMDENTRIES_FH_IDX],
              { "NoMDEntries", "eobi.nomdentries",
                FT_UINT8, BASE_DEC, NULL, 0x0,
                NULL, HFILL }
          }
        , { &hf_eobi[NORELATEDSYM_FH_IDX],
              { "NoRelatedSym", "eobi.norelatedsym",
                FT_UINT8, BASE_DEC, NULL, 0x0,
                NULL, HFILL }
          }
        , { &hf_eobi[NUMBEROFBUYORDERS_FH_IDX],
              { "NumberOfBuyOrders", "eobi.numberofbuyorders",
                FT_UINT16, BASE_DEC, NULL, 0x0,
                NULL, HFILL }
          }
        , { &hf_eobi[NUMBEROFSELLORDERS_FH_IDX],
              { "NumberOfSellOrders", "eobi.numberofsellorders",
                FT_UINT16, BASE_DEC, NULL, 0x0,
                NULL, HFILL }
          }
        , { &hf_eobi[OFFERORDTYPE_FH_IDX],
              { "OfferOrdType", "eobi.offerordtype",
                FT_UINT8, BASE_DEC, VALS(bid_ord_type_vals), 0x0,
                NULL, HFILL }
          }
        , { &hf_eobi[OFFERPX_FH_IDX],
              { "OfferPx", "eobi.offerpx",
                FT_INT64, BASE_DEC, NULL, 0x0,
                NULL, HFILL }
          }
        , { &hf_eobi[OFFERSIZE_FH_IDX],
              { "OfferSize", "eobi.offersize",
                FT_INT64, BASE_DEC, NULL, 0x0,
                NULL, HFILL }
          }
        , { &hf_eobi[ORDTYPE_FH_IDX],
              { "OrdType", "eobi.ordtype",
                FT_UINT8, BASE_DEC, VALS(bid_ord_type_vals), 0x0,
                NULL, HFILL }
          }
        , { &hf_eobi[PARTITIONID_FH_IDX],
              { "PartitionID", "eobi.partitionid",
                FT_UINT8, BASE_DEC, NULL, 0x0,
                NULL, HFILL }
          }
        , { &hf_eobi[POTENTIALSECURITYTRADINGEVENT_FH_IDX],
              { "PotentialSecurityTradingEvent", "eobi.potentialsecuritytradingevent",
                FT_UINT8, BASE_DEC, VALS(potential_security_trading_event_vals), 0x0,
                NULL, HFILL }
          }
        , { &hf_eobi[PREVDISPLAYQTY_FH_IDX],
              { "PrevDisplayQty", "eobi.prevdisplayqty",
                FT_INT64, BASE_DEC, NULL, 0x0,
                NULL, HFILL }
          }
        , { &hf_eobi[PREVPRICE_FH_IDX],
              { "PrevPrice", "eobi.prevprice",
                FT_INT64, BASE_DEC, NULL, 0x0,
                NULL, HFILL }
          }
        , { &hf_eobi[PRICE_FH_IDX],
              { "Price", "eobi.price",
                FT_INT64, BASE_DEC, NULL, 0x0,
                NULL, HFILL }
          }
        , { &hf_eobi[PRODUCTCOMPLEX_FH_IDX],
              { "ProductComplex", "eobi.productcomplex",
                FT_UINT8, BASE_DEC| BASE_EXT_STRING, &instrument_scope_product_complex_vals_ext, 0x0,
                NULL, HFILL }
          }
        , { &hf_eobi[REQUESTTIME_FH_IDX],
              { "RequestTime", "eobi.requesttime",
                FT_ABSOLUTE_TIME, ABSOLUTE_TIME_UTC, NULL, 0x0,
                NULL, HFILL }
          }
        , { &hf_eobi[RESTINGCXLQTY_FH_IDX],
              { "RestingCxlQty", "eobi.restingcxlqty",
                FT_INT64, BASE_DEC, NULL, 0x0,
                NULL, HFILL }
          }
        , { &hf_eobi[RESTINGHIDDENQTY_FH_IDX],
              { "RestingHiddenQty", "eobi.restinghiddenqty",
                FT_INT64, BASE_DEC, NULL, 0x0,
                NULL, HFILL }
          }
        , { &hf_eobi[SECURITYID_FH_IDX],
              { "SecurityID", "eobi.securityid",
                FT_INT64, BASE_DEC, NULL, 0x0,
                NULL, HFILL }
          }
        , { &hf_eobi[SECURITYMASSSTATUS_FH_IDX],
              { "SecurityMassStatus", "eobi.securitymassstatus",
                FT_UINT8, BASE_DEC| BASE_EXT_STRING, &security_mass_status_vals_ext, 0x0,
                NULL, HFILL }
          }
        , { &hf_eobi[SECURITYMASSTRADINGEVENT_FH_IDX],
              { "SecurityMassTradingEvent", "eobi.securitymasstradingevent",
                FT_UINT8, BASE_DEC, VALS(security_mass_trading_event_vals), 0x0,
                NULL, HFILL }
          }
        , { &hf_eobi[SECURITYMASSTRADINGSTATUS_FH_IDX],
              { "SecurityMassTradingStatus", "eobi.securitymasstradingstatus",
                FT_UINT8, BASE_DEC| BASE_EXT_STRING, &security_mass_trading_status_vals_ext, 0x0,
                NULL, HFILL }
          }
        , { &hf_eobi[SECURITYSTATUS_FH_IDX],
              { "SecurityStatus", "eobi.securitystatus",
                FT_UINT8, BASE_DEC| BASE_EXT_STRING, &security_mass_status_vals_ext, 0x0,
                NULL, HFILL }
          }
        , { &hf_eobi[SECURITYSUBTYPE_FH_IDX],
              { "SecuritySubType", "eobi.securitysubtype",
                FT_INT32, BASE_DEC, NULL, 0x0,
                NULL, HFILL }
          }
        , { &hf_eobi[SECURITYTRADINGEVENT_FH_IDX],
              { "SecurityTradingEvent", "eobi.securitytradingevent",
                FT_UINT8, BASE_DEC, VALS(security_mass_trading_event_vals), 0x0,
                NULL, HFILL }
          }
        , { &hf_eobi[SECURITYTRADINGSTATUS_FH_IDX],
              { "SecurityTradingStatus", "eobi.securitytradingstatus",
                FT_UINT8, BASE_DEC| BASE_EXT_STRING, &security_mass_trading_status_vals_ext, 0x0,
                NULL, HFILL }
          }
        , { &hf_eobi[SIDE_FH_IDX],
              { "Side", "eobi.side",
                FT_UINT8, BASE_DEC, VALS(aggressor_side_vals), 0x0,
                NULL, HFILL }
          }
        , { &hf_eobi[SOLDOUTINDICATOR_FH_IDX],
              { "SoldOutIndicator", "eobi.soldoutindicator",
                FT_UINT8, BASE_DEC, VALS(mass_sold_out_indicator_vals), 0x0,
                NULL, HFILL }
          }
        , { &hf_eobi[TEMPLATEID_FH_IDX],
              { "TemplateID", "eobi.templateid",
                FT_UINT16, BASE_DEC, NULL, 0x0,
                NULL, HFILL }
          }
        , { &hf_eobi[TOTNOORDERS_FH_IDX],
              { "TotNoOrders", "eobi.totnoorders",
                FT_UINT16, BASE_DEC, NULL, 0x0,
                NULL, HFILL }
          }
        , { &hf_eobi[TRADSESSTATUS_FH_IDX],
              { "TradSesStatus", "eobi.tradsesstatus",
                FT_UINT8, BASE_DEC, VALS(trad_ses_status_vals), 0x0,
                NULL, HFILL }
          }
        , { &hf_eobi[TRADECONDITION_FH_IDX],
              { "TradeCondition", "eobi.tradecondition",
                FT_UINT16, BASE_DEC, VALS(trade_condition_vals), 0x0,
                NULL, HFILL }
          }
        , { &hf_eobi[TRADINGSESSIONID_FH_IDX],
              { "TradingSessionID", "eobi.tradingsessionid",
                FT_UINT8, BASE_DEC, VALS(trading_session_id_vals), 0x0,
                NULL, HFILL }
          }
        , { &hf_eobi[TRADINGSESSIONSUBID_FH_IDX],
              { "TradingSessionSubID", "eobi.tradingsessionsubid",
                FT_UINT8, BASE_DEC, VALS(trading_session_sub_id_vals), 0x0,
                NULL, HFILL }
          }
        , { &hf_eobi[TRANSACTTIME_FH_IDX],
              { "TransactTime", "eobi.transacttime",
                FT_ABSOLUTE_TIME, ABSOLUTE_TIME_UTC, NULL, 0x0,
                NULL, HFILL }
          }
        , { &hf_eobi[TRDMATCHID_FH_IDX],
              { "TrdMatchID", "eobi.trdmatchid",
                FT_UINT32, BASE_DEC, NULL, 0x0,
                NULL, HFILL }
          }
        , { &hf_eobi[TRDREGTSEXECUTIONTIME_FH_IDX],
              { "TrdRegTSExecutionTime", "eobi.trdregtsexecutiontime",
                FT_ABSOLUTE_TIME, ABSOLUTE_TIME_UTC, NULL, 0x0,
                NULL, HFILL }
          }
        , { &hf_eobi[TRDREGTSPREVTIMEPRIORITY_FH_IDX],
              { "TrdRegTSPrevTimePriority", "eobi.trdregtsprevtimepriority",
                FT_ABSOLUTE_TIME, ABSOLUTE_TIME_UTC, NULL, 0x0,
                NULL, HFILL }
          }
        , { &hf_eobi[TRDREGTSTIMEIN_FH_IDX],
              { "TrdRegTSTimeIn", "eobi.trdregtstimein",
                FT_ABSOLUTE_TIME, ABSOLUTE_TIME_UTC, NULL, 0x0,
                NULL, HFILL }
          }
        , { &hf_eobi[TRDREGTSTIMEPRIORITY_FH_IDX],
              { "TrdRegTSTimePriority", "eobi.trdregtstimepriority",
                FT_ABSOLUTE_TIME, ABSOLUTE_TIME_UTC, NULL, 0x0,
                NULL, HFILL }
          }
        , { &hf_eobi_dscp_exec_summary,
              { "DSCP_ExecSummary", "eobi.dscp_execsummary",
                FT_BOOLEAN, 8, NULL, 0x10,
                NULL, HFILL }
          }
        , { &hf_eobi_dscp_improved,
              { "DSCP_Improved", "eobi.dscp_improved",
                FT_BOOLEAN, 8, NULL, 0x20,
                NULL, HFILL }
          }
        , { &hf_eobi_dscp_widened,
              { "DSCP_Widened", "eobi.dscp_widened",
                FT_BOOLEAN, 8, NULL, 0x40,
                NULL, HFILL }
          }
    };
    static ei_register_info ei[] = {
        {
            &ei_eobi_counter_overflow,
            { "eobi.counter_overflow", PI_PROTOCOL, PI_WARN, "Counter Overflow", EXPFILL }
        },
        {
            &ei_eobi_invalid_template,
            { "eobi.invalid_template", PI_PROTOCOL, PI_ERROR, "Invalid Template ID", EXPFILL }
        },
        {
            &ei_eobi_invalid_length,
            { "eobi.invalid_length", PI_PROTOCOL, PI_ERROR, "Invalid Body Length", EXPFILL }
        },
        {
            &ei_eobi_missing,
            { "eobi.missing", PI_PROTOCOL, PI_WARN, "A required value is missing", EXPFILL }
        },
        {
            &ei_eobi_overused,
            { "eobi.overused", PI_PROTOCOL, PI_WARN, "An unused value is set", EXPFILL }
        }
    };
    proto_eobi = proto_register_protocol("Enhanced Order Book Interface 10.0",
            "EOBI", "eobi");
    expert_module_t *expert_eobi = expert_register_protocol(proto_eobi);
    expert_register_field_array(expert_eobi, ei, array_length(ei));
    proto_register_field_array(proto_eobi, hf, array_length(hf));
    static gint * const ett[] = { &ett_eobi[0], &ett_eobi[1], &ett_eobi[2], &ett_eobi[3], &ett_eobi[4], &ett_eobi[5], &ett_eobi[6], &ett_eobi_dscp };
    proto_register_subtree_array(ett, array_length(ett));
    proto_disable_by_default(proto_eobi);

    eobi_handle = register_dissector("eobi", dissect_eobi, proto_eobi);
}

void
proto_reg_handoff_eobi(void)
{
    // cf. N7 Network Access Guide, e.g.
    // https://www.xetra.com/xetra-en/technology/t7/system-documentation/release10-0/Release-10.0-2692700?frag=2692724
    // https://www.xetra.com/resource/blob/2762078/388b727972b5122945eedf0e63c36920/data/N7-Network-Access-Guide-v2.0.59.pdf


    static const int ports[] = {
        59000, // Snapshot    EUREX US-allowed    PROD
        59001, // Incremental EUREX US-allowed    PROD
        59032, // Snapshot    EUREX US-restricted PROD
        59033, // Incremental EUREX US-restricted PROD
        59500, // Snapshot    EUREX US-allowed    SIMU
        59501, // Incremental EUREX US-allowed    SIMU
        59532, // Snapshot    EUREX US-restricted SIMU
        59533, // Incremental EUREX US-restricted SIMU

        57000, // Snapshot    FX US-allowed    PROD
        57001, // Incremental FX US-allowed    PROD
        57032, // Snapshot    FX US-restricted PROD
        57033, // Incremental FX US-restricted PROD
        57500, // Snapshot    FX US-allowed    SIMU
        57501, // Incremental FX US-allowed    SIMU
        57532, // Snapshot    FX US-restricted SIMU
        57533, // Incremental FX US-restricted SIMU

        59000, // Snapshot    Xetra PROD
        59001, // Incremental Xetra PROD
        59500, // Snapshot    Xetra SIMU
        59501, // Incremental Xetra SIMU

        56000, // Snapshot    Boerse Frankfurt PROD
        56001, // Incremental Boerse Frankfurt PROD
        56500, // Snapshot    Boerse Frankfurt SIMU
        56501  // Incremental Boerse Frankfurt SIMU
    };
    for (unsigned i = 0; i < sizeof ports / sizeof ports[0]; ++i)
        dissector_add_uint("udp.port", ports[i], eobi_handle);
}
