SEBA-317

Change-Id: Ifb582cbd4764b6995b191ed5c9bc08f2d1ba3c4b
diff --git a/api/abstract_olt_api.proto b/api/abstract_olt_api.proto
index dd8fcea..0a031bb 100644
--- a/api/abstract_olt_api.proto
+++ b/api/abstract_olt_api.proto
@@ -78,6 +78,17 @@
    int32 OntNumber=4;
    string SerialNumber=5;
 }
+message AddOntFullMessage{
+   string CLLI=1;
+   int32 SlotNumber=2;
+   int32 PortNumber=3;
+   int32 OntNumber=4;
+   string SerialNumber=5;
+   uint32 STag=7;
+   uint32 CTag=8;
+   string NasPortID=9;
+   string CircuitID=10;
+}
 message AddOntReturn{
    bool Success=1;
 }
@@ -129,6 +140,12 @@
 	 body:"*"
       };
    }
+   rpc ProvisionOntFull(AddOntFullMessage) returns (AddOntReturn) {
+      option(google.api.http) = {
+         post:"/v1/ProvsionOtFull"
+	 body:"*"
+      };
+   }
    rpc DeleteOnt(DeleteOntMessage) returns (DeleteOntReturn){
       option(google.api.http)={
         post:"/v1/DeleteOnt"
diff --git a/api/handler.go b/api/handler.go
index bd9d2f0..593afed 100644
--- a/api/handler.go
+++ b/api/handler.go
@@ -217,6 +217,26 @@
 	isDirty = true
 	return &AddOntReturn{Success: true}, nil
 }
+func (s *Server) ProvisionOntFull(ctx context.Context, in *AddOntFullMessage) (*AddOntReturn, error) {
+	myChan := getSyncChannel()
+	<-myChan
+	defer done(myChan, true)
+	chassisMap := models.GetChassisMap()
+	clli := in.GetCLLI()
+	chassisHolder := (*chassisMap)[clli]
+	if chassisHolder == nil {
+		errString := fmt.Sprintf("There is no chassis with CLLI of %s", clli)
+		return &AddOntReturn{Success: false}, errors.New(errString)
+	}
+	err := chassisHolder.AbstractChassis.ActivateONTFull(int(in.GetSlotNumber()), int(in.GetPortNumber()), int(in.GetOntNumber()), in.GetSerialNumber(),
+		in.GetCTag(), in.GetSTag(), in.GetNasPortID(), in.GetCircuitID())
+
+	if err != nil {
+		return nil, err
+	}
+	isDirty = true
+	return &AddOntReturn{Success: true}, nil
+}
 
 /*
 DeleteOnt - deletes a previously provision ont
diff --git a/client/main.go b/client/main.go
index ed2da71..f4b7826 100644
--- a/client/main.go
+++ b/client/main.go
@@ -31,14 +31,14 @@
 
 func main() {
 	/* COMMAND FLAGS */
-	output := flag.Bool("output", false, "dump output")
 	echo := flag.Bool("e", false, "echo")
-	message := flag.String("message", "ping", "message to be echoed back")
 	create := flag.Bool("c", false, "create?")
 	update := flag.Bool("u", false, "update?")
 	addOlt := flag.Bool("s", false, "addOlt?")
 	provOnt := flag.Bool("o", false, "provisionOnt?")
+	provOntFull := flag.Bool("f", false, "provsionOntFull?")
 	deleteOnt := flag.Bool("d", false, "deleteOnt")
+	output := flag.Bool("output", false, "dump output")
 	/* END COMMAND FLAGS */
 
 	/* CREATE CHASSIS FLAGS */
@@ -65,6 +65,17 @@
 	serial := flag.String("serial", "", "serial number of ont")
 	/* END PROVISION / DELETE ONT FLAGS */
 
+	/*PROVISION ONT FULL EXTRA FLAGS*/
+	stag := flag.Uint("stag", 0, "s-tag for ont")
+	ctag := flag.Uint("ctag", 0, "c-tag for ont")
+	nasPort := flag.String("nas_port", "", "NasPortID for ont")
+	circuitID := flag.String("circuit_id", "", "CircuitID for ont")
+	/*END PROVISION ONT FULL EXTRA FLAGS*/
+
+	/* ECHO FLAGS */
+	message := flag.String("message", "ping", "message to be echoed back")
+	/*END ECHO FLAGS*/
+
 	/*GENERIC FLAGS */
 	clli := flag.String("clli", "", "clli of abstract chassis")
 	useSsl := flag.Bool("ssl", false, "use ssl")
@@ -83,7 +94,7 @@
 		}
 	}
 
-	cmdFlags := []*bool{echo, addOlt, update, create, provOnt, deleteOnt, output}
+	cmdFlags := []*bool{echo, addOlt, update, create, provOnt, provOntFull, deleteOnt, output}
 	cmdCount := 0
 	for _, flag := range cmdFlags {
 		if *flag {
@@ -141,6 +152,8 @@
 		addOltChassis(c, clli, oltAddress, oltPort, name, driver, oltType)
 	} else if *provOnt {
 		provisionONT(c, clli, slot, port, ont, serial)
+	} else if *provOntFull {
+		provisionONTFull(c, clli, slot, port, ont, serial, stag, ctag, nasPort, circuitID)
 	} else if *echo {
 		ping(c, *message)
 	} else if *output {
@@ -264,7 +277,24 @@
 	}
 	log.Printf("Response from server: %t", res.GetSuccess())
 	return nil
-
+}
+func provisionONTFull(c api.AbstractOLTClient, clli *string, slot *uint, port *uint, ont *uint, serial *string, stag *uint, ctag *uint, nasPort *string, circuitID *string) error {
+	fmt.Println("clli", *clli)
+	fmt.Println("slot", *slot)
+	fmt.Println("port", *port)
+	fmt.Println("ont", *ont)
+	fmt.Println("serial", *serial)
+	fmt.Println("stag", *stag)
+	fmt.Println("ctag", *ctag)
+	fmt.Println("nasPort", *nasPort)
+	fmt.Println("circuitID", *circuitID)
+	res, err := c.ProvisionOntFull(context.Background(), &api.AddOntFullMessage{CLLI: *clli, SlotNumber: int32(*slot), PortNumber: int32(*port), OntNumber: int32(*ont), SerialNumber: *serial, STag: uint32(*stag), CTag: uint32(*ctag), NasPortID: *nasPort, CircuitID: *circuitID})
+	if err != nil {
+		debug.PrintStack()
+		fmt.Printf("Error when calling ProvsionOnt %s", err)
+		return err
+	}
+	log.Printf("Response from server: %t", res.GetSuccess())
 	return nil
 }
 func deleteONT(c api.AbstractOLTClient, clli *string, slot *uint, port *uint, ont *uint, serial *string) error {
@@ -326,6 +356,18 @@
 	 -ont ONT_NUMBER [1-64]
 	 -serial ONT_SERIAL_NUM
 	 e.g. ./client -server=localhost:7777 -o -clli=MY_CLLI -slot=1 -port=1 -ont=22 -serial=aer900jasdf
+   -f provision ont full - same as -o above but allows explicit set of s/c vlans , NasPortID and CircuitID
+      params:
+	 -clli CLLI_NAME
+	 -slot SLOT_NUMBER [1-16]
+	 -port OLT_PORT_NUMBER [1-16]
+	 -ont ONT_NUMBER [1-64]
+	 -serial ONT_SERIAL_NUM
+	 -stag S_TAG
+	 -ctag C_TAG
+	 -nas_port NAS_PORT_ID
+	 -circuit_id CIRCUIT_ID
+	 e.g. ./client -server=localhost:7777 -f -clli=MY_CLLI -slot=1 -port=1 -ont=22 -serial=aer900jasdf -stag=33 -ctag=104 -nas_port="pon 1/1/1/3:1.1" -circuit_id="CLLI 1/1/1/13:1.1"
    -d delete ont - removes ont from service
       params:
 	 -clli CLLI_NAME
diff --git a/models/abstract/ChassisUtils.go b/models/abstract/ChassisUtils.go
index 0cacf79..964234f 100644
--- a/models/abstract/ChassisUtils.go
+++ b/models/abstract/ChassisUtils.go
@@ -47,31 +47,32 @@
 
 	var onts [64]Ont
 	//i starts with 1 because :P Architects - blah
-	for i := 1; i < 65; i++ {
+	var i uint32
+	for i = 1; i < 65; i++ {
 		/* adding one because the system that provisions is 1 based on everything not 0 based*/
-		onts[i-1] = Ont{Number: i, Svlan: calculateSvlan(s.Number, n, i),
-			Cvlan: calculateCvlan(s.Number, n, i+1), Parent: &port}
+		onts[int(i-1)] = Ont{Number: int(i), Svlan: calculateSvlan(s.Number, n, int(i)),
+			Cvlan: calculateCvlan(s.Number, n, int(i+1)), Parent: &port}
 	}
 
 	port.Onts = onts
 	return port
 }
 
-func calculateCvlan(slot int, port int, ont int) int {
+func calculateCvlan(slot int, port int, ont int) uint32 {
 	ontPortOffset := 120 // Max(ONT_SLOT) * Max(ONT_PORT) = 10 * 12 = 120
 	ontSlotOffset := 12  //= Max(ONT_PORT) = 12
 	vlanOffset := 1      //(VID 1 is reserved)
 
-	cVid := ((ont-2)%32)*ontPortOffset + (slot-3)*ontSlotOffset + port + vlanOffset
+	cVid := uint32(((ont-2)%32)*ontPortOffset + (slot-3)*ontSlotOffset + port + vlanOffset)
 
 	return cVid
 }
 
-func calculateSvlan(slot int, port int, ont int) int {
+func calculateSvlan(slot int, port int, ont int) uint32 {
 	ltSlotOffset := 16
 	vlanGap := 288  // Max(LT_SLOT) * Max(ltSlotOffset) = 18 * 16 = 288
 	vlanOffset := 1 //(VID 1 is reserved)
-	sVid := ((slot-3)*ltSlotOffset + port) + ((ont-1)/32)*vlanGap + vlanOffset
+	sVid := uint32(((slot-3)*ltSlotOffset + port) + ((ont-1)/32)*vlanGap + vlanOffset)
 
 	return sVid
 }
diff --git a/models/abstract/chassis.go b/models/abstract/chassis.go
index 9b62c8c..a86822d 100644
--- a/models/abstract/chassis.go
+++ b/models/abstract/chassis.go
@@ -62,6 +62,11 @@
 
 	return nextPort, nil
 }
+func (chassis *Chassis) ActivateONTFull(slotNumber int, portNumber int, ontNumber int, serialNumber string, cTag uint32, sTag uint32, nasPortID string, circuitID string) error {
+	err := chassis.Slots[slotNumber-1].Ports[portNumber-1].provisionOntFull(ontNumber, serialNumber, cTag, sTag, nasPortID, circuitID)
+	return err
+}
+
 func (chassis *Chassis) ActivateONT(slotNumber int, portNumber int, ontNumber int, serialNumber string) error {
 	err := chassis.Slots[slotNumber-1].Ports[portNumber-1].provisionOnt(ontNumber, serialNumber)
 	return err
diff --git a/models/abstract/ont.go b/models/abstract/ont.go
index bfd6d60..6a058a0 100644
--- a/models/abstract/ont.go
+++ b/models/abstract/ont.go
@@ -21,7 +21,7 @@
 */
 type Ont struct {
 	Number int
-	Svlan  int
-	Cvlan  int
+	Svlan  uint32
+	Cvlan  uint32
 	Parent *Port `json:"-"`
 }
diff --git a/models/abstract/port.go b/models/abstract/port.go
index 1af3d6e..efb3054 100644
--- a/models/abstract/port.go
+++ b/models/abstract/port.go
@@ -51,19 +51,30 @@
 func (port *Port) provisionOnt(ontNumber int, serialNumber string) error {
 
 	slot := port.Parent
-	chassis := *slot.Parent
+	chassis := slot.Parent
 	baseID := fmt.Sprintf("%d/%d/%d/%d:%d.1.1", chassis.Rack, chassis.Shelf, slot.Number, port.Number, ontNumber)
 	nasPortID := fmt.Sprintf("PON %s", baseID)
 	circuitID := fmt.Sprintf("%s %s", chassis.CLLI, baseID)
 
 	if port.PhysPort == nil {
+		err := UnprovisonedPortError{oltNum: slot.Number, clli: chassis.CLLI, portNum: port.Number}
+		return &err
+	}
+	phyPort := port.PhysPort
+	ont := port.Onts[ontNumber-1]
+	err := phyPort.ActivateOnt(ontNumber, ont.Svlan, ont.Cvlan, serialNumber, nasPortID, circuitID)
+	return err
+}
+func (port *Port) provisionOntFull(ontNumber int, serialNumber string, cTag uint32, sTag uint32, nasPortID string, circuitID string) error {
+	slot := port.Parent
+
+	if port.PhysPort == nil {
 		chassis := slot.Parent
 		err := UnprovisonedPortError{oltNum: slot.Number, clli: chassis.CLLI, portNum: port.Number}
 		return &err
 	}
 	phyPort := port.PhysPort
-	ont := port.Onts[ontNumber-1]
-	err := phyPort.ActivateOnt(ontNumber, ont.Svlan, ont.Cvlan, serialNumber, nasPortID, circuitID)
+	err := phyPort.ActivateOnt(ontNumber, sTag, cTag, serialNumber, nasPortID, circuitID)
 	return err
 }
 func (port *Port) deleteOnt(ontNumber int, serialNumber string) error {
diff --git a/models/physical/ont.go b/models/physical/ont.go
index 21fbbae..8c8949b 100644
--- a/models/physical/ont.go
+++ b/models/physical/ont.go
@@ -21,8 +21,8 @@
 */
 type Ont struct {
 	Number       int      `json:",omitempty"`
-	Svlan        int      `,json:",omitempty"`
-	Cvlan        int      `,json:",omitempty"`
+	Svlan        uint32   `,json:",omitempty"`
+	Cvlan        uint32   `,json:",omitempty"`
 	SerialNumber string   `,json:",omitempty"`
 	Parent       *PONPort `json:"-" bson:"-"`
 	Active       bool     `json:",omitempty"`
diff --git a/models/physical/ponport.go b/models/physical/ponport.go
index 9c626c3..1064992 100644
--- a/models/physical/ponport.go
+++ b/models/physical/ponport.go
@@ -67,7 +67,7 @@
 /*
 ActivateOnt - passes ont information to chassis to make call to NEM to activate (whitelist) ont
 */
-func (port *PONPort) ActivateOnt(number int, sVlan int, cVlan int, serialNumber string, nasPortID string, circuitID string) error {
+func (port *PONPort) ActivateOnt(number int, sVlan uint32, cVlan uint32, serialNumber string, nasPortID string, circuitID string) error {
 	slot := port.Parent
 	chassis := slot.Parent
 
@@ -86,7 +86,7 @@
 /*
 DeleteOnt - passes ont information to chassis to make call to NEM to de-activate (de-whitelist) ont
 */
-func (port *PONPort) DeleteOnt(number int, sVlan int, cVlan int, serialNumber string) error {
+func (port *PONPort) DeleteOnt(number int, sVlan uint32, cVlan uint32, serialNumber string) error {
 	slot := port.Parent
 	chassis := slot.Parent
 	if port.Onts[number-1].Active != true {
diff --git a/models/tosca/addSubscriber.go b/models/tosca/addSubscriber.go
index 448569c..680dd5e 100644
--- a/models/tosca/addSubscriber.go
+++ b/models/tosca/addSubscriber.go
@@ -52,8 +52,8 @@
 				Properties struct {
 					Name      string `yaml:"name"`
 					Status    string `yaml:"status"`
-					CTag      int    `yaml:"c_tag"`
-					STag      int    `yaml:"s_tag"`
+					CTag      uint32 `yaml:"c_tag"`
+					STag      uint32 `yaml:"s_tag"`
 					OnuDevice string `yaml:"onu_device"`
 					NasPortID string `yaml:"nas_port_id"`
 					CircuitID string `yaml:"circuit_id"`
@@ -64,7 +64,7 @@
 	} `yaml:"topology_template"`
 }
 
-func NewSubscriberProvision(name string, cTag int, sTag int, onuDevice string, nasPortID string, circuitID string, remoteID string) SubscriberProvision {
+func NewSubscriberProvision(name string, cTag uint32, sTag uint32, onuDevice string, nasPortID string, circuitID string, remoteID string) SubscriberProvision {
 	s := SubscriberProvision{}
 	err := yaml.Unmarshal([]byte(subSubscriberTemplate), &s)
 	if err != nil {