added timestamps
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..e43b0f9
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+.DS_Store
diff --git a/src/main/java/org.onosproject.xran/controller/XranControllerImpl.java b/src/main/java/org.onosproject.xran/controller/XranControllerImpl.java
index 5f3bf5b..8ef2ddc 100644
--- a/src/main/java/org.onosproject.xran/controller/XranControllerImpl.java
+++ b/src/main/java/org.onosproject.xran/controller/XranControllerImpl.java
@@ -33,6 +33,7 @@
 import org.onosproject.net.host.HostService;
 import org.onosproject.xran.XranStore;
 import org.onosproject.xran.codecs.api.*;
+import org.onosproject.xran.codecs.ber.types.BerInteger;
 import org.onosproject.xran.codecs.pdu.*;
 import org.onosproject.xran.entities.RnibCell;
 import org.onosproject.xran.entities.RnibLink;
@@ -44,7 +45,6 @@
 import org.onosproject.xran.wrapper.CellMap;
 import org.onosproject.xran.wrapper.LinkMap;
 import org.onosproject.xran.wrapper.UeMap;
-import org.onosproject.xran.codecs.ber.types.BerInteger;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -763,8 +763,10 @@
                                     RSRPRange rsrp = rxSigReport.getRsrp();
 
                                     RnibLink.LinkQuality quality = link.getQuality();
-                                    quality.setRsrp(rsrp.value.intValue() - 140);
-                                    quality.setRsrq((rsrq.value.intValue() * 0.5) - 19.5);
+                                    quality.setRX(new RnibLink.LinkQuality.RX(
+                                            rsrp.value.intValue() - 140,
+                                            (rsrq.value.intValue() * 0.5) - 19.5
+                                    ));
                                 }
                             } else {
                                 log.warn("Could not find cell with PCI-ARFCN: {}", rxSigReport.getPciArfcn());
@@ -785,7 +787,6 @@
                             if (link != null) {
                                 RadioRepPerServCell.CqiHist cqiHist = servCell.getCqiHist();
                                 RnibLink.LinkQuality quality = link.getQuality();
-                                quality.setCqiHist(cqiHist);
 
                                 final double[] values = {0, 0, 0};
                                 int i = 1;
@@ -795,8 +796,11 @@
                                     values[2] += value.intValue();
                                 });
 
-                                quality.setCqiMode(values[0]);
-                                quality.setCqiMean(values[1] / values[2]);
+                                quality.setCQI(new RnibLink.LinkQuality.CQI(
+                                        cqiHist,
+                                        values[0],
+                                        values[1] / values[0]
+                                ));
 
                             } else {
                                 log.warn("Could not find link between: {}-{}", cell.getEcgi(), radioMeasReportPerUE.getCrnti());
@@ -821,11 +825,15 @@
                         if (cell != null) {
                             RnibLink link = linkMap.get(cell.getEcgi(), schedMeasReportPerUE.getCrnti());
                             if (link != null) {
-                                link.getQuality().setMcsDl(servCell.getMcsDl());
-                                link.getQuality().setMcsUl(servCell.getMcsUl());
+                                link.getQuality().setMCS(new RnibLink.LinkQuality.MCS(
+                                        servCell.getMcsDl(),
+                                        servCell.getMcsUl()
+                                ));
 
-                                link.getResourceUsage().setDl(servCell.getPrbUsage().getPrbUsageDl());
-                                link.getResourceUsage().setUl(servCell.getPrbUsage().getPrbUsageUl());
+                                link.setResourceUsage(new RnibLink.ResourceUsage(
+                                        servCell.getPrbUsage().getPrbUsageDl(),
+                                        servCell.getPrbUsage().getPrbUsageUl()
+                                ));
                             } else {
                                 log.warn("Could not find link between: {}-{}", cell.getEcgi(),
                                         schedMeasReportPerUE.getCrnti());
@@ -840,8 +848,11 @@
                     SchedMeasReportPerCell schedMeasReportPerCell = recv_pdu.getBody().getSchedMeasReportPerCell();
                     RnibCell cell = cellMap.get(schedMeasReportPerCell.getEcgi());
                     if (cell != null) {
-                        cell.setPrimaryPrbUsage(schedMeasReportPerCell.getPrbUsagePcell());
-                        cell.setSecondaryPrbUsage(schedMeasReportPerCell.getPrbUsageScell());
+                        cell.setPrbUsage(new RnibCell.PrbUsageContainer(
+                                schedMeasReportPerCell.getPrbUsagePcell(),
+                                schedMeasReportPerCell.getPrbUsageScell()
+                        ));
+
                         cell.setQci(schedMeasReportPerCell.getQciVals());
                     } else {
                         log.warn("Could not find cell with ECGI: {}", schedMeasReportPerCell.getEcgi());
@@ -853,10 +864,15 @@
 
                     RnibLink link = linkMap.get(pdcpMeasReportPerUe.getEcgi(), pdcpMeasReportPerUe.getCrnti());
                     if (link != null) {
-                        link.getPdcpThroughput().setDl(pdcpMeasReportPerUe.getThroughputDl());
-                        link.getPdcpThroughput().setUl(pdcpMeasReportPerUe.getThroughputUl());
-                        link.getPdcpPackDelay().setDl(pdcpMeasReportPerUe.getPktDelayDl());
-                        link.getPdcpPackDelay().setUl(pdcpMeasReportPerUe.getPktDelayUl());
+                        link.setPdcpThroughput(new RnibLink.PDCPThroughput(
+                                pdcpMeasReportPerUe.getThroughputDl(),
+                                pdcpMeasReportPerUe.getThroughputUl()
+                        ));
+
+                        link.setPdcpPackDelay(new RnibLink.PDCPPacketDelay(
+                                pdcpMeasReportPerUe.getPktDelayDl(),
+                                pdcpMeasReportPerUe.getPktDelayUl()
+                        ));
                     } else {
                         log.warn("Could not find link between: {}-{}", pdcpMeasReportPerUe.getEcgi(),
                                 pdcpMeasReportPerUe.getCrnti());
diff --git a/src/main/java/org.onosproject.xran/entities/RnibCell.java b/src/main/java/org.onosproject.xran/entities/RnibCell.java
index dae002c..2e6a8c8 100644
--- a/src/main/java/org.onosproject.xran/entities/RnibCell.java
+++ b/src/main/java/org.onosproject.xran/entities/RnibCell.java
@@ -16,21 +16,19 @@
 
 package org.onosproject.xran.entities;
 
-import com.fasterxml.jackson.annotation.JsonIgnore;
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+import com.fasterxml.jackson.annotation.*;
 import com.fasterxml.jackson.databind.JsonNode;
 import org.onosproject.net.DeviceId;
+import org.onosproject.store.Timestamp;
+import org.onosproject.store.service.WallClockTimestamp;
 import org.onosproject.xran.codecs.api.ECGI;
 import org.onosproject.xran.codecs.api.PRBUsage;
+import org.onosproject.xran.codecs.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.codecs.ber.types.BerInteger;
 import org.onosproject.xran.codecs.pdu.CellConfigReport;
 import org.onosproject.xran.codecs.pdu.L2MeasConfig;
 import org.onosproject.xran.codecs.pdu.RRMConfig;
 import org.onosproject.xran.codecs.pdu.SchedMeasReportPerCell;
-import org.onosproject.xran.codecs.ber.BerByteArrayOutputStream;
-import org.onosproject.xran.codecs.ber.types.BerBitString;
-import org.onosproject.xran.codecs.ber.types.BerInteger;
 
 import javax.xml.bind.DatatypeConverter;
 import java.io.ByteArrayInputStream;
@@ -76,7 +74,6 @@
     private String version;
 
     public RnibCell() {
-        prbUsage = new PrbUsageContainer();
         version = "3";
 
         rrmConfig = new RRMConfig();
@@ -152,10 +149,6 @@
         return conf;
     }
 
-    /*public RRMConfig getRrmConfig() {
-        return rrmConfig;
-    }*/
-
     @JsonProperty("Configuration")
     public void setConf(CellConfigReport conf) {
         this.conf = conf;
@@ -242,14 +235,6 @@
         this.qci = qci;
     }
 
-    public void setPrimaryPrbUsage(PRBUsage primary) {
-        this.prbUsage.primary = primary;
-    }
-
-    public void setSecondaryPrbUsage(PRBUsage secondary) {
-        this.prbUsage.secondary = secondary;
-    }
-
     @JsonProperty("MeasurementConfiguration")
     public L2MeasConfig getMeasConfig() {
         return measConfig;
@@ -290,12 +275,21 @@
 
     @JsonPropertyOrder({
             "primary",
-            "secondary"
+            "secondary",
+            "timesincelastupdate"
     })
     @JsonIgnoreProperties(ignoreUnknown = true)
-    class PrbUsageContainer {
+    public static class PrbUsageContainer {
         PRBUsage primary;
         PRBUsage secondary;
+        WallClockTimestamp timesincelastupdate;
+
+        @JsonCreator
+        public PrbUsageContainer(@JsonProperty("primary") PRBUsage primary, @JsonProperty("secondary") PRBUsage secondary) {
+            this.primary = primary;
+            this.secondary = secondary;
+            this.timesincelastupdate = new WallClockTimestamp();
+        }
 
         public PRBUsage getPrimary() {
             return primary;
@@ -313,11 +307,19 @@
             this.secondary = secondary;
         }
 
+        public long getTimesincelastupdate() {
+            return timesincelastupdate.unixTimestamp();
+        }
+        public void setTimesincelastupdate(WallClockTimestamp timesincelastupdate) {
+            this.timesincelastupdate = timesincelastupdate;
+        }
+
         @Override
         public String toString() {
             return "PrbUsageContainer{" +
                     "primary=" + primary +
                     ", secondary=" + secondary +
+                    ", timesincelastupdate=" + timesincelastupdate +
                     '}';
         }
     }
diff --git a/src/main/java/org.onosproject.xran/entities/RnibLink.java b/src/main/java/org.onosproject.xran/entities/RnibLink.java
index ade8f58..70ffe4f 100644
--- a/src/main/java/org.onosproject.xran/entities/RnibLink.java
+++ b/src/main/java/org.onosproject.xran/entities/RnibLink.java
@@ -16,17 +16,15 @@
 
 package org.onosproject.xran.entities;
 
-import com.fasterxml.jackson.annotation.JsonIgnore;
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+import com.fasterxml.jackson.annotation.*;
 import com.fasterxml.jackson.databind.JsonNode;
 import com.google.common.collect.Lists;
+import org.onosproject.store.service.WallClockTimestamp;
 import org.onosproject.xran.codecs.api.*;
+import org.onosproject.xran.codecs.ber.types.BerInteger;
 import org.onosproject.xran.codecs.pdu.PDCPMeasReportPerUe;
 import org.onosproject.xran.codecs.pdu.RRMConfig;
 import org.onosproject.xran.identifiers.LinkId;
-import org.onosproject.xran.codecs.ber.types.BerInteger;
 
 import java.util.Arrays;
 import java.util.List;
@@ -76,16 +74,14 @@
         trafficPercent.setTrafficPercentDl(new BerInteger(100));
         trafficPercent.setTrafficPercentUl(new BerInteger(100));
 
-        pdcpThroughput = new PDCPThroughput();
-        quality = new LinkQuality();
-        pdcpPackDelay = new PDCPPacketDelay();
-        resourceUsage = new ResourceUsage();
         timer = new Timer();
 
         type = Type.NON_SERVING;
 
         linkId = LinkId.valueOf(cell, ue);
 
+        quality = new LinkQuality();
+
         rrmParameters = new RRMConfig();
         RRMConfig.Crnti crnti = new RRMConfig.Crnti();
         crnti.addCRNTI(linkId.getUe().getRanId());
@@ -326,14 +322,227 @@
     }
 
     @JsonPropertyOrder({
+            "RX",
+            "CQI",
+            "MCS"
+    })
+    @JsonIgnoreProperties(ignoreUnknown = true)
+    public static class LinkQuality {
+        RX RX = null;
+        CQI CQI = null;
+        MCS MCS = null;
+
+        public LinkQuality.RX getRX() {
+            return RX;
+        }
+
+        public void setRX(LinkQuality.RX RX) {
+            this.RX = RX;
+        }
+
+        public LinkQuality.CQI getCQI() {
+            return CQI;
+        }
+
+        public void setCQI(LinkQuality.CQI CQI) {
+            this.CQI = CQI;
+        }
+
+        public LinkQuality.MCS getMCS() {
+            return MCS;
+        }
+
+        public void setMCS(LinkQuality.MCS MCS) {
+            this.MCS = MCS;
+        }
+
+        @JsonPropertyOrder({
+                "RSRP",
+                "RSRQ",
+                "timesincelastupdate"
+        })
+        @JsonIgnoreProperties(ignoreUnknown = true)
+        public static class RX {
+            double RSRP;
+            double RSRQ;
+            WallClockTimestamp timesincelastupdate;
+
+            @JsonCreator
+            public RX(@JsonProperty("RSRP") double RSRP, @JsonProperty("RSRQ") double RSRQ) {
+                this.RSRP = RSRP;
+                this.RSRQ = RSRQ;
+                this.timesincelastupdate = new WallClockTimestamp();
+            }
+
+            public double getRSRP() {
+                return RSRP;
+            }
+
+            public void setRSRP(double RSRP) {
+                this.RSRP = RSRP;
+            }
+
+            public double getRSRQ() {
+                return RSRQ;
+            }
+
+            public void setRSRQ(double RSRQ) {
+                this.RSRQ = RSRQ;
+            }
+
+            public long getTimesincelastupdate() {
+                return timesincelastupdate.unixTimestamp();
+            }
+
+            public void setTimesincelastupdate(WallClockTimestamp timesincelastupdate) {
+                this.timesincelastupdate = timesincelastupdate;
+            }
+
+            @Override
+            public String toString() {
+                return "RX{" +
+                        "RSRP=" + RSRP +
+                        ", RSRQ=" + RSRQ +
+                        ", timesincelastupdate=" + timesincelastupdate +
+                        '}';
+            }
+        }
+
+        @JsonPropertyOrder({
+                "Hist",
+                "Mode",
+                "Mean",
+                "timesincelastupdate"
+        })
+        @JsonIgnoreProperties(ignoreUnknown = true)
+        public static class CQI {
+            RadioRepPerServCell.CqiHist Hist;
+            double Mode;
+            double Mean;
+            WallClockTimestamp timesincelastupdate;
+
+            @JsonCreator
+            public CQI(@JsonProperty("Hist") RadioRepPerServCell.CqiHist hist, @JsonProperty("Mode") double mode, @JsonProperty("Mean") double mean) {
+                Hist = hist;
+                Mode = mode;
+                Mean = mean;
+                this.timesincelastupdate = new WallClockTimestamp();
+            }
+
+            public RadioRepPerServCell.CqiHist getHist() {
+                return Hist;
+            }
+
+            public void setHist(RadioRepPerServCell.CqiHist hist) {
+                Hist = hist;
+            }
+
+            public double getMode() {
+                return Mode;
+            }
+
+            public void setMode(double mode) {
+                Mode = mode;
+            }
+
+            public double getMean() {
+                return Mean;
+            }
+
+            public void setMean(double mean) {
+                Mean = mean;
+            }
+
+            public long getTimesincelastupdate() {
+                return timesincelastupdate.unixTimestamp();
+            }
+
+            public void setTimesincelastupdate(WallClockTimestamp timesincelastupdate) {
+                this.timesincelastupdate = timesincelastupdate;
+            }
+
+            @Override
+            public String toString() {
+                return "CQI{" +
+                        "Hist=" + Hist +
+                        ", Mode=" + Mode +
+                        ", Mean=" + Mean +
+                        ", timesincelastupdate=" + timesincelastupdate +
+                        '}';
+            }
+        }
+
+        @JsonPropertyOrder({
+                "dl",
+                "ul",
+                "timesincelastupdate"
+        })
+        @JsonIgnoreProperties(ignoreUnknown = true)
+        public static class MCS {
+            SchedMeasRepPerServCell.McsDl dl;
+            SchedMeasRepPerServCell.McsUl ul;
+            WallClockTimestamp timesincelastupdate;
+
+            @JsonCreator
+            public MCS(@JsonProperty("dl") SchedMeasRepPerServCell.McsDl dl, @JsonProperty("ul") SchedMeasRepPerServCell.McsUl ul) {
+                this.dl = dl;
+                this.ul = ul;
+                this.timesincelastupdate = new WallClockTimestamp();
+            }
+
+            public SchedMeasRepPerServCell.McsDl getDl() {
+                return dl;
+            }
+
+            public void setDl(SchedMeasRepPerServCell.McsDl dl) {
+                this.dl = dl;
+            }
+
+            public SchedMeasRepPerServCell.McsUl getUl() {
+                return ul;
+            }
+
+            public void setUl(SchedMeasRepPerServCell.McsUl ul) {
+                this.ul = ul;
+            }
+
+            public long getTimesincelastupdate() {
+                return timesincelastupdate.unixTimestamp();
+            }
+
+            public void setTimesincelastupdate(WallClockTimestamp timesincelastupdate) {
+                this.timesincelastupdate = timesincelastupdate;
+            }
+
+            @Override
+            public String toString() {
+                return "MCS{" +
+                        "dl=" + dl +
+                        ", ul=" + ul +
+                        ", timesincelastupdate=" + timesincelastupdate +
+                        '}';
+            }
+        }
+
+    }
+
+    @JsonPropertyOrder({
             "dl",
             "ul"
     })
     @JsonIgnoreProperties(ignoreUnknown = true)
-    public class PDCPThroughput {
+    public static class PDCPThroughput {
+        WallClockTimestamp timesincelastupdate;
         private PDCPMeasReportPerUe.ThroughputDl dl;
         private PDCPMeasReportPerUe.ThroughputUl ul;
 
+        @JsonCreator
+        public PDCPThroughput(@JsonProperty("dl") PDCPMeasReportPerUe.ThroughputDl dl, @JsonProperty("ul") PDCPMeasReportPerUe.ThroughputUl ul) {
+            this.dl = dl;
+            this.ul = ul;
+            this.timesincelastupdate = new WallClockTimestamp();
+        }
+
         public PDCPMeasReportPerUe.ThroughputDl getDl() {
             return dl;
         }
@@ -350,11 +559,21 @@
             this.ul = ul;
         }
 
+        public long getTimesincelastupdate() {
+            return timesincelastupdate.unixTimestamp();
+        }
+
+        public void setTimesincelastupdate(WallClockTimestamp timesincelastupdate) {
+            this.timesincelastupdate = timesincelastupdate;
+        }
+
         @Override
-        public String toString() {
+        public String
+        toString() {
             return "PDCPThroughput{" +
                     "dl=" + dl +
                     ", ul=" + ul +
+                    ", timesincelastupdate=" + timesincelastupdate +
                     '}';
         }
     }
@@ -364,9 +583,17 @@
             "ul"
     })
     @JsonIgnoreProperties(ignoreUnknown = true)
-    public class PDCPPacketDelay {
+    public static class PDCPPacketDelay {
         PDCPMeasReportPerUe.PktDelayDl dl;
         PDCPMeasReportPerUe.PktDelayUl ul;
+        WallClockTimestamp timesincelastupdate;
+
+        @JsonCreator
+        public PDCPPacketDelay(@JsonProperty("dl") PDCPMeasReportPerUe.PktDelayDl dl, @JsonProperty("ul") PDCPMeasReportPerUe.PktDelayUl ul) {
+            this.dl = dl;
+            this.ul = ul;
+            this.timesincelastupdate = new WallClockTimestamp();
+        }
 
         public PDCPMeasReportPerUe.PktDelayDl getDl() {
             return dl;
@@ -384,11 +611,20 @@
             this.ul = ul;
         }
 
+        public long getTimesincelastupdate() {
+            return timesincelastupdate.unixTimestamp();
+        }
+
+        public void setTimesincelastupdate(WallClockTimestamp timesincelastupdate) {
+            this.timesincelastupdate = timesincelastupdate;
+        }
+
         @Override
         public String toString() {
             return "PDCPPacketDelay{" +
                     "dl=" + dl +
                     ", ul=" + ul +
+                    ", timesincelastupdate=" + timesincelastupdate +
                     '}';
         }
     }
@@ -398,9 +634,17 @@
             "ul"
     })
     @JsonIgnoreProperties(ignoreUnknown = true)
-    public class ResourceUsage {
+    public static class ResourceUsage {
         PRBUsage.PrbUsageDl dl;
         PRBUsage.PrbUsageUl ul;
+        WallClockTimestamp timesincelastupdate;
+
+        @JsonCreator
+        public ResourceUsage(@JsonProperty("dl") PRBUsage.PrbUsageDl dl, @JsonProperty("ul") PRBUsage.PrbUsageUl ul) {
+            this.dl = dl;
+            this.ul = ul;
+            this.timesincelastupdate = new WallClockTimestamp();
+        }
 
         public PRBUsage.PrbUsageDl getDl() {
             return dl;
@@ -418,100 +662,20 @@
             this.ul = ul;
         }
 
+        public long getTimesincelastupdate() {
+            return timesincelastupdate.unixTimestamp();
+        }
+
+        public void setTimesincelastupdate(WallClockTimestamp timesincelastupdate) {
+            this.timesincelastupdate = timesincelastupdate;
+        }
+
         @Override
         public String toString() {
             return "ResourceUsage{" +
                     "dl=" + dl +
                     ", ul=" + ul +
-                    '}';
-        }
-    }
-
-    @JsonPropertyOrder({
-            "rsrp",
-            "rsrq",
-            "cqiHist",
-            "cqiMode",
-            "cqiMean",
-            "mcsDl",
-            "mcsUl"
-    })
-    @JsonIgnoreProperties(ignoreUnknown = true)
-    public class LinkQuality {
-        double rsrp;
-        double rsrq;
-        RadioRepPerServCell.CqiHist cqiHist;
-        double cqiMode;
-        double cqiMean;
-        SchedMeasRepPerServCell.McsDl mcsDl;
-        SchedMeasRepPerServCell.McsUl mcsUl;
-
-        public double getRsrp() {
-            return rsrp;
-        }
-
-        public void setRsrp(double rsrp) {
-            this.rsrp = rsrp;
-        }
-
-        public double getRsrq() {
-            return rsrq;
-        }
-
-        public void setRsrq(double rsrq) {
-            this.rsrq = rsrq;
-        }
-
-        public RadioRepPerServCell.CqiHist getCqiHist() {
-            return cqiHist;
-        }
-
-        public void setCqiHist(RadioRepPerServCell.CqiHist cqiHist) {
-            this.cqiHist = cqiHist;
-        }
-
-        public double getCqiMode() {
-            return cqiMode;
-        }
-
-        public void setCqiMode(double cqiMode) {
-            this.cqiMode = cqiMode;
-        }
-
-        public double getCqiMean() {
-            return cqiMean;
-        }
-
-        public void setCqiMean(double cqiMean) {
-            this.cqiMean = cqiMean;
-        }
-
-        public SchedMeasRepPerServCell.McsDl getMcsDl() {
-            return mcsDl;
-        }
-
-        public void setMcsDl(SchedMeasRepPerServCell.McsDl mcsDl) {
-            this.mcsDl = mcsDl;
-        }
-
-        public SchedMeasRepPerServCell.McsUl getMcsUl() {
-            return mcsUl;
-        }
-
-        public void setMcsUl(SchedMeasRepPerServCell.McsUl mcsUl) {
-            this.mcsUl = mcsUl;
-        }
-
-        @Override
-        public String toString() {
-            return "LinkQuality{" +
-                    "rsrp=" + rsrp +
-                    ", rsrq=" + rsrq +
-                    ", cqiHist=" + cqiHist +
-                    ", cqiMode=" + cqiMode +
-                    ", cqiMean=" + cqiMean +
-                    ", mcsDl=" + mcsDl +
-                    ", mcsUl=" + mcsUl +
+                    ", timesincelastupdate=" + timesincelastupdate +
                     '}';
         }
     }