Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-ecpri.c
blob72826b4738d355ff786498e0166279a7a1b3e71b
1 /* packet-ecpri.c
2 * Routines for eCPRI dissection
3 * Copyright 2019, Maximilian Kohler <maximilian.kohler@viavisolutions.com>
4 * Copyright 2024, Tomasz Woszczynski <duchowe50k@gmail.com>
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * SPDX-License-Identifier: GPL-2.0-or-later
12 * ------------------------------------------------------------------------------------------------
13 * eCPRI Transport Network V1.2 -- Specifications
14 * http://www.cpri.info/downloads/Requirements_for_the_eCPRI_Transport_Network_V1_2_2018_06_25.pdf
15 * eCPRI Transport Network V2.0 -- Specifications
16 * https://www.cpri.info/downloads/eCPRI_v_2.0_2019_05_10c.pdf
18 * May carry ORAN FH-CUS (packet-oran.c) - Message Types, 0, 2
19 * See https://specifications.o-ran.org/specifications, WG4, Fronthaul Interfaces Workgroup
20 * ------------------------------------------------------------------------------------------------
23 #include "config.h"
24 #include <epan/packet.h>
25 #include <epan/prefs.h>
26 #include <epan/expert.h>
27 #include <epan/etypes.h>
28 #include <epan/tfs.h>
29 #include <epan/unit_strings.h>
30 #include <proto.h>
32 #include "epan/dissectors/packet-ptp.h"
34 /**************************************************************************************************/
35 /* Definition for eCPRI lengths */
36 /**************************************************************************************************/
37 /* eCPRI Common Header (4 Bytes) */
38 #define ECPRI_HEADER_LENGTH 4U
39 /* Message Type Length */
40 #define ECPRI_MSG_TYPE_0_PAYLOAD_MIN_LENGTH 4U
41 #define ECPRI_MSG_TYPE_1_PAYLOAD_MIN_LENGTH 4U
42 #define ECPRI_MSG_TYPE_2_PAYLOAD_MIN_LENGTH 4U
43 #define ECPRI_MSG_TYPE_3_PAYLOAD_MIN_LENGTH 8U
44 #define ECPRI_MSG_TYPE_4_PAYLOAD_MIN_LENGTH 12U
45 #define ECPRI_MSG_TYPE_5_PAYLOAD_MIN_LENGTH 20U
46 #define ECPRI_MSG_TYPE_6_PAYLOAD_MIN_LENGTH 3U
47 #define ECPRI_MSG_TYPE_7_PAYLOAD_MIN_LENGTH 4U
48 #define ECPRI_MSG_TYPE_8_PAYLOAD_MIN_LENGTH 9U
49 #define ECPRI_MSG_TYPE_11_PAYLOAD_LENGTH 12U
50 #define ECPRI_MSG_TYPE_7_ELEMENT_SIZE 8U
52 /**************************************************************************************************/
53 /* Definition for Action Types in Message Type 5: One-way Delay Measurement */
54 /**************************************************************************************************/
55 #define ECPRI_MSG_TYPE_5_REQ 0x00
56 #define ECPRI_MSG_TYPE_5_REQ_FOLLOWUP 0x01
57 #define ECPRI_MSG_TYPE_5_RESPONSE 0x02
58 #define ECPRI_MSG_TYPE_5_REMOTE_REQ 0x03
59 #define ECPRI_MSG_TYPE_5_REMOTE_REQ_FOLLOWUP 0x04
60 #define ECPRI_MSG_TYPE_5_FOLLOWUP 0x05
61 #define ECPRI_MSG_TYPE_5_RESERVED_MIN 0x06
62 #define ECPRI_MSG_TYPE_5_RESERVED_MAX 0xFF
64 /**************************************************************************************************/
65 /* Definition for Event Types in Message Type 7: Event Indication */
66 /**************************************************************************************************/
67 #define ECPRI_MSG_TYPE_7_FAULT_INDICATION 0x00
68 #define ECPRI_MSG_TYPE_7_FAULT_INDICATION_ACK 0x01
69 #define ECPRI_MSG_TYPE_7_NOTIF_INDICATION 0x02
70 #define ECPRI_MSG_TYPE_7_SYNC_REQUEST 0x03
71 #define ECPRI_MSG_TYPE_7_SYNC_ACK 0x04
72 #define ECPRI_MSG_TYPE_7_SYNC_END_INDICATION 0x05
73 #define ECPRI_MSG_TYPE_7_RESERVED_MIN 0x06
74 #define ECPRI_MSG_TYPE_7_RESERVED_MAX 0xFF
76 /**************************************************************************************************/
77 /* Definition for Fault/Notification Ranges in Message Type 7: Event Indication */
78 /**************************************************************************************************/
79 #define ECPRI_MSG_TYPE_7_FAULTS_MIN 0x000
80 #define ECPRI_MSG_TYPE_7_FAULTS_MAX 0x3FF
81 #define ECPRI_MSG_TYPE_7_NOTIF_MIN 0x400
82 #define ECPRI_MSG_TYPE_7_NOTIF_MAX 0x7FF
83 #define ECPRI_MSG_TYPE_7_VENDOR_MIN 0x800
84 #define ECPRI_MSG_TYPE_7_VENDOR_MAX 0xFFF
86 /**************************************************************************************************/
87 /* Definition for Action Types in Message Type 11: IWF Delay Control */
88 /**************************************************************************************************/
89 #define ECPRI_MSG_TYPE_11_REQUEST_GET_DELAYS 0x00
90 #define ECPRI_MSG_TYPE_11_RESPONSE_GET_DELAYS 0x01
91 #define ECPRI_MSG_TYPE_11_RESERVED_MIN 0x02
92 #define ECPRI_MSG_TYPE_11_RESERVED_MAX 0xFF
94 /**************************************************************************************************/
95 /* Function Prototypes */
96 /**************************************************************************************************/
97 void proto_register_ecpri(void);
98 void proto_reg_handoff_ecpri(void);
100 /**************************************************************************************************/
101 /* Initialize the subtree pointers */
102 /**************************************************************************************************/
103 static int ett_ecpri;
104 static int ett_ecpri_header;
105 static int ett_ecpri_payload;
106 static int ett_ecpri_timestamp;
107 static int ett_ecpri_element;
109 /**************************************************************************************************/
110 /* Initialize the protocol and registered fields */
111 /**************************************************************************************************/
112 static int proto_ecpri;
114 static int hf_payload;
116 /* Fields for eCPRI Common Header */
117 static int hf_common_header;
118 static int hf_common_header_ecpri_protocol_revision;
119 static int hf_common_header_reserved;
120 static int hf_common_header_c_bit;
121 static int hf_common_header_ecpri_message_type;
122 static int hf_common_header_ecpri_payload_size;
124 /* Common to several message types */
125 static int hf_pc_id;
127 /* Fields for Message Type 0: IQ Data */
128 static int hf_iq_data_seq_id;
129 static int hf_iq_data_iq_samples_of_user_data;
131 /* Fields for Message Type 1: Bit Sequence */
132 static int hf_bit_sequence_seq_id;
133 static int hf_bit_sequence_bit_sequence_of_user_data;
135 /* Fields for Message Type 2: Real-Time Control Data */
136 static int hf_real_time_control_data_rtc_id;
137 static int hf_real_time_control_data_seq_id;
138 static int hf_real_time_control_data_rtc_data;
140 /* Fields for Message Type 3: Generic Data Transfer */
141 static int hf_generic_data_transfer_seq_id;
142 static int hf_generic_data_transfer_data_transferred;
144 /* Fields for Message Type 4: Remote Memory Access */
145 static int hf_remote_memory_access_id;
146 static int hf_remote_memory_access_read_write;
147 static int hf_remote_memory_access_request_response;
148 static int hf_remote_memory_access_element_id;
149 static int hf_remote_memory_access_address;
150 static int hf_remote_memory_access_data_length;
151 static int hf_remote_memory_access_data;
153 /* Fields for Message Type 5: One-Way Delay Measurement */
154 static int hf_one_way_delay_measurement_id;
155 static int hf_one_way_delay_measurement_action_type;
156 static int hf_one_way_delay_measurement_timestamp;
157 static int hf_one_way_delay_measurement_timestamp_seconds;
158 static int hf_one_way_delay_measurement_timestamp_nanoseconds;
159 static int hf_one_way_delay_measurement_compensation_value;
160 static int hf_one_way_delay_measurement_compensation_value_subns;
161 static int hf_one_way_delay_measurement_dummy_bytes;
163 static int hf_one_way_delay_measurement_calculated_delay;
164 static int hf_one_way_delay_measurement_calculated_delay_request_frame;
165 static int hf_one_way_delay_measurement_calculated_delay_response_frame;
168 /* Fields for Message Type 6: Remote Reset */
169 static int hf_remote_reset_reset_id;
170 static int hf_remote_reset_reset_code;
171 static int hf_remote_reset_vendor_specific_payload;
173 /* Fields for Message Type 7: Event Indication */
174 static int hf_event_indication_event_id;
175 static int hf_event_indication_event_type;
176 static int hf_event_indication_sequence_number;
177 static int hf_event_indication_number_of_faults_notifications;
178 static int hf_event_indication_element;
179 static int hf_event_indication_element_id;
180 static int hf_event_indication_raise_cease;
181 static int hf_event_indication_fault_notification;
182 static int hf_event_indication_additional_information;
184 /* Fields for Message Type 8: IWF Start-Up */
185 static int hf_iwf_start_up_hyperframe_number; /* #Z field */
186 static int hf_iwf_start_up_subframe_number; /* #X field */
187 static int hf_iwf_start_up_timestamp;
188 static int hf_iwf_start_up_fec_bit_indicator;
189 static int hf_iwf_start_up_scrambling_bit_indicator;
190 static int hf_iwf_start_up_line_rate;
191 static int hf_iwf_start_up_data_transferred;
193 /* Fields for Message Type 11: IWF Delay Control */
194 static int hf_iwf_delay_control_delay_control_id;
195 static int hf_iwf_delay_control_action_type;
196 static int hf_iwf_delay_control_delay_a;
197 static int hf_iwf_delay_control_delay_b;
199 /**************************************************************************************************/
200 /* Preference to use the eCPRI Specification 2.0 encoding */
201 /**************************************************************************************************/
202 static bool pref_message_type_decoding = true;
204 /**************************************************************************************************/
205 /* eCPRI Handle */
206 /**************************************************************************************************/
207 static dissector_handle_t ecpri_handle;
209 /**************************************************************************************************/
210 /* Initialize expert info fields */
211 /**************************************************************************************************/
212 static expert_field ei_ecpri_frame_length;
213 static expert_field ei_payload_size;
214 static expert_field ei_comp_val;
215 static expert_field ei_time_stamp;
216 static expert_field ei_compensation_value_nonzero;
217 static expert_field ei_data_length;
218 static expert_field ei_c_bit;
219 static expert_field ei_fault_notif;
220 static expert_field ei_number_faults;
221 static expert_field ei_iwf_delay_control_action_type;
222 static expert_field ei_ecpri_not_dis_yet;
224 /**************************************************************************************************/
225 /* Field Encoding of Message Types */
226 /**************************************************************************************************/
228 #define ECPRI_MESSAGE_TYPE_IQ_DATA 0
229 #define ECPRI_MESSAGE_TYPE_BIT_SEQUENCE 1
230 #define ECPRI_MESSAGE_TYPE_REAL_TIME_CONTROL_DATA 2
231 #define ECPRI_MESSAGE_TYPE_GENERIC_DATA_TRANSFER 3
232 #define ECPRI_MESSAGE_TYPE_REMOTE_MEMORY_ACCESS 4
233 #define ECPRI_MESSAGE_TYPE_ONE_WAY_DELAY_MEASUREMENT 5
234 #define ECPRI_MESSAGE_TYPE_REMOTE_RESET 6
235 #define ECPRI_MESSAGE_TYPE_EVENT_INDICATION 7
236 #define ECPRI_MESSAGE_TYPE_IWF_STARTUP 8
237 #define ECPRI_MESSAGE_TYPE_IWF_OPERATION 9
238 #define ECPRI_MESSAGE_TYPE_IWF_MAPPING 10
239 #define ECPRI_MESSAGE_TYPE_IWF_DELAY_CONTROL 11
241 static const range_string ecpri_msg_types[] = {
242 /* Message Types (3.2.4) */
243 { ECPRI_MESSAGE_TYPE_IQ_DATA, ECPRI_MESSAGE_TYPE_IQ_DATA, "IQ Data" },
244 { ECPRI_MESSAGE_TYPE_BIT_SEQUENCE, ECPRI_MESSAGE_TYPE_BIT_SEQUENCE, "Bit Sequence" },
245 { ECPRI_MESSAGE_TYPE_REAL_TIME_CONTROL_DATA, ECPRI_MESSAGE_TYPE_REAL_TIME_CONTROL_DATA, "Real-Time Control Data" },
246 { ECPRI_MESSAGE_TYPE_GENERIC_DATA_TRANSFER, ECPRI_MESSAGE_TYPE_GENERIC_DATA_TRANSFER, "Generic Data Transfer" },
247 { ECPRI_MESSAGE_TYPE_REMOTE_MEMORY_ACCESS, ECPRI_MESSAGE_TYPE_REMOTE_MEMORY_ACCESS, "Remote Memory Access" },
248 { ECPRI_MESSAGE_TYPE_ONE_WAY_DELAY_MEASUREMENT, ECPRI_MESSAGE_TYPE_ONE_WAY_DELAY_MEASUREMENT, "One-Way Delay Measurement" },
249 { ECPRI_MESSAGE_TYPE_REMOTE_RESET, ECPRI_MESSAGE_TYPE_REMOTE_RESET, "Remote Reset" },
250 { ECPRI_MESSAGE_TYPE_EVENT_INDICATION, ECPRI_MESSAGE_TYPE_EVENT_INDICATION, "Event Indication" },
251 { ECPRI_MESSAGE_TYPE_IWF_STARTUP, ECPRI_MESSAGE_TYPE_IWF_STARTUP, "IWF Start-Up" },
252 { ECPRI_MESSAGE_TYPE_IWF_OPERATION, ECPRI_MESSAGE_TYPE_IWF_OPERATION, "IWF Operation" },
253 { ECPRI_MESSAGE_TYPE_IWF_MAPPING, ECPRI_MESSAGE_TYPE_IWF_MAPPING, "IWF Mapping" },
254 { ECPRI_MESSAGE_TYPE_IWF_DELAY_CONTROL, ECPRI_MESSAGE_TYPE_IWF_DELAY_CONTROL, "IWF Delay Control" },
255 /* Message Types 12 - 63*/
256 { 12, 63, "Reserved" },
257 /* Message Types 64 - 255 */
258 { 64, 255, "Vendor Specific" },
259 { 0, 0, NULL }
262 /**************************************************************************************************/
263 /* Field Encoding of Message Type 4: Remote Memory Access */
264 /**************************************************************************************************/
265 static const value_string remote_memory_access_read_write_coding[] = {
266 { 0x0, "Read" },
267 { 0x1, "Write" },
268 { 0x2, "Write_No_resp" },
269 { 0x3, "Reserved" },
270 { 0x4, "Reserved" },
271 { 0x5, "Reserved" },
272 { 0x6, "Reserved" },
273 { 0x7, "Reserved" },
274 { 0x8, "Reserved" },
275 { 0x9, "Reserved" },
276 { 0xA, "Reserved" },
277 { 0xB, "Reserved" },
278 { 0xC, "Reserved" },
279 { 0xD, "Reserved" },
280 { 0xE, "Reserved" },
281 { 0xF, "Reserved" },
282 { 0, NULL }
285 static const value_string remote_memory_access_request_response_coding[] = {
286 { 0x0, "Request" },
287 { 0x1, "Response" },
288 { 0x2, "Failure" },
289 { 0x3, "Reserved" },
290 { 0x4, "Reserved" },
291 { 0x5, "Reserved" },
292 { 0x6, "Reserved" },
293 { 0x7, "Reserved" },
294 { 0x8, "Reserved" },
295 { 0x9, "Reserved" },
296 { 0xA, "Reserved" },
297 { 0xB, "Reserved" },
298 { 0xC, "Reserved" },
299 { 0xD, "Reserved" },
300 { 0xE, "Reserved" },
301 { 0xF, "Reserved" },
302 { 0, NULL }
305 /**************************************************************************************************/
306 /* Field Encoding of Message Type 5: One-way Delay Measurement */
307 /**************************************************************************************************/
308 static const range_string one_way_delay_measurement_action_type_coding[] = {
309 { 0x00, 0x00, "Request" },
310 { 0x01, 0x01, "Request with Follow_Up" },
311 { 0x02, 0x02, "Response" },
312 { 0x03, 0x03, "Remote Request" },
313 { 0x04, 0x04, "Remote request with Follow_Up" },
314 { 0x05, 0x05, "Follow_Up" },
315 { 0x06, 0xFF, "Reserved" },
316 { 0, 0, NULL }
319 /**************************************************************************************************/
320 /* Field Encoding of Message Type 6: Remote Reset */
321 /**************************************************************************************************/
322 static const range_string remote_reset_reset_coding[] = {
323 { 0x00, 0x00, "Reserved" },
324 { 0x01, 0x01, "Remote reset request" },
325 { 0x02, 0x02, "Remote reset response" },
326 { 0x03, 0xFF, "Reserved" },
327 { 0, 0, NULL }
330 /**************************************************************************************************/
331 /* Field Encoding of Message Type 7: Event Indication */
332 /**************************************************************************************************/
333 static const range_string event_indication_event_type_coding[] = {
334 { 0x00, 0x00, "Fault(s) Indication" },
335 { 0x01, 0x01, "Fault(s) Indication Acknowledge" },
336 { 0x02, 0x02, "Notification(s) Indication" },
337 { 0x03, 0x03, "Synchronization Request" },
338 { 0x04, 0x04, "Synchronization Acknowledge" },
339 { 0x05, 0x05, "Synchronization End Indication" },
340 { 0x06, 0xFF, "Reserved" },
341 { 0, 0, NULL }
344 static const range_string event_indication_element_id_coding[] = {
345 { 0x0000, 0xFFFE, "Vendor specific usage" },
346 { 0xFFFF, 0xFFFF, "Fault/Notification applicable for all Elements" },
347 { 0, 0, NULL }
350 static const value_string event_indication_raise_ceased_coding[] = {
351 { 0x00, "Raise a fault" },
352 { 0x01, "Cease a fault" },
353 { 0x02, "Reserved" },
354 { 0x03, "Reserved" },
355 { 0x04, "Reserved" },
356 { 0x05, "Reserved" },
357 { 0x06, "Reserved" },
358 { 0x07, "Reserved" },
359 { 0x08, "Reserved" },
360 { 0x09, "Reserved" },
361 { 0x0A, "Reserved" },
362 { 0x0B, "Reserved" },
363 { 0x0C, "Reserved" },
364 { 0x0D, "Reserved" },
365 { 0x0E, "Reserved" },
366 { 0x0F, "Reserved" },
367 { 0, NULL }
370 static const range_string event_indication_fault_notif_coding[] = {
371 /* eCPRI reserved Faults from 0x000 to 0x3FF */
372 { 0x000, 0x000, "General Userplane HW Fault" },
373 { 0x001, 0x001, "General Userplane SW Fault" },
374 { 0x002, 0x3FF, "eCPRI reserved Faults" },
375 /* eCPRI reserved Notifications from 0x400 to 0x7FF */
376 { 0x400, 0x400, "Unknown message type received" },
377 { 0x401, 0x401, "Userplane data buffer underflow" },
378 { 0x402, 0x402, "Userplane data buffer overflow" },
379 { 0x403, 0x403, "Userplane data arrived too early" },
380 { 0x404, 0x404, "Userplane data received too late" },
381 { 0x405, 0x7FF, "eCPRI reserved Notifications" },
382 /* Vendor Specific Fault Indication and Notification from 0x800 to 0xFFF */
383 { 0x800, 0xFFF, "Vendor Specific Fault Indication/Notification" },
384 { 0, 0, NULL }
387 /**************************************************************************************************/
388 /* Field Encoding of Message Type 8: IWF Start-Up */
389 /**************************************************************************************************/
390 static const range_string iwf_start_up_line_rate_coding[] = {
391 { 0x00, 0x00, "Reserved" },
392 { 0x01, 0x01, "CPRI line bit rate option 1" },
393 { 0x02, 0x02, "CPRI line bit rate option 2" },
394 { 0x03, 0x03, "CPRI line bit rate option 3" },
395 { 0x04, 0x04, "CPRI line bit rate option 4" },
396 { 0x05, 0x05, "CPRI line bit rate option 5" },
397 { 0x06, 0x06, "CPRI line bit rate option 6" },
398 { 0x07, 0x07, "CPRI line bit rate option 7" },
399 { 0x08, 0x08, "CPRI line bit rate option 7A" },
400 { 0x09, 0x09, "CPRI line bit rate option 8" },
401 { 0x0A, 0x0A, "CPRI line bit rate option 9" },
402 { 0x0B, 0x0B, "CPRI line bit rate option 10" },
403 { 0x0C, 0x1F, "Reserved" },
404 { 0, 0, NULL }
407 /**************************************************************************************************/
408 /* Field Encoding of Message Type 11: IWF Delay Control */
409 /**************************************************************************************************/
410 static const range_string iwf_delay_control_action_type_coding[] = {
411 { 0x00, 0x00, "Request get delays" },
412 { 0x01, 0x01, "Response get delays" },
413 { 0x02, 0xFF, "Reserved" },
414 { 0, 0, NULL }
417 static const true_false_string tfs_c_bit =
419 "Another eCPRI message follows this one with eCPRI PDU",
420 "This eCPRI message is last one inside eCPRI PDU"
424 /**************************************************************************************************/
425 /* Tracking/remembering One-Way Delay measurements */
426 /**************************************************************************************************/
428 /* Table maintained on first pass from measurement-id (uint32_t) -> meas_state_t* */
429 /* N.B. maintaining in a single table, assuming that the same ID will not be reused within */
430 /* the same capture. If this is not valid, can move table into conversation object later. */
431 static wmem_tree_t *meas_id_table;
433 /* Table consulted on subsequent passes: frame_num -> meas_result_t */
434 static wmem_tree_t *meas_results_table;
436 typedef struct {
437 /* Inputs for delay calculation */
438 bool t1_known;
439 uint64_t t1;
440 int64_t tcv1;
441 uint32_t t1_frame_number;
442 bool t2_known;
443 uint64_t t2;
444 int64_t tcv2;
445 uint32_t t2_frame_number;
446 } meas_state_t;
448 typedef struct {
449 uint64_t delay_in_ns;
450 uint32_t request_frame;
451 uint32_t response_frame;
452 } meas_result_t;
455 /* Cached for calling ORAN FH CUS dissector for message types that it handles */
456 static dissector_handle_t oran_fh_handle;
458 /**************************************************************************************************/
459 /* Implementation of the functions */
460 /**************************************************************************************************/
461 static int dissect_ecpri(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
463 tvbuff_t *next_tvb;
465 /* Proto Items/Trees for eCPRI */
466 proto_item *ecpri_item;
467 proto_tree *ecpri_tree;
469 /* Proto Items/Trees for eCPRI Common Header */
470 proto_item *header_item;
471 proto_tree *header_tree;
472 proto_item *ti_payload_size;
473 proto_item *ti_c_bit;
475 /* Proto Items/Trees for eCPRI Payload */
476 proto_item *payload_item;
477 proto_tree *payload_tree;
478 /* Proto Items/Trees for Message Type 4: Remote Memory Access */
479 proto_item *ti_data_length;
480 /* Proto Items/Trees for Message Type 5: One-way Delay Measurement */
481 proto_item *timestamp_item;
482 proto_tree *timestamp_tree;
483 proto_tree *comp_tree;
484 /* Proto Items/Trees for Message Type 7: Event Indication */
485 proto_item *element_item;
486 proto_tree *element_tree;
487 proto_item *ti_num_faults;
488 proto_item *ti_fault_notif;
490 int offset;
491 uint32_t msg_type;
492 uint32_t event_type;
493 uint32_t concatenation;
494 uint32_t num_faults_notif;
495 uint32_t action_type;
496 uint32_t fault_notif;
497 uint16_t payload_size; /* size of this ecpri message beyond 4-byte header */
499 unsigned int reported_length; /* total reported length of this overall tvb */
500 unsigned int remaining_length; /* length remaining in current message */
502 uint32_t time_stamp_ns;
503 uint64_t time_stamp_s;
504 int64_t comp_val;
506 reported_length = tvb_reported_length(tvb);
508 /* Check of eCPRI min. length (header-length) */
509 if (reported_length < ECPRI_HEADER_LENGTH)
510 return 0;
512 /* Set column of protocol eCPRI */
513 col_set_str(pinfo->cinfo, COL_PROTOCOL, "eCPRI");
514 col_clear(pinfo->cinfo, COL_INFO);
516 offset = 0;
517 concatenation = tvb_get_uint8(tvb, offset) & 0x01;
518 if (concatenation != 0x00)
520 col_append_str(pinfo->cinfo, COL_INFO, "Concatenation");
523 /* do-while loop for concatenation check */
524 bool concatenation_bit;
527 /* 4-byte boundary check for concatenation */
528 if (offset % 4 != 0)
530 offset = offset + 4 - (offset % 4);
533 /* Read ahead to eCPRI Payload Size */
534 payload_size = tvb_get_ntohs(tvb, offset+2);
536 /* eCPRI tree */
537 if ((unsigned int)(offset + ECPRI_HEADER_LENGTH + payload_size) <= reported_length)
539 ecpri_item = proto_tree_add_item(tree, proto_ecpri, tvb, offset, payload_size + ECPRI_HEADER_LENGTH, ENC_NA);
541 else
543 ecpri_item = proto_tree_add_item(tree, proto_ecpri, tvb, offset, -1, ENC_NA);
544 expert_add_info_format(
545 pinfo, ecpri_item, &ei_ecpri_frame_length,
546 "eCPRI frame length %u is too small, Should be min. %d",
547 reported_length-offset, ECPRI_HEADER_LENGTH + payload_size);
549 ecpri_tree = proto_item_add_subtree(ecpri_item, ett_ecpri);
550 /* TODO: create a subtvb for just this message (ECPRI_HEADER_LENGTH + payload_size) from offset? */
551 /* This would simplify some of the confusing range checks below.. */
553 /* eCPRI header subtree */
554 header_item = proto_tree_add_string_format(ecpri_tree, hf_common_header, tvb, offset, ECPRI_HEADER_LENGTH, "", "eCPRI Common Header");
555 header_tree = proto_item_add_subtree(header_item, ett_ecpri_header);
557 /* eCPRI Protocol Revision */
558 proto_tree_add_item(header_tree, hf_common_header_ecpri_protocol_revision, tvb, offset, 1, ENC_NA);
559 /* Reserved */
560 proto_tree_add_item(header_tree, hf_common_header_reserved, tvb, offset, 1, ENC_NA);
561 /* Concatenated */
562 ti_c_bit = proto_tree_add_item_ret_boolean(header_tree, hf_common_header_c_bit, tvb, offset, 1, ENC_NA, &concatenation_bit);
563 offset += 1;
565 /* eCPRI Message Type */
566 proto_tree_add_item_ret_uint(header_tree, hf_common_header_ecpri_message_type, tvb, offset, 1, ENC_NA, &msg_type);
567 /* Append Message Type into info column & header item */
568 col_append_sep_fstr(pinfo->cinfo, COL_INFO, ",", "Message Type: %s", try_rval_to_str(msg_type, ecpri_msg_types));
569 proto_item_append_text(header_item, " MessageType: %s", try_rval_to_str(msg_type, ecpri_msg_types));
570 offset += 1;
572 /* eCPRI Payload Size */
573 ti_payload_size = proto_tree_add_item(header_tree, hf_common_header_ecpri_payload_size, tvb, offset, 2, ENC_BIG_ENDIAN);
574 offset += 2;
576 /* Note if C is set (i.e. further messages to follow after this one) */
577 if (concatenation_bit) {
578 proto_item_append_text(header_item, " (further eCPRI message in frame)");
581 /* eCPRI payload-subtree */
582 /* Length Check */
583 if (reported_length >= ECPRI_HEADER_LENGTH + payload_size)
585 /* OK, add undecoded payload */
586 payload_item = proto_tree_add_item(ecpri_tree, hf_payload, tvb, offset, payload_size, ENC_NA);
588 else
590 expert_add_info_format(
591 pinfo, ti_payload_size, &ei_payload_size,
592 "Payload Size %u is too big, maximal %u is possible",
593 payload_size, reported_length - ECPRI_HEADER_LENGTH);
594 payload_item = proto_tree_add_item(ecpri_tree, hf_payload, tvb, offset, -1, ENC_NA);
597 payload_tree = proto_item_add_subtree(payload_item, ett_ecpri_payload);
598 remaining_length = payload_size;
600 /* Call the FH CUS dissector (for all message types) if preference set */
601 if (pref_message_type_decoding)
603 tvbuff_t *fh_tvb = tvb_new_subset_length(tvb, offset, payload_size);
604 /***********************************************************************************************/
605 /* See whether O-RAN fronthaul sub-dissector handles this, otherwise decode as vanilla eCPRI */
606 /* N.B. FH CUS dissector only handles: */
607 /* - message type 0 (IQ DATA) */
608 /* - message type 2 (RT CTRL DATA) */
609 /***********************************************************************************************/
610 if (call_dissector_only(oran_fh_handle, fh_tvb, pinfo, tree, &msg_type))
612 /* Assume that it has claimed the entire paylength offered to it */
613 offset += payload_size;
615 else
617 /* ORAN FH-CUS dissector didn't handle it */
618 switch (msg_type)
620 case ECPRI_MESSAGE_TYPE_IQ_DATA: /* Message Type 0: 3.2.4.1. IQ Data */
621 /* N.B. if ORAN dissector is enabled, it will handle this type instead! */
622 if (payload_size < ECPRI_MSG_TYPE_0_PAYLOAD_MIN_LENGTH)
624 expert_add_info_format(
625 pinfo, ti_payload_size, &ei_payload_size,
626 "Payload Size %u is too small for encoding Message Type %u. Should be min. %d",
627 payload_size, msg_type, ECPRI_MSG_TYPE_0_PAYLOAD_MIN_LENGTH);
629 offset += payload_size;
630 break;
633 if (remaining_length >= ECPRI_MSG_TYPE_0_PAYLOAD_MIN_LENGTH)
635 proto_tree_add_item(ecpri_tree, hf_pc_id, tvb, offset, 2, ENC_BIG_ENDIAN);
636 offset += 2;
637 proto_tree_add_item(ecpri_tree, hf_iq_data_seq_id, tvb, offset, 2, ENC_BIG_ENDIAN);
638 offset += 2;
639 remaining_length -= ECPRI_MSG_TYPE_0_PAYLOAD_MIN_LENGTH;
640 if (remaining_length >= payload_size - ECPRI_MSG_TYPE_0_PAYLOAD_MIN_LENGTH)
642 proto_tree_add_item(ecpri_tree, hf_iq_data_iq_samples_of_user_data, tvb, offset, payload_size - ECPRI_MSG_TYPE_0_PAYLOAD_MIN_LENGTH, ENC_NA);
643 offset += payload_size - ECPRI_MSG_TYPE_0_PAYLOAD_MIN_LENGTH;
646 break;
647 case ECPRI_MESSAGE_TYPE_BIT_SEQUENCE: /* Message Type 1: 3.2.4.2. Bit Sequence */
648 if (payload_size < ECPRI_MSG_TYPE_1_PAYLOAD_MIN_LENGTH)
650 expert_add_info_format(
651 pinfo, ti_payload_size, &ei_payload_size,
652 "Payload Size %u is too small for encoding Message Type %u. Should be min. %d",
653 payload_size, msg_type, ECPRI_MSG_TYPE_1_PAYLOAD_MIN_LENGTH);
655 offset += payload_size;
656 break;
659 if (remaining_length >= ECPRI_MSG_TYPE_1_PAYLOAD_MIN_LENGTH)
661 proto_tree_add_item(ecpri_tree, hf_pc_id, tvb, offset, 2, ENC_BIG_ENDIAN);
662 offset += 2;
663 proto_tree_add_item(ecpri_tree, hf_bit_sequence_seq_id, tvb, offset, 2, ENC_BIG_ENDIAN);
664 offset += 2;
665 remaining_length -= ECPRI_MSG_TYPE_1_PAYLOAD_MIN_LENGTH;
666 if (remaining_length >= payload_size - ECPRI_MSG_TYPE_1_PAYLOAD_MIN_LENGTH)
668 proto_tree_add_item(ecpri_tree, hf_bit_sequence_bit_sequence_of_user_data, tvb, offset, payload_size - ECPRI_MSG_TYPE_1_PAYLOAD_MIN_LENGTH, ENC_NA);
669 offset += payload_size - ECPRI_MSG_TYPE_1_PAYLOAD_MIN_LENGTH;
672 break;
674 case ECPRI_MESSAGE_TYPE_REAL_TIME_CONTROL_DATA: /* Message Type 2: 3.2.4.3. Real-Time Control Data */
675 /* N.B. if ORAN dissector is enabled, it will handle this type instead! */
676 if (payload_size < ECPRI_MSG_TYPE_2_PAYLOAD_MIN_LENGTH)
678 expert_add_info_format(
679 pinfo, ti_payload_size, &ei_payload_size,
680 "Payload Size %u is too small for encoding Message Type %u. Should be min. %d",
681 payload_size, msg_type, ECPRI_MSG_TYPE_2_PAYLOAD_MIN_LENGTH);
683 offset += payload_size;
684 break;
687 if (remaining_length >= ECPRI_MSG_TYPE_2_PAYLOAD_MIN_LENGTH)
689 proto_tree_add_item(ecpri_tree, hf_real_time_control_data_rtc_id, tvb, offset, 2, ENC_BIG_ENDIAN);
690 offset += 2;
691 proto_tree_add_item(ecpri_tree, hf_real_time_control_data_seq_id, tvb, offset, 2, ENC_BIG_ENDIAN);
692 offset += 2;
693 remaining_length -= ECPRI_MSG_TYPE_2_PAYLOAD_MIN_LENGTH;
694 if (remaining_length >= payload_size - ECPRI_MSG_TYPE_2_PAYLOAD_MIN_LENGTH)
696 proto_tree_add_item(ecpri_tree, hf_real_time_control_data_rtc_data, tvb, offset, payload_size - ECPRI_MSG_TYPE_2_PAYLOAD_MIN_LENGTH, ENC_NA);
697 offset += payload_size - ECPRI_MSG_TYPE_2_PAYLOAD_MIN_LENGTH;
700 break;
702 case ECPRI_MESSAGE_TYPE_GENERIC_DATA_TRANSFER: /* Message Type 3: 3.2.4.4. Generic Data Transfer */
703 if (payload_size < ECPRI_MSG_TYPE_3_PAYLOAD_MIN_LENGTH)
705 expert_add_info_format(
706 pinfo, ti_payload_size, &ei_payload_size,
707 "Payload Size %u is too small for encoding Message Type %u. Should be min. %d",
708 payload_size, msg_type, ECPRI_MSG_TYPE_3_PAYLOAD_MIN_LENGTH);
710 offset += payload_size;
711 break;
714 if (remaining_length >= ECPRI_MSG_TYPE_3_PAYLOAD_MIN_LENGTH)
716 proto_tree_add_item(ecpri_tree, hf_pc_id, tvb, offset, 4, ENC_BIG_ENDIAN);
717 offset += 4;
718 proto_tree_add_item(ecpri_tree, hf_generic_data_transfer_seq_id, tvb, offset, 4, ENC_BIG_ENDIAN);
719 offset += 4;
720 remaining_length -= ECPRI_MSG_TYPE_3_PAYLOAD_MIN_LENGTH;
721 if (remaining_length >= payload_size - ECPRI_MSG_TYPE_3_PAYLOAD_MIN_LENGTH)
723 proto_tree_add_item(ecpri_tree, hf_generic_data_transfer_data_transferred, tvb, offset, payload_size - ECPRI_MSG_TYPE_3_PAYLOAD_MIN_LENGTH, ENC_NA);
724 offset += payload_size - ECPRI_MSG_TYPE_3_PAYLOAD_MIN_LENGTH;
727 break;
729 case ECPRI_MESSAGE_TYPE_REMOTE_MEMORY_ACCESS: /* Message Type 4: 3.2.4.5. Remote Memory Access */
730 if (payload_size < ECPRI_MSG_TYPE_4_PAYLOAD_MIN_LENGTH)
732 expert_add_info_format(
733 pinfo, ti_payload_size, &ei_payload_size,
734 "Payload Size %u is too small for encoding Message Type %u. Should be min. %d",
735 payload_size, msg_type, ECPRI_MSG_TYPE_4_PAYLOAD_MIN_LENGTH);
737 offset += payload_size;
738 break;
741 if (remaining_length >= ECPRI_MSG_TYPE_4_PAYLOAD_MIN_LENGTH)
743 proto_tree_add_item(ecpri_tree, hf_remote_memory_access_id, tvb, offset, 1, ENC_NA);
744 offset += 1;
745 proto_tree_add_item(ecpri_tree, hf_remote_memory_access_read_write, tvb, offset, 1, ENC_NA);
746 proto_tree_add_item(ecpri_tree, hf_remote_memory_access_request_response, tvb, offset, 1, ENC_NA);
747 offset += 1;
748 proto_tree_add_item(ecpri_tree, hf_remote_memory_access_element_id, tvb, offset, 2, ENC_BIG_ENDIAN);
749 offset += 2;
750 proto_tree_add_item(ecpri_tree, hf_remote_memory_access_address, tvb, offset, 6, ENC_NA);
751 offset += 6;
752 /* Data length */
753 unsigned int data_length;
754 ti_data_length = proto_tree_add_item_ret_uint(ecpri_tree, hf_remote_memory_access_data_length, tvb, offset, 2, ENC_BIG_ENDIAN, &data_length);
755 offset += 2;
756 remaining_length -= ECPRI_MSG_TYPE_4_PAYLOAD_MIN_LENGTH;
757 if (remaining_length >= (payload_size - ECPRI_MSG_TYPE_4_PAYLOAD_MIN_LENGTH))
759 if (data_length == ((uint32_t)(payload_size - ECPRI_MSG_TYPE_4_PAYLOAD_MIN_LENGTH)))
761 proto_tree_add_item(ecpri_tree, hf_remote_memory_access_data, tvb, offset, payload_size - ECPRI_MSG_TYPE_4_PAYLOAD_MIN_LENGTH, ENC_NA);
762 offset += payload_size - ECPRI_MSG_TYPE_4_PAYLOAD_MIN_LENGTH;
764 else if (data_length < ((uint32_t)(payload_size - ECPRI_MSG_TYPE_4_PAYLOAD_MIN_LENGTH)))
766 expert_add_info_format(
767 pinfo, ti_data_length, &ei_data_length,
768 "Data Length %u is too small, should be %u",
769 data_length, payload_size - ECPRI_MSG_TYPE_4_PAYLOAD_MIN_LENGTH);
771 else
773 expert_add_info_format(
774 pinfo, ti_data_length, &ei_data_length,
775 "Data Length %u is too big, should be %u",
776 data_length, payload_size - ECPRI_MSG_TYPE_4_PAYLOAD_MIN_LENGTH);
780 break;
782 case ECPRI_MESSAGE_TYPE_ONE_WAY_DELAY_MEASUREMENT: /* Message Type 5: 3.2.4.6. One-way Delay Measurement */
783 if (payload_size < ECPRI_MSG_TYPE_5_PAYLOAD_MIN_LENGTH)
785 expert_add_info_format(
786 pinfo, ti_payload_size, &ei_payload_size,
787 "Payload Size %u is too small for encoding Message Type %u. Should be min. %d",
788 payload_size, msg_type, ECPRI_MSG_TYPE_5_PAYLOAD_MIN_LENGTH);
790 offset += payload_size;
791 break;
794 if (remaining_length >= ECPRI_MSG_TYPE_5_PAYLOAD_MIN_LENGTH)
796 /* Measurement ID (1 byte) */
797 unsigned int meas_id;
798 proto_tree_add_item_ret_uint(ecpri_tree, hf_one_way_delay_measurement_id, tvb, offset, 1, ENC_NA, &meas_id);
799 offset += 1;
800 /* Action Type (1 byte) */
801 proto_tree_add_item_ret_uint(ecpri_tree, hf_one_way_delay_measurement_action_type, tvb, offset, 1, ENC_NA, &action_type);
802 offset += 1;
804 col_append_fstr(pinfo->cinfo, COL_INFO, " (MeasId=%u, ActionType=%s)",
805 meas_id,
806 rval_to_str_const(action_type, one_way_delay_measurement_action_type_coding, "Unknown"));
808 /* Time Stamp for seconds and nano-seconds (6 bytes seconds, 4 bytes nanoseconds) */
809 timestamp_item = proto_tree_add_item(ecpri_tree, hf_one_way_delay_measurement_timestamp, tvb, offset, 10, ENC_NA);
810 timestamp_tree = proto_item_add_subtree(timestamp_item, ett_ecpri_timestamp);
811 proto_tree_add_item_ret_uint64(timestamp_tree, hf_one_way_delay_measurement_timestamp_seconds, tvb, offset, 6, ENC_BIG_ENDIAN, &time_stamp_s);
812 offset += 6;
813 proto_tree_add_item_ret_uint(timestamp_tree, hf_one_way_delay_measurement_timestamp_nanoseconds, tvb, offset, 4, ENC_BIG_ENDIAN, &time_stamp_ns);
814 offset += 4;
815 /* Isn't set for all action types */
816 if (action_type != ECPRI_MSG_TYPE_5_REQ &&
817 action_type != ECPRI_MSG_TYPE_5_RESPONSE &&
818 action_type != ECPRI_MSG_TYPE_5_FOLLOWUP &&
819 time_stamp_s != 0 && time_stamp_ns != 0)
821 expert_add_info_format(
822 pinfo, timestamp_item, &ei_time_stamp,
823 "Time stamp is not defined for Action Type %u (%s), should be 0",
824 action_type, rval_to_str_const(action_type, one_way_delay_measurement_action_type_coding, "Unknown"));
826 else {
827 /* Show value in ts root */
828 proto_item_append_text(timestamp_item, " (%" PRId64 ".%09u seconds)", time_stamp_s, time_stamp_ns);
831 /* Compensation value (8 bytes). Same format as PTP's correctionField */
832 dissect_ptp_v2_timeInterval(tvb, (uint16_t*)&offset, ecpri_tree, "Compensation value",
833 hf_one_way_delay_measurement_compensation_value,
834 hf_one_way_delay_measurement_compensation_value_subns,
835 &comp_tree,
836 &comp_val);
837 /* Isn't valid for all Action Types */
838 if (action_type != ECPRI_MSG_TYPE_5_REQ &&
839 action_type != ECPRI_MSG_TYPE_5_RESPONSE &&
840 action_type != ECPRI_MSG_TYPE_5_FOLLOWUP &&
841 comp_val != 0)
843 expert_add_info_format(
844 pinfo, comp_tree, &ei_compensation_value_nonzero,
845 "Compensation Value is not defined for Action Type %u (%s), should be 0",
846 action_type, rval_to_str_const(action_type, one_way_delay_measurement_action_type_coding, "Unknown"));
849 /* Any remaining bytes are dummy */
850 remaining_length -= ECPRI_MSG_TYPE_5_PAYLOAD_MIN_LENGTH;
851 if (remaining_length > 0)
853 proto_item *dummy_ti = proto_tree_add_item(ecpri_tree, hf_one_way_delay_measurement_dummy_bytes, tvb, offset,
854 payload_size - ECPRI_MSG_TYPE_5_PAYLOAD_MIN_LENGTH, ENC_NA);
855 offset += (payload_size - ECPRI_MSG_TYPE_5_PAYLOAD_MIN_LENGTH);
856 /* Only useful to send dummy bytes for requests */
857 if ((action_type != ECPRI_MSG_TYPE_5_REQ) &&
858 (action_type != ECPRI_MSG_TYPE_5_REQ_FOLLOWUP)) {
859 proto_item_append_text(dummy_ti, " (dummy bytes are only needed for action types 0-1");
863 /* For involved message types, try to work out and show the delay */
864 if ((action_type == ECPRI_MSG_TYPE_5_REQ) ||
865 (action_type == ECPRI_MSG_TYPE_5_FOLLOWUP) ||
866 (action_type == ECPRI_MSG_TYPE_5_RESPONSE)) {
868 meas_state_t* meas = (meas_state_t*)wmem_tree_lookup32(meas_id_table, meas_id);
869 if (!PINFO_FD_VISITED(pinfo)) {
870 /* First pass, fill in details for this measurement ID */
871 if (meas == NULL) {
872 /* Allocate new state, and add to table */
873 meas = wmem_new0(wmem_file_scope(), meas_state_t);
874 wmem_tree_insert32(meas_id_table, meas_id, meas);
877 /* Request - fill in t1 and tcv1 */
878 if ((action_type == ECPRI_MSG_TYPE_5_REQ) ||
879 (action_type == ECPRI_MSG_TYPE_5_FOLLOWUP)) {
880 meas->t1_known = true;
881 meas->t1 = time_stamp_s*1000000000 + time_stamp_ns;
882 meas->tcv1 = comp_val;
883 meas->t1_frame_number = pinfo->num;
885 /* Response - fill in t2 and tcv2 */
886 else {
887 meas->t2_known = true;
888 meas->t2 = time_stamp_s*1000000000 + time_stamp_ns;
889 meas->tcv2 = comp_val;
890 meas->t2_frame_number = pinfo->num;
893 /* Do calculation if possible */
894 if (meas->t1_known && meas->t2_known) {
895 meas_result_t *result = wmem_new0(wmem_file_scope(), meas_result_t);
896 result->delay_in_ns = (meas->t2 - meas->tcv2) - (meas->t1 - meas->tcv1);
897 result->request_frame = meas->t1_frame_number;
898 result->response_frame = meas->t2_frame_number;
899 /* Insert result for this frame and the requesting frame.. */
900 wmem_tree_insert32(meas_results_table, meas->t2_frame_number, result);
901 wmem_tree_insert32(meas_results_table, meas->t1_frame_number, result);
904 else {
905 /* Subsequent passes, show any calculated delays */
906 meas_result_t *result = wmem_tree_lookup32(meas_results_table, pinfo->num);
907 if (result) {
908 proto_item *delay_ti = proto_tree_add_uint64(ecpri_tree, hf_one_way_delay_measurement_calculated_delay,
909 tvb, 0, 0, result->delay_in_ns);
910 PROTO_ITEM_SET_GENERATED(delay_ti);
912 /* Link to other frame involved in the calculation */
913 proto_item *frame_ti;
914 if (action_type == ECPRI_MSG_TYPE_5_RESPONSE) {
915 frame_ti = proto_tree_add_uint(ecpri_tree, hf_one_way_delay_measurement_calculated_delay_request_frame,
916 tvb, 0, 0, result->request_frame);
917 col_append_fstr(pinfo->cinfo, COL_INFO, " [Delay=%" PRIu64 "uns]", result->delay_in_ns);
919 else {
920 frame_ti = proto_tree_add_uint(ecpri_tree, hf_one_way_delay_measurement_calculated_delay_response_frame,
921 tvb, 0, 0, result->response_frame);
923 PROTO_ITEM_SET_GENERATED(frame_ti);
928 break;
930 case ECPRI_MESSAGE_TYPE_REMOTE_RESET: /* Message Type 6: 3.2.4.7. Remote Reset */
931 if (payload_size < ECPRI_MSG_TYPE_6_PAYLOAD_MIN_LENGTH)
933 expert_add_info_format(
934 pinfo, ti_payload_size, &ei_payload_size,
935 "Payload Size %u is too small for encoding Message Type %u. Should be min. %d",
936 payload_size, msg_type, ECPRI_MSG_TYPE_6_PAYLOAD_MIN_LENGTH);
938 offset += payload_size;
939 break;
942 if (remaining_length >= ECPRI_MSG_TYPE_6_PAYLOAD_MIN_LENGTH)
944 proto_tree_add_item(ecpri_tree, hf_remote_reset_reset_id, tvb, offset, 2, ENC_BIG_ENDIAN);
945 offset += 2;
946 proto_tree_add_item(ecpri_tree, hf_remote_reset_reset_code, tvb, offset, 1, ENC_NA);
947 offset += 1;
948 remaining_length -= ECPRI_MSG_TYPE_6_PAYLOAD_MIN_LENGTH;
949 if (remaining_length >= payload_size - ECPRI_MSG_TYPE_6_PAYLOAD_MIN_LENGTH)
951 proto_tree_add_item(ecpri_tree, hf_remote_reset_vendor_specific_payload, tvb, offset, payload_size - ECPRI_MSG_TYPE_6_PAYLOAD_MIN_LENGTH, ENC_NA);
952 offset += payload_size - ECPRI_MSG_TYPE_6_PAYLOAD_MIN_LENGTH;
955 break;
957 case ECPRI_MESSAGE_TYPE_EVENT_INDICATION: /* Message Type 7: 3.2.4.8. Event Indication */
958 if (payload_size < ECPRI_MSG_TYPE_7_PAYLOAD_MIN_LENGTH)
960 expert_add_info_format(
961 pinfo, ti_payload_size, &ei_payload_size,
962 "Payload Size %u is too small for encoding Message Type %u. Should be min. %d",
963 payload_size, msg_type, ECPRI_MSG_TYPE_7_PAYLOAD_MIN_LENGTH);
965 offset += payload_size;
966 break;
969 if (remaining_length >= ECPRI_MSG_TYPE_7_PAYLOAD_MIN_LENGTH)
971 proto_tree_add_item(ecpri_tree, hf_event_indication_event_id, tvb, offset, 1, ENC_NA);
972 offset += 1;
973 proto_tree_add_item_ret_uint(ecpri_tree, hf_event_indication_event_type, tvb, offset, 1, ENC_NA, &event_type);
974 offset += 1;
975 proto_tree_add_item(ecpri_tree, hf_event_indication_sequence_number, tvb, offset, 1, ENC_NA);
976 offset += 1;
977 ti_num_faults = proto_tree_add_item_ret_uint(ecpri_tree, hf_event_indication_number_of_faults_notifications, tvb, offset, 1, ENC_NA, &num_faults_notif);
978 offset += 1;
979 /* Only for Event Type Fault Indication (0x00) and Notification Indication (0x02) */
980 if (event_type == ECPRI_MSG_TYPE_7_FAULT_INDICATION || event_type == ECPRI_MSG_TYPE_7_NOTIF_INDICATION)
982 /* These two Event Types should have notifications or faults */
983 if (num_faults_notif == 0)
985 expert_add_info_format(
986 pinfo, ti_num_faults, &ei_number_faults,
987 "Number of Faults/Notif %u should be > 0",
988 num_faults_notif);
989 break;
992 /* Check Size of Elements */
993 const uint16_t expected_payload_size = ECPRI_MSG_TYPE_7_PAYLOAD_MIN_LENGTH + num_faults_notif * ECPRI_MSG_TYPE_7_ELEMENT_SIZE;
994 if (payload_size == expected_payload_size)
996 /* Dissect elements in loop */
997 for (uint32_t i = 0; i < num_faults_notif; i++)
999 element_item = proto_tree_add_item(ecpri_tree, hf_event_indication_element, tvb, offset, ECPRI_MSG_TYPE_7_ELEMENT_SIZE, ENC_NA);
1000 proto_item_prepend_text(element_item, "#%u: ", i + 1);
1001 element_tree = proto_item_add_subtree(element_item, ett_ecpri_element);
1003 proto_tree_add_item(element_tree, hf_event_indication_element_id, tvb, offset, 2, ENC_BIG_ENDIAN);
1004 offset += 2;
1005 proto_tree_add_item(element_tree, hf_event_indication_raise_cease, tvb, offset, 1, ENC_NA);
1006 ti_fault_notif = proto_tree_add_item_ret_uint(element_tree, hf_event_indication_fault_notification, tvb, offset, 2, ENC_BIG_ENDIAN, &fault_notif);
1008 /* Faults and Notifications cannot be mixed */
1009 const bool is_fault_event = event_type == ECPRI_MSG_TYPE_7_FAULT_INDICATION;
1010 const bool is_notif_event = event_type == ECPRI_MSG_TYPE_7_NOTIF_INDICATION;
1012 const bool is_fault_notif_in_fault_range = fault_notif <= ECPRI_MSG_TYPE_7_FAULTS_MAX;
1014 const bool is_fault_notif_in_notif_range =
1015 fault_notif >= ECPRI_MSG_TYPE_7_NOTIF_MIN &&
1016 fault_notif <= ECPRI_MSG_TYPE_7_NOTIF_MAX;
1018 const bool is_fault_notif_in_vendor_range =
1019 fault_notif >= ECPRI_MSG_TYPE_7_VENDOR_MIN &&
1020 fault_notif <= ECPRI_MSG_TYPE_7_VENDOR_MAX;
1022 if (is_fault_event && !(is_fault_notif_in_fault_range || is_fault_notif_in_vendor_range))
1024 expert_add_info_format(
1025 pinfo, ti_fault_notif, &ei_fault_notif,
1026 "Only Faults are permitted with Event Type Faults Indication (0x%.2X)",
1027 event_type);
1029 else if (is_notif_event && !(is_fault_notif_in_notif_range || is_fault_notif_in_vendor_range))
1031 expert_add_info_format(
1032 pinfo, ti_fault_notif, &ei_fault_notif,
1033 "Only Notifications are permitted with Event Type Notifications Indication (0x%.2X)",
1034 event_type);
1036 offset += 2;
1037 proto_tree_add_item(element_tree, hf_event_indication_additional_information, tvb, offset, 4, ENC_BIG_ENDIAN);
1038 offset += 4;
1041 else if (payload_size < expected_payload_size)
1043 expert_add_info_format(
1044 pinfo, ti_num_faults, &ei_number_faults,
1045 "Number of Faults/Notif %u is maybe too big",
1046 num_faults_notif);
1048 expert_add_info_format(
1049 pinfo, ti_payload_size, &ei_payload_size,
1050 "Payload Size is maybe too small: %u",
1051 payload_size);
1053 else
1055 expert_add_info_format(
1056 pinfo, ti_num_faults, &ei_number_faults,
1057 "Number of Faults/Notif %u is maybe too small",
1058 num_faults_notif);
1060 expert_add_info_format(
1061 pinfo, ti_payload_size, &ei_payload_size,
1062 "Payload Size is maybe too big: %u",
1063 payload_size);
1067 else if (
1068 event_type == ECPRI_MSG_TYPE_7_FAULT_INDICATION_ACK ||
1069 event_type == ECPRI_MSG_TYPE_7_SYNC_REQUEST ||
1070 event_type == ECPRI_MSG_TYPE_7_SYNC_ACK ||
1071 event_type == ECPRI_MSG_TYPE_7_SYNC_END_INDICATION)
1073 /* Number of Faults/Notifs should be 0, only 4 Byte possible*/
1074 if (payload_size > 4)
1076 expert_add_info_format(
1077 pinfo, ti_payload_size, &ei_payload_size,
1078 "Payload Size %u should be 4",
1079 payload_size);
1081 /* These Event Types shouldn't have faults or notifications */
1082 if (num_faults_notif != 0)
1084 expert_add_info_format(
1085 pinfo, ti_num_faults, &ei_number_faults,
1086 "Number of Faults/Notif %u should be 0",
1087 num_faults_notif);
1090 else
1092 /* These Event Types are reserved, don't know how to decode */
1093 if (num_faults_notif != 0)
1095 expert_add_info_format(
1096 pinfo, ti_num_faults, &ei_number_faults,
1097 "Number of Faults/Notif %u, but no knowledge about encoding, because Event Type is reserved.",
1098 num_faults_notif);
1102 break;
1104 case ECPRI_MESSAGE_TYPE_IWF_STARTUP: /* Message Type 8: 3.2.4.9. IWF Start-Up */
1105 if (payload_size < ECPRI_MSG_TYPE_8_PAYLOAD_MIN_LENGTH)
1107 expert_add_info_format(
1108 pinfo, ti_payload_size, &ei_payload_size,
1109 "Payload Size %u is too small for encoding Message Type %u. Should be min. %d",
1110 payload_size, msg_type, ECPRI_MSG_TYPE_8_PAYLOAD_MIN_LENGTH);
1112 offset += payload_size;
1113 break;
1116 if (remaining_length >= ECPRI_MSG_TYPE_8_PAYLOAD_MIN_LENGTH)
1118 proto_tree_add_item(ecpri_tree, hf_pc_id, tvb, offset, 2, ENC_BIG_ENDIAN);
1119 offset += 2;
1121 proto_tree_add_item(ecpri_tree, hf_iwf_start_up_hyperframe_number, tvb, offset, 1, ENC_BIG_ENDIAN);
1122 offset += 1;
1124 proto_tree_add_item(ecpri_tree, hf_iwf_start_up_subframe_number, tvb, offset, 1, ENC_BIG_ENDIAN);
1125 offset += 1;
1127 /* Time Stamp as nanoseconds */
1128 proto_tree_add_item(ecpri_tree, hf_iwf_start_up_timestamp, tvb, offset, 4, ENC_BIG_ENDIAN);
1129 offset += 4;
1131 /* F, S, r (skipped), Line Rate */
1132 proto_tree_add_item(ecpri_tree, hf_iwf_start_up_fec_bit_indicator, tvb, offset, 1, ENC_BIG_ENDIAN);
1133 proto_tree_add_item(ecpri_tree, hf_iwf_start_up_scrambling_bit_indicator, tvb, offset, 1, ENC_BIG_ENDIAN);
1134 proto_tree_add_item(ecpri_tree, hf_iwf_start_up_line_rate, tvb, offset, 1, ENC_BIG_ENDIAN);
1135 offset += 1;
1137 remaining_length -= ECPRI_MSG_TYPE_8_PAYLOAD_MIN_LENGTH;
1138 if (remaining_length >= payload_size - ECPRI_MSG_TYPE_8_PAYLOAD_MIN_LENGTH)
1140 proto_tree_add_item(ecpri_tree, hf_iwf_start_up_data_transferred, tvb, offset, payload_size - ECPRI_MSG_TYPE_8_PAYLOAD_MIN_LENGTH, ENC_NA);
1141 offset += payload_size - ECPRI_MSG_TYPE_8_PAYLOAD_MIN_LENGTH;
1144 break;
1145 case ECPRI_MESSAGE_TYPE_IWF_OPERATION: /* Message Type 9: 3.2.4.10. IWF Operation */
1146 //proto_tree_add_item(ecpri_tree, hf_pc_id, tvb, offset, 2, ENC_BIG_ENDIAN);
1147 //offset += 2;
1148 /* TODO: */
1149 proto_tree_add_expert(payload_tree, pinfo, &ei_ecpri_not_dis_yet, tvb, offset, payload_size);
1150 break;
1151 case ECPRI_MESSAGE_TYPE_IWF_MAPPING: /* Message Type 10: 3.2.4.11. IWF Mapping */
1152 //proto_tree_add_item(ecpri_tree, hf_pc_id, tvb, offset, 2, ENC_BIG_ENDIAN);
1153 //offset += 2;
1154 /* TODO: */
1155 proto_tree_add_expert(payload_tree, pinfo, &ei_ecpri_not_dis_yet, tvb, offset, payload_size);
1156 break;
1157 case ECPRI_MESSAGE_TYPE_IWF_DELAY_CONTROL: /* Message Type 11: 3.2.4.12. IWF Delay Control */
1158 if (payload_size != ECPRI_MSG_TYPE_11_PAYLOAD_LENGTH)
1160 expert_add_info_format(
1161 pinfo, ti_payload_size, &ei_payload_size,
1162 "Payload Size %u is too small or too big for encoding Message Type %u. Should be exactly %d",
1163 payload_size, msg_type, ECPRI_MSG_TYPE_11_PAYLOAD_LENGTH);
1165 offset += payload_size;
1166 break;
1169 if (remaining_length >= ECPRI_MSG_TYPE_11_PAYLOAD_LENGTH)
1171 proto_tree_add_item(ecpri_tree, hf_pc_id, tvb, offset, 2, ENC_BIG_ENDIAN);
1172 offset += 2;
1174 proto_tree_add_item(ecpri_tree, hf_iwf_delay_control_delay_control_id, tvb, offset, 1, ENC_BIG_ENDIAN);
1175 offset += 1;
1177 proto_item *ti_iwf_delay_control_action_type;
1178 uint32_t iwf_delay_control_action_type;
1179 ti_iwf_delay_control_action_type = proto_tree_add_item_ret_uint(
1180 ecpri_tree, hf_iwf_delay_control_action_type, tvb, offset, 1, ENC_NA, &iwf_delay_control_action_type);
1181 offset += 1;
1183 proto_item *ti_iwf_delay_control_delay_a;
1184 uint32_t iwf_delay_control_delay_a;
1185 ti_iwf_delay_control_delay_a = proto_tree_add_item_ret_uint(
1186 ecpri_tree, hf_iwf_delay_control_delay_a, tvb, offset, 4, ENC_BIG_ENDIAN, &iwf_delay_control_delay_a);
1187 proto_item_append_text(ti_iwf_delay_control_delay_a, " = %fns", iwf_delay_control_delay_a / 16.0);
1188 offset += 4;
1190 proto_item *ti_iwf_delay_control_delay_b;
1191 uint32_t iwf_delay_control_delay_b;
1192 ti_iwf_delay_control_delay_b = proto_tree_add_item_ret_uint(
1193 ecpri_tree, hf_iwf_delay_control_delay_b, tvb, offset, 4, ENC_BIG_ENDIAN, &iwf_delay_control_delay_b);
1194 proto_item_append_text(ti_iwf_delay_control_delay_b, " = %fns", iwf_delay_control_delay_b / 16.0);
1195 offset += 4;
1197 const bool is_action_type_req = iwf_delay_control_action_type == ECPRI_MSG_TYPE_11_REQUEST_GET_DELAYS;
1198 const bool are_delays_zero = iwf_delay_control_delay_a == 0 && iwf_delay_control_delay_b == 0;
1199 if (is_action_type_req && !are_delays_zero)
1201 expert_add_info_format(
1202 pinfo, ti_iwf_delay_control_action_type, &ei_iwf_delay_control_action_type,
1203 "Action Type %u is Request Get Delays, but Delays are not 0",
1204 iwf_delay_control_action_type);
1206 else if (!is_action_type_req && are_delays_zero)
1208 expert_add_info_format(
1209 pinfo, ti_iwf_delay_control_action_type, &ei_iwf_delay_control_action_type,
1210 "Action Type %u is not Request Get Delays, but Delays are 0",
1211 iwf_delay_control_action_type);
1214 break;
1215 default:
1216 /* Reserved or Vendor Specific */
1217 offset += payload_size;
1218 break;
1222 /* If Preference not chosen, Payload will be not decoded */
1223 else
1225 if ((unsigned int)(offset + payload_size) <= reported_length)
1227 offset += payload_size;
1230 } while (concatenation_bit != 0 && ((reported_length - offset) >= ECPRI_HEADER_LENGTH));
1232 /* Expecting last concatenation bit to be false */
1233 if (concatenation_bit != false)
1235 expert_add_info_format(pinfo, ti_c_bit, &ei_c_bit, "Last concatenation Bit is 1, should be 0");
1238 /* Not dissected buffer - any remainder passed to data dissector */
1239 if (offset != 0)
1241 next_tvb = tvb_new_subset_remaining(tvb, offset);
1242 call_data_dissector(next_tvb, pinfo, tree);
1245 /* Claiming entire frame */
1246 return reported_length;
1249 void proto_register_ecpri(void)
1251 static hf_register_info hf[] = {
1252 /* eCPRI Common Header */
1253 { &hf_common_header, { "eCPRI Common Header", "ecpri.header", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } },
1254 { &hf_common_header_ecpri_protocol_revision, { "Protocol Revision", "ecpri.revision", FT_UINT8, BASE_DEC, NULL, 0xF0, NULL, HFILL } },
1255 { &hf_common_header_reserved, { "Reserved", "ecpri.reserved", FT_UINT8, BASE_DEC, NULL, 0x0E, NULL, HFILL } },
1256 { &hf_common_header_c_bit, { "C-Bit", "ecpri.cbit", FT_BOOLEAN, 8, TFS(&tfs_c_bit), 0x01, "Concatenation indicator", HFILL } },
1257 { &hf_common_header_ecpri_message_type, { "Message Type", "ecpri.type", FT_UINT8, BASE_HEX|BASE_RANGE_STRING, RVALS(ecpri_msg_types), 0x0, NULL, HFILL } },
1258 { &hf_common_header_ecpri_payload_size, { "Payload Size", "ecpri.size", FT_UINT16, BASE_DEC, NULL, 0x0, "Size of eCPRI message payload in bytes", HFILL } },
1259 /* eCPRI Payload */
1260 { &hf_payload, { "eCPRI Payload", "ecpri.payload", FT_BYTES, SEP_COLON, NULL, 0x0, NULL, HFILL } },
1261 /* Common to several message types */
1262 { &hf_pc_id, { "PC_ID", "ecpri.pcid", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL } },
1263 /* Message Type 0: IQ Data */
1264 { &hf_iq_data_seq_id, { "SEQ_ID", "ecpri.iqd.seqid", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } },
1265 { &hf_iq_data_iq_samples_of_user_data, { "IQ Samples of User Data", "ecpri.iqd.iqdata", FT_BYTES, SEP_COLON, NULL, 0x0, NULL, HFILL } },
1266 /* Message Type 1: Bit Sequence */
1267 { &hf_bit_sequence_seq_id, { "SEQ_ID", "ecpri.bs.seqid", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } },
1268 { &hf_bit_sequence_bit_sequence_of_user_data, { "Bit Sequence", "ecpri.bs.bitseq", FT_BYTES, SEP_COLON, NULL, 0x0, NULL, HFILL } },
1269 /* Message Type 2: Real-Time Control Data */
1270 { &hf_real_time_control_data_rtc_id, { "RTC_ID", "ecpri.rtcd.rtcid", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } },
1271 { &hf_real_time_control_data_seq_id, { "SEQ_ID", "ecpri.rtcd.seqid", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } },
1272 { &hf_real_time_control_data_rtc_data, { "Real-Time Control Data", "ecpri.rtcd.rtcdata", FT_BYTES, SEP_COLON, NULL, 0x0, NULL, HFILL } },
1273 /* Message Type 3: Generic Data Transfer */
1274 { &hf_generic_data_transfer_seq_id, { "SEQ_ID", "ecpri.gdt.seqid", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL } },
1275 { &hf_generic_data_transfer_data_transferred, { "Data transferred", "ecpri.gdt.gendata", FT_BYTES, SEP_COLON, NULL, 0x0, NULL, HFILL } },
1276 /* Message Type 4: Remote Memory Access */
1277 { &hf_remote_memory_access_id, { "Remote Memory Access ID", "ecpri.rma.rmaid", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } },
1278 { &hf_remote_memory_access_read_write, { "Read/Write", "ecpri.rma.rw", FT_UINT8, BASE_HEX, VALS(remote_memory_access_read_write_coding), 0xF0, NULL, HFILL } },
1279 { &hf_remote_memory_access_request_response, { "Request/Response", "ecpri.rma.reqresp", FT_UINT8, BASE_HEX, VALS(remote_memory_access_request_response_coding), 0x0F, NULL, HFILL } },
1280 { &hf_remote_memory_access_element_id, { "Element ID", "ecpri.rma.elementid", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } },
1281 { &hf_remote_memory_access_address, { "Address", "ecpri.rma.address", FT_BYTES, SEP_COLON, NULL, 0x0, NULL, HFILL } },
1282 { &hf_remote_memory_access_data_length, { "Data Length", "ecpri.rma.datalength", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } },
1283 { &hf_remote_memory_access_data, { "Data", "ecpri.rma.rmadata", FT_BYTES, SEP_COLON, NULL, 0x0, NULL, HFILL } },
1284 /* Message Type 5: One-Way Delay Measurement */
1285 { &hf_one_way_delay_measurement_id, { "Measurement ID", "ecpri.owdm.measurementid", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } },
1286 { &hf_one_way_delay_measurement_action_type, { "Action Type", "ecpri.owdm.actiontype", FT_UINT8, BASE_HEX|BASE_RANGE_STRING, RVALS(one_way_delay_measurement_action_type_coding), 0x0, NULL, HFILL } },
1287 { &hf_one_way_delay_measurement_timestamp, { "Timestamp", "ecpri.owdm.timestamp", FT_BYTES, SEP_COLON, NULL, 0x0, NULL, HFILL } },
1288 { &hf_one_way_delay_measurement_timestamp_seconds, { "Seconds", "ecpri.owdm.sec", FT_UINT48, BASE_DEC|BASE_UNIT_STRING, UNS(&units_seconds), 0x0, NULL, HFILL } },
1289 { &hf_one_way_delay_measurement_timestamp_nanoseconds, { "Nanoseconds", "ecpri.owdm.nanosec", FT_UINT32, BASE_DEC|BASE_UNIT_STRING, UNS(&units_nanoseconds), 0x0, NULL, HFILL } },
1290 { &hf_one_way_delay_measurement_compensation_value, { "Compensation", "ecpri.owdm.compval", FT_INT64, BASE_DEC|BASE_UNIT_STRING, UNS(&units_nanosecond_nanoseconds), 0x0, NULL, HFILL } },
1291 { &hf_one_way_delay_measurement_compensation_value_subns, { "Compensation (subns)", "ecpri.owdm.compval-subns", FT_DOUBLE, BASE_NONE|BASE_UNIT_STRING, UNS(&units_nanosecond_nanoseconds), 0x0, NULL, HFILL } },
1292 { &hf_one_way_delay_measurement_dummy_bytes, { "Dummy bytes", "ecpri.owdm.owdmdata", FT_BYTES, SEP_COLON, NULL, 0x0, NULL, HFILL } },
1293 { &hf_one_way_delay_measurement_calculated_delay, { "Calculated Delay", "ecpri.owdm.calculated-delay", FT_UINT64, BASE_DEC, NULL, 0x0, "Calculated delay in ns", HFILL } },
1294 { &hf_one_way_delay_measurement_calculated_delay_request_frame, { "Request Frame", "ecpri.owdm.request-frame", FT_FRAMENUM, BASE_NONE, NULL, 0x0, "Request frame used in calculation", HFILL } },
1295 { &hf_one_way_delay_measurement_calculated_delay_response_frame, { "Response Frame", "ecpri.owdm.response-frame", FT_FRAMENUM, BASE_NONE, NULL, 0x0, "Response frame used to answer this request", HFILL } },
1296 /* Message Type 6: Remote Reset */
1297 { &hf_remote_reset_reset_id, { "Reset ID", "ecpri.rr.resetid", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } },
1298 { &hf_remote_reset_reset_code, { "Reset Code Op", "ecpri.rr.resetcode", FT_UINT8, BASE_HEX|BASE_RANGE_STRING, RVALS(remote_reset_reset_coding), 0x0, NULL, HFILL } },
1299 { &hf_remote_reset_vendor_specific_payload, { "Vendor Specific Payload", "ecpri.rr.vendorpayload", FT_BYTES, SEP_COLON, NULL, 0x0, NULL, HFILL } },
1300 /* Message Type 7: Event Indication */
1301 { &hf_event_indication_event_id, { "Event ID", "ecpri.ei.eventid", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } },
1302 { &hf_event_indication_event_type, { "Event Type", "ecpri.ei.eventtype", FT_UINT8, BASE_HEX|BASE_RANGE_STRING, RVALS(event_indication_event_type_coding), 0x0, NULL, HFILL } },
1303 { &hf_event_indication_sequence_number, { "Sequence Number", "ecpri.ei.seqnum", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } },
1304 { &hf_event_indication_number_of_faults_notifications, { "Number of Faults/Notifications", "ecpri.ei.numberfaultnotif", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } },
1305 { &hf_event_indication_element, { "Element", "ecpri.ei.element", FT_BYTES, SEP_COLON, NULL, 0x0, NULL, HFILL } },
1306 { &hf_event_indication_element_id, { "Element ID", "ecpri.ei.elementid", FT_UINT16, BASE_HEX|BASE_RANGE_STRING, RVALS(event_indication_element_id_coding), 0x0, NULL, HFILL } },
1307 { &hf_event_indication_raise_cease, { "Raise/Cease", "ecpri.ei.raisecease", FT_UINT8, BASE_HEX, VALS(event_indication_raise_ceased_coding), 0xF0, NULL, HFILL } },
1308 { &hf_event_indication_fault_notification, { "Fault/Notification", "ecpri.ei.faultnotif", FT_UINT16, BASE_HEX|BASE_RANGE_STRING, RVALS(event_indication_fault_notif_coding), 0x0FFF, NULL, HFILL } },
1309 { &hf_event_indication_additional_information, { "Additional Information", "ecpri.ei.addinfo", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL } },
1310 /* Message Type 8: IWF Start-Up */
1311 { &hf_iwf_start_up_hyperframe_number, { "Hyperframe Number #Z", "ecpri.iwfsu.hfn", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } },
1312 { &hf_iwf_start_up_subframe_number, { "Subframe Number #Y", "ecpri.iwfsu.sfn", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } },
1313 { &hf_iwf_start_up_timestamp, { "Timestamp", "ecpri.iwfsu.timestamp", FT_UINT32, BASE_DEC|BASE_UNIT_STRING, UNS(&units_nanoseconds), 0x0, NULL, HFILL } },
1314 { &hf_iwf_start_up_fec_bit_indicator, { "FEC Bit Indicator", "ecpri.iwfsu.fecbit", FT_BOOLEAN, 8, TFS(&tfs_enabled_disabled), 0x80, NULL, HFILL } },
1315 { &hf_iwf_start_up_scrambling_bit_indicator, { "Scrambling Bit Indicator", "ecpri.iwfsu.scramblingbit", FT_BOOLEAN, 8, TFS(&tfs_enabled_disabled), 0x40, NULL, HFILL } },
1316 { &hf_iwf_start_up_line_rate, { "Line Rate", "ecpri.iwfsu.linerate", FT_UINT8, BASE_HEX|BASE_RANGE_STRING, RVALS(iwf_start_up_line_rate_coding), 0x1F, NULL, HFILL } },
1317 { &hf_iwf_start_up_data_transferred, { "Data transferred", "ecpri.iwfsu.vendorpayload", FT_BYTES, SEP_COLON, NULL, 0x0, NULL, HFILL } },
1318 /* Message Type 11: IWF Delay Control */
1319 { &hf_iwf_delay_control_delay_control_id, { "Delay Control ID", "ecpri.iwfdc.id", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } },
1320 { &hf_iwf_delay_control_action_type, { "Action Type", "ecpri.iwfdc.actiontype", FT_UINT8, BASE_HEX|BASE_RANGE_STRING, RVALS(iwf_delay_control_action_type_coding), 0x0, NULL, HFILL } },
1321 { &hf_iwf_delay_control_delay_a, { "Delay A", "ecpri.iwfdc.delaya", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
1322 { &hf_iwf_delay_control_delay_b, { "Delay B", "ecpri.iwfdc.delayb", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
1325 /* Setup protocol subtree array */
1326 static int *ett[] = {
1327 &ett_ecpri,
1328 &ett_ecpri_header,
1329 &ett_ecpri_payload,
1330 &ett_ecpri_timestamp,
1331 &ett_ecpri_element
1334 static ei_register_info ei[] = {
1335 { &ei_ecpri_frame_length, { "ecpri.frame.length.invalid", PI_PROTOCOL, PI_ERROR, "Invalid eCPRI Frame Length", EXPFILL }},
1336 { &ei_payload_size, { "ecpri.payload.size.invalid", PI_PROTOCOL, PI_ERROR, "Invalid Payload Size", EXPFILL }},
1337 { &ei_data_length, { "ecpri.data.length.invalid", PI_PROTOCOL, PI_ERROR, "Invalid Data Length", EXPFILL }},
1338 { &ei_comp_val, { "ecpri.comp.val.invalid", PI_PROTOCOL, PI_ERROR, "Invalid Compensation Value", EXPFILL }},
1339 { &ei_time_stamp, { "ecpri.time.stamp.invalid", PI_PROTOCOL, PI_ERROR, "Invalid Time Stamp", EXPFILL }},
1340 { &ei_compensation_value_nonzero, { "ecpri.compensation-value.nonzero", PI_PROTOCOL, PI_WARN, "Compensation Value should be zero", EXPFILL }},
1341 { &ei_c_bit, { "ecpri.concat.bit.invalid", PI_PROTOCOL, PI_ERROR, "Invalid Concatenation Bit", EXPFILL }},
1342 { &ei_fault_notif, { "ecpri.fault.notif.invalid", PI_PROTOCOL, PI_ERROR, "Invalid Fault/Notification", EXPFILL }},
1343 { &ei_number_faults, { "ecpri.num.faults.invalid", PI_PROTOCOL, PI_ERROR, "Invalid Number of Faults", EXPFILL }},
1344 { &ei_iwf_delay_control_action_type, { "ecpri.action.type.invalid", PI_PROTOCOL, PI_ERROR, "Invalid Action Type", EXPFILL }},
1345 { &ei_ecpri_not_dis_yet, { "ecpri.not_dissected_yet", PI_PROTOCOL, PI_NOTE, "Not dissected yet", EXPFILL }}
1348 expert_module_t* expert_ecpri;
1349 module_t* ecpri_module;
1351 /* Register the protocol name and description */
1352 proto_ecpri = proto_register_protocol("evolved Common Public Radio Interface", /* Protoname */
1353 "eCPRI", /* Proto Shortname */
1354 "ecpri"); /* Proto Abbrev */
1355 ecpri_handle = register_dissector("ecpri", dissect_ecpri, proto_ecpri);
1358 /* Required function calls to register the header fields and subtrees used */
1359 proto_register_field_array(proto_ecpri, hf, array_length(hf));
1360 proto_register_subtree_array(ett, array_length(ett));
1361 /* Register Expert Info */
1362 expert_ecpri = expert_register_protocol(proto_ecpri);
1363 expert_register_field_array(expert_ecpri, ei, array_length(ei));
1364 /* Register Preference */
1365 ecpri_module = prefs_register_protocol(proto_ecpri, NULL);
1366 /* If not set, it shows which message type was used, but no decoding of payload */
1367 prefs_register_bool_preference(ecpri_module,
1368 "ecpripref.msg.decoding",
1369 "Decode Message Types",
1370 "Decode the Message Types according to eCPRI Specification V2.0",
1371 &pref_message_type_decoding);
1373 meas_id_table = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
1374 meas_results_table = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
1377 void proto_reg_handoff_ecpri(void)
1379 dissector_add_uint("ethertype", ETHERTYPE_ECPRI, ecpri_handle); /* Ethertypes 0xAEFE */
1380 dissector_add_uint_range_with_preference("udp.port", "", ecpri_handle); /* UDP Port Preference */
1382 oran_fh_handle = find_dissector("oran_fh_cus");
1386 * Editor modelines - https://www.wireshark.org/tools/modelines.html
1388 * Local variables:
1389 * c-basic-offset: 4
1390 * tab-width: 8
1391 * indent-tabs-mode: nil
1392 * End:
1394 * vi: set shiftwidth=4 tabstop=8 expandtab:
1395 * :indentSize=4:tabSize=8:noTabs=true: