Updated E2AP ports
[o-du/l2.git] / src / codec_utils / e2ap.lua
1 ----------------------------------------
2 -- script-name: e2ap.lua
3 ----------------------------------------
4
5 ----------------------------------------
6 -- creates a Proto object, but doesn't register it yet
7 local E2AP = Proto("E2AP","E2 Application Protocol")
8
9 ----------------------------------------                
10 local E2apPduEnum = {
11                 [0] = "initiatingMessage",
12                 [1] = "successfulOutcome",
13                 [2] = "unsuccessfulOutcome" }
14         
15 local ProcedureCodeE2 = {
16                 [1] = "ProcedureCodeE2_id_E2setup",
17                 [2] = "ProcedureCodeE2_id_ErrorIndicationE2",
18                 [3] = "ProcedureCodeE2_id_Reset",
19                 [4] = "ProcedureCodeE2_id_RICcontrol",
20                 [5] = "ProcedureCodeE2_id_RICindication",
21                 [6] = "ProcedureCodeE2_id_RICserviceQuery",
22                 [7] = "ProcedureCodeE2_id_RICserviceUpdate",
23                 [8] = "ProcedureCodeE2_id_RICsubscription",
24                 [9] = "ProcedureCodeE2_id_RICsubscriptionDelete" }
25
26 local CriticalityE2 ={
27                 [0] = "CriticalityE2_reject",
28                 [1] = "CriticalityE2_ignore",
29                 [2] = "CriticalityE2_notify" }
30                 
31 local InitiatingMessageE2ValuePrEnum = {
32                 [0] = "InitiatingMessageE2__value_PR_NOTHING",
33                 [1] = "InitiatingMessageE2__value_PR_RICsubscriptionRequest",
34                 [2] = "InitiatingMessageE2__value_PR_RICsubscriptionDeleteRequest",
35                 [3] = "InitiatingMessageE2__value_PR_RICserviceUpdate",
36                 [4] = "InitiatingMessageE2__value_PR_RICcontrolRequest",
37                 [5] = "InitiatingMessageE2__value_PR_E2setupRequest",
38                 [6] = "InitiatingMessageE2__value_PR_ResetRequest",
39                 [7] = "InitiatingMessageE2__value_PR_RICindication",
40                 [8] = "InitiatingMessageE2__value_PR_RICserviceQuery",
41                 [9] = "InitiatingMessageE2__value_PR_ErrorIndicationE2" }
42         
43 --payload fields start
44 local RIC_indication = "Ric Indication Message"
45
46 local Initiating_Message_Type_Value = {
47         value = "value"--, nil,InitiatingMessageE2ValuePrEnum, 0xFF)
48 }
49
50 local InitiatingMessageE2 = {
51         Initiating_Message_E2 = "Initiating Message E2",
52         procedureCode = "ProcedureCode: ",
53         criticality   = "Criticality: "
54 }
55         --value       = ProtoField.uint16("Initiating_Message_Type_Value.value", "value")
56
57 local InitiatingMessageE2__value_u = {
58 RICsubscriptionRequest           = "RIC subscription Request",
59 RICsubscriptionDeleteRequest = "RIC subscription Delete Request",
60 RICserviceUpdate                         = "RIC service Update",
61 RICcontrolRequest                        = "RIC control Request",
62 E2setupRequest                           = "E2 setup Request",
63 ResetRequest                             = "Reset Request",
64 RICindication                            = "RIC indication",
65 RICserviceQuery                          = "RIC service Query",
66 ErrorIndicationE2                        = "Error Indication E2"
67 }
68
69 local successfulOutcomeE2 = {
70         successOutcomeMsg = "successfulOutcome",
71         procedureCode = "procedureCode: ",
72         criticality = "criticality: "
73 }
74
75 local e2SetupResponse = {
76         e2SetupResponseMsg = "E2SetupResponse"
77 }
78
79 E2AP.fields = {
80         --successfulOutcomeE2.procedureCode
81 }
82
83 function addE2apInitiatingMessageToTree(tvbuf, tree, offset, endianness)
84
85         local info = tvbuf:range(offset, 1)
86         local initiatingMessageE2Tree = tree:add(info, InitiatingMessageE2.Initiating_Message_E2)
87
88         local procId = tvbuf:range(offset,1):le_uint()
89         strId = tostring(ProcedureCodeE2[procId]) .. " (" .. tostring(procId) ..")"
90         tree:add(tvbuf:range(offset,1), InitiatingMessageE2.procedureCode .. strId)
91         offset = offset + 1
92
93         local criticalityId = tvbuf:range(offset,1):le_uint()
94         strId = tostring(CriticalityE2[criticalityId]) .. " (" .. tostring(criticalityId) ..")"
95         tree:add(tvbuf:range(offset,1), InitiatingMessageE2.criticality .. strId)
96         offset = offset + 1
97
98         -- value cfg
99         --local valueinitiatingMessageType = initiatingMessageE2Tree:add(tvbuf:range(offset,offset),Initiating_Message_E2.value)
100
101 end
102
103 function addE2SetupResponseToTree(tvbuf, tree, offset, pktlen, endianness)
104         local valueTree = tree:add(tvbuf:range(offset, (pktlen - offset)), "value")
105                 local e2SetupResponseTree = valueTree:add(e2SetupResponse.e2SetupResponseMsg)
106                         
107                         local extBit = tvbuf:range(offset,1):le_uint()
108                         if(extBit == 0) then
109                                 e2SetupResponseTree:add(tvbuf:range(offset,1), "<" .. extBit .. "... .... Extension Bit: FALSE>")
110                         else
111                                 e2SetupResponseTree:add(tvbuf:range(offset,1), "<" .. extBit .. "... .... Extension Bit: TRUE>")
112                         end
113                         offset = offset + 1
114                         
115                         local seqLen = tvbuf:range(offset, 2):le_uint()
116                         e2SetupResponseTree:add(tvbuf:range(offset, 2), "<Sequence-Of Length: " .. seqLen .. ">")
117                         offset = offset + 2
118                         
119 end
120
121 function addE2apSuccessfulOutcomeToTree(tvbuf, tree, offset, pktlen, endianness)
122         local successfulOutcomeTree = tree:add(tvbuf:range(offset, (pktlen-offset)), successfulOutcomeE2.successOutcomeMsg)
123                 local procId = tvbuf:range(offset,1):le_uint()
124                 strId = tostring(ProcedureCodeE2[procId]) .. " (" .. tostring(procId) ..")"
125                 successfulOutcomeTree:add(tvbuf:range(offset,1), successfulOutcomeE2.procedureCode .. strId)
126                 offset = offset + 1
127                 
128                 local criticalityId = tvbuf:range(offset,1):le_uint()
129                 successfulOutcomeTree:add(tvbuf:range(offset,1), "<Enumerated Index: " .. criticalityId ..">")
130         strId = tostring(CriticalityE2[criticalityId]) .. " (" .. tostring(criticalityId) ..")"
131         successfulOutcomeTree:add(tvbuf:range(offset,1), successfulOutcomeE2.criticality .. strId)
132         offset = offset + 1
133                 
134                 local valueLen = tvbuf:range(offset,1):le_uint()
135                 successfulOutcomeTree:add(tvbuf:range(offset,1), "<Value length: " .. valueLen ..">")
136                 offset = offset + 1
137                 
138                 if(procId == 1) then
139                         addE2SetupResponseToTree(tvbuf, successfulOutcomeTree, offset, pktlen, endianness)
140                 end
141 end
142 ----------------------------------------
143 -- The following creates the callback function for the dissector.
144 -- The 'tvbuf' is a Tvb object, 'pktinfo' is a Pinfo object, and 'root' is a TreeItem object.
145 -- Whenever Wireshark dissects a packet that our Protocol is hooked into, it will call
146 -- this function and pass it these arguments for the packet it's dissecting.
147 function E2AP.dissector(tvbuf,pktinfo,root)
148
149     -- set the protocol column to show our protocol name
150     pktinfo.cols.protocol:set("E2AP")
151
152     -- We want to check that the packet size is rational during dissection, so let's get the length of the
153     -- packet buffer (Tvb).
154     local pktlen = tvbuf:reported_length_remaining()
155
156     -- We start by adding our protocol to the dissection display tree.
157     -- A call to tree:add_packet_field() returns the child created, so we can add more "under" it using that return value.
158     -- The second argument is how much of the buffer/packet this added tree item covers/represents
159     local offset = 0
160     stream = " "
161     local endianness = string.byte(string.dump(function() end), 7)
162     local tree = root:add(E2AP, tvbuf:range(offset,pktlen))
163
164        
165     -- Now let's add our protocol header fields under the protocol tree we just created.
166
167     local fByte = tvbuf:range(offset,1):le_uint()
168         local apiId = bit.rshift(fByte, 5)
169         tree:add(tvbuf:range(offset,1), "<Choice Index: " .. apiId ..">")
170     strId = tostring(E2apPduEnum[apiId]) .. " (" .. tostring(apiId) ..")"
171     tree:add(tvbuf:range(offset,1), "E2AP-PDU: " .. strId)
172         offset = offset + 1
173
174     -- Now let's add our protocol fields under the protocol tree we just created.
175         if (apiId == 0) then
176                 addE2apInitiatingMessageToTree(tvbuf, tree, offset, endianness)
177         end
178         if(apiId == 1) then
179                 addE2apSuccessfulOutcomeToTree(tvbuf, tree, offset, pktlen, endianness)
180         end
181         
182 end -- end of dissector funciton
183
184         ----------------------------------------
185         -- we want to have our protocol dissection invoked for a specific UDP port,
186         -- so get the udp dissector table and add our protocol to it
187         DissectorTable.get("sctp.port"):add(36421, E2AP)
188         -- our protocol (Proto) gets automatically registered after this script finishes loading
189         ----------------------------------------
190