From 7ec884b78c82afedb638d011ba31e928ab0e2b08 Mon Sep 17 00:00:00 2001
From: Gianpietro Lavado <glavado@whitestack.com>
Date: Wed, 27 May 2020 19:41:34 +0000
Subject: [PATCH] fixes to native charms and zeroMQ adoption

---
 .../charms/enodeb/actions.yaml                | 11 ++-
 .../charms/enodeb/src/charm.py                | 89 +++++++++++--------
 2 files changed, 64 insertions(+), 36 deletions(-)

diff --git a/magma/hackfest_magma-agw-enb_vnfd/charms/enodeb/actions.yaml b/magma/hackfest_magma-agw-enb_vnfd/charms/enodeb/actions.yaml
index c578a9c9..25cea587 100644
--- a/magma/hackfest_magma-agw-enb_vnfd/charms/enodeb/actions.yaml
+++ b/magma/hackfest_magma-agw-enb_vnfd/charms/enodeb/actions.yaml
@@ -17,6 +17,15 @@ register:
     - mme-addr
     - gtp-bind-addr
     - s1c-bind-addr
+kill-pid:
+  description: "Kill PID."
+  params:
+    pid:
+      description: "PID."
+      type: string
+      default: ""
+  required:
+    - pid
 attach-ue:
   description: Attach User Emulator to enodeB
   params:
@@ -35,4 +44,4 @@ attach-ue:
   required:
     - usim-imsi
     - usim-k
-    - usim-opc
+    - usim-opc
\ No newline at end of file
diff --git a/magma/hackfest_magma-agw-enb_vnfd/charms/enodeb/src/charm.py b/magma/hackfest_magma-agw-enb_vnfd/charms/enodeb/src/charm.py
index ab52f067..b113ac0c 100755
--- a/magma/hackfest_magma-agw-enb_vnfd/charms/enodeb/src/charm.py
+++ b/magma/hackfest_magma-agw-enb_vnfd/charms/enodeb/src/charm.py
@@ -12,11 +12,8 @@
 #     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 #     See the License for the specific language governing permissions and
 #     limitations under the License.
-
 import sys
-
 sys.path.append("lib")
-
 from ops.charm import CharmBase
 from ops.framework import StoredState
 from ops.main import main
@@ -28,21 +25,19 @@ from ops.model import (
     ModelError,
 )
 import subprocess
-
-
+import logging
+import asyncio
+import random
+logger = logging.getLogger(__name__)
 class EnodebCharm(CharmBase):
     state = StoredState()
-
     def __init__(self, *args):
         super().__init__(*args)
-
         # An example of setting charm state
         # that's persistent across events
         self.state.set_default(is_started=False)
-
         if not self.state.is_started:
             self.state.is_started = True
-
         # Register all of the events we want to observe
         for event in (
             # Charm events
@@ -51,81 +46,105 @@ class EnodebCharm(CharmBase):
             self.on.upgrade_charm,
             self.on.register_action,
             self.on.attach_ue_action,
+            self.on.kill_pid_action,
         ):
             self.framework.observe(event, self)
-
     def on_config_changed(self, event):
         """Handle changes in configuration"""
         unit = self.model.unit
-
     def on_install(self, event):
         """Called when the charm is being installed"""
         unit = self.model.unit
-
         # Install your software and its dependencies
-
         unit.status = ActiveStatus()
-
     def on_upgrade_charm(self, event):
         """Upgrade the charm."""
         unit = self.model.unit
-
         # Mark the unit as under Maintenance.
         unit.status = MaintenanceStatus("Upgrading charm")
-
         self.on_install(event)
-
         # When maintenance is done, return to an Active state
         unit.status = ActiveStatus()
-
     def on_register_action(self, event):
         """Register to AGW (EPC)."""
         try:
             mme_addr = event.params["mme-addr"]
             gtp_bind_addr = event.params["gtp-bind-addr"]
             s1c_bind_addr = event.params["s1c-bind-addr"]
+            log_file = "/tmp/{}.log".format(random.randint(1000, 100000))
             command = " ".join(
                 [
-                    "srsenb",
+                    "/home/ubuntu/srsLTE/build/srsenb/src/srsenb",
                     "--enb.name=dummyENB01",
                     "--enb.mcc=901",
                     "--enb.mnc=70",
                     "--enb.mme_addr={}".format(mme_addr),
                     "--enb.gtp_bind_addr={}".format(gtp_bind_addr),
                     "--enb.s1c_bind_addr={}".format(s1c_bind_addr),
-                    "--enb_files.rr_config=/config/rr.conf",
-                    "--enb_files.sib_config=/config/sib.conf",
-                    "--enb_files.drb_config=/config/drb.conf",
-                    "/config/enb.conf.fauxrf",
+                    "--enb_files.rr_config=/configzmq/rr.conf",
+                    "--enb_files.sib_config=/configzmq/sib.conf",
+                    "--enb_files.drb_config=/configzmq/drb.conf",
+                    "/configzmq/enb.conf",
+                    "--rf.device_name=zmq",
+                    "--rf.device_args='fail_on_disconnect=true,tx_port=tcp://*:2000,rx_port=tcp://localhost:2001,id=enb,base_srate=23.04e6'"
                 ]
             )
-            stdout = subprocess.check_output(command, shell=True)
-            event.set_results({"output": stdout})
-        except subprocess.CalledProcessError as ex:
-            event.fail(ex)
-
+            logger.debug("Register action: executing")
+            process = self._run_daemon(command, log_file)
+            logger.debug("Register action: executed")
+            event.set_results(
+                {"status": "ok", "pid": process.pid, "log_file": log_file}
+            )
+        except subprocess.CalledProcessError as e:
+            event.fail("Command error: {}".format(e.output))
+        except asyncio.TimeoutError as e:
+            event.fail("Timeout error")
+        except Exception as e:
+            event.fail(e)
+    def on_kill_pid_action(self, event):
+        """Kill PID"""
+        try:
+            pid = event.params["pid"]
+            command = "kill -9 {}".format(pid)
+            subprocess.check_output(command, shell=True)
+            event.set_results(
+                {"status": "ok", "pid": pid, "message": "PID {} killed".format(pid)}
+            )
+        except subprocess.CalledProcessError as e:
+            event.fail("Command error: {}".format(e.output))
+        except Exception as e:
+            event.fail(e)
+    def _run_daemon(self, cmd, stdout_file):
+        with open(stdout_file, "wb") as f:
+            return subprocess.Popen(cmd, shell=True, stdout=f)
     def on_attach_ue_action(self, event):
         """Attach User Emulator to EnodeB."""
         try:
             usim_imsi = event.params["usim-imsi"]
             usim_k = event.params["usim-k"]
             usim_opc = event.params["usim-opc"]
+            log_file = "/tmp/{}.log".format(random.randint(1000, 100000))
             command = " ".join(
                 [
-                    "srsue",
+                    "sudo",
+                    "/home/ubuntu/srsLTE/build/srsue/src/srsue",
                     "--usim.imsi={}".format(usim_imsi),
                     "--usim.k={}".format(usim_k),
                     "--usim.algo=milenage",
                     "--usim.opc={}".format(usim_opc),
                     "--nas.apn=oai.ipv4",
-                    "/config/ue.conf.fauxrf",
+                    "--rf.device_name=zmq",
+                    "--rf.device_args='tx_port=tcp://*:2001,rx_port=tcp://localhost:2000,id=ue,base_srate=23.04e6'",
+                    "/configzmq/ue.conf"
                 ]
             )
-            stdout = subprocess.check_output(command, shell=True)
-            event.set_results({"output": stdout})
+            logger.debug("Attach UE action: executing")
+            process = self._run_daemon(command, log_file)
+            logger.debug("Attach UE action: executed")
+            event.set_results(
+                {"status": "ok", "pid": process.pid, "log_file": log_file}
+            )
         except subprocess.CalledProcessError as ex:
             event.fail(ex)
-
-
 if __name__ == "__main__":
-    main(EnodebCharm)
+    main(EnodebCharm)
\ No newline at end of file
-- 
GitLab