blob: 1f70bd2e510e64f641b63660462bdd9643f6a14e [file] [log] [blame]
Holger Hildebrandtfa074992020-03-27 15:42:06 +00001/*
2 * Copyright 2020-present Open Networking Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000017//Package adaptercoreonu provides the utility for onu devices, flows and statistics
18package adaptercoreonu
Holger Hildebrandtfa074992020-03-27 15:42:06 +000019
20import (
21 "container/list"
22 "context"
23 "encoding/binary"
24 "encoding/hex"
25 "errors"
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +000026 "strconv"
Holger Hildebrandtfa074992020-03-27 15:42:06 +000027 "sync"
mpagenkodff5dda2020-08-28 11:52:01 +000028
Holger Hildebrandtfa074992020-03-27 15:42:06 +000029 //"time"
30
31 "github.com/google/gopacket"
32 // TODO!!! Some references could be resolved auto, but some need specific context ....
33 gp "github.com/google/gopacket"
34
35 "github.com/opencord/omci-lib-go"
36 me "github.com/opencord/omci-lib-go/generated"
37 "github.com/opencord/voltha-lib-go/v3/pkg/adapters/adapterif"
38
39 //"github.com/opencord/voltha-lib-go/v3/pkg/kafka"
40 "github.com/opencord/voltha-lib-go/v3/pkg/log"
41 ic "github.com/opencord/voltha-protos/v3/go/inter_container"
42 //"github.com/opencord/voltha-protos/v3/go/openflow_13"
43 //"github.com/opencord/voltha-protos/v3/go/voltha"
44)
45
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +000046// ### OMCI related definitions - retrieved from Python adapter code/trace ####
Holger Hildebrandtfa074992020-03-27 15:42:06 +000047const ConstDefaultOmciTimeout = 10 // ( 3 ?) Seconds
48
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +000049const galEthernetEID = uint16(1)
50const maxGemPayloadSize = uint16(48)
51const connectivityModeValue = uint8(5)
Himani Chawla4d908332020-08-31 12:30:20 +053052
53//const defaultTPID = uint16(0x8100)
54//const broadComDefaultVID = uint16(4091)
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +000055const macBridgeServiceProfileEID = uint16(0x201) // TODO: most all these need better definition or tuning
56const ieeeMapperServiceProfileEID = uint16(0x8001)
57const macBridgePortAniEID = uint16(0x2102)
58
59// ### OMCI related definitions - end
60
Holger Hildebrandtccd390c2020-05-29 13:49:04 +000061//CallbackPairEntry to be used for OMCI send/receive correlation
62type CallbackPairEntry struct {
63 cbRespChannel chan Message
64 cbFunction func(*omci.OMCI, *gp.Packet, chan Message) error
65}
66
Holger Hildebrandtfa074992020-03-27 15:42:06 +000067//CallbackPair to be used for ReceiveCallback init
68type CallbackPair struct {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +000069 cbKey uint16
70 cbEntry CallbackPairEntry
Holger Hildebrandtfa074992020-03-27 15:42:06 +000071}
72
73type omciTransferStructure struct {
74 txFrame []byte
75 timeout int
76 retry int
77 highPrio bool
78}
79
80//OmciCC structure holds information needed for OMCI communication (to/from OLT Adapter)
81type OmciCC struct {
82 enabled bool
83 pOnuDeviceEntry *OnuDeviceEntry
84 deviceID string
85 pBaseDeviceHandler *DeviceHandler
86 coreProxy adapterif.CoreProxy
87 adapterProxy adapterif.AdapterProxy
88 supportExtMsg bool
89 //txRequest
90 //rxResponse
91 //pendingRequest
92 txFrames, txOnuFrames uint32
93 rxFrames, rxOnuFrames, rxOnuDiscards uint32
94
95 // OMCI params
96 mutexTid sync.Mutex
97 tid uint16
98 mutexHpTid sync.Mutex
99 hpTid uint16
100 uploadSequNo uint16
101 uploadNoOfCmds uint16
102
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000103 mutexTxQueue sync.Mutex
104 txQueue *list.List
105 mutexRxSchedMap sync.Mutex
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000106 rxSchedulerMap map[uint16]CallbackPairEntry
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000107 pLastTxMeInstance *me.ManagedEntity
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000108}
109
110//NewOmciCC constructor returns a new instance of a OmciCC
111//mib_db (as well as not inluded alarm_db not really used in this code? VERIFY!!)
Himani Chawla4d908332020-08-31 12:30:20 +0530112func NewOmciCC(ctx context.Context, onuDeviceEntry *OnuDeviceEntry,
113 deviceID string, deviceHandler *DeviceHandler,
114 coreProxy adapterif.CoreProxy, adapterProxy adapterif.AdapterProxy) *OmciCC {
115 logger.Infow("init-omciCC", log.Fields{"device-id": deviceID})
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000116 var omciCC OmciCC
117 omciCC.enabled = false
Himani Chawla4d908332020-08-31 12:30:20 +0530118 omciCC.pOnuDeviceEntry = onuDeviceEntry
119 omciCC.deviceID = deviceID
120 omciCC.pBaseDeviceHandler = deviceHandler
121 omciCC.coreProxy = coreProxy
122 omciCC.adapterProxy = adapterProxy
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000123 omciCC.supportExtMsg = false
124 omciCC.txFrames = 0
125 omciCC.txOnuFrames = 0
126 omciCC.rxFrames = 0
127 omciCC.rxOnuFrames = 0
128 omciCC.rxOnuDiscards = 0
129 omciCC.tid = 0x1
130 omciCC.hpTid = 0x8000
131 omciCC.uploadSequNo = 0
132 omciCC.uploadNoOfCmds = 0
133
134 omciCC.txQueue = list.New()
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000135 omciCC.rxSchedulerMap = make(map[uint16]CallbackPairEntry)
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000136
137 return &omciCC
138}
139
140// Rx handler for omci messages
141func (oo *OmciCC) ReceiveOnuMessage(ctx context.Context, omciMsg *omci.OMCI) error {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000142 logger.Debugw("rx-onu-autonomous-message", log.Fields{"omciMsgType": omciMsg.MessageType,
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000143 "payload": hex.EncodeToString(omciMsg.Payload)})
144 /*
145 msgType = rxFrame.fields["message_type"] //assumed OmciOperationsValue
146 rxOnuFrames++
147
148 switch msgType {
149 case AlarmNotification:
150 {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000151 logger.Info("Unhandled: received-onu-alarm-message")
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000152 // python code was:
153 //if msg_type == EntityOperations.AlarmNotification.value:
154 // topic = OMCI_CC.event_bus_topic(self._device_id, RxEvent.Alarm_Notification)
155 // self.reactor.callLater(0, self.event_bus.publish, topic, msg)
156 //
157 return errors.New("RxAlarmNotification unimplemented")
158 }
159 case AttributeValueChange:
160 {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000161 logger.Info("Unhandled: received-attribute-value-change")
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000162 // python code was:
163 //elif msg_type == EntityOperations.AttributeValueChange.value:
164 // topic = OMCI_CC.event_bus_topic(self._device_id, RxEvent.AVC_Notification)
165 // self.reactor.callLater(0, self.event_bus.publish, topic, msg)
166 //
167 return errors.New("RxAttributeValueChange unimplemented")
168 }
169 case TestResult:
170 {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000171 logger.Info("Unhandled: received-test-result")
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000172 // python code was:
173 //elif msg_type == EntityOperations.TestResult.value:
174 // topic = OMCI_CC.event_bus_topic(self._device_id, RxEvent.Test_Result)
175 // self.reactor.callLater(0, self.event_bus.publish, topic, msg)
176 //
177 return errors.New("RxTestResult unimplemented")
178 }
179 default:
180 {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000181 logger.Errorw("rx-onu-unsupported-autonomous-message", log.Fields{"msgType": msgType})
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000182 rxOnuDiscards++
183 return errors.New("RxOnuMsgType unimplemented")
184 }
185 }
186 */
Himani Chawla4d908332020-08-31 12:30:20 +0530187 return errors.New("receiveOnuMessage unimplemented")
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000188}
189
190// Rx handler for onu messages
191// e.g. would call ReceiveOnuMessage() in case of TID=0 or Action=test ...
192func (oo *OmciCC) ReceiveMessage(ctx context.Context, rxMsg []byte) error {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000193 //logger.Debugw("cc-receive-omci-message", log.Fields{"RxOmciMessage-x2s": hex.EncodeToString(rxMsg)})
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000194 if len(rxMsg) >= 44 { // then it should normally include the BaseFormat trailer Len
195 // NOTE: autocorrection only valid for OmciBaseFormat, which is not specifically verified here!!!
196 // (am extendedFormat message could be destroyed this way!)
197 trailerLenData := rxMsg[42:44]
198 trailerLen := binary.BigEndian.Uint16(trailerLenData)
mpagenko1cc3cb42020-07-27 15:24:38 +0000199 //logger.Debugw("omci-received-trailer-len", log.Fields{"Length": trailerLen})
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000200 if trailerLen != 40 { // invalid base Format entry -> autocorrect
201 binary.BigEndian.PutUint16(rxMsg[42:44], 40)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000202 logger.Debug("cc-corrected-omci-message: trailer len inserted")
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000203 }
204 } else {
Himani Chawla4d908332020-08-31 12:30:20 +0530205 logger.Errorw("received omci-message too small for OmciBaseFormat - abort", log.Fields{"Length": len(rxMsg)})
206 return errors.New("rxOmciMessage too small for BaseFormat")
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000207 }
208
209 packet := gopacket.NewPacket(rxMsg, omci.LayerTypeOMCI, gopacket.NoCopy)
210 if packet == nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000211 logger.Error("omci-message could not be decoded")
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000212 return errors.New("could not decode rxMsg as OMCI")
213 }
214 omciLayer := packet.Layer(omci.LayerTypeOMCI)
215 if omciLayer == nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000216 logger.Error("omci-message could not decode omci layer")
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000217 return errors.New("could not decode omci layer")
218 }
219 omciMsg, ok := omciLayer.(*omci.OMCI)
220 if !ok {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000221 logger.Error("omci-message could not assign omci layer")
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000222 return errors.New("could not assign omci layer")
223 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000224 logger.Debugw("omci-message-decoded:", log.Fields{"omciMsgType": omciMsg.MessageType,
mpagenko3dbcdd22020-07-22 07:38:45 +0000225 "transCorrId": strconv.FormatInt(int64(omciMsg.TransactionID), 16), "DeviceIdent": omciMsg.DeviceIdentifier})
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000226 if byte(omciMsg.MessageType) & ^me.AK == 0 {
227 // Not a response
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000228 logger.Debug("RxMsg is no Omci Response Message")
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000229 if omciMsg.TransactionID == 0 {
230 return oo.ReceiveOnuMessage(ctx, omciMsg)
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000231 }
Himani Chawla4d908332020-08-31 12:30:20 +0530232 logger.Errorw("Unexpected TransCorrId != 0 not accepted for autonomous messages",
233 log.Fields{"msgType": omciMsg.MessageType, "payload": hex.EncodeToString(omciMsg.Payload)})
234 return errors.New("autonomous Omci Message with TranSCorrId != 0 not acccepted")
235
236 }
237 //logger.Debug("RxMsg is a Omci Response Message: try to schedule it to the requester")
238 oo.mutexRxSchedMap.Lock()
239 rxCallbackEntry, ok := oo.rxSchedulerMap[omciMsg.TransactionID]
240 if ok && rxCallbackEntry.cbFunction != nil {
241 //disadvantage of decoupling: error verification made difficult, but anyway the question is
242 // how to react on erroneous frame reception, maybe can simply be ignored
243 go rxCallbackEntry.cbFunction(omciMsg, &packet, rxCallbackEntry.cbRespChannel)
244 // having posted the response the request is regarded as 'done'
245 delete(oo.rxSchedulerMap, omciMsg.TransactionID)
246 oo.mutexRxSchedMap.Unlock()
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000247 } else {
Himani Chawla4d908332020-08-31 12:30:20 +0530248 oo.mutexRxSchedMap.Unlock()
249 logger.Error("omci-message-response for not registered transCorrId")
250 return errors.New("could not find registered response handler tor transCorrId")
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000251 }
252
253 return nil
254 /* py code was:
255 Receive and OMCI message from the proxy channel to the OLT.
256
257 Call this from your ONU Adapter on a new OMCI Rx on the proxy channel
258 :param msg: (str) OMCI binary message (used as input to Scapy packet decoder)
259 """
260 if not self.enabled:
261 return
262
263 try:
264 now = arrow.utcnow()
265 d = None
266
267 # NOTE: Since we may need to do an independent ME map on a per-ONU basis
268 # save the current value of the entity_id_to_class_map, then
269 # replace it with our custom one before decode, and then finally
270 # restore it later. Tried other ways but really made the code messy.
271 saved_me_map = omci_entities.entity_id_to_class_map
272 omci_entities.entity_id_to_class_map = self._me_map
273
274 try:
275 rx_frame = msg if isinstance(msg, OmciFrame) else OmciFrame(msg)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000276 self.logger.debug('recv-omci-msg', omci_msg=hexlify(msg))
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000277 except KeyError as e:
278 # Unknown, Unsupported, or vendor-specific ME. Key is the unknown classID
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000279 self.logger.debug('frame-decode-key-error', omci_msg=hexlify(msg), e=e)
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000280 rx_frame = self._decode_unknown_me(msg)
281 self._rx_unknown_me += 1
282
283 except Exception as e:
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000284 self.logger.exception('frame-decode', omci_msg=hexlify(msg), e=e)
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000285 return
286
287 finally:
288 omci_entities.entity_id_to_class_map = saved_me_map # Always restore it.
289
290 rx_tid = rx_frame.fields['transaction_id']
291 msg_type = rx_frame.fields['message_type']
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000292 self.logger.debug('Received message for rx_tid', rx_tid = rx_tid, msg_type = msg_type)
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000293 # Filter the Test Result frame and route through receive onu
294 # message method.
295 if rx_tid == 0 or msg_type == EntityOperations.TestResult.value:
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000296 self.logger.debug('Receive ONU message', rx_tid=0)
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000297 return self._receive_onu_message(rx_frame)
298
299 # Previously unreachable if this is the very first round-trip Rx or we
300 # have been running consecutive errors
301 if self._rx_frames == 0 or self._consecutive_errors != 0:
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000302 self.logger.debug('Consecutive errors for rx', err = self._consecutive_errors)
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000303 self.reactor.callLater(0, self._publish_connectivity_event, True)
304
305 self._rx_frames += 1
306 self._consecutive_errors = 0
307
308 try:
309 high_priority = self._tid_is_high_priority(rx_tid)
310 index = self._get_priority_index(high_priority)
311
312 # (timestamp, defer, frame, timeout, retry, delayedCall)
313 last_tx_tuple = self._tx_request[index]
314
315 if last_tx_tuple is None or \
316 last_tx_tuple[OMCI_CC.REQUEST_FRAME].fields.get('transaction_id') != rx_tid:
317 # Possible late Rx on a message that timed-out
318 if last_tx_tuple:
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000319 self.logger.debug('Unknown message', rx_tid=rx_tid,
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000320 tx_id=last_tx_tuple[OMCI_CC.REQUEST_FRAME].fields.get('transaction_id'))
321 self._rx_unknown_tid += 1
322 self._rx_late += 1
323 return
324
325 ts, d, tx_frame, timeout, retry, dc = last_tx_tuple
326 if dc is not None and not dc.cancelled and not dc.called:
327 dc.cancel()
328
329 _secs = self._update_rx_tx_stats(now, ts)
330
331 # Late arrival already serviced by a timeout?
332 if d.called:
333 self._rx_late += 1
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000334 self.logger.debug('Serviced by timeout. Late arrival', rx_late = self._rx_late)
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000335 return
336
337 except Exception as e:
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000338 self.logger.exception('frame-match', msg=hexlify(msg), e=e)
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000339 if d is not None:
340 return d.errback(failure.Failure(e))
341 return
342
343 # Publish Rx event to listeners in a different task
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000344 self.logger.debug('Publish rx event', rx_tid = rx_tid,
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000345 tx_tid = tx_frame.fields['transaction_id'])
346 reactor.callLater(0, self._publish_rx_frame, tx_frame, rx_frame)
347
348 # begin success callback chain (will cancel timeout and queue next Tx message)
349 self._rx_response[index] = rx_frame
350 d.callback(rx_frame)
351
352 except Exception as e:
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000353 self.logger.exception('rx-msg', e=e)
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000354 */
355}
356
357func (oo *OmciCC) PublishRxResponseFrame(ctx context.Context, txFrame []byte, rxFrame []byte) error {
Himani Chawla4d908332020-08-31 12:30:20 +0530358 return errors.New("publishRxResponseFrame unimplemented")
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000359 /*
360 def _publish_rx_frame(self, tx_frame, rx_frame):
361 */
362}
363
364//Queue the OMCI Frame for a transmit to the ONU via the proxy_channel
365func (oo *OmciCC) Send(ctx context.Context, txFrame []byte, timeout int, retry int, highPrio bool,
366 receiveCallbackPair CallbackPair) error {
367
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000368 logger.Debugw("register-response-callback:", log.Fields{"for TansCorrId": receiveCallbackPair.cbKey})
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000369 // it could be checked, if the callback keay is already registered - but simply overwrite may be acceptable ...
370 oo.mutexRxSchedMap.Lock()
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000371 oo.rxSchedulerMap[receiveCallbackPair.cbKey] = receiveCallbackPair.cbEntry
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000372 oo.mutexRxSchedMap.Unlock()
373
374 //just use a simple list for starting - might need some more effort, especially for multi source write access
375 omciTxRequest := omciTransferStructure{
376 txFrame,
377 timeout,
378 retry,
379 highPrio,
380 }
381 oo.mutexTxQueue.Lock()
382 oo.txQueue.PushBack(omciTxRequest) // enqueue
383 oo.mutexTxQueue.Unlock()
384
385 // for first test just bypass and send directly:
386 go oo.sendNextRequest(ctx)
387 return nil
388}
389
390//Pull next tx request and send it
391func (oo *OmciCC) sendNextRequest(ctx context.Context) error {
392 // return errors.New("sendNextRequest unimplemented")
393
394 // just try to get something transferred !!
395 // avoid accessing the txQueue from parallel send requests
396 // block parallel omci send requests at least until SendIAP is 'committed'
397 // that should be feasible for an onu instance as on OMCI anyway window size 1 is assumed
398 oo.mutexTxQueue.Lock()
mpagenkodff5dda2020-08-28 11:52:01 +0000399 defer oo.mutexTxQueue.Unlock()
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000400 for oo.txQueue.Len() > 0 {
401 queueElement := oo.txQueue.Front() // First element
402 omciTxRequest := queueElement.Value.(omciTransferStructure)
403 /* compare olt device handler code:
404 func (dh *DeviceHandler) omciIndication(omciInd *oop.OmciIndication) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000405 logger.Debugw("omci indication", log.Fields{"intfID": omciInd.IntfId, "onuID": omciInd.OnuId})
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000406 var deviceType string
407 var deviceID string
408 var proxyDeviceID string
409
410 onuKey := dh.formOnuKey(omciInd.IntfId, omciInd.OnuId)
411
412 if onuInCache, ok := dh.onus.Load(onuKey); !ok {
413
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000414 logger.Debugw("omci indication for a device not in cache.", log.Fields{"intfID": omciInd.IntfId, "onuID": omciInd.OnuId})
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000415 ponPort := IntfIDToPortNo(omciInd.GetIntfId(), voltha.Port_PON_OLT)
416 kwargs := make(map[string]interface{})
417 kwargs["onu_id"] = omciInd.OnuId
418 kwargs["parent_port_no"] = ponPort
419
420 onuDevice, err := dh.coreProxy.GetChildDevice(context.TODO(), dh.device.Id, kwargs)
421 if err != nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000422 logger.Errorw("onu not found", log.Fields{"intfID": omciInd.IntfId, "onuID": omciInd.OnuId, "error": err})
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000423 return
424 }
425 deviceType = onuDevice.Type
426 deviceID = onuDevice.Id
427 proxyDeviceID = onuDevice.ProxyAddress.DeviceId
428 //if not exist in cache, then add to cache.
429 dh.onus.Store(onuKey, NewOnuDevice(deviceID, deviceType, onuDevice.SerialNumber, omciInd.OnuId, omciInd.IntfId, proxyDeviceID))
430 } else {
431 //found in cache
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000432 logger.Debugw("omci indication for a device in cache.", log.Fields{"intfID": omciInd.IntfId, "onuID": omciInd.OnuId})
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000433 deviceType = onuInCache.(*OnuDevice).deviceType
434 deviceID = onuInCache.(*OnuDevice).deviceID
435 proxyDeviceID = onuInCache.(*OnuDevice).proxyDeviceID
436 }
437 */
438 /* and compare onu_adapter py code:
439 omci_msg = InterAdapterOmciMessage(
440 message=bytes(frame),
441 proxy_address=self._proxy_address,
442 connect_status=self._device.connect_status)
443
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000444 self.logger.debug('sent-omci-msg', tid=tx_tid, omci_msg=hexlify(bytes(frame)))
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000445
446 yield self._adapter_proxy.send_inter_adapter_message(
447 msg=omci_msg,
448 type=InterAdapterMessageType.OMCI_REQUEST,
449 from_adapter=self._device.type,
450 to_adapter=self._proxy_address.device_type,
451 to_device_id=self._device_id,
452 proxy_device_id=self._proxy_address.device_id
453 )
454 */
455 device, err := oo.coreProxy.GetDevice(ctx,
456 oo.pBaseDeviceHandler.deviceID, oo.deviceID) //parent, child
457 if err != nil || device == nil {
458 /*TODO: needs to handle error scenarios */
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000459 logger.Errorw("Failed to fetch device", log.Fields{"err": err, "ParentId": oo.pBaseDeviceHandler.deviceID,
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000460 "ChildId": oo.deviceID})
461 return errors.New("failed to fetch device")
462 }
463
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000464 logger.Debugw("omci-message-sending", log.Fields{"fromDeviceType": oo.pBaseDeviceHandler.DeviceType,
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000465 "toDeviceType": oo.pBaseDeviceHandler.ProxyAddressType,
466 "onuDeviceID": oo.deviceID, "proxyDeviceID": oo.pBaseDeviceHandler.ProxyAddressID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000467 logger.Debugw("omci-message-to-send:",
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000468 log.Fields{"TxOmciMessage": hex.EncodeToString(omciTxRequest.txFrame)})
469
470 omciMsg := &ic.InterAdapterOmciMessage{Message: omciTxRequest.txFrame}
471 if sendErr := oo.adapterProxy.SendInterAdapterMessage(context.Background(), omciMsg,
472 ic.InterAdapterMessageType_OMCI_REQUEST,
473 //fromType,toType,toDevId, ProxyDevId
474 oo.pBaseDeviceHandler.DeviceType, oo.pBaseDeviceHandler.ProxyAddressType,
475 oo.deviceID, oo.pBaseDeviceHandler.ProxyAddressID, ""); sendErr != nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000476 logger.Errorw("send omci request error", log.Fields{"error": sendErr})
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000477 return sendErr
478 }
479 oo.txQueue.Remove(queueElement) // Dequeue
480 }
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000481 return nil
482}
483
484func (oo *OmciCC) GetNextTid(highPriority bool) uint16 {
485 var next uint16
486 if highPriority {
487 oo.mutexTid.Lock()
488 next = oo.hpTid
Himani Chawla4d908332020-08-31 12:30:20 +0530489 oo.hpTid++
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000490 if oo.hpTid < 0x8000 {
491 oo.hpTid = 0x8000
492 }
493 oo.mutexTid.Unlock()
494 } else {
495 oo.mutexHpTid.Lock()
496 next = oo.tid
Himani Chawla4d908332020-08-31 12:30:20 +0530497 oo.tid++
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000498 if oo.tid >= 0x8000 {
499 oo.tid = 1
500 }
501 oo.mutexHpTid.Unlock()
502 }
503 return next
504}
505
506// ###################################################################################
507// # utility methods provided to work on OMCI messages
508func serialize(msgType omci.MessageType, request gopacket.SerializableLayer, tid uint16) ([]byte, error) {
509 omciLayer := &omci.OMCI{
510 TransactionID: tid,
511 MessageType: msgType,
512 }
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000513 return serializeOmciLayer(omciLayer, request)
514}
515
Himani Chawla4d908332020-08-31 12:30:20 +0530516func serializeOmciLayer(aOmciLayer *omci.OMCI, aRequest gopacket.SerializableLayer) ([]byte, error) {
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000517 var options gopacket.SerializeOptions
518 options.FixLengths = true
519
520 buffer := gopacket.NewSerializeBuffer()
Himani Chawla4d908332020-08-31 12:30:20 +0530521 err := gopacket.SerializeLayers(buffer, options, aOmciLayer, aRequest)
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000522 if err != nil {
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000523 logger.Errorw("Could not create goPacket Omci serial buffer", log.Fields{"Err": err})
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000524 return nil, err
525 }
526 return buffer.Bytes(), nil
527}
528
Himani Chawla4d908332020-08-31 12:30:20 +0530529/*
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000530func hexEncode(omciPkt []byte) ([]byte, error) {
531 dst := make([]byte, hex.EncodedLen(len(omciPkt)))
532 hex.Encode(dst, omciPkt)
533 return dst, nil
534}
Himani Chawla4d908332020-08-31 12:30:20 +0530535*/
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000536
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000537//supply a response handler for omci response messages to be transferred to the requested FSM
538func (oo *OmciCC) receiveOmciResponse(omciMsg *omci.OMCI, packet *gp.Packet, respChan chan Message) error {
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000539
mpagenko3dbcdd22020-07-22 07:38:45 +0000540 logger.Debugw("omci-message-response - transfer on omciRespChannel", log.Fields{"omciMsgType": omciMsg.MessageType,
divyadesai4d299552020-08-18 07:13:49 +0000541 "transCorrId": strconv.FormatInt(int64(omciMsg.TransactionID), 16), "device-id": oo.deviceID})
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000542
543 if oo.pOnuDeviceEntry == nil {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000544 logger.Errorw("Abort receiving OMCI response, DeviceEntryPointer is nil", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +0000545 "device-id": oo.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +0530546 return errors.New("deviceEntryPointer is nil")
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000547 }
548
549 // no further test on SeqNo is done here, assignment from rxScheduler is trusted
550 // MibSync responses are simply transferred via deviceEntry to MibSync, no specific analysis here
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000551 omciRespMsg := Message{
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000552 Type: OMCI,
553 Data: OmciMessage{
554 OmciMsg: omciMsg,
555 OmciPacket: packet,
556 },
557 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000558 //logger.Debugw("Message to be sent into channel:", log.Fields{"mibSyncMsg": mibSyncMsg})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000559 respChan <- omciRespMsg
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000560
561 return nil
562}
563
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000564func (oo *OmciCC) sendMibReset(ctx context.Context, timeout int, highPrio bool) error {
565
divyadesai4d299552020-08-18 07:13:49 +0000566 logger.Debugw("send MibReset-msg to:", log.Fields{"device-id": oo.deviceID})
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000567 request := &omci.MibResetRequest{
568 MeBasePacket: omci.MeBasePacket{
569 EntityClass: me.OnuDataClassID,
570 },
571 }
572 tid := oo.GetNextTid(highPrio)
573 pkt, err := serialize(omci.MibResetRequestType, request, tid)
574 if err != nil {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000575 logger.Errorw("Cannot serialize MibResetRequest", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +0000576 "Err": err, "device-id": oo.deviceID})
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000577 return err
578 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000579 omciRxCallbackPair := CallbackPair{
580 cbKey: tid,
581 cbEntry: CallbackPairEntry{(*oo.pOnuDeviceEntry).pMibUploadFsm.commChan, oo.receiveOmciResponse},
582 }
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000583 return oo.Send(ctx, pkt, timeout, 0, highPrio, omciRxCallbackPair)
584}
585
ozgecanetsiae11479f2020-07-06 09:44:47 +0300586func (oo *OmciCC) sendReboot(ctx context.Context, timeout int, highPrio bool, responseChannel chan Message) error {
divyadesai4d299552020-08-18 07:13:49 +0000587 logger.Debugw("send Reboot-msg to:", log.Fields{"device-id": oo.deviceID})
ozgecanetsiae11479f2020-07-06 09:44:47 +0300588 request := &omci.RebootRequest{
589 MeBasePacket: omci.MeBasePacket{
590 EntityClass: me.OnuGClassID,
591 },
592 }
593 tid := oo.GetNextTid(highPrio)
594 pkt, err := serialize(omci.RebootRequestType, request, tid)
595 if err != nil {
596 logger.Errorw("Cannot serialize RebootRequest", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +0000597 "Err": err, "device-id": oo.deviceID})
ozgecanetsiae11479f2020-07-06 09:44:47 +0300598 return err
599 }
600 omciRxCallbackPair := CallbackPair{
601 cbKey: tid,
602 cbEntry: CallbackPairEntry{oo.pOnuDeviceEntry.omciRebootMessageReceivedChannel, oo.receiveOmciResponse},
603 }
604
605 err = oo.Send(ctx, pkt, timeout, 0, highPrio, omciRxCallbackPair)
606 if err != nil {
607 logger.Errorw("Cannot send RebootRequest", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +0000608 "Err": err, "device-id": oo.deviceID})
ozgecanetsiae11479f2020-07-06 09:44:47 +0300609 return err
610 }
611 err = oo.pOnuDeviceEntry.waitForRebootResponse(responseChannel)
612 if err != nil {
613 logger.Error("aborting ONU Reboot!")
Himani Chawla4d908332020-08-31 12:30:20 +0530614 _ = oo.pOnuDeviceEntry.pMibDownloadFsm.pFsm.Event("reset")
ozgecanetsiae11479f2020-07-06 09:44:47 +0300615 return err
616 }
617 return nil
618}
619
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000620func (oo *OmciCC) sendMibUpload(ctx context.Context, timeout int, highPrio bool) error {
divyadesai4d299552020-08-18 07:13:49 +0000621 logger.Debugw("send MibUpload-msg to:", log.Fields{"device-id": oo.deviceID})
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000622 request := &omci.MibUploadRequest{
623 MeBasePacket: omci.MeBasePacket{
624 EntityClass: me.OnuDataClassID,
625 },
626 }
627 tid := oo.GetNextTid(highPrio)
628 pkt, err := serialize(omci.MibUploadRequestType, request, tid)
629 if err != nil {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000630 logger.Errorw("Cannot serialize MibUploadRequest", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +0000631 "Err": err, "device-id": oo.deviceID})
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000632 return err
633 }
634 oo.uploadSequNo = 0
635 oo.uploadNoOfCmds = 0
636
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000637 omciRxCallbackPair := CallbackPair{
638 cbKey: tid,
639 cbEntry: CallbackPairEntry{(*oo.pOnuDeviceEntry).pMibUploadFsm.commChan, oo.receiveOmciResponse},
640 }
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000641 return oo.Send(ctx, pkt, timeout, 0, highPrio, omciRxCallbackPair)
642}
643
644func (oo *OmciCC) sendMibUploadNext(ctx context.Context, timeout int, highPrio bool) error {
divyadesai4d299552020-08-18 07:13:49 +0000645 logger.Debugw("send MibUploadNext-msg to:", log.Fields{"device-id": oo.deviceID, "uploadSequNo": oo.uploadSequNo})
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000646 request := &omci.MibUploadNextRequest{
647 MeBasePacket: omci.MeBasePacket{
648 EntityClass: me.OnuDataClassID,
649 },
650 CommandSequenceNumber: oo.uploadSequNo,
651 }
652 tid := oo.GetNextTid(highPrio)
653 pkt, err := serialize(omci.MibUploadNextRequestType, request, tid)
654 if err != nil {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000655 logger.Errorw("Cannot serialize MibUploadNextRequest", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +0000656 "Err": err, "device-id": oo.deviceID})
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000657 return err
658 }
659 oo.uploadSequNo++
660
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000661 omciRxCallbackPair := CallbackPair{
662 cbKey: tid,
663 cbEntry: CallbackPairEntry{(*oo.pOnuDeviceEntry).pMibUploadFsm.commChan, oo.receiveOmciResponse},
664 }
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000665 return oo.Send(ctx, pkt, timeout, 0, highPrio, omciRxCallbackPair)
666}
667
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000668func (oo *OmciCC) sendCreateGalEthernetProfile(ctx context.Context, timeout int, highPrio bool) *me.ManagedEntity {
669 tid := oo.GetNextTid(highPrio)
divyadesai4d299552020-08-18 07:13:49 +0000670 logger.Debugw("send GalEnetProfile-Create-msg:", log.Fields{"device-id": oo.deviceID,
mpagenko3dbcdd22020-07-22 07:38:45 +0000671 "SequNo": strconv.FormatInt(int64(tid), 16)})
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000672
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000673 meParams := me.ParamData{
674 EntityID: galEthernetEID,
675 Attributes: me.AttributeValueMap{"MaximumGemPayloadSize": maxGemPayloadSize},
676 }
677 meInstance, omciErr := me.NewGalEthernetProfile(meParams)
678 if omciErr.GetError() == nil {
679 //all setByCreate parameters already set, no default option required ...
680 omciLayer, msgLayer, err := omci.EncodeFrame(meInstance, omci.CreateRequestType, omci.TransactionID(tid))
681 if err != nil {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000682 logger.Errorw("Cannot encode GalEnetProfileInstance for create", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +0000683 "Err": err, "device-id": oo.deviceID})
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000684 return nil
685 }
686
687 pkt, err := serializeOmciLayer(omciLayer, msgLayer)
688 if err != nil {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000689 logger.Errorw("Cannot serialize GalEnetProfile create", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +0000690 "Err": err, "device-id": oo.deviceID})
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000691 return nil
692 }
693
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000694 omciRxCallbackPair := CallbackPair{
695 cbKey: tid,
696 cbEntry: CallbackPairEntry{(*oo.pOnuDeviceEntry).pMibDownloadFsm.commChan, oo.receiveOmciResponse},
697 }
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000698 err = oo.Send(ctx, pkt, timeout, 0, highPrio, omciRxCallbackPair)
699 if err != nil {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000700 logger.Errorw("Cannot send GalEnetProfile create", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +0000701 "Err": err, "device-id": oo.deviceID})
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000702 return nil
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000703 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000704 logger.Debug("send GalEnetProfile-Create-msg done")
705 return meInstance
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000706 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000707 logger.Errorw("Cannot generate GalEnetProfileInstance", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +0000708 "Err": omciErr.GetError(), "device-id": oo.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000709 return nil
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000710}
711
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000712// might be needed to extend for parameter arguments, here just for setting the ConnectivityMode!!
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000713func (oo *OmciCC) sendSetOnu2g(ctx context.Context, timeout int, highPrio bool) *me.ManagedEntity {
714 tid := oo.GetNextTid(highPrio)
divyadesai4d299552020-08-18 07:13:49 +0000715 logger.Debugw("send ONU2-G-Set-msg:", log.Fields{"device-id": oo.deviceID,
mpagenko3dbcdd22020-07-22 07:38:45 +0000716 "SequNo": strconv.FormatInt(int64(tid), 16)})
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000717
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000718 // ONU-G ME-ID is defined to be 0, but we could verify, if the ONU really supports the desired
719 // connectivity mode 5 (in ConnCap)
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000720 // By now we just use fix values to fire - this is anyway what the python adapter does
721 // read ONU-2G from DB ???? //TODO!!!
722 meParams := me.ParamData{
723 EntityID: 0,
724 Attributes: me.AttributeValueMap{"CurrentConnectivityMode": connectivityModeValue},
725 }
726 meInstance, omciErr := me.NewOnu2G(meParams)
727 if omciErr.GetError() == nil {
728 omciLayer, msgLayer, err := omci.EncodeFrame(meInstance, omci.SetRequestType, omci.TransactionID(tid))
729 if err != nil {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000730 logger.Errorw("Cannot encode ONU2-G instance for set", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +0000731 "Err": err, "device-id": oo.deviceID})
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000732 return nil
733 }
734
735 pkt, err := serializeOmciLayer(omciLayer, msgLayer)
736 if err != nil {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000737 logger.Errorw("Cannot serialize ONU2-G set", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +0000738 "Err": err, "device-id": oo.deviceID})
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000739 return nil
740 }
741
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000742 omciRxCallbackPair := CallbackPair{
743 cbKey: tid,
744 cbEntry: CallbackPairEntry{(*oo.pOnuDeviceEntry).pMibDownloadFsm.commChan, oo.receiveOmciResponse},
745 }
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000746 err = oo.Send(ctx, pkt, timeout, 0, highPrio, omciRxCallbackPair)
747 if err != nil {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000748 logger.Errorw("Cannot send ONU2-G set", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +0000749 "Err": err, "device-id": oo.deviceID})
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000750 return nil
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000751 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000752 logger.Debug("send ONU2-G-Set-msg done")
753 return meInstance
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000754 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000755 logger.Errorw("Cannot generate ONU2-G", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +0000756 "Err": omciErr.GetError(), "device-id": oo.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000757 return nil
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000758}
759
760func (oo *OmciCC) sendCreateMBServiceProfile(ctx context.Context,
Himani Chawla4d908332020-08-31 12:30:20 +0530761 aPUniPort *OnuUniPort, timeout int, highPrio bool) *me.ManagedEntity {
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000762 tid := oo.GetNextTid(highPrio)
Himani Chawla4d908332020-08-31 12:30:20 +0530763 instID := macBridgeServiceProfileEID + uint16(aPUniPort.macBpNo)
divyadesai4d299552020-08-18 07:13:49 +0000764 logger.Debugw("send MBSP-Create-msg:", log.Fields{"device-id": oo.deviceID,
mpagenko3dbcdd22020-07-22 07:38:45 +0000765 "SequNo": strconv.FormatInt(int64(tid), 16), "InstId": strconv.FormatInt(int64(instID), 16)})
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000766
767 meParams := me.ParamData{
768 EntityID: instID,
769 Attributes: me.AttributeValueMap{
770 "Priority": 0x8000,
771 "MaxAge": 20 * 256, //20s
772 "HelloTime": 2 * 256, //2s
773 "ForwardDelay": 15 * 256, //15s
774 //note: DynamicFilteringAgeingTime is taken from omci lib default as
775 // which is obviously different from default value used in python lib,
776 // where the value seems to be 0 (ONU defined) - to be considered in case of test artifacts ...
777 },
778 }
779
780 meInstance, omciErr := me.NewMacBridgeServiceProfile(meParams)
781 if omciErr.GetError() == nil {
782 //obviously we have to set all 'untouched' parameters to default by some additional option parameter!!
783 omciLayer, msgLayer, err := omci.EncodeFrame(meInstance, omci.CreateRequestType,
784 omci.TransactionID(tid), omci.AddDefaults(true))
785 if err != nil {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000786 logger.Errorw("Cannot encode MBSP for create", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +0000787 "Err": err, "device-id": oo.deviceID})
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000788 return nil
789 }
790
791 pkt, err := serializeOmciLayer(omciLayer, msgLayer)
792 if err != nil {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000793 logger.Errorw("Cannot serialize MBSP create", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +0000794 "Err": err, "device-id": oo.deviceID})
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000795 return nil
796 }
797
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000798 omciRxCallbackPair := CallbackPair{
799 cbKey: tid,
800 cbEntry: CallbackPairEntry{(*oo.pOnuDeviceEntry).pMibDownloadFsm.commChan, oo.receiveOmciResponse},
801 }
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000802 err = oo.Send(ctx, pkt, timeout, 0, highPrio, omciRxCallbackPair)
803 if err != nil {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000804 logger.Errorw("Cannot send MBSP create", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +0000805 "Err": err, "device-id": oo.deviceID})
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000806 return nil
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000807 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000808 logger.Debug("send MBSP-Create-msg done")
809 return meInstance
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000810 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000811 logger.Errorw("Cannot generate MBSP Instance", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +0000812 "Err": omciErr.GetError(), "device-id": oo.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000813 return nil
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000814}
815
816func (oo *OmciCC) sendCreateMBPConfigData(ctx context.Context,
Himani Chawla4d908332020-08-31 12:30:20 +0530817 aPUniPort *OnuUniPort, timeout int, highPrio bool) *me.ManagedEntity {
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000818 tid := oo.GetNextTid(highPrio)
Himani Chawla4d908332020-08-31 12:30:20 +0530819 instID := macBridgePortAniEID + aPUniPort.entityId
divyadesai4d299552020-08-18 07:13:49 +0000820 logger.Debugw("send MBPCD-Create-msg:", log.Fields{"device-id": oo.deviceID,
mpagenko3dbcdd22020-07-22 07:38:45 +0000821 "SequNo": strconv.FormatInt(int64(tid), 16), "InstId": strconv.FormatInt(int64(instID), 16)})
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000822
823 meParams := me.ParamData{
824 EntityID: instID,
825 Attributes: me.AttributeValueMap{
Himani Chawla4d908332020-08-31 12:30:20 +0530826 "BridgeIdPointer": macBridgeServiceProfileEID + uint16(aPUniPort.macBpNo),
827 "PortNum": aPUniPort.macBpNo,
828 "TpType": uint8(aPUniPort.portType),
829 "TpPointer": aPUniPort.entityId,
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000830 },
831 }
832 meInstance, omciErr := me.NewMacBridgePortConfigurationData(meParams)
833 if omciErr.GetError() == nil {
834 //obviously we have to set all 'untouched' parameters to default by some additional option parameter!!
835 omciLayer, msgLayer, err := omci.EncodeFrame(meInstance, omci.CreateRequestType,
836 omci.TransactionID(tid), omci.AddDefaults(true))
837 if err != nil {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000838 logger.Errorw("Cannot encode MBPCD for create", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +0000839 "Err": err, "device-id": oo.deviceID})
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000840 return nil
841 }
842
843 pkt, err := serializeOmciLayer(omciLayer, msgLayer)
844 if err != nil {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000845 logger.Errorw("Cannot serialize MBPCD create", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +0000846 "Err": err, "device-id": oo.deviceID})
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000847 return nil
848 }
849
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000850 omciRxCallbackPair := CallbackPair{
851 cbKey: tid,
852 cbEntry: CallbackPairEntry{(*oo.pOnuDeviceEntry).pMibDownloadFsm.commChan, oo.receiveOmciResponse},
853 }
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000854 err = oo.Send(ctx, pkt, timeout, 0, highPrio, omciRxCallbackPair)
855 if err != nil {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000856 logger.Errorw("Cannot send MBPCD create", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +0000857 "Err": err, "device-id": oo.deviceID})
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000858 return nil
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000859 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000860 logger.Debug("send MBPCD-Create-msg done")
861 return meInstance
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000862 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000863 logger.Errorw("Cannot generate MBPCD Instance", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +0000864 "Err": omciErr.GetError(), "device-id": oo.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000865 return nil
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000866}
867
868func (oo *OmciCC) sendCreateEVTOConfigData(ctx context.Context,
Himani Chawla4d908332020-08-31 12:30:20 +0530869 aPUniPort *OnuUniPort, timeout int, highPrio bool) *me.ManagedEntity {
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000870 tid := oo.GetNextTid(highPrio)
871 //same entityId is used as for MBSP (see there), but just arbitrary ...
Himani Chawla4d908332020-08-31 12:30:20 +0530872 instID := macBridgeServiceProfileEID + uint16(aPUniPort.macBpNo)
divyadesai4d299552020-08-18 07:13:49 +0000873 logger.Debugw("send EVTOCD-Create-msg:", log.Fields{"device-id": oo.deviceID,
mpagenko3dbcdd22020-07-22 07:38:45 +0000874 "SequNo": strconv.FormatInt(int64(tid), 16), "InstId": strconv.FormatInt(int64(instID), 16)})
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000875
876 // compare python adapter code WA VOL-1311: this is not done here!
877 // (setting TPID values for the create would probably anyway be ignored by the omci lib)
878 // but perhaps we have to be aware of possible problems at get(Next) Request handling for EVTOOCD tables later ...
879 assType := uint8(2) // default AssociationType is PPTPEthUni
Himani Chawla4d908332020-08-31 12:30:20 +0530880 if aPUniPort.portType == UniVEIP {
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000881 assType = uint8(10) // for VEIP
882 }
883 meParams := me.ParamData{
884 EntityID: instID,
885 Attributes: me.AttributeValueMap{
886 "AssociationType": assType,
Himani Chawla4d908332020-08-31 12:30:20 +0530887 "AssociatedMePointer": aPUniPort.entityId,
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000888 },
889 }
890 meInstance, omciErr := me.NewExtendedVlanTaggingOperationConfigurationData(meParams)
891 if omciErr.GetError() == nil {
892 //all setByCreate parameters already set, no default option required ...
893 omciLayer, msgLayer, err := omci.EncodeFrame(meInstance, omci.CreateRequestType, omci.TransactionID(tid))
894 if err != nil {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000895 logger.Errorw("Cannot encode EVTOCD for create", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +0000896 "Err": err, "device-id": oo.deviceID})
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000897 return nil
898 }
899
900 pkt, err := serializeOmciLayer(omciLayer, msgLayer)
901 if err != nil {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000902 logger.Errorw("Cannot serialize EVTOCD create", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +0000903 "Err": err, "device-id": oo.deviceID})
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000904 return nil
905 }
906
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000907 omciRxCallbackPair := CallbackPair{
908 cbKey: tid,
909 cbEntry: CallbackPairEntry{(*oo.pOnuDeviceEntry).pMibDownloadFsm.commChan, oo.receiveOmciResponse},
910 }
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000911 err = oo.Send(ctx, pkt, timeout, 0, highPrio, omciRxCallbackPair)
912 if err != nil {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000913 logger.Errorw("Cannot send EVTOCD create", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +0000914 "Err": err, "device-id": oo.deviceID})
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000915 return nil
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000916 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000917 logger.Debug("send EVTOCD-Create-msg done")
918 return meInstance
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000919 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000920 logger.Errorw("Cannot generate EVTOCD Instance", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +0000921 "Err": omciErr.GetError(), "device-id": oo.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000922 return nil
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000923}
924
925func (oo *OmciCC) sendSetOnuGLS(ctx context.Context, timeout int,
926 highPrio bool, requestedAttributes me.AttributeValueMap, rxChan chan Message) *me.ManagedEntity {
927 tid := oo.GetNextTid(highPrio)
divyadesai4d299552020-08-18 07:13:49 +0000928 logger.Debugw("send ONU-G-Set-msg:", log.Fields{"device-id": oo.deviceID,
mpagenko3dbcdd22020-07-22 07:38:45 +0000929 "SequNo": strconv.FormatInt(int64(tid), 16)})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000930
931 // ONU-G ME-ID is defined to be 0, no need to perform a DB lookup
932 meParams := me.ParamData{
933 EntityID: 0,
934 Attributes: requestedAttributes,
935 }
936 meInstance, omciErr := me.NewOnuG(meParams)
937 if omciErr.GetError() == nil {
938 omciLayer, msgLayer, err := omci.EncodeFrame(meInstance, omci.SetRequestType, omci.TransactionID(tid))
939 if err != nil {
940 logger.Errorw("Cannot encode ONU-G instance for set", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +0000941 "Err": err, "device-id": oo.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000942 return nil
943 }
944
945 pkt, err := serializeOmciLayer(omciLayer, msgLayer)
946 if err != nil {
947 logger.Errorw("Cannot serialize ONU-G set", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +0000948 "Err": err, "device-id": oo.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000949 return nil
950 }
951
952 omciRxCallbackPair := CallbackPair{
953 cbKey: tid,
954 cbEntry: CallbackPairEntry{rxChan, oo.receiveOmciResponse},
955 }
956 err = oo.Send(ctx, pkt, timeout, 0, highPrio, omciRxCallbackPair)
957 if err != nil {
958 logger.Errorw("Cannot send ONU-G set", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +0000959 "Err": err, "device-id": oo.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000960 return nil
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000961 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000962 logger.Debug("send ONU-G-Set-msg done")
963 return meInstance
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000964 }
mpagenko3dbcdd22020-07-22 07:38:45 +0000965 logger.Errorw("Cannot generate ONU-G", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +0000966 "Err": omciErr.GetError(), "device-id": oo.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +0000967 return nil
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000968}
969
970func (oo *OmciCC) sendSetUniGLS(ctx context.Context, aInstNo uint16, timeout int,
971 highPrio bool, requestedAttributes me.AttributeValueMap, rxChan chan Message) *me.ManagedEntity {
972 tid := oo.GetNextTid(highPrio)
divyadesai4d299552020-08-18 07:13:49 +0000973 logger.Debugw("send UNI-G-Set-msg:", log.Fields{"device-id": oo.deviceID,
mpagenko3dbcdd22020-07-22 07:38:45 +0000974 "SequNo": strconv.FormatInt(int64(tid), 16)})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000975
976 // UNI-G ME-ID is taken from Mib Upload stored OnuUniPort instance (argument)
977 meParams := me.ParamData{
978 EntityID: aInstNo,
979 Attributes: requestedAttributes,
980 }
981 meInstance, omciErr := me.NewUniG(meParams)
982 if omciErr.GetError() == nil {
983 omciLayer, msgLayer, err := omci.EncodeFrame(meInstance, omci.SetRequestType, omci.TransactionID(tid))
984 if err != nil {
985 logger.Errorw("Cannot encode UNI-G instance for set", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +0000986 "Err": err, "device-id": oo.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000987 return nil
988 }
989
990 pkt, err := serializeOmciLayer(omciLayer, msgLayer)
991 if err != nil {
992 logger.Errorw("Cannot serialize UNI-G-Set", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +0000993 "Err": err, "device-id": oo.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000994 return nil
995 }
996
997 omciRxCallbackPair := CallbackPair{
998 cbKey: tid,
999 cbEntry: CallbackPairEntry{rxChan, oo.receiveOmciResponse},
1000 }
1001 err = oo.Send(ctx, pkt, timeout, 0, highPrio, omciRxCallbackPair)
1002 if err != nil {
1003 logger.Errorw("Cannot send UNIG-G-Set", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00001004 "Err": err, "device-id": oo.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001005 return nil
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001006 }
mpagenko3dbcdd22020-07-22 07:38:45 +00001007 logger.Debug("send UNI-G-Set-msg done")
1008 return meInstance
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001009 }
mpagenko3dbcdd22020-07-22 07:38:45 +00001010 logger.Errorw("Cannot generate UNI-G", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00001011 "Err": omciErr.GetError(), "device-id": oo.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001012 return nil
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001013}
1014
1015func (oo *OmciCC) sendSetVeipLS(ctx context.Context, aInstNo uint16, timeout int,
1016 highPrio bool, requestedAttributes me.AttributeValueMap, rxChan chan Message) *me.ManagedEntity {
1017 tid := oo.GetNextTid(highPrio)
divyadesai4d299552020-08-18 07:13:49 +00001018 logger.Debugw("send VEIP-Set-msg:", log.Fields{"device-id": oo.deviceID,
mpagenko3dbcdd22020-07-22 07:38:45 +00001019 "SequNo": strconv.FormatInt(int64(tid), 16)})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001020
1021 // ONU-G ME-ID is defined to be 0, no need to perform a DB lookup
1022 meParams := me.ParamData{
1023 EntityID: aInstNo,
1024 Attributes: requestedAttributes,
1025 }
1026 meInstance, omciErr := me.NewVirtualEthernetInterfacePoint(meParams)
1027 if omciErr.GetError() == nil {
1028 omciLayer, msgLayer, err := omci.EncodeFrame(meInstance, omci.SetRequestType, omci.TransactionID(tid))
1029 if err != nil {
1030 logger.Errorw("Cannot encode VEIP instance for set", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00001031 "Err": err, "device-id": oo.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001032 return nil
1033 }
1034
1035 pkt, err := serializeOmciLayer(omciLayer, msgLayer)
1036 if err != nil {
1037 logger.Errorw("Cannot serialize VEIP-Set", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00001038 "Err": err, "device-id": oo.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001039 return nil
1040 }
1041
1042 omciRxCallbackPair := CallbackPair{
1043 cbKey: tid,
1044 cbEntry: CallbackPairEntry{rxChan, oo.receiveOmciResponse},
1045 }
1046 err = oo.Send(ctx, pkt, timeout, 0, highPrio, omciRxCallbackPair)
1047 if err != nil {
1048 logger.Errorw("Cannot send VEIP-Set", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00001049 "Err": err, "device-id": oo.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001050 return nil
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001051 }
mpagenko3dbcdd22020-07-22 07:38:45 +00001052 logger.Debug("send VEIP-Set-msg done")
1053 return meInstance
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +00001054 }
mpagenko3dbcdd22020-07-22 07:38:45 +00001055 logger.Errorw("Cannot generate VEIP", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00001056 "Err": omciErr.GetError(), "device-id": oo.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001057 return nil
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +00001058}
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00001059
1060func (oo *OmciCC) sendGetMe(ctx context.Context, classID me.ClassID, entityID uint16, requestedAttributes me.AttributeValueMap,
1061 timeout int, highPrio bool) *me.ManagedEntity {
1062
1063 tid := oo.GetNextTid(highPrio)
divyadesai4d299552020-08-18 07:13:49 +00001064 logger.Debugw("send get-request-msg", log.Fields{"classID": classID, "device-id": oo.deviceID,
mpagenko3dbcdd22020-07-22 07:38:45 +00001065 "SequNo": strconv.FormatInt(int64(tid), 16)})
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00001066
1067 meParams := me.ParamData{
1068 EntityID: entityID,
1069 Attributes: requestedAttributes,
1070 }
1071 meInstance, omciErr := me.LoadManagedEntityDefinition(classID, meParams)
1072 if omciErr.GetError() == nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301073 meClassIDName := meInstance.GetName()
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00001074 omciLayer, msgLayer, err := omci.EncodeFrame(meInstance, omci.GetRequestType, omci.TransactionID(tid))
1075 if err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301076 logger.Errorf("Cannot encode instance for get-request", log.Fields{"meClassIDName": meClassIDName, "Err": err, "device-id": oo.deviceID})
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00001077 return nil
1078 }
1079 pkt, err := serializeOmciLayer(omciLayer, msgLayer)
1080 if err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301081 logger.Errorw("Cannot serialize get-request", log.Fields{"meClassIDName": meClassIDName, "Err": err, "device-id": oo.deviceID})
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00001082 return nil
1083 }
1084 omciRxCallbackPair := CallbackPair{
1085 cbKey: tid,
1086 cbEntry: CallbackPairEntry{(*oo.pOnuDeviceEntry).pMibUploadFsm.commChan, oo.receiveOmciResponse},
1087 }
1088 err = oo.Send(ctx, pkt, timeout, 0, highPrio, omciRxCallbackPair)
1089 if err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301090 logger.Errorw("Cannot send get-request-msg", log.Fields{"meClassIDName": meClassIDName, "Err": err, "device-id": oo.deviceID})
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00001091 return nil
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00001092 }
Himani Chawla4d908332020-08-31 12:30:20 +05301093 logger.Debugw("send get-request-msg done", log.Fields{"meClassIDName": meClassIDName, "device-id": oo.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001094 return meInstance
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00001095 }
divyadesai4d299552020-08-18 07:13:49 +00001096 logger.Errorw("Cannot generate meDefinition", log.Fields{"classID": classID, "Err": omciErr.GetError(), "device-id": oo.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001097 return nil
1098}
1099
1100func (oo *OmciCC) sendCreateDot1PMapper(ctx context.Context, timeout int, highPrio bool,
1101 aInstID uint16, rxChan chan Message) *me.ManagedEntity {
1102 tid := oo.GetNextTid(highPrio)
divyadesai4d299552020-08-18 07:13:49 +00001103 logger.Debugw("send .1pMapper-Create-msg:", log.Fields{"device-id": oo.deviceID,
mpagenko3dbcdd22020-07-22 07:38:45 +00001104 "SequNo": strconv.FormatInt(int64(tid), 16), "InstId": strconv.FormatInt(int64(aInstID), 16)})
1105
1106 meParams := me.ParamData{
1107 EntityID: aInstID,
1108 Attributes: me.AttributeValueMap{},
1109 }
1110 meInstance, omciErr := me.NewIeee8021PMapperServiceProfile(meParams)
1111 if omciErr.GetError() == nil {
1112 //we have to set all 'untouched' parameters to default by some additional option parameter!!
1113 omciLayer, msgLayer, err := omci.EncodeFrame(meInstance, omci.CreateRequestType,
1114 omci.TransactionID(tid), omci.AddDefaults(true))
1115 if err != nil {
1116 logger.Errorw("Cannot encode .1pMapper for create", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00001117 "Err": err, "device-id": oo.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001118 return nil
1119 }
1120
1121 pkt, err := serializeOmciLayer(omciLayer, msgLayer)
1122 if err != nil {
1123 logger.Errorw("Cannot serialize .1pMapper create", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00001124 "Err": err, "device-id": oo.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001125 return nil
1126 }
1127
1128 omciRxCallbackPair := CallbackPair{
1129 cbKey: tid,
1130 cbEntry: CallbackPairEntry{rxChan, oo.receiveOmciResponse},
1131 }
1132 err = oo.Send(ctx, pkt, timeout, 0, highPrio, omciRxCallbackPair)
1133 if err != nil {
1134 logger.Errorw("Cannot send .1pMapper create", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00001135 "Err": err, "device-id": oo.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001136 return nil
1137 }
1138 logger.Debug("send .1pMapper-create-msg done")
1139 return meInstance
1140 }
1141 logger.Errorw("Cannot generate .1pMapper", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00001142 "Err": omciErr.GetError(), "device-id": oo.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001143 return nil
1144}
1145
1146func (oo *OmciCC) sendCreateMBPConfigDataVar(ctx context.Context, timeout int, highPrio bool,
1147 rxChan chan Message, params ...me.ParamData) *me.ManagedEntity {
1148 tid := oo.GetNextTid(highPrio)
divyadesai4d299552020-08-18 07:13:49 +00001149 logger.Debugw("send MBPCD-Create-msg:", log.Fields{"device-id": oo.deviceID,
mpagenko3dbcdd22020-07-22 07:38:45 +00001150 "SequNo": strconv.FormatInt(int64(tid), 16),
1151 "InstId": strconv.FormatInt(int64(params[0].EntityID), 16)})
1152
1153 meInstance, omciErr := me.NewMacBridgePortConfigurationData(params[0])
1154 if omciErr.GetError() == nil {
1155 //obviously we have to set all 'untouched' parameters to default by some additional option parameter!!
1156 omciLayer, msgLayer, err := omci.EncodeFrame(meInstance, omci.CreateRequestType,
1157 omci.TransactionID(tid), omci.AddDefaults(true))
1158 if err != nil {
1159 logger.Errorw("Cannot encode MBPCD for create", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00001160 "Err": err, "device-id": oo.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001161 return nil
1162 }
1163
1164 pkt, err := serializeOmciLayer(omciLayer, msgLayer)
1165 if err != nil {
1166 logger.Errorw("Cannot serialize MBPCD create", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00001167 "Err": err, "device-id": oo.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001168 return nil
1169 }
1170
1171 omciRxCallbackPair := CallbackPair{
1172 cbKey: tid,
1173 cbEntry: CallbackPairEntry{rxChan, oo.receiveOmciResponse},
1174 }
1175 err = oo.Send(ctx, pkt, timeout, 0, highPrio, omciRxCallbackPair)
1176 if err != nil {
1177 logger.Errorw("Cannot send MBPCD create", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00001178 "Err": err, "device-id": oo.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001179 return nil
1180 }
1181 logger.Debug("send MBPCD-Create-msg done")
1182 return meInstance
1183 }
1184 logger.Errorw("Cannot generate MBPCD Instance", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00001185 "Err": omciErr.GetError(), "device-id": oo.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001186 return nil
1187}
1188
1189func (oo *OmciCC) sendCreateGemNCTPVar(ctx context.Context, timeout int, highPrio bool,
1190 rxChan chan Message, params ...me.ParamData) *me.ManagedEntity {
1191 tid := oo.GetNextTid(highPrio)
divyadesai4d299552020-08-18 07:13:49 +00001192 logger.Debugw("send GemNCTP-Create-msg:", log.Fields{"device-id": oo.deviceID,
mpagenko3dbcdd22020-07-22 07:38:45 +00001193 "SequNo": strconv.FormatInt(int64(tid), 16),
1194 "InstId": strconv.FormatInt(int64(params[0].EntityID), 16)})
1195
1196 meInstance, omciErr := me.NewGemPortNetworkCtp(params[0])
1197 if omciErr.GetError() == nil {
1198 //obviously we have to set all 'untouched' parameters to default by some additional option parameter!!
1199 omciLayer, msgLayer, err := omci.EncodeFrame(meInstance, omci.CreateRequestType,
1200 omci.TransactionID(tid), omci.AddDefaults(true))
1201 if err != nil {
1202 logger.Errorw("Cannot encode GemNCTP for create", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00001203 "Err": err, "device-id": oo.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001204 return nil
1205 }
1206
1207 pkt, err := serializeOmciLayer(omciLayer, msgLayer)
1208 if err != nil {
1209 logger.Errorw("Cannot serialize GemNCTP create", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00001210 "Err": err, "device-id": oo.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001211 return nil
1212 }
1213
1214 omciRxCallbackPair := CallbackPair{
1215 cbKey: tid,
1216 cbEntry: CallbackPairEntry{rxChan, oo.receiveOmciResponse},
1217 }
1218 err = oo.Send(ctx, pkt, timeout, 0, highPrio, omciRxCallbackPair)
1219 if err != nil {
1220 logger.Errorw("Cannot send GemNCTP create", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00001221 "Err": err, "device-id": oo.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001222 return nil
1223 }
1224 logger.Debug("send GemNCTP-Create-msg done")
1225 return meInstance
1226 }
1227 logger.Errorw("Cannot generate GemNCTP Instance", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00001228 "Err": omciErr.GetError(), "device-id": oo.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001229 return nil
1230}
1231
1232func (oo *OmciCC) sendCreateGemIWTPVar(ctx context.Context, timeout int, highPrio bool,
1233 rxChan chan Message, params ...me.ParamData) *me.ManagedEntity {
1234 tid := oo.GetNextTid(highPrio)
divyadesai4d299552020-08-18 07:13:49 +00001235 logger.Debugw("send GemIwTp-Create-msg:", log.Fields{"device-id": oo.deviceID,
mpagenko3dbcdd22020-07-22 07:38:45 +00001236 "SequNo": strconv.FormatInt(int64(tid), 16),
1237 "InstId": strconv.FormatInt(int64(params[0].EntityID), 16)})
1238
1239 meInstance, omciErr := me.NewGemInterworkingTerminationPoint(params[0])
1240 if omciErr.GetError() == nil {
1241 //all SetByCreate Parameters (assumed to be) set here, for optimisation no 'AddDefaults'
1242 omciLayer, msgLayer, err := omci.EncodeFrame(meInstance, omci.CreateRequestType,
1243 omci.TransactionID(tid))
1244 if err != nil {
1245 logger.Errorw("Cannot encode GemIwTp for create", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00001246 "Err": err, "device-id": oo.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001247 return nil
1248 }
1249
1250 pkt, err := serializeOmciLayer(omciLayer, msgLayer)
1251 if err != nil {
1252 logger.Errorw("Cannot serialize GemIwTp create", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00001253 "Err": err, "device-id": oo.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001254 return nil
1255 }
1256
1257 omciRxCallbackPair := CallbackPair{
1258 cbKey: tid,
1259 cbEntry: CallbackPairEntry{rxChan, oo.receiveOmciResponse},
1260 }
1261 err = oo.Send(ctx, pkt, timeout, 0, highPrio, omciRxCallbackPair)
1262 if err != nil {
1263 logger.Errorw("Cannot send GemIwTp create", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00001264 "Err": err, "device-id": oo.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001265 return nil
1266 }
1267 logger.Debug("send GemIwTp-Create-msg done")
1268 return meInstance
1269 }
1270 logger.Errorw("Cannot generate GemIwTp Instance", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00001271 "Err": omciErr.GetError(), "device-id": oo.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001272 return nil
1273}
1274
1275func (oo *OmciCC) sendSetTcontVar(ctx context.Context, timeout int, highPrio bool,
1276 rxChan chan Message, params ...me.ParamData) *me.ManagedEntity {
1277 tid := oo.GetNextTid(highPrio)
divyadesai4d299552020-08-18 07:13:49 +00001278 logger.Debugw("send TCont-Set-msg:", log.Fields{"device-id": oo.deviceID,
mpagenko3dbcdd22020-07-22 07:38:45 +00001279 "SequNo": strconv.FormatInt(int64(tid), 16),
1280 "InstId": strconv.FormatInt(int64(params[0].EntityID), 16)})
1281
1282 meInstance, omciErr := me.NewTCont(params[0])
1283 if omciErr.GetError() == nil {
1284 omciLayer, msgLayer, err := omci.EncodeFrame(meInstance, omci.SetRequestType, omci.TransactionID(tid))
1285 if err != nil {
1286 logger.Errorw("Cannot encode TCont for set", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00001287 "Err": err, "device-id": oo.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001288 return nil
1289 }
1290
1291 pkt, err := serializeOmciLayer(omciLayer, msgLayer)
1292 if err != nil {
1293 logger.Errorw("Cannot serialize TCont set", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00001294 "Err": err, "device-id": oo.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001295 return nil
1296 }
1297
1298 omciRxCallbackPair := CallbackPair{
1299 cbKey: tid,
1300 cbEntry: CallbackPairEntry{rxChan, oo.receiveOmciResponse},
1301 }
1302 err = oo.Send(ctx, pkt, timeout, 0, highPrio, omciRxCallbackPair)
1303 if err != nil {
1304 logger.Errorw("Cannot send TCont set", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00001305 "Err": err, "device-id": oo.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001306 return nil
1307 }
1308 logger.Debug("send TCont-set msg done")
1309 return meInstance
1310 }
1311 logger.Errorw("Cannot generate TCont Instance", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00001312 "Err": omciErr.GetError(), "device-id": oo.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001313 return nil
1314}
1315
1316func (oo *OmciCC) sendSetPrioQueueVar(ctx context.Context, timeout int, highPrio bool,
1317 rxChan chan Message, params ...me.ParamData) *me.ManagedEntity {
1318 tid := oo.GetNextTid(highPrio)
divyadesai4d299552020-08-18 07:13:49 +00001319 logger.Debugw("send PrioQueue-Set-msg:", log.Fields{"device-id": oo.deviceID,
mpagenko3dbcdd22020-07-22 07:38:45 +00001320 "SequNo": strconv.FormatInt(int64(tid), 16),
1321 "InstId": strconv.FormatInt(int64(params[0].EntityID), 16)})
1322
1323 meInstance, omciErr := me.NewPriorityQueue(params[0])
1324 if omciErr.GetError() == nil {
1325 omciLayer, msgLayer, err := omci.EncodeFrame(meInstance, omci.SetRequestType, omci.TransactionID(tid))
1326 if err != nil {
1327 logger.Errorw("Cannot encode PrioQueue for set", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00001328 "Err": err, "device-id": oo.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001329 return nil
1330 }
1331
1332 pkt, err := serializeOmciLayer(omciLayer, msgLayer)
1333 if err != nil {
1334 logger.Errorw("Cannot serialize PrioQueue set", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00001335 "Err": err, "device-id": oo.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001336 return nil
1337 }
1338
1339 omciRxCallbackPair := CallbackPair{
1340 cbKey: tid,
1341 cbEntry: CallbackPairEntry{rxChan, oo.receiveOmciResponse},
1342 }
1343 err = oo.Send(ctx, pkt, timeout, 0, highPrio, omciRxCallbackPair)
1344 if err != nil {
1345 logger.Errorw("Cannot send PrioQueue set", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00001346 "Err": err, "device-id": oo.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001347 return nil
1348 }
1349 logger.Debug("send PrioQueue-set msg done")
1350 return meInstance
1351 }
1352 logger.Errorw("Cannot generate PrioQueue Instance", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00001353 "Err": omciErr.GetError(), "device-id": oo.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001354 return nil
1355}
1356
1357func (oo *OmciCC) sendSetDot1PMapperVar(ctx context.Context, timeout int, highPrio bool,
1358 rxChan chan Message, params ...me.ParamData) *me.ManagedEntity {
1359 tid := oo.GetNextTid(highPrio)
divyadesai4d299552020-08-18 07:13:49 +00001360 logger.Debugw("send 1PMapper-Set-msg:", log.Fields{"device-id": oo.deviceID,
mpagenko3dbcdd22020-07-22 07:38:45 +00001361 "SequNo": strconv.FormatInt(int64(tid), 16),
1362 "InstId": strconv.FormatInt(int64(params[0].EntityID), 16)})
1363
1364 meInstance, omciErr := me.NewIeee8021PMapperServiceProfile(params[0])
1365 if omciErr.GetError() == nil {
1366 omciLayer, msgLayer, err := omci.EncodeFrame(meInstance, omci.SetRequestType, omci.TransactionID(tid))
1367 if err != nil {
1368 logger.Errorw("Cannot encode 1PMapper for set", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00001369 "Err": err, "device-id": oo.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001370 return nil
1371 }
1372
1373 pkt, err := serializeOmciLayer(omciLayer, msgLayer)
1374 if err != nil {
1375 logger.Errorw("Cannot serialize 1PMapper set", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00001376 "Err": err, "device-id": oo.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001377 return nil
1378 }
1379
1380 omciRxCallbackPair := CallbackPair{
1381 cbKey: tid,
1382 cbEntry: CallbackPairEntry{rxChan, oo.receiveOmciResponse},
1383 }
1384 err = oo.Send(ctx, pkt, timeout, 0, highPrio, omciRxCallbackPair)
1385 if err != nil {
1386 logger.Errorw("Cannot send 1PMapper set", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00001387 "Err": err, "device-id": oo.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001388 return nil
1389 }
1390 logger.Debug("send 1PMapper-set msg done")
1391 return meInstance
1392 }
1393 logger.Errorw("Cannot generate 1PMapper Instance", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00001394 "Err": omciErr.GetError(), "device-id": oo.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001395 return nil
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00001396}
mpagenkodff5dda2020-08-28 11:52:01 +00001397
1398func (oo *OmciCC) sendCreateVtfdVar(ctx context.Context, timeout int, highPrio bool,
1399 rxChan chan Message, params ...me.ParamData) *me.ManagedEntity {
1400 tid := oo.GetNextTid(highPrio)
1401 logger.Debugw("send VTFD-Create-msg:", log.Fields{"device-id": oo.deviceID,
1402 "SequNo": strconv.FormatInt(int64(tid), 16),
1403 "InstId": strconv.FormatInt(int64(params[0].EntityID), 16)})
1404
1405 meInstance, omciErr := me.NewVlanTaggingFilterData(params[0])
1406 if omciErr.GetError() == nil {
1407 //all SetByCreate Parameters (assumed to be) set here, for optimisation no 'AddDefaults'
1408 omciLayer, msgLayer, err := omci.EncodeFrame(meInstance, omci.CreateRequestType,
1409 omci.TransactionID(tid))
1410 if err != nil {
1411 logger.Errorw("Cannot encode VTFD for create", log.Fields{
1412 "Err": err, "device-id": oo.deviceID})
1413 //TODO!!: refactoring improvement requested, here as an example for [VOL-3457]:
1414 // return (dual format) error code that can be used at caller for immediate error treatment
1415 // (relevant to all used sendXX() methods and their error conditions)
1416 return nil
1417 }
1418
1419 pkt, err := serializeOmciLayer(omciLayer, msgLayer)
1420 if err != nil {
1421 logger.Errorw("Cannot serialize VTFD create", log.Fields{
1422 "Err": err, "device-id": oo.deviceID})
1423 return nil
1424 }
1425
1426 omciRxCallbackPair := CallbackPair{
1427 cbKey: tid,
1428 cbEntry: CallbackPairEntry{rxChan, oo.receiveOmciResponse},
1429 }
1430 err = oo.Send(ctx, pkt, timeout, 0, highPrio, omciRxCallbackPair)
1431 if err != nil {
1432 logger.Errorw("Cannot send VTFD create", log.Fields{
1433 "Err": err, "device-id": oo.deviceID})
1434 return nil
1435 }
1436 logger.Debug("send VTFD-Create-msg done")
1437 return meInstance
1438 }
1439 logger.Errorw("Cannot generate VTFD Instance", log.Fields{
1440 "Err": omciErr.GetError(), "device-id": oo.deviceID})
1441 return nil
1442}
1443
1444func (oo *OmciCC) sendSetEvtocdVar(ctx context.Context, timeout int, highPrio bool,
1445 rxChan chan Message, params ...me.ParamData) *me.ManagedEntity {
1446 tid := oo.GetNextTid(highPrio)
1447 logger.Debugw("send EVTOCD-Set-msg:", log.Fields{"device-id": oo.deviceID,
1448 "SequNo": strconv.FormatInt(int64(tid), 16),
1449 "InstId": strconv.FormatInt(int64(params[0].EntityID), 16)})
1450
1451 meInstance, omciErr := me.NewExtendedVlanTaggingOperationConfigurationData(params[0])
1452 if omciErr.GetError() == nil {
1453 omciLayer, msgLayer, err := omci.EncodeFrame(meInstance, omci.SetRequestType, omci.TransactionID(tid))
1454 if err != nil {
1455 logger.Errorw("Cannot encode EVTOCD for set", log.Fields{
1456 "Err": err, "device-id": oo.deviceID})
1457 return nil
1458 }
1459
1460 pkt, err := serializeOmciLayer(omciLayer, msgLayer)
1461 if err != nil {
1462 logger.Errorw("Cannot serialize EVTOCD set", log.Fields{
1463 "Err": err, "device-id": oo.deviceID})
1464 return nil
1465 }
1466
1467 omciRxCallbackPair := CallbackPair{
1468 cbKey: tid,
1469 cbEntry: CallbackPairEntry{rxChan, oo.receiveOmciResponse},
1470 }
1471 err = oo.Send(ctx, pkt, timeout, 0, highPrio, omciRxCallbackPair)
1472 if err != nil {
1473 logger.Errorw("Cannot send EVTOCD set", log.Fields{
1474 "Err": err, "device-id": oo.deviceID})
1475 return nil
1476 }
1477 logger.Debug("send EVTOCD-set msg done")
1478 return meInstance
1479 }
1480 logger.Errorw("Cannot generate EVTOCD Instance", log.Fields{
1481 "Err": omciErr.GetError(), "device-id": oo.deviceID})
1482 return nil
1483}