Matteo Scandolo | 4747d29 | 2019-08-05 11:50:18 -0700 | [diff] [blame] | 1 | package devices |
| 2 | |
| 3 | import ( |
Matteo Scandolo | 84f7d48 | 2019-08-08 19:00:47 -0700 | [diff] [blame] | 4 | "gerrit.opencord.org/bbsim/api/openolt" |
Matteo Scandolo | 4747d29 | 2019-08-05 11:50:18 -0700 | [diff] [blame] | 5 | "github.com/looplab/fsm" |
| 6 | log "github.com/sirupsen/logrus" |
| 7 | ) |
| 8 | |
Matteo Scandolo | 9a3518c | 2019-08-13 14:36:01 -0700 | [diff] [blame^] | 9 | var onuLogger = log.WithFields(log.Fields{ |
| 10 | "module": "ONU", |
| 11 | }) |
| 12 | |
Matteo Scandolo | 4747d29 | 2019-08-05 11:50:18 -0700 | [diff] [blame] | 13 | func CreateONU(olt OltDevice, pon PonPort, id uint32) Onu { |
| 14 | o := Onu{ |
| 15 | ID: id, |
Matteo Scandolo | 4747d29 | 2019-08-05 11:50:18 -0700 | [diff] [blame] | 16 | PonPortID: pon.ID, |
| 17 | PonPort: pon, |
Matteo Scandolo | 9a3518c | 2019-08-13 14:36:01 -0700 | [diff] [blame^] | 18 | channel: make(chan Message), |
Matteo Scandolo | 4747d29 | 2019-08-05 11:50:18 -0700 | [diff] [blame] | 19 | } |
| 20 | o.SerialNumber = o.NewSN(olt.ID, pon.ID, o.ID) |
| 21 | |
Matteo Scandolo | 9a3518c | 2019-08-13 14:36:01 -0700 | [diff] [blame^] | 22 | // NOTE this state machine is used to track the operational |
| 23 | // state as requested by VOLTHA |
| 24 | o.OperState = getOperStateFSM(func(e *fsm.Event) { |
| 25 | onuLogger.WithFields(log.Fields{ |
| 26 | "ID": o.ID, |
| 27 | }).Debugf("Changing ONU OperState from %s to %s", e.Src, e.Dst) |
| 28 | }) |
| 29 | |
| 30 | // NOTE this state machine is used to activate the OMCI, EAPOL and DHCP clients |
Matteo Scandolo | 4747d29 | 2019-08-05 11:50:18 -0700 | [diff] [blame] | 31 | o.InternalState = fsm.NewFSM( |
| 32 | "created", |
| 33 | fsm.Events{ |
| 34 | {Name: "discover", Src: []string{"created"}, Dst: "discovered"}, |
| 35 | {Name: "enable", Src: []string{"discovered"}, Dst: "enabled"}, |
Matteo Scandolo | 9a3518c | 2019-08-13 14:36:01 -0700 | [diff] [blame^] | 36 | {Name: "start_omci", Src: []string{"enabled"}, Dst: "starting_openomci"}, |
Matteo Scandolo | 4747d29 | 2019-08-05 11:50:18 -0700 | [diff] [blame] | 37 | }, |
| 38 | fsm.Callbacks{ |
| 39 | "enter_state": func(e *fsm.Event) { |
Matteo Scandolo | 9a3518c | 2019-08-13 14:36:01 -0700 | [diff] [blame^] | 40 | onuLogger.WithFields(log.Fields{ |
| 41 | "ID": o.ID, |
| 42 | }).Debugf("Changing ONU InternalState from %s to %s", e.Src, e.Dst) |
Matteo Scandolo | 4747d29 | 2019-08-05 11:50:18 -0700 | [diff] [blame] | 43 | }, |
| 44 | }, |
| 45 | ) |
| 46 | return o |
| 47 | } |
| 48 | |
Matteo Scandolo | 9a3518c | 2019-08-13 14:36:01 -0700 | [diff] [blame^] | 49 | func (o Onu) processOnuMessages(stream openolt.Openolt_EnableIndicationServer) { |
| 50 | onuLogger.WithFields(log.Fields{ |
Matteo Scandolo | 4747d29 | 2019-08-05 11:50:18 -0700 | [diff] [blame] | 51 | "onuID": o.ID, |
| 52 | "onuSN": o.SerialNumber, |
Matteo Scandolo | 9a3518c | 2019-08-13 14:36:01 -0700 | [diff] [blame^] | 53 | }).Debug("Started ONU Indication Channel") |
| 54 | |
| 55 | for message := range o.channel { |
| 56 | onuLogger.WithFields(log.Fields{ |
| 57 | "onuID": o.ID, |
| 58 | "onuSN": o.SerialNumber, |
| 59 | "messageType": message.Type, |
| 60 | }).Trace("Received message") |
| 61 | |
| 62 | switch message.Type { |
| 63 | case OnuDiscIndication: |
| 64 | msg, _ := message.Data.(OnuDiscIndicationMessage) |
| 65 | o.sendOnuDiscIndication(msg, stream) |
| 66 | case OnuIndication: |
| 67 | msg, _ := message.Data.(OnuIndicationMessage) |
| 68 | o.sendOnuIndication(msg, stream) |
| 69 | case OMCI: |
| 70 | o.InternalState.Event("start_omci") |
| 71 | onuLogger.Warn("Don't know how to handle OMCI Messages yet...") |
| 72 | default: |
| 73 | onuLogger.Warnf("Received unknown message data %v for type %v in OLT channel", message.Data, message.Type) |
| 74 | } |
| 75 | } |
Matteo Scandolo | 4747d29 | 2019-08-05 11:50:18 -0700 | [diff] [blame] | 76 | } |
| 77 | |
| 78 | func (o Onu) NewSN(oltid int, intfid uint32, onuid uint32) *openolt.SerialNumber { |
| 79 | |
| 80 | sn := new(openolt.SerialNumber) |
| 81 | |
| 82 | sn = new(openolt.SerialNumber) |
| 83 | sn.VendorId = []byte("BBSM") |
| 84 | sn.VendorSpecific = []byte{0, byte(oltid % 256), byte(intfid), byte(onuid)} |
| 85 | |
| 86 | return sn |
| 87 | } |
| 88 | |
| 89 | func (o Onu) sendOnuDiscIndication(msg OnuDiscIndicationMessage, stream openolt.Openolt_EnableIndicationServer) { |
| 90 | discoverData := &openolt.Indication_OnuDiscInd{OnuDiscInd: &openolt.OnuDiscIndication{ |
| 91 | IntfId: msg.Onu.PonPortID, |
| 92 | SerialNumber: msg.Onu.SerialNumber, |
| 93 | }} |
| 94 | if err := stream.Send(&openolt.Indication{Data: discoverData}); err != nil { |
| 95 | log.Error("Failed to send Indication_OnuDiscInd: %v", err) |
| 96 | } |
Matteo Scandolo | 9a3518c | 2019-08-13 14:36:01 -0700 | [diff] [blame^] | 97 | o.InternalState.Event("discover") |
| 98 | onuLogger.WithFields(log.Fields{ |
Matteo Scandolo | 4747d29 | 2019-08-05 11:50:18 -0700 | [diff] [blame] | 99 | "IntfId": msg.Onu.PonPortID, |
| 100 | "SerialNumber": msg.Onu.SerialNumber, |
| 101 | }).Debug("Sent Indication_OnuDiscInd") |
| 102 | } |
| 103 | |
| 104 | func (o Onu) sendOnuIndication(msg OnuIndicationMessage, stream openolt.Openolt_EnableIndicationServer) { |
| 105 | // NOTE voltha returns an ID, but if we use that ID then it complains: |
| 106 | // expected_onu_id: 1, received_onu_id: 1024, event: ONU-id-mismatch, can happen if both voltha and the olt rebooted |
| 107 | // so we're using the internal ID that is 1 |
| 108 | // o.ID = msg.OnuID |
Matteo Scandolo | 9a3518c | 2019-08-13 14:36:01 -0700 | [diff] [blame^] | 109 | o.OperState.Event("enable") |
Matteo Scandolo | 4747d29 | 2019-08-05 11:50:18 -0700 | [diff] [blame] | 110 | |
| 111 | indData := &openolt.Indication_OnuInd{OnuInd: &openolt.OnuIndication{ |
| 112 | IntfId: o.PonPortID, |
| 113 | OnuId: o.ID, |
Matteo Scandolo | 9a3518c | 2019-08-13 14:36:01 -0700 | [diff] [blame^] | 114 | OperState: o.OperState.Current(), |
| 115 | AdminState: o.OperState.Current(), |
Matteo Scandolo | 4747d29 | 2019-08-05 11:50:18 -0700 | [diff] [blame] | 116 | SerialNumber: o.SerialNumber, |
| 117 | }} |
| 118 | if err := stream.Send(&openolt.Indication{Data: indData}); err != nil { |
| 119 | log.Error("Failed to send Indication_OnuInd: %v", err) |
| 120 | } |
Matteo Scandolo | 9a3518c | 2019-08-13 14:36:01 -0700 | [diff] [blame^] | 121 | o.InternalState.Event("enable") |
| 122 | onuLogger.WithFields(log.Fields{ |
Matteo Scandolo | 4747d29 | 2019-08-05 11:50:18 -0700 | [diff] [blame] | 123 | "IntfId": o.PonPortID, |
| 124 | "OnuId": o.ID, |
| 125 | "OperState": msg.OperState.String(), |
| 126 | "AdminState": msg.OperState.String(), |
| 127 | "SerialNumber": o.SerialNumber, |
| 128 | }).Debug("Sent Indication_OnuInd") |
| 129 | } |