blob: 7edd20efe62b81e8d6e2b2ebfe001dcc58e6731a [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"
28
29 //"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)
52const defaultTPID = uint16(0x8100)
53const broadComDefaultVID = uint16(4091)
54const macBridgeServiceProfileEID = uint16(0x201) // TODO: most all these need better definition or tuning
55const ieeeMapperServiceProfileEID = uint16(0x8001)
56const macBridgePortAniEID = uint16(0x2102)
57
58// ### OMCI related definitions - end
59
Holger Hildebrandtccd390c2020-05-29 13:49:04 +000060//CallbackPairEntry to be used for OMCI send/receive correlation
61type CallbackPairEntry struct {
62 cbRespChannel chan Message
63 cbFunction func(*omci.OMCI, *gp.Packet, chan Message) error
64}
65
Holger Hildebrandtfa074992020-03-27 15:42:06 +000066//CallbackPair to be used for ReceiveCallback init
67type CallbackPair struct {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +000068 cbKey uint16
69 cbEntry CallbackPairEntry
Holger Hildebrandtfa074992020-03-27 15:42:06 +000070}
71
72type omciTransferStructure struct {
73 txFrame []byte
74 timeout int
75 retry int
76 highPrio bool
77}
78
79//OmciCC structure holds information needed for OMCI communication (to/from OLT Adapter)
80type OmciCC struct {
81 enabled bool
82 pOnuDeviceEntry *OnuDeviceEntry
83 deviceID string
84 pBaseDeviceHandler *DeviceHandler
85 coreProxy adapterif.CoreProxy
86 adapterProxy adapterif.AdapterProxy
87 supportExtMsg bool
88 //txRequest
89 //rxResponse
90 //pendingRequest
91 txFrames, txOnuFrames uint32
92 rxFrames, rxOnuFrames, rxOnuDiscards uint32
93
94 // OMCI params
95 mutexTid sync.Mutex
96 tid uint16
97 mutexHpTid sync.Mutex
98 hpTid uint16
99 uploadSequNo uint16
100 uploadNoOfCmds uint16
101
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000102 mutexTxQueue sync.Mutex
103 txQueue *list.List
104 mutexRxSchedMap sync.Mutex
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000105 rxSchedulerMap map[uint16]CallbackPairEntry
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000106 pLastTxMeInstance *me.ManagedEntity
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000107}
108
109//NewOmciCC constructor returns a new instance of a OmciCC
110//mib_db (as well as not inluded alarm_db not really used in this code? VERIFY!!)
111func NewOmciCC(ctx context.Context, onu_device_entry *OnuDeviceEntry,
112 device_id string, device_handler *DeviceHandler,
113 core_proxy adapterif.CoreProxy, adapter_proxy adapterif.AdapterProxy) *OmciCC {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000114 logger.Infow("init-omciCC", log.Fields{"deviceId": device_id})
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000115 var omciCC OmciCC
116 omciCC.enabled = false
117 omciCC.pOnuDeviceEntry = onu_device_entry
118 omciCC.deviceID = device_id
119 omciCC.pBaseDeviceHandler = device_handler
120 omciCC.coreProxy = core_proxy
121 omciCC.adapterProxy = adapter_proxy
122 omciCC.supportExtMsg = false
123 omciCC.txFrames = 0
124 omciCC.txOnuFrames = 0
125 omciCC.rxFrames = 0
126 omciCC.rxOnuFrames = 0
127 omciCC.rxOnuDiscards = 0
128 omciCC.tid = 0x1
129 omciCC.hpTid = 0x8000
130 omciCC.uploadSequNo = 0
131 omciCC.uploadNoOfCmds = 0
132
133 omciCC.txQueue = list.New()
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000134 omciCC.rxSchedulerMap = make(map[uint16]CallbackPairEntry)
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000135
136 return &omciCC
137}
138
139// Rx handler for omci messages
140func (oo *OmciCC) ReceiveOnuMessage(ctx context.Context, omciMsg *omci.OMCI) error {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000141 logger.Debugw("rx-onu-autonomous-message", log.Fields{"omciMsgType": omciMsg.MessageType,
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000142 "payload": hex.EncodeToString(omciMsg.Payload)})
143 /*
144 msgType = rxFrame.fields["message_type"] //assumed OmciOperationsValue
145 rxOnuFrames++
146
147 switch msgType {
148 case AlarmNotification:
149 {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000150 logger.Info("Unhandled: received-onu-alarm-message")
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000151 // python code was:
152 //if msg_type == EntityOperations.AlarmNotification.value:
153 // topic = OMCI_CC.event_bus_topic(self._device_id, RxEvent.Alarm_Notification)
154 // self.reactor.callLater(0, self.event_bus.publish, topic, msg)
155 //
156 return errors.New("RxAlarmNotification unimplemented")
157 }
158 case AttributeValueChange:
159 {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000160 logger.Info("Unhandled: received-attribute-value-change")
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000161 // python code was:
162 //elif msg_type == EntityOperations.AttributeValueChange.value:
163 // topic = OMCI_CC.event_bus_topic(self._device_id, RxEvent.AVC_Notification)
164 // self.reactor.callLater(0, self.event_bus.publish, topic, msg)
165 //
166 return errors.New("RxAttributeValueChange unimplemented")
167 }
168 case TestResult:
169 {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000170 logger.Info("Unhandled: received-test-result")
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000171 // python code was:
172 //elif msg_type == EntityOperations.TestResult.value:
173 // topic = OMCI_CC.event_bus_topic(self._device_id, RxEvent.Test_Result)
174 // self.reactor.callLater(0, self.event_bus.publish, topic, msg)
175 //
176 return errors.New("RxTestResult unimplemented")
177 }
178 default:
179 {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000180 logger.Errorw("rx-onu-unsupported-autonomous-message", log.Fields{"msgType": msgType})
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000181 rxOnuDiscards++
182 return errors.New("RxOnuMsgType unimplemented")
183 }
184 }
185 */
186 return errors.New("ReceiveOnuMessage unimplemented")
187}
188
189// Rx handler for onu messages
190// e.g. would call ReceiveOnuMessage() in case of TID=0 or Action=test ...
191func (oo *OmciCC) ReceiveMessage(ctx context.Context, rxMsg []byte) error {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000192 //logger.Debugw("cc-receive-omci-message", log.Fields{"RxOmciMessage-x2s": hex.EncodeToString(rxMsg)})
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000193 if len(rxMsg) >= 44 { // then it should normally include the BaseFormat trailer Len
194 // NOTE: autocorrection only valid for OmciBaseFormat, which is not specifically verified here!!!
195 // (am extendedFormat message could be destroyed this way!)
196 trailerLenData := rxMsg[42:44]
197 trailerLen := binary.BigEndian.Uint16(trailerLenData)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000198 logger.Infow("omci-received-trailer-len", log.Fields{"Length": trailerLen})
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000199 if trailerLen != 40 { // invalid base Format entry -> autocorrect
200 binary.BigEndian.PutUint16(rxMsg[42:44], 40)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000201 logger.Debug("cc-corrected-omci-message: trailer len inserted")
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000202 }
203 } else {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000204 logger.Errorw("received omci-message to small for OmciBaseFormat - abort", log.Fields{"Length": len(rxMsg)})
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000205 return errors.New("RxOmciMessage to small for BaseFormat")
206 }
207
208 packet := gopacket.NewPacket(rxMsg, omci.LayerTypeOMCI, gopacket.NoCopy)
209 if packet == nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000210 logger.Error("omci-message could not be decoded")
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000211 return errors.New("could not decode rxMsg as OMCI")
212 }
213 omciLayer := packet.Layer(omci.LayerTypeOMCI)
214 if omciLayer == nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000215 logger.Error("omci-message could not decode omci layer")
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000216 return errors.New("could not decode omci layer")
217 }
218 omciMsg, ok := omciLayer.(*omci.OMCI)
219 if !ok {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000220 logger.Error("omci-message could not assign omci layer")
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000221 return errors.New("could not assign omci layer")
222 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000223 logger.Debugw("omci-message-decoded:", log.Fields{"omciMsgType": omciMsg.MessageType,
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000224 "transCorrId": omciMsg.TransactionID, "DeviceIdent": omciMsg.DeviceIdentifier})
225 if byte(omciMsg.MessageType) & ^me.AK == 0 {
226 // Not a response
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000227 logger.Debug("RxMsg is no Omci Response Message")
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000228 if omciMsg.TransactionID == 0 {
229 return oo.ReceiveOnuMessage(ctx, omciMsg)
230 } else {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000231 logger.Errorw("Unexpected TransCorrId != 0 not accepted for autonomous messages",
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000232 log.Fields{"msgType": omciMsg.MessageType, "payload": hex.EncodeToString(omciMsg.Payload)})
233 return errors.New("Autonomous Omci Message with TranSCorrId != 0 not acccepted")
234 }
235 } else {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000236 logger.Debug("RxMsg is a Omci Response Message: try to schedule it to the requester")
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000237 oo.mutexRxSchedMap.Lock()
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000238 rxCallbackEntry, ok := oo.rxSchedulerMap[omciMsg.TransactionID]
239 if ok && rxCallbackEntry.cbFunction != nil {
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000240 //disadvantage of decoupling: error verification made difficult, but anyway the question is
241 // how to react on erroneous frame reception, maybe can simply be ignored
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000242 go rxCallbackEntry.cbFunction(omciMsg, &packet, rxCallbackEntry.cbRespChannel)
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000243 // having posted the response the request is regarded as 'done'
244 delete(oo.rxSchedulerMap, omciMsg.TransactionID)
245 oo.mutexRxSchedMap.Unlock()
246 } else {
247 oo.mutexRxSchedMap.Unlock()
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000248 logger.Error("omci-message-response for not registered transCorrId")
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000249 return errors.New("could not find registered response handler tor transCorrId")
250 }
251 }
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 {
358 return errors.New("PublishRxResponseFrame unimplemented")
359 /*
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()
399 for oo.txQueue.Len() > 0 {
400 queueElement := oo.txQueue.Front() // First element
401 omciTxRequest := queueElement.Value.(omciTransferStructure)
402 /* compare olt device handler code:
403 func (dh *DeviceHandler) omciIndication(omciInd *oop.OmciIndication) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000404 logger.Debugw("omci indication", log.Fields{"intfID": omciInd.IntfId, "onuID": omciInd.OnuId})
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000405 var deviceType string
406 var deviceID string
407 var proxyDeviceID string
408
409 onuKey := dh.formOnuKey(omciInd.IntfId, omciInd.OnuId)
410
411 if onuInCache, ok := dh.onus.Load(onuKey); !ok {
412
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000413 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 +0000414 ponPort := IntfIDToPortNo(omciInd.GetIntfId(), voltha.Port_PON_OLT)
415 kwargs := make(map[string]interface{})
416 kwargs["onu_id"] = omciInd.OnuId
417 kwargs["parent_port_no"] = ponPort
418
419 onuDevice, err := dh.coreProxy.GetChildDevice(context.TODO(), dh.device.Id, kwargs)
420 if err != nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000421 logger.Errorw("onu not found", log.Fields{"intfID": omciInd.IntfId, "onuID": omciInd.OnuId, "error": err})
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000422 return
423 }
424 deviceType = onuDevice.Type
425 deviceID = onuDevice.Id
426 proxyDeviceID = onuDevice.ProxyAddress.DeviceId
427 //if not exist in cache, then add to cache.
428 dh.onus.Store(onuKey, NewOnuDevice(deviceID, deviceType, onuDevice.SerialNumber, omciInd.OnuId, omciInd.IntfId, proxyDeviceID))
429 } else {
430 //found in cache
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000431 logger.Debugw("omci indication for a device in cache.", log.Fields{"intfID": omciInd.IntfId, "onuID": omciInd.OnuId})
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000432 deviceType = onuInCache.(*OnuDevice).deviceType
433 deviceID = onuInCache.(*OnuDevice).deviceID
434 proxyDeviceID = onuInCache.(*OnuDevice).proxyDeviceID
435 }
436 */
437 /* and compare onu_adapter py code:
438 omci_msg = InterAdapterOmciMessage(
439 message=bytes(frame),
440 proxy_address=self._proxy_address,
441 connect_status=self._device.connect_status)
442
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000443 self.logger.debug('sent-omci-msg', tid=tx_tid, omci_msg=hexlify(bytes(frame)))
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000444
445 yield self._adapter_proxy.send_inter_adapter_message(
446 msg=omci_msg,
447 type=InterAdapterMessageType.OMCI_REQUEST,
448 from_adapter=self._device.type,
449 to_adapter=self._proxy_address.device_type,
450 to_device_id=self._device_id,
451 proxy_device_id=self._proxy_address.device_id
452 )
453 */
454 device, err := oo.coreProxy.GetDevice(ctx,
455 oo.pBaseDeviceHandler.deviceID, oo.deviceID) //parent, child
456 if err != nil || device == nil {
457 /*TODO: needs to handle error scenarios */
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000458 logger.Errorw("Failed to fetch device", log.Fields{"err": err, "ParentId": oo.pBaseDeviceHandler.deviceID,
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000459 "ChildId": oo.deviceID})
460 return errors.New("failed to fetch device")
461 }
462
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000463 logger.Debugw("omci-message-sending", log.Fields{"fromDeviceType": oo.pBaseDeviceHandler.DeviceType,
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000464 "toDeviceType": oo.pBaseDeviceHandler.ProxyAddressType,
465 "onuDeviceID": oo.deviceID, "proxyDeviceID": oo.pBaseDeviceHandler.ProxyAddressID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000466 logger.Debugw("omci-message-to-send:",
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000467 log.Fields{"TxOmciMessage": hex.EncodeToString(omciTxRequest.txFrame)})
468
469 omciMsg := &ic.InterAdapterOmciMessage{Message: omciTxRequest.txFrame}
470 if sendErr := oo.adapterProxy.SendInterAdapterMessage(context.Background(), omciMsg,
471 ic.InterAdapterMessageType_OMCI_REQUEST,
472 //fromType,toType,toDevId, ProxyDevId
473 oo.pBaseDeviceHandler.DeviceType, oo.pBaseDeviceHandler.ProxyAddressType,
474 oo.deviceID, oo.pBaseDeviceHandler.ProxyAddressID, ""); sendErr != nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000475 logger.Errorw("send omci request error", log.Fields{"error": sendErr})
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000476 return sendErr
477 }
478 oo.txQueue.Remove(queueElement) // Dequeue
479 }
480 oo.mutexTxQueue.Unlock()
481 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
489 oo.hpTid += 1
490 if oo.hpTid < 0x8000 {
491 oo.hpTid = 0x8000
492 }
493 oo.mutexTid.Unlock()
494 } else {
495 oo.mutexHpTid.Lock()
496 next = oo.tid
497 oo.tid += 1
498 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
516func serializeOmciLayer(a_omciLayer *omci.OMCI, a_request 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()
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000521 err := gopacket.SerializeLayers(buffer, options, a_omciLayer, a_request)
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
529func hexEncode(omciPkt []byte) ([]byte, error) {
530 dst := make([]byte, hex.EncodedLen(len(omciPkt)))
531 hex.Encode(dst, omciPkt)
532 return dst, nil
533}
534
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000535//supply a response handler for omci response messages to be transferred to the requested FSM
536func (oo *OmciCC) receiveOmciResponse(omciMsg *omci.OMCI, packet *gp.Packet, respChan chan Message) error {
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000537
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000538 logger.Debugw("omci-message-response received:", log.Fields{"omciMsgType": omciMsg.MessageType,
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000539 "transCorrId": omciMsg.TransactionID, "deviceId": oo.deviceID})
540
541 if oo.pOnuDeviceEntry == nil {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000542 logger.Errorw("Abort receiving OMCI response, DeviceEntryPointer is nil", log.Fields{
543 "deviceId": oo.deviceID})
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000544 return errors.New("DeviceEntryPointer is nil")
545 }
546
547 // no further test on SeqNo is done here, assignment from rxScheduler is trusted
548 // MibSync responses are simply transferred via deviceEntry to MibSync, no specific analysis here
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000549 omciRespMsg := Message{
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000550 Type: OMCI,
551 Data: OmciMessage{
552 OmciMsg: omciMsg,
553 OmciPacket: packet,
554 },
555 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000556 //logger.Debugw("Message to be sent into channel:", log.Fields{"mibSyncMsg": mibSyncMsg})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000557 respChan <- omciRespMsg
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000558
559 return nil
560}
561
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000562func (oo *OmciCC) sendMibReset(ctx context.Context, timeout int, highPrio bool) error {
563
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000564 logger.Debugw("send MibReset-msg to:", log.Fields{"deviceId": oo.deviceID})
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000565 request := &omci.MibResetRequest{
566 MeBasePacket: omci.MeBasePacket{
567 EntityClass: me.OnuDataClassID,
568 },
569 }
570 tid := oo.GetNextTid(highPrio)
571 pkt, err := serialize(omci.MibResetRequestType, request, tid)
572 if err != nil {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000573 logger.Errorw("Cannot serialize MibResetRequest", log.Fields{
574 "Err": err, "deviceId": oo.deviceID})
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000575 return err
576 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000577 omciRxCallbackPair := CallbackPair{
578 cbKey: tid,
579 cbEntry: CallbackPairEntry{(*oo.pOnuDeviceEntry).pMibUploadFsm.commChan, oo.receiveOmciResponse},
580 }
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000581 return oo.Send(ctx, pkt, timeout, 0, highPrio, omciRxCallbackPair)
582}
583
584func (oo *OmciCC) sendMibUpload(ctx context.Context, timeout int, highPrio bool) error {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000585 logger.Debugw("send MibUpload-msg to:", log.Fields{"deviceId": oo.deviceID})
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000586 request := &omci.MibUploadRequest{
587 MeBasePacket: omci.MeBasePacket{
588 EntityClass: me.OnuDataClassID,
589 },
590 }
591 tid := oo.GetNextTid(highPrio)
592 pkt, err := serialize(omci.MibUploadRequestType, request, tid)
593 if err != nil {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000594 logger.Errorw("Cannot serialize MibUploadRequest", log.Fields{
595 "Err": err, "deviceId": oo.deviceID})
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000596 return err
597 }
598 oo.uploadSequNo = 0
599 oo.uploadNoOfCmds = 0
600
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000601 omciRxCallbackPair := CallbackPair{
602 cbKey: tid,
603 cbEntry: CallbackPairEntry{(*oo.pOnuDeviceEntry).pMibUploadFsm.commChan, oo.receiveOmciResponse},
604 }
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000605 return oo.Send(ctx, pkt, timeout, 0, highPrio, omciRxCallbackPair)
606}
607
608func (oo *OmciCC) sendMibUploadNext(ctx context.Context, timeout int, highPrio bool) error {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000609 logger.Debugw("send MibUploadNext-msg to:", log.Fields{"deviceId": oo.deviceID, "uploadSequNo": oo.uploadSequNo})
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000610 request := &omci.MibUploadNextRequest{
611 MeBasePacket: omci.MeBasePacket{
612 EntityClass: me.OnuDataClassID,
613 },
614 CommandSequenceNumber: oo.uploadSequNo,
615 }
616 tid := oo.GetNextTid(highPrio)
617 pkt, err := serialize(omci.MibUploadNextRequestType, request, tid)
618 if err != nil {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000619 logger.Errorw("Cannot serialize MibUploadNextRequest", log.Fields{
620 "Err": err, "deviceId": oo.deviceID})
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000621 return err
622 }
623 oo.uploadSequNo++
624
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000625 omciRxCallbackPair := CallbackPair{
626 cbKey: tid,
627 cbEntry: CallbackPairEntry{(*oo.pOnuDeviceEntry).pMibUploadFsm.commChan, oo.receiveOmciResponse},
628 }
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000629 return oo.Send(ctx, pkt, timeout, 0, highPrio, omciRxCallbackPair)
630}
631
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000632func (oo *OmciCC) sendCreateGalEthernetProfile(ctx context.Context, timeout int, highPrio bool) *me.ManagedEntity {
633 tid := oo.GetNextTid(highPrio)
634 logger.Debugw("send GalEnetProfile-Create-msg:", log.Fields{"deviceId": oo.deviceID, "SequNo": strconv.FormatInt(int64(tid), 16)})
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000635
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000636 meParams := me.ParamData{
637 EntityID: galEthernetEID,
638 Attributes: me.AttributeValueMap{"MaximumGemPayloadSize": maxGemPayloadSize},
639 }
640 meInstance, omciErr := me.NewGalEthernetProfile(meParams)
641 if omciErr.GetError() == nil {
642 //all setByCreate parameters already set, no default option required ...
643 omciLayer, msgLayer, err := omci.EncodeFrame(meInstance, omci.CreateRequestType, omci.TransactionID(tid))
644 if err != nil {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000645 logger.Errorw("Cannot encode GalEnetProfileInstance for create", log.Fields{
646 "Err": err, "deviceId": oo.deviceID})
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000647 return nil
648 }
649
650 pkt, err := serializeOmciLayer(omciLayer, msgLayer)
651 if err != nil {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000652 logger.Errorw("Cannot serialize GalEnetProfile create", log.Fields{
653 "Err": err, "deviceId": oo.deviceID})
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000654 return nil
655 }
656
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000657 omciRxCallbackPair := CallbackPair{
658 cbKey: tid,
659 cbEntry: CallbackPairEntry{(*oo.pOnuDeviceEntry).pMibDownloadFsm.commChan, oo.receiveOmciResponse},
660 }
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000661 err = oo.Send(ctx, pkt, timeout, 0, highPrio, omciRxCallbackPair)
662 if err != nil {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000663 logger.Errorw("Cannot send GalEnetProfile create", log.Fields{
664 "Err": err, "deviceId": oo.deviceID})
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000665 return nil
666 } else {
667 logger.Debug("send GalEnetProfile-Create-msg done")
668 return meInstance
669 }
670 } else {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000671 logger.Errorw("Cannot generate GalEnetProfileInstance", log.Fields{
672 "Err": omciErr.GetError(), "deviceId": oo.deviceID})
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000673 return nil
674 }
675}
676
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000677// might be needed to extend for parameter arguments, here just for setting the ConnectivityMode!!
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000678func (oo *OmciCC) sendSetOnu2g(ctx context.Context, timeout int, highPrio bool) *me.ManagedEntity {
679 tid := oo.GetNextTid(highPrio)
680 logger.Debugw("send ONU2-G-Set-msg:", log.Fields{"deviceId": oo.deviceID, "SequNo": strconv.FormatInt(int64(tid), 16)})
681
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000682 // ONU-G ME-ID is defined to be 0, but we could verify, if the ONU really supports the desired
683 // connectivity mode 5 (in ConnCap)
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000684 // By now we just use fix values to fire - this is anyway what the python adapter does
685 // read ONU-2G from DB ???? //TODO!!!
686 meParams := me.ParamData{
687 EntityID: 0,
688 Attributes: me.AttributeValueMap{"CurrentConnectivityMode": connectivityModeValue},
689 }
690 meInstance, omciErr := me.NewOnu2G(meParams)
691 if omciErr.GetError() == nil {
692 omciLayer, msgLayer, err := omci.EncodeFrame(meInstance, omci.SetRequestType, omci.TransactionID(tid))
693 if err != nil {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000694 logger.Errorw("Cannot encode ONU2-G instance for set", log.Fields{
695 "Err": err, "deviceId": oo.deviceID})
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000696 return nil
697 }
698
699 pkt, err := serializeOmciLayer(omciLayer, msgLayer)
700 if err != nil {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000701 logger.Errorw("Cannot serialize ONU2-G set", log.Fields{
702 "Err": err, "deviceId": oo.deviceID})
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000703 return nil
704 }
705
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000706 omciRxCallbackPair := CallbackPair{
707 cbKey: tid,
708 cbEntry: CallbackPairEntry{(*oo.pOnuDeviceEntry).pMibDownloadFsm.commChan, oo.receiveOmciResponse},
709 }
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000710 err = oo.Send(ctx, pkt, timeout, 0, highPrio, omciRxCallbackPair)
711 if err != nil {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000712 logger.Errorw("Cannot send ONU2-G set", log.Fields{
713 "Err": err, "deviceId": oo.deviceID})
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000714 return nil
715 } else {
716 logger.Debug("send ONU2-G-Set-msg done")
717 return meInstance
718 }
719 } else {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000720 logger.Errorw("Cannot generate ONU2-G", log.Fields{
721 "Err": omciErr.GetError(), "deviceId": oo.deviceID})
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000722 return nil
723 }
724}
725
726func (oo *OmciCC) sendCreateMBServiceProfile(ctx context.Context,
727 a_pUniPort *OnuUniPort, timeout int, highPrio bool) *me.ManagedEntity {
728 tid := oo.GetNextTid(highPrio)
729 instID := macBridgeServiceProfileEID + uint16(a_pUniPort.macBpNo)
730 logger.Debugw("send MBSP-Create-msg:", log.Fields{
731 "deviceId": oo.deviceID, "SequNo": strconv.FormatInt(int64(tid), 16), "InstId": instID})
732
733 meParams := me.ParamData{
734 EntityID: instID,
735 Attributes: me.AttributeValueMap{
736 "Priority": 0x8000,
737 "MaxAge": 20 * 256, //20s
738 "HelloTime": 2 * 256, //2s
739 "ForwardDelay": 15 * 256, //15s
740 //note: DynamicFilteringAgeingTime is taken from omci lib default as
741 // which is obviously different from default value used in python lib,
742 // where the value seems to be 0 (ONU defined) - to be considered in case of test artifacts ...
743 },
744 }
745
746 meInstance, omciErr := me.NewMacBridgeServiceProfile(meParams)
747 if omciErr.GetError() == nil {
748 //obviously we have to set all 'untouched' parameters to default by some additional option parameter!!
749 omciLayer, msgLayer, err := omci.EncodeFrame(meInstance, omci.CreateRequestType,
750 omci.TransactionID(tid), omci.AddDefaults(true))
751 if err != nil {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000752 logger.Errorw("Cannot encode MBSP for create", log.Fields{
753 "Err": err, "deviceId": oo.deviceID})
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000754 return nil
755 }
756
757 pkt, err := serializeOmciLayer(omciLayer, msgLayer)
758 if err != nil {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000759 logger.Errorw("Cannot serialize MBSP create", log.Fields{
760 "Err": err, "deviceId": oo.deviceID})
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000761 return nil
762 }
763
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000764 omciRxCallbackPair := CallbackPair{
765 cbKey: tid,
766 cbEntry: CallbackPairEntry{(*oo.pOnuDeviceEntry).pMibDownloadFsm.commChan, oo.receiveOmciResponse},
767 }
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000768 err = oo.Send(ctx, pkt, timeout, 0, highPrio, omciRxCallbackPair)
769 if err != nil {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000770 logger.Errorw("Cannot send MBSP create", log.Fields{
771 "Err": err, "deviceId": oo.deviceID})
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000772 return nil
773 } else {
774 logger.Debug("send MBSP-Create-msg done")
775 return meInstance
776 }
777 } else {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000778 logger.Errorw("Cannot generate MBSP Instance", log.Fields{
779 "Err": omciErr.GetError(), "deviceId": oo.deviceID})
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000780 return nil
781 }
782}
783
784func (oo *OmciCC) sendCreateMBPConfigData(ctx context.Context,
785 a_pUniPort *OnuUniPort, timeout int, highPrio bool) *me.ManagedEntity {
786 tid := oo.GetNextTid(highPrio)
787 instID := macBridgePortAniEID + a_pUniPort.entityId
788 logger.Debugw("send MBPCD-Create-msg:", log.Fields{
789 "deviceId": oo.deviceID, "SequNo": strconv.FormatInt(int64(tid), 16), "InstId": instID})
790
791 meParams := me.ParamData{
792 EntityID: instID,
793 Attributes: me.AttributeValueMap{
794 "BridgeIdPointer": macBridgeServiceProfileEID + uint16(a_pUniPort.macBpNo),
795 "PortNum": a_pUniPort.macBpNo,
796 "TpType": uint8(a_pUniPort.portType),
797 "TpPointer": a_pUniPort.entityId,
798 },
799 }
800 meInstance, omciErr := me.NewMacBridgePortConfigurationData(meParams)
801 if omciErr.GetError() == nil {
802 //obviously we have to set all 'untouched' parameters to default by some additional option parameter!!
803 omciLayer, msgLayer, err := omci.EncodeFrame(meInstance, omci.CreateRequestType,
804 omci.TransactionID(tid), omci.AddDefaults(true))
805 if err != nil {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000806 logger.Errorw("Cannot encode MBPCD for create", log.Fields{
807 "Err": err, "deviceId": oo.deviceID})
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000808 return nil
809 }
810
811 pkt, err := serializeOmciLayer(omciLayer, msgLayer)
812 if err != nil {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000813 logger.Errorw("Cannot serialize MBPCD create", log.Fields{
814 "Err": err, "deviceId": oo.deviceID})
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000815 return nil
816 }
817
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000818 omciRxCallbackPair := CallbackPair{
819 cbKey: tid,
820 cbEntry: CallbackPairEntry{(*oo.pOnuDeviceEntry).pMibDownloadFsm.commChan, oo.receiveOmciResponse},
821 }
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000822 err = oo.Send(ctx, pkt, timeout, 0, highPrio, omciRxCallbackPair)
823 if err != nil {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000824 logger.Errorw("Cannot send MBPCD create", log.Fields{
825 "Err": err, "deviceId": oo.deviceID})
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000826 return nil
827 } else {
828 logger.Debug("send MBPCD-Create-msg done")
829 return meInstance
830 }
831 } else {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000832 logger.Errorw("Cannot generate MBPCD Instance", log.Fields{
833 "Err": omciErr.GetError(), "deviceId": oo.deviceID})
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000834 return nil
835 }
836}
837
838func (oo *OmciCC) sendCreateEVTOConfigData(ctx context.Context,
839 a_pUniPort *OnuUniPort, timeout int, highPrio bool) *me.ManagedEntity {
840 tid := oo.GetNextTid(highPrio)
841 //same entityId is used as for MBSP (see there), but just arbitrary ...
842 instID := macBridgeServiceProfileEID + uint16(a_pUniPort.macBpNo)
843 logger.Debugw("send EVTOCD-Create-msg:", log.Fields{
844 "deviceId": oo.deviceID, "SequNo": strconv.FormatInt(int64(tid), 16), "InstId": instID})
845
846 // compare python adapter code WA VOL-1311: this is not done here!
847 // (setting TPID values for the create would probably anyway be ignored by the omci lib)
848 // but perhaps we have to be aware of possible problems at get(Next) Request handling for EVTOOCD tables later ...
849 assType := uint8(2) // default AssociationType is PPTPEthUni
850 if a_pUniPort.portType == UniVEIP {
851 assType = uint8(10) // for VEIP
852 }
853 meParams := me.ParamData{
854 EntityID: instID,
855 Attributes: me.AttributeValueMap{
856 "AssociationType": assType,
857 "AssociatedMePointer": a_pUniPort.entityId,
858 },
859 }
860 meInstance, omciErr := me.NewExtendedVlanTaggingOperationConfigurationData(meParams)
861 if omciErr.GetError() == nil {
862 //all setByCreate parameters already set, no default option required ...
863 omciLayer, msgLayer, err := omci.EncodeFrame(meInstance, omci.CreateRequestType, omci.TransactionID(tid))
864 if err != nil {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000865 logger.Errorw("Cannot encode EVTOCD for create", log.Fields{
866 "Err": err, "deviceId": oo.deviceID})
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000867 return nil
868 }
869
870 pkt, err := serializeOmciLayer(omciLayer, msgLayer)
871 if err != nil {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000872 logger.Errorw("Cannot serialize EVTOCD create", log.Fields{
873 "Err": err, "deviceId": oo.deviceID})
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000874 return nil
875 }
876
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000877 omciRxCallbackPair := CallbackPair{
878 cbKey: tid,
879 cbEntry: CallbackPairEntry{(*oo.pOnuDeviceEntry).pMibDownloadFsm.commChan, oo.receiveOmciResponse},
880 }
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000881 err = oo.Send(ctx, pkt, timeout, 0, highPrio, omciRxCallbackPair)
882 if err != nil {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000883 logger.Errorw("Cannot send EVTOCD create", log.Fields{
884 "Err": err, "deviceId": oo.deviceID})
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000885 return nil
886 } else {
887 logger.Debug("send EVTOCD-Create-msg done")
888 return meInstance
889 }
890 } else {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000891 logger.Errorw("Cannot generate EVTOCD Instance", log.Fields{
892 "Err": omciErr.GetError(), "deviceId": oo.deviceID})
893 return nil
894 }
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{"deviceId": oo.deviceID, "SequNo": strconv.FormatInt(int64(tid), 16)})
901
902 // ONU-G ME-ID is defined to be 0, no need to perform a DB lookup
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, "deviceId": 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, "deviceId": 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, "deviceId": oo.deviceID})
931 return nil
932 } else {
933 logger.Debug("send ONU-G-Set-msg done")
934 return meInstance
935 }
936 } else {
937 logger.Errorw("Cannot generate ONU-G", log.Fields{
938 "Err": omciErr.GetError(), "deviceId": oo.deviceID})
939 return nil
940 }
941}
942
943func (oo *OmciCC) sendSetUniGLS(ctx context.Context, aInstNo uint16, timeout int,
944 highPrio bool, requestedAttributes me.AttributeValueMap, rxChan chan Message) *me.ManagedEntity {
945 tid := oo.GetNextTid(highPrio)
946 logger.Debugw("send UNI-G-Set-msg:", log.Fields{"deviceId": oo.deviceID, "SequNo": strconv.FormatInt(int64(tid), 16)})
947
948 // UNI-G ME-ID is taken from Mib Upload stored OnuUniPort instance (argument)
949 meParams := me.ParamData{
950 EntityID: aInstNo,
951 Attributes: requestedAttributes,
952 }
953 meInstance, omciErr := me.NewUniG(meParams)
954 if omciErr.GetError() == nil {
955 omciLayer, msgLayer, err := omci.EncodeFrame(meInstance, omci.SetRequestType, omci.TransactionID(tid))
956 if err != nil {
957 logger.Errorw("Cannot encode UNI-G instance for set", log.Fields{
958 "Err": err, "deviceId": oo.deviceID})
959 return nil
960 }
961
962 pkt, err := serializeOmciLayer(omciLayer, msgLayer)
963 if err != nil {
964 logger.Errorw("Cannot serialize UNI-G-Set", log.Fields{
965 "Err": err, "deviceId": oo.deviceID})
966 return nil
967 }
968
969 omciRxCallbackPair := CallbackPair{
970 cbKey: tid,
971 cbEntry: CallbackPairEntry{rxChan, oo.receiveOmciResponse},
972 }
973 err = oo.Send(ctx, pkt, timeout, 0, highPrio, omciRxCallbackPair)
974 if err != nil {
975 logger.Errorw("Cannot send UNIG-G-Set", log.Fields{
976 "Err": err, "deviceId": oo.deviceID})
977 return nil
978 } else {
979 logger.Debug("send UNI-G-Set-msg done")
980 return meInstance
981 }
982 } else {
983 logger.Errorw("Cannot generate UNI-G", log.Fields{
984 "Err": omciErr.GetError(), "deviceId": oo.deviceID})
985 return nil
986 }
987}
988
989func (oo *OmciCC) sendSetVeipLS(ctx context.Context, aInstNo uint16, timeout int,
990 highPrio bool, requestedAttributes me.AttributeValueMap, rxChan chan Message) *me.ManagedEntity {
991 tid := oo.GetNextTid(highPrio)
992 logger.Debugw("send VEIP-Set-msg:", log.Fields{"deviceId": oo.deviceID, "SequNo": strconv.FormatInt(int64(tid), 16)})
993
994 // ONU-G ME-ID is defined to be 0, no need to perform a DB lookup
995 meParams := me.ParamData{
996 EntityID: aInstNo,
997 Attributes: requestedAttributes,
998 }
999 meInstance, omciErr := me.NewVirtualEthernetInterfacePoint(meParams)
1000 if omciErr.GetError() == nil {
1001 omciLayer, msgLayer, err := omci.EncodeFrame(meInstance, omci.SetRequestType, omci.TransactionID(tid))
1002 if err != nil {
1003 logger.Errorw("Cannot encode VEIP instance for set", log.Fields{
1004 "Err": err, "deviceId": oo.deviceID})
1005 return nil
1006 }
1007
1008 pkt, err := serializeOmciLayer(omciLayer, msgLayer)
1009 if err != nil {
1010 logger.Errorw("Cannot serialize VEIP-Set", log.Fields{
1011 "Err": err, "deviceId": oo.deviceID})
1012 return nil
1013 }
1014
1015 omciRxCallbackPair := CallbackPair{
1016 cbKey: tid,
1017 cbEntry: CallbackPairEntry{rxChan, oo.receiveOmciResponse},
1018 }
1019 err = oo.Send(ctx, pkt, timeout, 0, highPrio, omciRxCallbackPair)
1020 if err != nil {
1021 logger.Errorw("Cannot send VEIP-Set", log.Fields{
1022 "Err": err, "deviceId": oo.deviceID})
1023 return nil
1024 } else {
1025 logger.Debug("send VEIP-Set-msg done")
1026 return meInstance
1027 }
1028 } else {
1029 logger.Errorw("Cannot generate VEIP", log.Fields{
1030 "Err": omciErr.GetError(), "deviceId": oo.deviceID})
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +00001031 return nil
1032 }
1033}
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00001034
1035func (oo *OmciCC) sendGetMe(ctx context.Context, classID me.ClassID, entityID uint16, requestedAttributes me.AttributeValueMap,
1036 timeout int, highPrio bool) *me.ManagedEntity {
1037
1038 tid := oo.GetNextTid(highPrio)
1039 logger.Debugw("send get-request-msg", log.Fields{"classID": classID, "deviceId": oo.deviceID, "SequNo": strconv.FormatInt(int64(tid), 16)})
1040
1041 meParams := me.ParamData{
1042 EntityID: entityID,
1043 Attributes: requestedAttributes,
1044 }
1045 meInstance, omciErr := me.LoadManagedEntityDefinition(classID, meParams)
1046 if omciErr.GetError() == nil {
1047 meClassIdName := meInstance.GetName()
1048 omciLayer, msgLayer, err := omci.EncodeFrame(meInstance, omci.GetRequestType, omci.TransactionID(tid))
1049 if err != nil {
1050 logger.Errorf("Cannot encode instance for get-request", log.Fields{"meClassIdName": meClassIdName, "Err": err, "deviceId": oo.deviceID})
1051 return nil
1052 }
1053 pkt, err := serializeOmciLayer(omciLayer, msgLayer)
1054 if err != nil {
1055 logger.Errorw("Cannot serialize get-request", log.Fields{"meClassIdName": meClassIdName, "Err": err, "deviceId": oo.deviceID})
1056 return nil
1057 }
1058 omciRxCallbackPair := CallbackPair{
1059 cbKey: tid,
1060 cbEntry: CallbackPairEntry{(*oo.pOnuDeviceEntry).pMibUploadFsm.commChan, oo.receiveOmciResponse},
1061 }
1062 err = oo.Send(ctx, pkt, timeout, 0, highPrio, omciRxCallbackPair)
1063 if err != nil {
1064 logger.Errorw("Cannot send get-request-msg", log.Fields{"meClassIdName": meClassIdName, "Err": err, "deviceId": oo.deviceID})
1065 return nil
1066 } else {
1067 logger.Debugw("send get-request-msg done", log.Fields{"meClassIdName": meClassIdName, "deviceId": oo.deviceID})
1068 return meInstance
1069 }
1070 } else {
1071 logger.Errorw("Cannot generate meDefinition", log.Fields{"classID": classID, "Err": omciErr.GetError(), "deviceId": oo.deviceID})
1072 return nil
1073 }
1074}