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 * ------------------------------------------------------------------------------------------------
24 #include <epan/packet.h>
25 #include <epan/prefs.h>
26 #include <epan/expert.h>
27 #include <epan/etypes.h>
29 #include <epan/unit_strings.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 */
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 /**************************************************************************************************/
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" },
262 /**************************************************************************************************/
263 /* Field Encoding of Message Type 4: Remote Memory Access */
264 /**************************************************************************************************/
265 static const value_string remote_memory_access_read_write_coding
[] = {
268 { 0x2, "Write_No_resp" },
285 static const value_string remote_memory_access_request_response_coding
[] = {
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" },
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" },
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" },
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" },
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" },
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" },
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" },
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" },
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
;
437 /* Inputs for delay calculation */
441 uint32_t t1_frame_number
;
445 uint32_t t2_frame_number
;
449 uint64_t delay_in_ns
;
450 uint32_t request_frame
;
451 uint32_t response_frame
;
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_
)
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
;
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
;
506 reported_length
= tvb_reported_length(tvb
);
508 /* Check of eCPRI min. length (header-length) */
509 if (reported_length
< ECPRI_HEADER_LENGTH
)
512 /* Set column of protocol eCPRI */
513 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "eCPRI");
514 col_clear(pinfo
->cinfo
, COL_INFO
);
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 */
530 offset
= offset
+ 4 - (offset
% 4);
533 /* Read ahead to eCPRI Payload Size */
534 payload_size
= tvb_get_ntohs(tvb
, offset
+2);
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
);
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
);
560 proto_tree_add_item(header_tree
, hf_common_header_reserved
, tvb
, offset
, 1, ENC_NA
);
562 ti_c_bit
= proto_tree_add_item_ret_boolean(header_tree
, hf_common_header_c_bit
, tvb
, offset
, 1, ENC_NA
, &concatenation_bit
);
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
));
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
);
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 */
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
);
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
;
617 /* ORAN FH-CUS dissector didn't handle it */
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
;
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
);
637 proto_tree_add_item(ecpri_tree
, hf_iq_data_seq_id
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
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
;
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
;
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
);
663 proto_tree_add_item(ecpri_tree
, hf_bit_sequence_seq_id
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
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
;
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
;
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
);
691 proto_tree_add_item(ecpri_tree
, hf_real_time_control_data_seq_id
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
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
;
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
;
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
);
718 proto_tree_add_item(ecpri_tree
, hf_generic_data_transfer_seq_id
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
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
;
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
;
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
);
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
);
748 proto_tree_add_item(ecpri_tree
, hf_remote_memory_access_element_id
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
750 proto_tree_add_item(ecpri_tree
, hf_remote_memory_access_address
, tvb
, offset
, 6, ENC_NA
);
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
);
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
);
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
);
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
;
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
);
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
);
804 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " (MeasId=%u, ActionType=%s)",
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
);
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
);
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"));
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
,
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
&&
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 */
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 */
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
);
905 /* Subsequent passes, show any calculated delays */
906 meas_result_t
*result
= wmem_tree_lookup32(meas_results_table
, pinfo
->num
);
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
);
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
);
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
;
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
);
946 proto_tree_add_item(ecpri_tree
, hf_remote_reset_reset_code
, tvb
, offset
, 1, ENC_NA
);
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
;
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
;
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
);
973 proto_tree_add_item_ret_uint(ecpri_tree
, hf_event_indication_event_type
, tvb
, offset
, 1, ENC_NA
, &event_type
);
975 proto_tree_add_item(ecpri_tree
, hf_event_indication_sequence_number
, tvb
, offset
, 1, ENC_NA
);
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
);
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",
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
);
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)",
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)",
1037 proto_tree_add_item(element_tree
, hf_event_indication_additional_information
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
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",
1048 expert_add_info_format(
1049 pinfo
, ti_payload_size
, &ei_payload_size
,
1050 "Payload Size is maybe too small: %u",
1055 expert_add_info_format(
1056 pinfo
, ti_num_faults
, &ei_number_faults
,
1057 "Number of Faults/Notif %u is maybe too small",
1060 expert_add_info_format(
1061 pinfo
, ti_payload_size
, &ei_payload_size
,
1062 "Payload Size is maybe too big: %u",
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",
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",
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.",
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
;
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
);
1121 proto_tree_add_item(ecpri_tree
, hf_iwf_start_up_hyperframe_number
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1124 proto_tree_add_item(ecpri_tree
, hf_iwf_start_up_subframe_number
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1127 /* Time Stamp as nanoseconds */
1128 proto_tree_add_item(ecpri_tree
, hf_iwf_start_up_timestamp
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
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
);
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
;
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);
1149 proto_tree_add_expert(payload_tree
, pinfo
, &ei_ecpri_not_dis_yet
, tvb
, offset
, payload_size
);
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);
1155 proto_tree_add_expert(payload_tree
, pinfo
, &ei_ecpri_not_dis_yet
, tvb
, offset
, payload_size
);
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
;
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
);
1174 proto_tree_add_item(ecpri_tree
, hf_iwf_delay_control_delay_control_id
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
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
);
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);
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);
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
);
1216 /* Reserved or Vendor Specific */
1217 offset
+= payload_size
;
1222 /* If Preference not chosen, Payload will be not decoded */
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 */
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
} },
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
[] = {
1330 &ett_ecpri_timestamp
,
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
1391 * indent-tabs-mode: nil
1394 * vi: set shiftwidth=4 tabstop=8 expandtab:
1395 * :indentSize=4:tabSize=8:noTabs=true: