blob: 9cf38acae00ec5de53fee7e4476d49f2a5e105fb [file] [log] [blame]
Takahiro Suzuki241c10e2020-12-17 20:17:57 +09001/*
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
17//Package adaptercoreonu provides the utility for onu devices, flows and statistics
18package adaptercoreonu
19
20import (
21 "container/list"
22 "context"
23 "encoding/binary"
24 "encoding/hex"
25 "errors"
26 "strconv"
27 "sync"
28
29
30 "github.com/google/gopacket"
31 gp "github.com/google/gopacket"
32
33 "github.com/opencord/omci-lib-go"
34 me "github.com/opencord/omci-lib-go/generated"
35 "github.com/opencord/voltha-lib-go/v3/pkg/adapters/adapterif"
36
37 "github.com/opencord/voltha-lib-go/v3/pkg/log"
38 ic "github.com/opencord/voltha-protos/v3/go/inter_container"
39)
40
41// ### OMCI related definitions - retrieved from Python adapter code/trace ####
42
43//ConstDefaultOmciTimeout - Default OMCI Timeout
44const ConstDefaultOmciTimeout = 10 // ( 3 ?) Seconds
45
46const galEthernetEID = uint16(1)
47const maxGemPayloadSize = uint16(48)
48const connectivityModeValue = uint8(5)
49
50//const defaultTPID = uint16(0x8100)
51//const broadComDefaultVID = uint16(4091)
52const macBridgeServiceProfileEID = uint16(0x201) // TODO: most all these need better definition or tuning
53const ieeeMapperServiceProfileEID = uint16(0x8001)
54const macBridgePortAniEID = uint16(0x2102)
55
56// ### OMCI related definitions - end
57
58//callbackPairEntry to be used for OMCI send/receive correlation
59type callbackPairEntry struct {
60 cbRespChannel chan Message
61 cbFunction func(*omci.OMCI, *gp.Packet, chan Message) error
62}
63
64//callbackPair to be used for ReceiveCallback init
65type callbackPair struct {
66 cbKey uint16
67 cbEntry callbackPairEntry
68}
69
70type omciTransferStructure struct {
71 txFrame []byte
72 timeout int
73 retry int
74 highPrio bool
75}
76
77//omciCC structure holds information needed for OMCI communication (to/from OLT Adapter)
78type omciCC struct {
79 enabled bool
80 pOnuDeviceEntry *OnuDeviceEntry
81 deviceID string
82 pBaseDeviceHandler *deviceHandler
83 coreProxy adapterif.CoreProxy
84 adapterProxy adapterif.AdapterProxy
85 supportExtMsg bool
86 txFrames, txOnuFrames uint32
87 rxFrames, rxOnuFrames, rxOnuDiscards uint32
88
89 mutexTid sync.Mutex
90 tid uint16
91 mutexHpTid sync.Mutex
92 hpTid uint16
93 uploadSequNo uint16
94 uploadNoOfCmds uint16
95
96 mutexTxQueue sync.Mutex
97 txQueue *list.List
98 mutexRxSchedMap sync.Mutex
99 rxSchedulerMap map[uint16]callbackPairEntry
100 pLastTxMeInstance *me.ManagedEntity
101}
102
103//newOmciCC constructor returns a new instance of a OmciCC
104//mib_db (as well as not inluded alarm_db not really used in this code? VERIFY!!)
105func newOmciCC(ctx context.Context, onuDeviceEntry *OnuDeviceEntry,
106 deviceID string, deviceHandler *deviceHandler,
107 coreProxy adapterif.CoreProxy, adapterProxy adapterif.AdapterProxy) *omciCC {
108 logger.Infow("init-omciCC", log.Fields{"device-id": deviceID})
109 var omciCC omciCC
110 omciCC.enabled = false
111 omciCC.pOnuDeviceEntry = onuDeviceEntry
112 omciCC.deviceID = deviceID
113 omciCC.pBaseDeviceHandler = deviceHandler
114 omciCC.coreProxy = coreProxy
115 omciCC.adapterProxy = adapterProxy
116 omciCC.supportExtMsg = false
117 omciCC.txFrames = 0
118 omciCC.txOnuFrames = 0
119 omciCC.rxFrames = 0
120 omciCC.rxOnuFrames = 0
121 omciCC.rxOnuDiscards = 0
122 omciCC.tid = 0x1
123 omciCC.hpTid = 0x8000
124 omciCC.uploadSequNo = 0
125 omciCC.uploadNoOfCmds = 0
126
127 omciCC.txQueue = list.New()
128 omciCC.rxSchedulerMap = make(map[uint16]callbackPairEntry)
129
130 return &omciCC
131}
132
133// Rx handler for omci messages
134func (oo *omciCC) receiveOnuMessage(ctx context.Context, omciMsg *omci.OMCI) error {
135 logger.Debugw("rx-onu-autonomous-message", log.Fields{"omciMsgType": omciMsg.MessageType,
136 "payload": hex.EncodeToString(omciMsg.Payload)})
137 /*
138 msgType = rxFrame.fields["message_type"] //assumed OmciOperationsValue
139 rxOnuFrames++
140
141 switch msgType {
142 case AlarmNotification:
143 {
144 logger.Info("Unhandled: received-onu-alarm-message")
145 // python code was:
146 //if msg_type == EntityOperations.AlarmNotification.value:
147 // topic = OMCI_CC.event_bus_topic(self._device_id, RxEvent.Alarm_Notification)
148 // self.reactor.callLater(0, self.event_bus.publish, topic, msg)
149 //
150 return errors.New("RxAlarmNotification unimplemented")
151 }
152 case AttributeValueChange:
153 {
154 logger.Info("Unhandled: received-attribute-value-change")
155 // python code was:
156 //elif msg_type == EntityOperations.AttributeValueChange.value:
157 // topic = OMCI_CC.event_bus_topic(self._device_id, RxEvent.AVC_Notification)
158 // self.reactor.callLater(0, self.event_bus.publish, topic, msg)
159 //
160 return errors.New("RxAttributeValueChange unimplemented")
161 }
162 case TestResult:
163 {
164 logger.Info("Unhandled: received-test-result")
165 // python code was:
166 //elif msg_type == EntityOperations.TestResult.value:
167 // topic = OMCI_CC.event_bus_topic(self._device_id, RxEvent.Test_Result)
168 // self.reactor.callLater(0, self.event_bus.publish, topic, msg)
169 //
170 return errors.New("RxTestResult unimplemented")
171 }
172 default:
173 {
174 logger.Errorw("rx-onu-unsupported-autonomous-message", log.Fields{"msgType": msgType})
175 rxOnuDiscards++
176 return errors.New("RxOnuMsgType unimplemented")
177 }
178 }
179 */
180 return errors.New("receiveOnuMessage unimplemented")
181}
182
183// Rx handler for onu messages
184// e.g. would call ReceiveOnuMessage() in case of TID=0 or Action=test ...
185func (oo *omciCC) receiveMessage(ctx context.Context, rxMsg []byte) error {
186 if len(rxMsg) >= 44 { // then it should normally include the BaseFormat trailer Len
187 // NOTE: autocorrection only valid for OmciBaseFormat, which is not specifically verified here!!!
188 // (am extendedFormat message could be destroyed this way!)
189 trailerLenData := rxMsg[42:44]
190 trailerLen := binary.BigEndian.Uint16(trailerLenData)
191 //logger.Debugw("omci-received-trailer-len", log.Fields{"Length": trailerLen})
192 if trailerLen != 40 { // invalid base Format entry -> autocorrect
193 binary.BigEndian.PutUint16(rxMsg[42:44], 40)
194 logger.Debug("cc-corrected-omci-message: trailer len inserted")
195 }
196 } else {
197 logger.Errorw("received omci-message too small for OmciBaseFormat - abort", log.Fields{"Length": len(rxMsg)})
198 return errors.New("rxOmciMessage too small for BaseFormat")
199 }
200
201 packet := gopacket.NewPacket(rxMsg, omci.LayerTypeOMCI, gopacket.NoCopy)
202 if packet == nil {
203 logger.Error("omci-message could not be decoded")
204 return errors.New("could not decode rxMsg as OMCI")
205 }
206 omciLayer := packet.Layer(omci.LayerTypeOMCI)
207 if omciLayer == nil {
208 logger.Error("omci-message could not decode omci layer")
209 return errors.New("could not decode omci layer")
210 }
211 omciMsg, ok := omciLayer.(*omci.OMCI)
212 if !ok {
213 logger.Error("omci-message could not assign omci layer")
214 return errors.New("could not assign omci layer")
215 }
216 logger.Debugw("omci-message-decoded:", log.Fields{"omciMsgType": omciMsg.MessageType,
217 "transCorrId": strconv.FormatInt(int64(omciMsg.TransactionID), 16), "DeviceIdent": omciMsg.DeviceIdentifier})
218 if byte(omciMsg.MessageType) & ^me.AK == 0 {
219 // Not a response
220 logger.Debug("RxMsg is no Omci Response Message")
221 if omciMsg.TransactionID == 0 {
222 return oo.receiveOnuMessage(ctx, omciMsg)
223 }
224 logger.Errorw("Unexpected TransCorrId != 0 not accepted for autonomous messages",
225 log.Fields{"msgType": omciMsg.MessageType, "payload": hex.EncodeToString(omciMsg.Payload)})
226 return errors.New("autonomous Omci Message with TranSCorrId != 0 not acccepted")
227
228 }
229 oo.mutexRxSchedMap.Lock()
230 rxCallbackEntry, ok := oo.rxSchedulerMap[omciMsg.TransactionID]
231 if ok && rxCallbackEntry.cbFunction != nil {
232 //disadvantage of decoupling: error verification made difficult, but anyway the question is
233 // how to react on erroneous frame reception, maybe can simply be ignored
234 go rxCallbackEntry.cbFunction(omciMsg, &packet, rxCallbackEntry.cbRespChannel)
235 // having posted the response the request is regarded as 'done'
236 delete(oo.rxSchedulerMap, omciMsg.TransactionID)
237 oo.mutexRxSchedMap.Unlock()
238 } else {
239 oo.mutexRxSchedMap.Unlock()
240 logger.Error("omci-message-response for not registered transCorrId")
241 return errors.New("could not find registered response handler tor transCorrId")
242 }
243
244 return nil
245 /* py code was:
246 Receive and OMCI message from the proxy channel to the OLT.
247
248 Call this from your ONU Adapter on a new OMCI Rx on the proxy channel
249 :param msg: (str) OMCI binary message (used as input to Scapy packet decoder)
250 """
251 if not self.enabled:
252 return
253
254 try:
255 now = arrow.utcnow()
256 d = None
257
258 # NOTE: Since we may need to do an independent ME map on a per-ONU basis
259 # save the current value of the entity_id_to_class_map, then
260 # replace it with our custom one before decode, and then finally
261 # restore it later. Tried other ways but really made the code messy.
262 saved_me_map = omci_entities.entity_id_to_class_map
263 omci_entities.entity_id_to_class_map = self._me_map
264
265 try:
266 rx_frame = msg if isinstance(msg, OmciFrame) else OmciFrame(msg)
267 self.logger.debug('recv-omci-msg', omci_msg=hexlify(msg))
268 except KeyError as e:
269 # Unknown, Unsupported, or vendor-specific ME. Key is the unknown classID
270 self.logger.debug('frame-decode-key-error', omci_msg=hexlify(msg), e=e)
271 rx_frame = self._decode_unknown_me(msg)
272 self._rx_unknown_me += 1
273
274 except Exception as e:
275 self.logger.exception('frame-decode', omci_msg=hexlify(msg), e=e)
276 return
277
278 finally:
279 omci_entities.entity_id_to_class_map = saved_me_map # Always restore it.
280
281 rx_tid = rx_frame.fields['transaction_id']
282 msg_type = rx_frame.fields['message_type']
283 self.logger.debug('Received message for rx_tid', rx_tid = rx_tid, msg_type = msg_type)
284 # Filter the Test Result frame and route through receive onu
285 # message method.
286 if rx_tid == 0 or msg_type == EntityOperations.TestResult.value:
287 self.logger.debug('Receive ONU message', rx_tid=0)
288 return self._receive_onu_message(rx_frame)
289
290 # Previously unreachable if this is the very first round-trip Rx or we
291 # have been running consecutive errors
292 if self._rx_frames == 0 or self._consecutive_errors != 0:
293 self.logger.debug('Consecutive errors for rx', err = self._consecutive_errors)
294 self.reactor.callLater(0, self._publish_connectivity_event, True)
295
296 self._rx_frames += 1
297 self._consecutive_errors = 0
298
299 try:
300 high_priority = self._tid_is_high_priority(rx_tid)
301 index = self._get_priority_index(high_priority)
302
303 # (timestamp, defer, frame, timeout, retry, delayedCall)
304 last_tx_tuple = self._tx_request[index]
305
306 if last_tx_tuple is None or \
307 last_tx_tuple[OMCI_CC.REQUEST_FRAME].fields.get('transaction_id') != rx_tid:
308 # Possible late Rx on a message that timed-out
309 if last_tx_tuple:
310 self.logger.debug('Unknown message', rx_tid=rx_tid,
311 tx_id=last_tx_tuple[OMCI_CC.REQUEST_FRAME].fields.get('transaction_id'))
312 self._rx_unknown_tid += 1
313 self._rx_late += 1
314 return
315
316 ts, d, tx_frame, timeout, retry, dc = last_tx_tuple
317 if dc is not None and not dc.cancelled and not dc.called:
318 dc.cancel()
319
320 _secs = self._update_rx_tx_stats(now, ts)
321
322 # Late arrival already serviced by a timeout?
323 if d.called:
324 self._rx_late += 1
325 self.logger.debug('Serviced by timeout. Late arrival', rx_late = self._rx_late)
326 return
327
328 except Exception as e:
329 self.logger.exception('frame-match', msg=hexlify(msg), e=e)
330 if d is not None:
331 return d.errback(failure.Failure(e))
332 return
333
334 # Publish Rx event to listeners in a different task
335 self.logger.debug('Publish rx event', rx_tid = rx_tid,
336 tx_tid = tx_frame.fields['transaction_id'])
337 reactor.callLater(0, self._publish_rx_frame, tx_frame, rx_frame)
338
339 # begin success callback chain (will cancel timeout and queue next Tx message)
340 self._rx_response[index] = rx_frame
341 d.callback(rx_frame)
342
343 except Exception as e:
344 self.logger.exception('rx-msg', e=e)
345 */
346}
347
348/*
349func (oo *omciCC) publishRxResponseFrame(ctx context.Context, txFrame []byte, rxFrame []byte) error {
350 return errors.New("publishRxResponseFrame unimplemented")
351 //def _publish_rx_frame(self, tx_frame, rx_frame):
352}
353*/
354
355//Queue the OMCI Frame for a transmit to the ONU via the proxy_channel
356func (oo *omciCC) send(ctx context.Context, txFrame []byte, timeout int, retry int, highPrio bool,
357 receiveCallbackPair callbackPair) error {
358
359 logger.Debugw("register-response-callback:", log.Fields{"for TansCorrId": receiveCallbackPair.cbKey})
360 oo.mutexRxSchedMap.Lock()
361 oo.rxSchedulerMap[receiveCallbackPair.cbKey] = receiveCallbackPair.cbEntry
362 oo.mutexRxSchedMap.Unlock()
363
364 omciTxRequest := omciTransferStructure{
365 txFrame,
366 timeout,
367 retry,
368 highPrio,
369 }
370 oo.mutexTxQueue.Lock()
371 oo.txQueue.PushBack(omciTxRequest) // enqueue
372 oo.mutexTxQueue.Unlock()
373
374 go oo.sendNextRequest(ctx)
375 return nil
376}
377
378//Pull next tx request and send it
379func (oo *omciCC) sendNextRequest(ctx context.Context) error {
380
381 oo.mutexTxQueue.Lock()
382 defer oo.mutexTxQueue.Unlock()
383 for oo.txQueue.Len() > 0 {
384 queueElement := oo.txQueue.Front() // First element
385 omciTxRequest := queueElement.Value.(omciTransferStructure)
386 /* compare olt device handler code:
387 func (dh *DeviceHandler) omciIndication(omciInd *oop.OmciIndication) {
388 logger.Debugw("omci indication", log.Fields{"intfID": omciInd.IntfId, "onuID": omciInd.OnuId})
389 var deviceType string
390 var deviceID string
391 var proxyDeviceID string
392
393 onuKey := dh.formOnuKey(omciInd.IntfId, omciInd.OnuId)
394
395 if onuInCache, ok := dh.onus.Load(onuKey); !ok {
396
397 logger.Debugw("omci indication for a device not in cache.", log.Fields{"intfID": omciInd.IntfId, "onuID": omciInd.OnuId})
398 ponPort := IntfIDToPortNo(omciInd.GetIntfId(), voltha.Port_PON_OLT)
399 kwargs := make(map[string]interface{})
400 kwargs["onu_id"] = omciInd.OnuId
401 kwargs["parent_port_no"] = ponPort
402
403 onuDevice, err := dh.coreProxy.GetChildDevice(context.TODO(), dh.device.Id, kwargs)
404 if err != nil {
405 logger.Errorw("onu not found", log.Fields{"intfID": omciInd.IntfId, "onuID": omciInd.OnuId, "error": err})
406 return
407 }
408 deviceType = onuDevice.Type
409 deviceID = onuDevice.Id
410 proxyDeviceID = onuDevice.ProxyAddress.DeviceId
411 //if not exist in cache, then add to cache.
412 dh.onus.Store(onuKey, NewOnuDevice(deviceID, deviceType, onuDevice.SerialNumber, omciInd.OnuId, omciInd.IntfId, proxyDeviceID))
413 } else {
414 //found in cache
415 logger.Debugw("omci indication for a device in cache.", log.Fields{"intfID": omciInd.IntfId, "onuID": omciInd.OnuId})
416 deviceType = onuInCache.(*OnuDevice).deviceType
417 deviceID = onuInCache.(*OnuDevice).deviceID
418 proxyDeviceID = onuInCache.(*OnuDevice).proxyDeviceID
419 }
420 */
421 /* and compare onu_adapter py code:
422 omci_msg = InterAdapterOmciMessage(
423 message=bytes(frame),
424 proxy_address=self._proxy_address,
425 connect_status=self._device.connect_status)
426
427 self.logger.debug('sent-omci-msg', tid=tx_tid, omci_msg=hexlify(bytes(frame)))
428
429 yield self._adapter_proxy.send_inter_adapter_message(
430 msg=omci_msg,
431 type=InterAdapterMessageType.OMCI_REQUEST,
432 from_adapter=self._device.type,
433 to_adapter=self._proxy_address.device_type,
434 to_device_id=self._device_id,
435 proxy_device_id=self._proxy_address.device_id
436 )
437 */
438 device, err := oo.coreProxy.GetDevice(ctx,
439 oo.pBaseDeviceHandler.deviceID, oo.deviceID) //parent, child
440 if err != nil || device == nil {
441 /*TODO: needs to handle error scenarios */
442 logger.Errorw("Failed to fetch device", log.Fields{"err": err, "ParentId": oo.pBaseDeviceHandler.deviceID,
443 "ChildId": oo.deviceID})
444 return errors.New("failed to fetch device")
445 }
446
447 logger.Debugw("omci-message-sending", log.Fields{"fromDeviceType": oo.pBaseDeviceHandler.DeviceType,
448 "toDeviceType": oo.pBaseDeviceHandler.ProxyAddressType,
449 "onuDeviceID": oo.deviceID, "proxyDeviceID": oo.pBaseDeviceHandler.ProxyAddressID})
450 logger.Debugw("omci-message-to-send:",
451 log.Fields{"TxOmciMessage": hex.EncodeToString(omciTxRequest.txFrame)})
452
453 omciMsg := &ic.InterAdapterOmciMessage{Message: omciTxRequest.txFrame}
454 if sendErr := oo.adapterProxy.SendInterAdapterMessage(context.Background(), omciMsg,
455 ic.InterAdapterMessageType_OMCI_REQUEST,
456 //fromType,toType,toDevId, ProxyDevId
457 oo.pBaseDeviceHandler.DeviceType, oo.pBaseDeviceHandler.ProxyAddressType,
458 oo.deviceID, oo.pBaseDeviceHandler.ProxyAddressID, ""); sendErr != nil {
459 logger.Errorw("send omci request error", log.Fields{"error": sendErr})
460 return sendErr
461 }
462 oo.txQueue.Remove(queueElement) // Dequeue
463 }
464 return nil
465}
466
467func (oo *omciCC) getNextTid(highPriority bool) uint16 {
468 var next uint16
469 if highPriority {
470 oo.mutexTid.Lock()
471 next = oo.hpTid
472 oo.hpTid++
473 if oo.hpTid < 0x8000 {
474 oo.hpTid = 0x8000
475 }
476 oo.mutexTid.Unlock()
477 } else {
478 oo.mutexHpTid.Lock()
479 next = oo.tid
480 oo.tid++
481 if oo.tid >= 0x8000 {
482 oo.tid = 1
483 }
484 oo.mutexHpTid.Unlock()
485 }
486 return next
487}
488
489// ###################################################################################
490// # utility methods provided to work on OMCI messages
491func serialize(msgType omci.MessageType, request gopacket.SerializableLayer, tid uint16) ([]byte, error) {
492 omciLayer := &omci.OMCI{
493 TransactionID: tid,
494 MessageType: msgType,
495 }
496 return serializeOmciLayer(omciLayer, request)
497}
498
499func serializeOmciLayer(aOmciLayer *omci.OMCI, aRequest gopacket.SerializableLayer) ([]byte, error) {
500 var options gopacket.SerializeOptions
501 options.FixLengths = true
502
503 buffer := gopacket.NewSerializeBuffer()
504 err := gopacket.SerializeLayers(buffer, options, aOmciLayer, aRequest)
505 if err != nil {
506 logger.Errorw("Could not create goPacket Omci serial buffer", log.Fields{"Err": err})
507 return nil, err
508 }
509 return buffer.Bytes(), nil
510}
511
512/*
513func hexEncode(omciPkt []byte) ([]byte, error) {
514 dst := make([]byte, hex.EncodedLen(len(omciPkt)))
515 hex.Encode(dst, omciPkt)
516 return dst, nil
517}
518*/
519
520//supply a response handler for omci response messages to be transferred to the requested FSM
521func (oo *omciCC) receiveOmciResponse(omciMsg *omci.OMCI, packet *gp.Packet, respChan chan Message) error {
522
523 logger.Debugw("omci-message-response - transfer on omciRespChannel", log.Fields{"omciMsgType": omciMsg.MessageType,
524 "transCorrId": strconv.FormatInt(int64(omciMsg.TransactionID), 16), "device-id": oo.deviceID})
525
526 if oo.pOnuDeviceEntry == nil {
527 logger.Errorw("Abort receiving OMCI response, DeviceEntryPointer is nil", log.Fields{
528 "device-id": oo.deviceID})
529 return errors.New("deviceEntryPointer is nil")
530 }
531
532 omciRespMsg := Message{
533 Type: OMCI,
534 Data: OmciMessage{
535 OmciMsg: omciMsg,
536 OmciPacket: packet,
537 },
538 }
539 respChan <- omciRespMsg
540
541 return nil
542}
543
544func (oo *omciCC) sendMibReset(ctx context.Context, timeout int, highPrio bool) error {
545
546 logger.Debugw("send MibReset-msg to:", log.Fields{"device-id": oo.deviceID})
547 request := &omci.MibResetRequest{
548 MeBasePacket: omci.MeBasePacket{
549 EntityClass: me.OnuDataClassID,
550 },
551 }
552 tid := oo.getNextTid(highPrio)
553 pkt, err := serialize(omci.MibResetRequestType, request, tid)
554 if err != nil {
555 logger.Errorw("Cannot serialize MibResetRequest", log.Fields{
556 "Err": err, "device-id": oo.deviceID})
557 return err
558 }
559 omciRxCallbackPair := callbackPair{
560 cbKey: tid,
561 cbEntry: callbackPairEntry{(*oo.pOnuDeviceEntry).pMibUploadFsm.commChan, oo.receiveOmciResponse},
562 }
563 return oo.send(ctx, pkt, timeout, 0, highPrio, omciRxCallbackPair)
564}
565
566func (oo *omciCC) sendReboot(ctx context.Context, timeout int, highPrio bool, responseChannel chan Message) error {
567 logger.Debugw("send Reboot-msg to:", log.Fields{"device-id": oo.deviceID})
568 request := &omci.RebootRequest{
569 MeBasePacket: omci.MeBasePacket{
570 EntityClass: me.OnuGClassID,
571 },
572 }
573 tid := oo.getNextTid(highPrio)
574 pkt, err := serialize(omci.RebootRequestType, request, tid)
575 if err != nil {
576 logger.Errorw("Cannot serialize RebootRequest", log.Fields{
577 "Err": err, "device-id": oo.deviceID})
578 return err
579 }
580 omciRxCallbackPair := callbackPair{
581 cbKey: tid,
582 cbEntry: callbackPairEntry{oo.pOnuDeviceEntry.omciRebootMessageReceivedChannel, oo.receiveOmciResponse},
583 }
584
585 err = oo.send(ctx, pkt, timeout, 0, highPrio, omciRxCallbackPair)
586 if err != nil {
587 logger.Errorw("Cannot send RebootRequest", log.Fields{
588 "Err": err, "device-id": oo.deviceID})
589 return err
590 }
591 err = oo.pOnuDeviceEntry.waitForRebootResponse(responseChannel)
592 if err != nil {
593 logger.Error("aborting ONU Reboot!")
594 _ = oo.pOnuDeviceEntry.pMibDownloadFsm.pFsm.Event("reset")
595 return err
596 }
597 return nil
598}
599
600func (oo *omciCC) sendMibUpload(ctx context.Context, timeout int, highPrio bool) error {
601 logger.Debugw("send MibUpload-msg to:", log.Fields{"device-id": oo.deviceID})
602 request := &omci.MibUploadRequest{
603 MeBasePacket: omci.MeBasePacket{
604 EntityClass: me.OnuDataClassID,
605 },
606 }
607 tid := oo.getNextTid(highPrio)
608 pkt, err := serialize(omci.MibUploadRequestType, request, tid)
609 if err != nil {
610 logger.Errorw("Cannot serialize MibUploadRequest", log.Fields{
611 "Err": err, "device-id": oo.deviceID})
612 return err
613 }
614 oo.uploadSequNo = 0
615 oo.uploadNoOfCmds = 0
616
617 omciRxCallbackPair := callbackPair{
618 cbKey: tid,
619 cbEntry: callbackPairEntry{(*oo.pOnuDeviceEntry).pMibUploadFsm.commChan, oo.receiveOmciResponse},
620 }
621 return oo.send(ctx, pkt, timeout, 0, highPrio, omciRxCallbackPair)
622}
623
624func (oo *omciCC) sendMibUploadNext(ctx context.Context, timeout int, highPrio bool) error {
625 logger.Debugw("send MibUploadNext-msg to:", log.Fields{"device-id": oo.deviceID, "uploadSequNo": oo.uploadSequNo})
626 request := &omci.MibUploadNextRequest{
627 MeBasePacket: omci.MeBasePacket{
628 EntityClass: me.OnuDataClassID,
629 },
630 CommandSequenceNumber: oo.uploadSequNo,
631 }
632 tid := oo.getNextTid(highPrio)
633 pkt, err := serialize(omci.MibUploadNextRequestType, request, tid)
634 if err != nil {
635 logger.Errorw("Cannot serialize MibUploadNextRequest", log.Fields{
636 "Err": err, "device-id": oo.deviceID})
637 return err
638 }
639 oo.uploadSequNo++
640
641 omciRxCallbackPair := callbackPair{
642 cbKey: tid,
643 cbEntry: callbackPairEntry{(*oo.pOnuDeviceEntry).pMibUploadFsm.commChan, oo.receiveOmciResponse},
644 }
645 return oo.send(ctx, pkt, timeout, 0, highPrio, omciRxCallbackPair)
646}
647
648func (oo *omciCC) sendCreateGalEthernetProfile(ctx context.Context, timeout int, highPrio bool) *me.ManagedEntity {
649 tid := oo.getNextTid(highPrio)
650 logger.Debugw("send GalEnetProfile-Create-msg:", log.Fields{"device-id": oo.deviceID,
651 "SequNo": strconv.FormatInt(int64(tid), 16)})
652
653 meParams := me.ParamData{
654 EntityID: galEthernetEID,
655 Attributes: me.AttributeValueMap{"MaximumGemPayloadSize": maxGemPayloadSize},
656 }
657 meInstance, omciErr := me.NewGalEthernetProfile(meParams)
658 if omciErr.GetError() == nil {
659 //all setByCreate parameters already set, no default option required ...
660 omciLayer, msgLayer, err := omci.EncodeFrame(meInstance, omci.CreateRequestType, omci.TransactionID(tid))
661 if err != nil {
662 logger.Errorw("Cannot encode GalEnetProfileInstance for create", log.Fields{
663 "Err": err, "device-id": oo.deviceID})
664 return nil
665 }
666
667 pkt, err := serializeOmciLayer(omciLayer, msgLayer)
668 if err != nil {
669 logger.Errorw("Cannot serialize GalEnetProfile create", log.Fields{
670 "Err": err, "device-id": oo.deviceID})
671 return nil
672 }
673
674 omciRxCallbackPair := callbackPair{
675 cbKey: tid,
676 cbEntry: callbackPairEntry{(*oo.pOnuDeviceEntry).pMibDownloadFsm.commChan, oo.receiveOmciResponse},
677 }
678 err = oo.send(ctx, pkt, timeout, 0, highPrio, omciRxCallbackPair)
679 if err != nil {
680 logger.Errorw("Cannot send GalEnetProfile create", log.Fields{
681 "Err": err, "device-id": oo.deviceID})
682 return nil
683 }
684 logger.Debug("send GalEnetProfile-Create-msg done")
685 return meInstance
686 }
687 logger.Errorw("Cannot generate GalEnetProfileInstance", log.Fields{
688 "Err": omciErr.GetError(), "device-id": oo.deviceID})
689 return nil
690}
691
692// might be needed to extend for parameter arguments, here just for setting the ConnectivityMode!!
693func (oo *omciCC) sendSetOnu2g(ctx context.Context, timeout int, highPrio bool) *me.ManagedEntity {
694 tid := oo.getNextTid(highPrio)
695 logger.Debugw("send ONU2-G-Set-msg:", log.Fields{"device-id": oo.deviceID,
696 "SequNo": strconv.FormatInt(int64(tid), 16)})
697
698 meParams := me.ParamData{
699 EntityID: 0,
700 Attributes: me.AttributeValueMap{"CurrentConnectivityMode": connectivityModeValue},
701 }
702 meInstance, omciErr := me.NewOnu2G(meParams)
703 if omciErr.GetError() == nil {
704 omciLayer, msgLayer, err := omci.EncodeFrame(meInstance, omci.SetRequestType, omci.TransactionID(tid))
705 if err != nil {
706 logger.Errorw("Cannot encode ONU2-G instance for set", log.Fields{
707 "Err": err, "device-id": oo.deviceID})
708 return nil
709 }
710
711 pkt, err := serializeOmciLayer(omciLayer, msgLayer)
712 if err != nil {
713 logger.Errorw("Cannot serialize ONU2-G set", log.Fields{
714 "Err": err, "device-id": oo.deviceID})
715 return nil
716 }
717
718 omciRxCallbackPair := callbackPair{
719 cbKey: tid,
720 cbEntry: callbackPairEntry{(*oo.pOnuDeviceEntry).pMibDownloadFsm.commChan, oo.receiveOmciResponse},
721 }
722 err = oo.send(ctx, pkt, timeout, 0, highPrio, omciRxCallbackPair)
723 if err != nil {
724 logger.Errorw("Cannot send ONU2-G set", log.Fields{
725 "Err": err, "device-id": oo.deviceID})
726 return nil
727 }
728 logger.Debug("send ONU2-G-Set-msg done")
729 return meInstance
730 }
731 logger.Errorw("Cannot generate ONU2-G", log.Fields{
732 "Err": omciErr.GetError(), "device-id": oo.deviceID})
733 return nil
734}
735
736func (oo *omciCC) sendCreateMBServiceProfile(ctx context.Context,
737 aPUniPort *onuUniPort, timeout int, highPrio bool) *me.ManagedEntity {
738 tid := oo.getNextTid(highPrio)
739 instID := macBridgeServiceProfileEID + uint16(aPUniPort.macBpNo)
740 logger.Debugw("send MBSP-Create-msg:", log.Fields{"device-id": oo.deviceID,
741 "SequNo": strconv.FormatInt(int64(tid), 16), "InstId": strconv.FormatInt(int64(instID), 16)})
742
743 meParams := me.ParamData{
744 EntityID: instID,
745 Attributes: me.AttributeValueMap{
746 "Priority": 0x8000,
747 "MaxAge": 20 * 256, //20s
748 "HelloTime": 2 * 256, //2s
749 "ForwardDelay": 15 * 256, //15s
750 //note: DynamicFilteringAgeingTime is taken from omci lib default as
751 // which is obviously different from default value used in python lib,
752 // where the value seems to be 0 (ONU defined) - to be considered in case of test artifacts ...
753 },
754 }
755
756 meInstance, omciErr := me.NewMacBridgeServiceProfile(meParams)
757 if omciErr.GetError() == nil {
758 //obviously we have to set all 'untouched' parameters to default by some additional option parameter!!
759 omciLayer, msgLayer, err := omci.EncodeFrame(meInstance, omci.CreateRequestType,
760 omci.TransactionID(tid), omci.AddDefaults(true))
761 if err != nil {
762 logger.Errorw("Cannot encode MBSP for create", log.Fields{
763 "Err": err, "device-id": oo.deviceID})
764 return nil
765 }
766
767 pkt, err := serializeOmciLayer(omciLayer, msgLayer)
768 if err != nil {
769 logger.Errorw("Cannot serialize MBSP create", log.Fields{
770 "Err": err, "device-id": oo.deviceID})
771 return nil
772 }
773
774 omciRxCallbackPair := callbackPair{
775 cbKey: tid,
776 cbEntry: callbackPairEntry{(*oo.pOnuDeviceEntry).pMibDownloadFsm.commChan, oo.receiveOmciResponse},
777 }
778 err = oo.send(ctx, pkt, timeout, 0, highPrio, omciRxCallbackPair)
779 if err != nil {
780 logger.Errorw("Cannot send MBSP create", log.Fields{
781 "Err": err, "device-id": oo.deviceID})
782 return nil
783 }
784 logger.Debug("send MBSP-Create-msg done")
785 return meInstance
786 }
787 logger.Errorw("Cannot generate MBSP Instance", log.Fields{
788 "Err": omciErr.GetError(), "device-id": oo.deviceID})
789 return nil
790}
791
792func (oo *omciCC) sendCreateMBPConfigData(ctx context.Context,
793 aPUniPort *onuUniPort, timeout int, highPrio bool) *me.ManagedEntity {
794 tid := oo.getNextTid(highPrio)
795 instID := macBridgePortAniEID + aPUniPort.entityID
796 logger.Debugw("send MBPCD-Create-msg:", log.Fields{"device-id": oo.deviceID,
797 "SequNo": strconv.FormatInt(int64(tid), 16), "InstId": strconv.FormatInt(int64(instID), 16)})
798
799 meParams := me.ParamData{
800 EntityID: instID,
801 Attributes: me.AttributeValueMap{
802 "BridgeIdPointer": macBridgeServiceProfileEID + uint16(aPUniPort.macBpNo),
803 "PortNum": aPUniPort.macBpNo,
804 "TpType": uint8(aPUniPort.portType),
805 "TpPointer": aPUniPort.entityID,
806 },
807 }
808 meInstance, omciErr := me.NewMacBridgePortConfigurationData(meParams)
809 if omciErr.GetError() == nil {
810 //obviously we have to set all 'untouched' parameters to default by some additional option parameter!!
811 omciLayer, msgLayer, err := omci.EncodeFrame(meInstance, omci.CreateRequestType,
812 omci.TransactionID(tid), omci.AddDefaults(true))
813 if err != nil {
814 logger.Errorw("Cannot encode MBPCD for create", log.Fields{
815 "Err": err, "device-id": oo.deviceID})
816 return nil
817 }
818
819 pkt, err := serializeOmciLayer(omciLayer, msgLayer)
820 if err != nil {
821 logger.Errorw("Cannot serialize MBPCD create", log.Fields{
822 "Err": err, "device-id": oo.deviceID})
823 return nil
824 }
825
826 omciRxCallbackPair := callbackPair{
827 cbKey: tid,
828 cbEntry: callbackPairEntry{(*oo.pOnuDeviceEntry).pMibDownloadFsm.commChan, oo.receiveOmciResponse},
829 }
830 err = oo.send(ctx, pkt, timeout, 0, highPrio, omciRxCallbackPair)
831 if err != nil {
832 logger.Errorw("Cannot send MBPCD create", log.Fields{
833 "Err": err, "device-id": oo.deviceID})
834 return nil
835 }
836 logger.Debug("send MBPCD-Create-msg done")
837 return meInstance
838 }
839 logger.Errorw("Cannot generate MBPCD Instance", log.Fields{
840 "Err": omciErr.GetError(), "device-id": oo.deviceID})
841 return nil
842}
843
844func (oo *omciCC) sendCreateEVTOConfigData(ctx context.Context,
845 aPUniPort *onuUniPort, timeout int, highPrio bool) *me.ManagedEntity {
846 tid := oo.getNextTid(highPrio)
847 instID := macBridgeServiceProfileEID + uint16(aPUniPort.macBpNo)
848 logger.Debugw("send EVTOCD-Create-msg:", log.Fields{"device-id": oo.deviceID,
849 "SequNo": strconv.FormatInt(int64(tid), 16), "InstId": strconv.FormatInt(int64(instID), 16)})
850
851 assType := uint8(2) // default AssociationType is PPTPEthUni
852 if aPUniPort.portType == uniVEIP {
853 assType = uint8(10) // for VEIP
854 }
855 meParams := me.ParamData{
856 EntityID: instID,
857 Attributes: me.AttributeValueMap{
858 "AssociationType": assType,
859 "AssociatedMePointer": aPUniPort.entityID,
860 },
861 }
862 meInstance, omciErr := me.NewExtendedVlanTaggingOperationConfigurationData(meParams)
863 if omciErr.GetError() == nil {
864 //all setByCreate parameters already set, no default option required ...
865 omciLayer, msgLayer, err := omci.EncodeFrame(meInstance, omci.CreateRequestType, omci.TransactionID(tid))
866 if err != nil {
867 logger.Errorw("Cannot encode EVTOCD for create", log.Fields{
868 "Err": err, "device-id": oo.deviceID})
869 return nil
870 }
871
872 pkt, err := serializeOmciLayer(omciLayer, msgLayer)
873 if err != nil {
874 logger.Errorw("Cannot serialize EVTOCD create", log.Fields{
875 "Err": err, "device-id": oo.deviceID})
876 return nil
877 }
878
879 omciRxCallbackPair := callbackPair{
880 cbKey: tid,
881 cbEntry: callbackPairEntry{(*oo.pOnuDeviceEntry).pMibDownloadFsm.commChan, oo.receiveOmciResponse},
882 }
883 err = oo.send(ctx, pkt, timeout, 0, highPrio, omciRxCallbackPair)
884 if err != nil {
885 logger.Errorw("Cannot send EVTOCD create", log.Fields{
886 "Err": err, "device-id": oo.deviceID})
887 return nil
888 }
889 logger.Debug("send EVTOCD-Create-msg done")
890 return meInstance
891 }
892 logger.Errorw("Cannot generate EVTOCD Instance", log.Fields{
893 "Err": omciErr.GetError(), "device-id": oo.deviceID})
894 return nil
895}
896
897func (oo *omciCC) sendSetOnuGLS(ctx context.Context, timeout int,
898 highPrio bool, requestedAttributes me.AttributeValueMap, rxChan chan Message) *me.ManagedEntity {
899 tid := oo.getNextTid(highPrio)
900 logger.Debugw("send ONU-G-Set-msg:", log.Fields{"device-id": oo.deviceID,
901 "SequNo": strconv.FormatInt(int64(tid), 16)})
902
903 meParams := me.ParamData{
904 EntityID: 0,
905 Attributes: requestedAttributes,
906 }
907 meInstance, omciErr := me.NewOnuG(meParams)
908 if omciErr.GetError() == nil {
909 omciLayer, msgLayer, err := omci.EncodeFrame(meInstance, omci.SetRequestType, omci.TransactionID(tid))
910 if err != nil {
911 logger.Errorw("Cannot encode ONU-G instance for set", log.Fields{
912 "Err": err, "device-id": oo.deviceID})
913 return nil
914 }
915
916 pkt, err := serializeOmciLayer(omciLayer, msgLayer)
917 if err != nil {
918 logger.Errorw("Cannot serialize ONU-G set", log.Fields{
919 "Err": err, "device-id": oo.deviceID})
920 return nil
921 }
922
923 omciRxCallbackPair := callbackPair{
924 cbKey: tid,
925 cbEntry: callbackPairEntry{rxChan, oo.receiveOmciResponse},
926 }
927 err = oo.send(ctx, pkt, timeout, 0, highPrio, omciRxCallbackPair)
928 if err != nil {
929 logger.Errorw("Cannot send ONU-G set", log.Fields{
930 "Err": err, "device-id": oo.deviceID})
931 return nil
932 }
933 logger.Debug("send ONU-G-Set-msg done")
934 return meInstance
935 }
936 logger.Errorw("Cannot generate ONU-G", log.Fields{
937 "Err": omciErr.GetError(), "device-id": oo.deviceID})
938 return nil
939}
940
941func (oo *omciCC) sendSetUniGLS(ctx context.Context, aInstNo uint16, timeout int,
942 highPrio bool, requestedAttributes me.AttributeValueMap, rxChan chan Message) *me.ManagedEntity {
943 tid := oo.getNextTid(highPrio)
944 logger.Debugw("send UNI-G-Set-msg:", log.Fields{"device-id": oo.deviceID,
945 "SequNo": strconv.FormatInt(int64(tid), 16)})
946
947 meParams := me.ParamData{
948 EntityID: aInstNo,
949 Attributes: requestedAttributes,
950 }
951 meInstance, omciErr := me.NewUniG(meParams)
952 if omciErr.GetError() == nil {
953 omciLayer, msgLayer, err := omci.EncodeFrame(meInstance, omci.SetRequestType, omci.TransactionID(tid))
954 if err != nil {
955 logger.Errorw("Cannot encode UNI-G instance for set", log.Fields{
956 "Err": err, "device-id": oo.deviceID})
957 return nil
958 }
959
960 pkt, err := serializeOmciLayer(omciLayer, msgLayer)
961 if err != nil {
962 logger.Errorw("Cannot serialize UNI-G-Set", log.Fields{
963 "Err": err, "device-id": oo.deviceID})
964 return nil
965 }
966
967 omciRxCallbackPair := callbackPair{
968 cbKey: tid,
969 cbEntry: callbackPairEntry{rxChan, oo.receiveOmciResponse},
970 }
971 err = oo.send(ctx, pkt, timeout, 0, highPrio, omciRxCallbackPair)
972 if err != nil {
973 logger.Errorw("Cannot send UNIG-G-Set", log.Fields{
974 "Err": err, "device-id": oo.deviceID})
975 return nil
976 }
977 logger.Debug("send UNI-G-Set-msg done")
978 return meInstance
979 }
980 logger.Errorw("Cannot generate UNI-G", log.Fields{
981 "Err": omciErr.GetError(), "device-id": oo.deviceID})
982 return nil
983}
984
985func (oo *omciCC) sendSetVeipLS(ctx context.Context, aInstNo uint16, timeout int,
986 highPrio bool, requestedAttributes me.AttributeValueMap, rxChan chan Message) *me.ManagedEntity {
987 tid := oo.getNextTid(highPrio)
988 logger.Debugw("send VEIP-Set-msg:", log.Fields{"device-id": oo.deviceID,
989 "SequNo": strconv.FormatInt(int64(tid), 16)})
990
991 meParams := me.ParamData{
992 EntityID: aInstNo,
993 Attributes: requestedAttributes,
994 }
995 meInstance, omciErr := me.NewVirtualEthernetInterfacePoint(meParams)
996 if omciErr.GetError() == nil {
997 omciLayer, msgLayer, err := omci.EncodeFrame(meInstance, omci.SetRequestType, omci.TransactionID(tid))
998 if err != nil {
999 logger.Errorw("Cannot encode VEIP instance for set", log.Fields{
1000 "Err": err, "device-id": oo.deviceID})
1001 return nil
1002 }
1003
1004 pkt, err := serializeOmciLayer(omciLayer, msgLayer)
1005 if err != nil {
1006 logger.Errorw("Cannot serialize VEIP-Set", log.Fields{
1007 "Err": err, "device-id": oo.deviceID})
1008 return nil
1009 }
1010
1011 omciRxCallbackPair := callbackPair{
1012 cbKey: tid,
1013 cbEntry: callbackPairEntry{rxChan, oo.receiveOmciResponse},
1014 }
1015 err = oo.send(ctx, pkt, timeout, 0, highPrio, omciRxCallbackPair)
1016 if err != nil {
1017 logger.Errorw("Cannot send VEIP-Set", log.Fields{
1018 "Err": err, "device-id": oo.deviceID})
1019 return nil
1020 }
1021 logger.Debug("send VEIP-Set-msg done")
1022 return meInstance
1023 }
1024 logger.Errorw("Cannot generate VEIP", log.Fields{
1025 "Err": omciErr.GetError(), "device-id": oo.deviceID})
1026 return nil
1027}
1028
1029func (oo *omciCC) sendGetMe(ctx context.Context, classID me.ClassID, entityID uint16, requestedAttributes me.AttributeValueMap,
1030 timeout int, highPrio bool) *me.ManagedEntity {
1031
1032 tid := oo.getNextTid(highPrio)
1033 logger.Debugw("send get-request-msg", log.Fields{"classID": classID, "device-id": oo.deviceID,
1034 "SequNo": strconv.FormatInt(int64(tid), 16)})
1035
1036 meParams := me.ParamData{
1037 EntityID: entityID,
1038 Attributes: requestedAttributes,
1039 }
1040 meInstance, omciErr := me.LoadManagedEntityDefinition(classID, meParams)
1041 if omciErr.GetError() == nil {
1042 meClassIDName := meInstance.GetName()
1043 omciLayer, msgLayer, err := omci.EncodeFrame(meInstance, omci.GetRequestType, omci.TransactionID(tid))
1044 if err != nil {
1045 logger.Errorf("Cannot encode instance for get-request", log.Fields{"meClassIDName": meClassIDName, "Err": err, "device-id": oo.deviceID})
1046 return nil
1047 }
1048 pkt, err := serializeOmciLayer(omciLayer, msgLayer)
1049 if err != nil {
1050 logger.Errorw("Cannot serialize get-request", log.Fields{"meClassIDName": meClassIDName, "Err": err, "device-id": oo.deviceID})
1051 return nil
1052 }
1053 omciRxCallbackPair := callbackPair{
1054 cbKey: tid,
1055 cbEntry: callbackPairEntry{(*oo.pOnuDeviceEntry).pMibUploadFsm.commChan, oo.receiveOmciResponse},
1056 }
1057 err = oo.send(ctx, pkt, timeout, 0, highPrio, omciRxCallbackPair)
1058 if err != nil {
1059 logger.Errorw("Cannot send get-request-msg", log.Fields{"meClassIDName": meClassIDName, "Err": err, "device-id": oo.deviceID})
1060 return nil
1061 }
1062 logger.Debugw("send get-request-msg done", log.Fields{"meClassIDName": meClassIDName, "device-id": oo.deviceID})
1063 return meInstance
1064 }
1065 logger.Errorw("Cannot generate meDefinition", log.Fields{"classID": classID, "Err": omciErr.GetError(), "device-id": oo.deviceID})
1066 return nil
1067}
1068
1069func (oo *omciCC) sendCreateDot1PMapper(ctx context.Context, timeout int, highPrio bool,
1070 aInstID uint16, rxChan chan Message) *me.ManagedEntity {
1071 tid := oo.getNextTid(highPrio)
1072 logger.Debugw("send .1pMapper-Create-msg:", log.Fields{"device-id": oo.deviceID,
1073 "SequNo": strconv.FormatInt(int64(tid), 16), "InstId": strconv.FormatInt(int64(aInstID), 16)})
1074
1075 meParams := me.ParamData{
1076 EntityID: aInstID,
1077 Attributes: me.AttributeValueMap{},
1078 }
1079 meInstance, omciErr := me.NewIeee8021PMapperServiceProfile(meParams)
1080 if omciErr.GetError() == nil {
1081 //we have to set all 'untouched' parameters to default by some additional option parameter!!
1082 omciLayer, msgLayer, err := omci.EncodeFrame(meInstance, omci.CreateRequestType,
1083 omci.TransactionID(tid), omci.AddDefaults(true))
1084 if err != nil {
1085 logger.Errorw("Cannot encode .1pMapper for create", log.Fields{
1086 "Err": err, "device-id": oo.deviceID})
1087 return nil
1088 }
1089
1090 pkt, err := serializeOmciLayer(omciLayer, msgLayer)
1091 if err != nil {
1092 logger.Errorw("Cannot serialize .1pMapper create", log.Fields{
1093 "Err": err, "device-id": oo.deviceID})
1094 return nil
1095 }
1096
1097 omciRxCallbackPair := callbackPair{
1098 cbKey: tid,
1099 cbEntry: callbackPairEntry{rxChan, oo.receiveOmciResponse},
1100 }
1101 err = oo.send(ctx, pkt, timeout, 0, highPrio, omciRxCallbackPair)
1102 if err != nil {
1103 logger.Errorw("Cannot send .1pMapper create", log.Fields{
1104 "Err": err, "device-id": oo.deviceID})
1105 return nil
1106 }
1107 logger.Debug("send .1pMapper-create-msg done")
1108 return meInstance
1109 }
1110 logger.Errorw("Cannot generate .1pMapper", log.Fields{
1111 "Err": omciErr.GetError(), "device-id": oo.deviceID})
1112 return nil
1113}
1114
1115func (oo *omciCC) sendCreateMBPConfigDataVar(ctx context.Context, timeout int, highPrio bool,
1116 rxChan chan Message, params ...me.ParamData) *me.ManagedEntity {
1117 tid := oo.getNextTid(highPrio)
1118 logger.Debugw("send MBPCD-Create-msg:", log.Fields{"device-id": oo.deviceID,
1119 "SequNo": strconv.FormatInt(int64(tid), 16),
1120 "InstId": strconv.FormatInt(int64(params[0].EntityID), 16)})
1121
1122 meInstance, omciErr := me.NewMacBridgePortConfigurationData(params[0])
1123 if omciErr.GetError() == nil {
1124 //obviously we have to set all 'untouched' parameters to default by some additional option parameter!!
1125 omciLayer, msgLayer, err := omci.EncodeFrame(meInstance, omci.CreateRequestType,
1126 omci.TransactionID(tid), omci.AddDefaults(true))
1127 if err != nil {
1128 logger.Errorw("Cannot encode MBPCD for create", log.Fields{
1129 "Err": err, "device-id": oo.deviceID})
1130 return nil
1131 }
1132
1133 pkt, err := serializeOmciLayer(omciLayer, msgLayer)
1134 if err != nil {
1135 logger.Errorw("Cannot serialize MBPCD create", log.Fields{
1136 "Err": err, "device-id": oo.deviceID})
1137 return nil
1138 }
1139
1140 omciRxCallbackPair := callbackPair{
1141 cbKey: tid,
1142 cbEntry: callbackPairEntry{rxChan, oo.receiveOmciResponse},
1143 }
1144 err = oo.send(ctx, pkt, timeout, 0, highPrio, omciRxCallbackPair)
1145 if err != nil {
1146 logger.Errorw("Cannot send MBPCD create", log.Fields{
1147 "Err": err, "device-id": oo.deviceID})
1148 return nil
1149 }
1150 logger.Debug("send MBPCD-Create-msg done")
1151 return meInstance
1152 }
1153 logger.Errorw("Cannot generate MBPCD Instance", log.Fields{
1154 "Err": omciErr.GetError(), "device-id": oo.deviceID})
1155 return nil
1156}
1157
1158func (oo *omciCC) sendCreateGemNCTPVar(ctx context.Context, timeout int, highPrio bool,
1159 rxChan chan Message, params ...me.ParamData) *me.ManagedEntity {
1160 tid := oo.getNextTid(highPrio)
1161 logger.Debugw("send GemNCTP-Create-msg:", log.Fields{"device-id": oo.deviceID,
1162 "SequNo": strconv.FormatInt(int64(tid), 16),
1163 "InstId": strconv.FormatInt(int64(params[0].EntityID), 16)})
1164
1165 meInstance, omciErr := me.NewGemPortNetworkCtp(params[0])
1166 if omciErr.GetError() == nil {
1167 //obviously we have to set all 'untouched' parameters to default by some additional option parameter!!
1168 omciLayer, msgLayer, err := omci.EncodeFrame(meInstance, omci.CreateRequestType,
1169 omci.TransactionID(tid), omci.AddDefaults(true))
1170 if err != nil {
1171 logger.Errorw("Cannot encode GemNCTP for create", log.Fields{
1172 "Err": err, "device-id": oo.deviceID})
1173 return nil
1174 }
1175
1176 pkt, err := serializeOmciLayer(omciLayer, msgLayer)
1177 if err != nil {
1178 logger.Errorw("Cannot serialize GemNCTP create", log.Fields{
1179 "Err": err, "device-id": oo.deviceID})
1180 return nil
1181 }
1182
1183 omciRxCallbackPair := callbackPair{
1184 cbKey: tid,
1185 cbEntry: callbackPairEntry{rxChan, oo.receiveOmciResponse},
1186 }
1187 err = oo.send(ctx, pkt, timeout, 0, highPrio, omciRxCallbackPair)
1188 if err != nil {
1189 logger.Errorw("Cannot send GemNCTP create", log.Fields{
1190 "Err": err, "device-id": oo.deviceID})
1191 return nil
1192 }
1193 logger.Debug("send GemNCTP-Create-msg done")
1194 return meInstance
1195 }
1196 logger.Errorw("Cannot generate GemNCTP Instance", log.Fields{
1197 "Err": omciErr.GetError(), "device-id": oo.deviceID})
1198 return nil
1199}
1200
1201func (oo *omciCC) sendCreateGemIWTPVar(ctx context.Context, timeout int, highPrio bool,
1202 rxChan chan Message, params ...me.ParamData) *me.ManagedEntity {
1203 tid := oo.getNextTid(highPrio)
1204 logger.Debugw("send GemIwTp-Create-msg:", log.Fields{"device-id": oo.deviceID,
1205 "SequNo": strconv.FormatInt(int64(tid), 16),
1206 "InstId": strconv.FormatInt(int64(params[0].EntityID), 16)})
1207
1208 meInstance, omciErr := me.NewGemInterworkingTerminationPoint(params[0])
1209 if omciErr.GetError() == nil {
1210 //all SetByCreate Parameters (assumed to be) set here, for optimisation no 'AddDefaults'
1211 omciLayer, msgLayer, err := omci.EncodeFrame(meInstance, omci.CreateRequestType,
1212 omci.TransactionID(tid))
1213 if err != nil {
1214 logger.Errorw("Cannot encode GemIwTp for create", log.Fields{
1215 "Err": err, "device-id": oo.deviceID})
1216 return nil
1217 }
1218
1219 pkt, err := serializeOmciLayer(omciLayer, msgLayer)
1220 if err != nil {
1221 logger.Errorw("Cannot serialize GemIwTp create", log.Fields{
1222 "Err": err, "device-id": oo.deviceID})
1223 return nil
1224 }
1225
1226 omciRxCallbackPair := callbackPair{
1227 cbKey: tid,
1228 cbEntry: callbackPairEntry{rxChan, oo.receiveOmciResponse},
1229 }
1230 err = oo.send(ctx, pkt, timeout, 0, highPrio, omciRxCallbackPair)
1231 if err != nil {
1232 logger.Errorw("Cannot send GemIwTp create", log.Fields{
1233 "Err": err, "device-id": oo.deviceID})
1234 return nil
1235 }
1236 logger.Debug("send GemIwTp-Create-msg done")
1237 return meInstance
1238 }
1239 logger.Errorw("Cannot generate GemIwTp Instance", log.Fields{
1240 "Err": omciErr.GetError(), "device-id": oo.deviceID})
1241 return nil
1242}
1243
1244func (oo *omciCC) sendSetTcontVar(ctx context.Context, timeout int, highPrio bool,
1245 rxChan chan Message, params ...me.ParamData) *me.ManagedEntity {
1246 tid := oo.getNextTid(highPrio)
1247 logger.Debugw("send TCont-Set-msg:", log.Fields{"device-id": oo.deviceID,
1248 "SequNo": strconv.FormatInt(int64(tid), 16),
1249 "InstId": strconv.FormatInt(int64(params[0].EntityID), 16)})
1250
1251 meInstance, omciErr := me.NewTCont(params[0])
1252 if omciErr.GetError() == nil {
1253 omciLayer, msgLayer, err := omci.EncodeFrame(meInstance, omci.SetRequestType, omci.TransactionID(tid))
1254 if err != nil {
1255 logger.Errorw("Cannot encode TCont for set", log.Fields{
1256 "Err": err, "device-id": oo.deviceID})
1257 return nil
1258 }
1259
1260 pkt, err := serializeOmciLayer(omciLayer, msgLayer)
1261 if err != nil {
1262 logger.Errorw("Cannot serialize TCont set", log.Fields{
1263 "Err": err, "device-id": oo.deviceID})
1264 return nil
1265 }
1266
1267 omciRxCallbackPair := callbackPair{
1268 cbKey: tid,
1269 cbEntry: callbackPairEntry{rxChan, oo.receiveOmciResponse},
1270 }
1271 err = oo.send(ctx, pkt, timeout, 0, highPrio, omciRxCallbackPair)
1272 if err != nil {
1273 logger.Errorw("Cannot send TCont set", log.Fields{
1274 "Err": err, "device-id": oo.deviceID})
1275 return nil
1276 }
1277 logger.Debug("send TCont-set msg done")
1278 return meInstance
1279 }
1280 logger.Errorw("Cannot generate TCont Instance", log.Fields{
1281 "Err": omciErr.GetError(), "device-id": oo.deviceID})
1282 return nil
1283}
1284
1285func (oo *omciCC) sendSetPrioQueueVar(ctx context.Context, timeout int, highPrio bool,
1286 rxChan chan Message, params ...me.ParamData) *me.ManagedEntity {
1287 tid := oo.getNextTid(highPrio)
1288 logger.Debugw("send PrioQueue-Set-msg:", log.Fields{"device-id": oo.deviceID,
1289 "SequNo": strconv.FormatInt(int64(tid), 16),
1290 "InstId": strconv.FormatInt(int64(params[0].EntityID), 16)})
1291
1292 meInstance, omciErr := me.NewPriorityQueue(params[0])
1293 if omciErr.GetError() == nil {
1294 omciLayer, msgLayer, err := omci.EncodeFrame(meInstance, omci.SetRequestType, omci.TransactionID(tid))
1295 if err != nil {
1296 logger.Errorw("Cannot encode PrioQueue for set", log.Fields{
1297 "Err": err, "device-id": oo.deviceID})
1298 return nil
1299 }
1300
1301 pkt, err := serializeOmciLayer(omciLayer, msgLayer)
1302 if err != nil {
1303 logger.Errorw("Cannot serialize PrioQueue set", log.Fields{
1304 "Err": err, "device-id": oo.deviceID})
1305 return nil
1306 }
1307
1308 omciRxCallbackPair := callbackPair{
1309 cbKey: tid,
1310 cbEntry: callbackPairEntry{rxChan, oo.receiveOmciResponse},
1311 }
1312 err = oo.send(ctx, pkt, timeout, 0, highPrio, omciRxCallbackPair)
1313 if err != nil {
1314 logger.Errorw("Cannot send PrioQueue set", log.Fields{
1315 "Err": err, "device-id": oo.deviceID})
1316 return nil
1317 }
1318 logger.Debug("send PrioQueue-set msg done")
1319 return meInstance
1320 }
1321 logger.Errorw("Cannot generate PrioQueue Instance", log.Fields{
1322 "Err": omciErr.GetError(), "device-id": oo.deviceID})
1323 return nil
1324}
1325
1326func (oo *omciCC) sendSetDot1PMapperVar(ctx context.Context, timeout int, highPrio bool,
1327 rxChan chan Message, params ...me.ParamData) *me.ManagedEntity {
1328 tid := oo.getNextTid(highPrio)
1329 logger.Debugw("send 1PMapper-Set-msg:", log.Fields{"device-id": oo.deviceID,
1330 "SequNo": strconv.FormatInt(int64(tid), 16),
1331 "InstId": strconv.FormatInt(int64(params[0].EntityID), 16)})
1332
1333 meInstance, omciErr := me.NewIeee8021PMapperServiceProfile(params[0])
1334 if omciErr.GetError() == nil {
1335 omciLayer, msgLayer, err := omci.EncodeFrame(meInstance, omci.SetRequestType, omci.TransactionID(tid))
1336 if err != nil {
1337 logger.Errorw("Cannot encode 1PMapper for set", log.Fields{
1338 "Err": err, "device-id": oo.deviceID})
1339 return nil
1340 }
1341
1342 pkt, err := serializeOmciLayer(omciLayer, msgLayer)
1343 if err != nil {
1344 logger.Errorw("Cannot serialize 1PMapper set", log.Fields{
1345 "Err": err, "device-id": oo.deviceID})
1346 return nil
1347 }
1348
1349 omciRxCallbackPair := callbackPair{
1350 cbKey: tid,
1351 cbEntry: callbackPairEntry{rxChan, oo.receiveOmciResponse},
1352 }
1353 err = oo.send(ctx, pkt, timeout, 0, highPrio, omciRxCallbackPair)
1354 if err != nil {
1355 logger.Errorw("Cannot send 1PMapper set", log.Fields{
1356 "Err": err, "device-id": oo.deviceID})
1357 return nil
1358 }
1359 logger.Debug("send 1PMapper-set msg done")
1360 return meInstance
1361 }
1362 logger.Errorw("Cannot generate 1PMapper Instance", log.Fields{
1363 "Err": omciErr.GetError(), "device-id": oo.deviceID})
1364 return nil
1365}
1366
1367func (oo *omciCC) sendCreateVtfdVar(ctx context.Context, timeout int, highPrio bool,
1368 rxChan chan Message, params ...me.ParamData) *me.ManagedEntity {
1369 tid := oo.getNextTid(highPrio)
1370 logger.Debugw("send VTFD-Create-msg:", log.Fields{"device-id": oo.deviceID,
1371 "SequNo": strconv.FormatInt(int64(tid), 16),
1372 "InstId": strconv.FormatInt(int64(params[0].EntityID), 16)})
1373
1374 meInstance, omciErr := me.NewVlanTaggingFilterData(params[0])
1375 if omciErr.GetError() == nil {
1376 //all SetByCreate Parameters (assumed to be) set here, for optimisation no 'AddDefaults'
1377 omciLayer, msgLayer, err := omci.EncodeFrame(meInstance, omci.CreateRequestType,
1378 omci.TransactionID(tid))
1379 if err != nil {
1380 logger.Errorw("Cannot encode VTFD for create", log.Fields{
1381 "Err": err, "device-id": oo.deviceID})
1382 //TODO!!: refactoring improvement requested, here as an example for [VOL-3457]:
1383 // return (dual format) error code that can be used at caller for immediate error treatment
1384 // (relevant to all used sendXX() methods and their error conditions)
1385 return nil
1386 }
1387
1388 pkt, err := serializeOmciLayer(omciLayer, msgLayer)
1389 if err != nil {
1390 logger.Errorw("Cannot serialize VTFD create", log.Fields{
1391 "Err": err, "device-id": oo.deviceID})
1392 return nil
1393 }
1394
1395 omciRxCallbackPair := callbackPair{
1396 cbKey: tid,
1397 cbEntry: callbackPairEntry{rxChan, oo.receiveOmciResponse},
1398 }
1399 err = oo.send(ctx, pkt, timeout, 0, highPrio, omciRxCallbackPair)
1400 if err != nil {
1401 logger.Errorw("Cannot send VTFD create", log.Fields{
1402 "Err": err, "device-id": oo.deviceID})
1403 return nil
1404 }
1405 logger.Debug("send VTFD-Create-msg done")
1406 return meInstance
1407 }
1408 logger.Errorw("Cannot generate VTFD Instance", log.Fields{
1409 "Err": omciErr.GetError(), "device-id": oo.deviceID})
1410 return nil
1411}
1412
1413func (oo *omciCC) sendSetEvtocdVar(ctx context.Context, timeout int, highPrio bool,
1414 rxChan chan Message, params ...me.ParamData) *me.ManagedEntity {
1415 tid := oo.getNextTid(highPrio)
1416 logger.Debugw("send EVTOCD-Set-msg:", log.Fields{"device-id": oo.deviceID,
1417 "SequNo": strconv.FormatInt(int64(tid), 16),
1418 "InstId": strconv.FormatInt(int64(params[0].EntityID), 16)})
1419
1420 meInstance, omciErr := me.NewExtendedVlanTaggingOperationConfigurationData(params[0])
1421 if omciErr.GetError() == nil {
1422 omciLayer, msgLayer, err := omci.EncodeFrame(meInstance, omci.SetRequestType, omci.TransactionID(tid))
1423 if err != nil {
1424 logger.Errorw("Cannot encode EVTOCD for set", log.Fields{
1425 "Err": err, "device-id": oo.deviceID})
1426 return nil
1427 }
1428
1429 pkt, err := serializeOmciLayer(omciLayer, msgLayer)
1430 if err != nil {
1431 logger.Errorw("Cannot serialize EVTOCD set", log.Fields{
1432 "Err": err, "device-id": oo.deviceID})
1433 return nil
1434 }
1435
1436 omciRxCallbackPair := callbackPair{
1437 cbKey: tid,
1438 cbEntry: callbackPairEntry{rxChan, oo.receiveOmciResponse},
1439 }
1440 err = oo.send(ctx, pkt, timeout, 0, highPrio, omciRxCallbackPair)
1441 if err != nil {
1442 logger.Errorw("Cannot send EVTOCD set", log.Fields{
1443 "Err": err, "device-id": oo.deviceID})
1444 return nil
1445 }
1446 logger.Debug("send EVTOCD-set msg done")
1447 return meInstance
1448 }
1449 logger.Errorw("Cannot generate EVTOCD Instance", log.Fields{
1450 "Err": omciErr.GetError(), "device-id": oo.deviceID})
1451 return nil
1452}